Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Side by Side Diff: sound/soc/codecs/88pm860x-codec.c

Issue 6577007: CHROMIUM: ASoC: Import entire upstream ASoC tree (Closed)
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sound/soc/blackfin/bf5xx-tdm.c ('k') | sound/soc/codecs/Kconfig » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * 88pm860x-codec.c -- 88PM860x ALSA SoC Audio Driver 2 * 88pm860x-codec.c -- 88PM860x ALSA SoC Audio Driver
3 * 3 *
4 * Copyright 2010 Marvell International Ltd. 4 * Copyright 2010 Marvell International Ltd.
5 * Author: Haojian Zhuang <haojian.zhuang@marvell.com> 5 * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12 #include <linux/kernel.h> 12 #include <linux/kernel.h>
13 #include <linux/module.h> 13 #include <linux/module.h>
14 #include <linux/i2c.h> 14 #include <linux/i2c.h>
15 #include <linux/platform_device.h> 15 #include <linux/platform_device.h>
16 #include <linux/mfd/88pm860x.h> 16 #include <linux/mfd/88pm860x.h>
17 #include <linux/slab.h> 17 #include <linux/slab.h>
18 #include <sound/core.h> 18 #include <sound/core.h>
19 #include <sound/pcm.h> 19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h> 20 #include <sound/pcm_params.h>
21 #include <sound/soc.h> 21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/tlv.h> 22 #include <sound/tlv.h>
24 #include <sound/initval.h> 23 #include <sound/initval.h>
25 #include <sound/jack.h> 24 #include <sound/jack.h>
25 #include <trace/events/asoc.h>
26 26
27 #include "88pm860x-codec.h" 27 #include "88pm860x-codec.h"
28 28
29 #define MAX_NAME_LEN 20 29 #define MAX_NAME_LEN 20
30 #define REG_CACHE_SIZE 0x40 30 #define REG_CACHE_SIZE 0x40
31 #define REG_CACHE_BASE 0xb0 31 #define REG_CACHE_BASE 0xb0
32 32
33 /* Status Register 1 (0x01) */ 33 /* Status Register 1 (0x01) */
34 #define REG_STATUS_1 0x01 34 #define REG_STATUS_1 0x01
35 #define MIC_STATUS (1 << 7) 35 #define MIC_STATUS (1 << 7)
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 unsigned int pcmclk; 139 unsigned int pcmclk;
140 unsigned int dir; 140 unsigned int dir;
141 unsigned int filter; 141 unsigned int filter;
142 struct snd_soc_codec *codec; 142 struct snd_soc_codec *codec;
143 struct i2c_client *i2c; 143 struct i2c_client *i2c;
144 struct pm860x_chip *chip; 144 struct pm860x_chip *chip;
145 struct pm860x_det det; 145 struct pm860x_det det;
146 146
147 int irq[4]; 147 int irq[4];
148 unsigned char name[4][MAX_NAME_LEN]; 148 unsigned char name[4][MAX_NAME_LEN];
149 unsigned char reg_cache[REG_CACHE_SIZE];
150 }; 149 };
151 150
152 /* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */ 151 /* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */
153 static const DECLARE_TLV_DB_SCALE(dpga_tlv, -9450, 150, 1); 152 static const DECLARE_TLV_DB_SCALE(dpga_tlv, -9450, 150, 1);
154 153
155 /* -9dB to 0db in 3dB steps */ 154 /* -9dB to 0db in 3dB steps */
156 static const DECLARE_TLV_DB_SCALE(adc_tlv, -900, 300, 0); 155 static const DECLARE_TLV_DB_SCALE(adc_tlv, -900, 300, 0);
157 156
158 /* {-23, -17, -13.5, -11, -9, -6, -3, 0}dB */ 157 /* {-23, -17, -13.5, -11, -9, -6, -3, 0}dB */
159 static const unsigned int mic_tlv[] = { 158 static const unsigned int mic_tlv[] = {
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 int data; 1164 int data;
1166 1165
1167 switch (level) { 1166 switch (level) {
1168 case SND_SOC_BIAS_ON: 1167 case SND_SOC_BIAS_ON:
1169 break; 1168 break;
1170 1169
1171 case SND_SOC_BIAS_PREPARE: 1170 case SND_SOC_BIAS_PREPARE:
1172 break; 1171 break;
1173 1172
1174 case SND_SOC_BIAS_STANDBY: 1173 case SND_SOC_BIAS_STANDBY:
1175 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { 1174 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1176 /* Enable Audio PLL & Audio section */ 1175 /* Enable Audio PLL & Audio section */
1177 data = AUDIO_PLL | AUDIO_SECTION_RESET 1176 data = AUDIO_PLL | AUDIO_SECTION_RESET
1178 | AUDIO_SECTION_ON; 1177 | AUDIO_SECTION_ON;
1179 pm860x_reg_write(codec->control_data, REG_MISC2, data); 1178 pm860x_reg_write(codec->control_data, REG_MISC2, data);
1180 } 1179 }
1181 break; 1180 break;
1182 1181
1183 case SND_SOC_BIAS_OFF: 1182 case SND_SOC_BIAS_OFF:
1184 data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON; 1183 data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON;
1185 pm860x_set_bits(codec->control_data, REG_MISC2, data, 0); 1184 pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
1186 break; 1185 break;
1187 } 1186 }
1188 » codec->bias_level = level; 1187 » codec->dapm.bias_level = level;
1189 return 0; 1188 return 0;
1190 } 1189 }
1191 1190
1192 static struct snd_soc_dai_ops pm860x_pcm_dai_ops = { 1191 static struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
1193 .digital_mute = pm860x_digital_mute, 1192 .digital_mute = pm860x_digital_mute,
1194 .hw_params = pm860x_pcm_hw_params, 1193 .hw_params = pm860x_pcm_hw_params,
1195 .set_fmt = pm860x_pcm_set_dai_fmt, 1194 .set_fmt = pm860x_pcm_set_dai_fmt,
1196 .set_sysclk = pm860x_set_dai_sysclk, 1195 .set_sysclk = pm860x_set_dai_sysclk,
1197 }; 1196 };
1198 1197
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 { 1255 {
1257 struct pm860x_priv *pm860x = data; 1256 struct pm860x_priv *pm860x = data;
1258 int status, shrt, report = 0, mic_report = 0; 1257 int status, shrt, report = 0, mic_report = 0;
1259 int mask; 1258 int mask;
1260 1259
1261 status = pm860x_reg_read(pm860x->i2c, REG_STATUS_1); 1260 status = pm860x_reg_read(pm860x->i2c, REG_STATUS_1);
1262 shrt = pm860x_reg_read(pm860x->i2c, REG_SHORTS); 1261 shrt = pm860x_reg_read(pm860x->i2c, REG_SHORTS);
1263 mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt 1262 mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt
1264 | pm860x->det.hp_det; 1263 | pm860x->det.hp_det;
1265 1264
1265 #ifndef CONFIG_SND_SOC_88PM860X_MODULE
1266 if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
1267 SHORT_LO1 | SHORT_LO2))
1268 trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
1269 #endif
1270
1266 if ((pm860x->det.hp_det & SND_JACK_HEADPHONE) 1271 if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
1267 && (status & HEADSET_STATUS)) 1272 && (status & HEADSET_STATUS))
1268 report |= SND_JACK_HEADPHONE; 1273 report |= SND_JACK_HEADPHONE;
1269 1274
1270 if ((pm860x->det.mic_det & SND_JACK_MICROPHONE) 1275 if ((pm860x->det.mic_det & SND_JACK_MICROPHONE)
1271 && (status & MIC_STATUS)) 1276 && (status & MIC_STATUS))
1272 mic_report |= SND_JACK_MICROPHONE; 1277 mic_report |= SND_JACK_MICROPHONE;
1273 1278
1274 if (pm860x->det.hs_shrt && (shrt & (SHORT_HS1 | SHORT_HS2))) 1279 if (pm860x->det.hs_shrt && (shrt & (SHORT_HS1 | SHORT_HS2)))
1275 report |= pm860x->det.hs_shrt; 1280 report |= pm860x->det.hs_shrt;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 1344
1340 /* sync status */ 1345 /* sync status */
1341 pm860x_codec_handler(0, pm860x); 1346 pm860x_codec_handler(0, pm860x);
1342 return 0; 1347 return 0;
1343 } 1348 }
1344 EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect); 1349 EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
1345 1350
1346 static int pm860x_probe(struct snd_soc_codec *codec) 1351 static int pm860x_probe(struct snd_soc_codec *codec)
1347 { 1352 {
1348 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); 1353 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1354 struct snd_soc_dapm_context *dapm = &codec->dapm;
1349 int i, ret; 1355 int i, ret;
1350 1356
1351 pm860x->codec = codec; 1357 pm860x->codec = codec;
1352 1358
1353 codec->control_data = pm860x->i2c; 1359 codec->control_data = pm860x->i2c;
1354 1360
1355 for (i = 0; i < 4; i++) { 1361 for (i = 0; i < 4; i++) {
1356 ret = request_threaded_irq(pm860x->irq[i], NULL, 1362 ret = request_threaded_irq(pm860x->irq[i], NULL,
1357 pm860x_codec_handler, IRQF_ONESHOT, 1363 pm860x_codec_handler, IRQF_ONESHOT,
1358 pm860x->name[i], pm860x); 1364 pm860x->name[i], pm860x);
1359 if (ret < 0) { 1365 if (ret < 0) {
1360 dev_err(codec->dev, "Failed to request IRQ!\n"); 1366 dev_err(codec->dev, "Failed to request IRQ!\n");
1361 » » » goto out_irq; 1367 » » » goto out;
1362 } 1368 }
1363 } 1369 }
1364 1370
1365 pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1371 pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1366 1372
1367 ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE, 1373 ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE,
1368 REG_CACHE_SIZE, codec->reg_cache); 1374 REG_CACHE_SIZE, codec->reg_cache);
1369 if (ret < 0) { 1375 if (ret < 0) {
1370 dev_err(codec->dev, "Failed to fill register cache: %d\n", 1376 dev_err(codec->dev, "Failed to fill register cache: %d\n",
1371 ret); 1377 ret);
1372 » » goto out_codec; 1378 » » goto out;
1373 } 1379 }
1374 1380
1375 snd_soc_add_controls(codec, pm860x_snd_controls, 1381 snd_soc_add_controls(codec, pm860x_snd_controls,
1376 ARRAY_SIZE(pm860x_snd_controls)); 1382 ARRAY_SIZE(pm860x_snd_controls));
1377 » snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets, 1383 » snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
1378 ARRAY_SIZE(pm860x_dapm_widgets)); 1384 ARRAY_SIZE(pm860x_dapm_widgets));
1379 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 1385 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1380 return 0; 1386 return 0;
1381 1387
1382 out_codec: 1388 out:
1383 » i = 3; 1389 » while (--i >= 0)
1384 out_irq:
1385 » for (; i >= 0; i--)
1386 free_irq(pm860x->irq[i], pm860x); 1390 free_irq(pm860x->irq[i], pm860x);
1387 » return -EINVAL; 1391 » return ret;
1388 } 1392 }
1389 1393
1390 static int pm860x_remove(struct snd_soc_codec *codec) 1394 static int pm860x_remove(struct snd_soc_codec *codec)
1391 { 1395 {
1392 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); 1396 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1393 int i; 1397 int i;
1394 1398
1395 for (i = 3; i >= 0; i--) 1399 for (i = 3; i >= 0; i--)
1396 free_irq(pm860x->irq[i], pm860x); 1400 free_irq(pm860x->irq[i], pm860x);
1397 pm860x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1401 pm860x_set_bias_level(codec, SND_SOC_BIAS_OFF);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 { 1481 {
1478 platform_driver_unregister(&pm860x_codec_driver); 1482 platform_driver_unregister(&pm860x_codec_driver);
1479 } 1483 }
1480 module_exit(pm860x_exit); 1484 module_exit(pm860x_exit);
1481 1485
1482 MODULE_DESCRIPTION("ASoC 88PM860x driver"); 1486 MODULE_DESCRIPTION("ASoC 88PM860x driver");
1483 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 1487 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
1484 MODULE_LICENSE("GPL"); 1488 MODULE_LICENSE("GPL");
1485 MODULE_ALIAS("platform:88pm860x-codec"); 1489 MODULE_ALIAS("platform:88pm860x-codec");
1486 1490
OLDNEW
« no previous file with comments | « sound/soc/blackfin/bf5xx-tdm.c ('k') | sound/soc/codecs/Kconfig » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698