diff options
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 161 |
1 files changed, 90 insertions, 71 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index aea0cb72d80a..ab099f482487 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <sound/soc.h> | 45 | #include <sound/soc.h> |
46 | #include <sound/soc-dapm.h> | 46 | #include <sound/soc-dapm.h> |
47 | #include <sound/initval.h> | 47 | #include <sound/initval.h> |
48 | #include <sound/tlv.h> | ||
48 | 49 | ||
49 | #include "tlv320aic3x.h" | 50 | #include "tlv320aic3x.h" |
50 | 51 | ||
@@ -250,56 +251,86 @@ static const struct soc_enum aic3x_enum[] = { | |||
250 | SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), | 251 | SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), |
251 | }; | 252 | }; |
252 | 253 | ||
254 | /* | ||
255 | * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps | ||
256 | */ | ||
257 | static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0); | ||
258 | /* ADC PGA gain volumes. From 0 to 59.5 dB in 0.5 dB steps */ | ||
259 | static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0); | ||
260 | /* | ||
261 | * Output stage volumes. From -78.3 to 0 dB. Muted below -78.3 dB. | ||
262 | * Step size is approximately 0.5 dB over most of the scale but increasing | ||
263 | * near the very low levels. | ||
264 | * Define dB scale so that it is mostly correct for range about -55 to 0 dB | ||
265 | * but having increasing dB difference below that (and where it doesn't count | ||
266 | * so much). This setting shows -50 dB (actual is -50.3 dB) for register | ||
267 | * value 100 and -58.5 dB (actual is -78.3 dB) for register value 117. | ||
268 | */ | ||
269 | static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1); | ||
270 | |||
253 | static const struct snd_kcontrol_new aic3x_snd_controls[] = { | 271 | static const struct snd_kcontrol_new aic3x_snd_controls[] = { |
254 | /* Output */ | 272 | /* Output */ |
255 | SOC_DOUBLE_R("PCM Playback Volume", LDAC_VOL, RDAC_VOL, 0, 0x7f, 1), | 273 | SOC_DOUBLE_R_TLV("PCM Playback Volume", |
274 | LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv), | ||
256 | 275 | ||
257 | SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL, | 276 | SOC_DOUBLE_R_TLV("Line DAC Playback Volume", |
258 | DACR1_2_RLOPM_VOL, 0, 0x7f, 1), | 277 | DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL, |
278 | 0, 118, 1, output_stage_tlv), | ||
259 | SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0), | 279 | SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0), |
260 | SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0), | 280 | SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0), |
261 | SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL, | 281 | SOC_DOUBLE_R_TLV("LineL DAC Playback Volume", |
262 | DACR1_2_LLOPM_VOL, 0, 0x7f, 1), | 282 | DACL1_2_LLOPM_VOL, DACR1_2_LLOPM_VOL, |
263 | SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL, | 283 | 0, 118, 1, output_stage_tlv), |
264 | 0, 0x7f, 1), | 284 | SOC_SINGLE_TLV("LineL Left PGA Bypass Playback Volume", |
265 | SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL, | 285 | PGAL_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), |
266 | 0, 0x7f, 1), | 286 | SOC_SINGLE_TLV("LineR Right PGA Bypass Playback Volume", |
267 | SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL, | 287 | PGAR_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), |
268 | LINE2R_2_LLOPM_VOL, 0, 0x7f, 1), | 288 | SOC_DOUBLE_R_TLV("LineL Line2 Bypass Playback Volume", |
269 | SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL, | 289 | LINE2L_2_LLOPM_VOL, LINE2R_2_LLOPM_VOL, |
270 | LINE2R_2_RLOPM_VOL, 0, 0x7f, 1), | 290 | 0, 118, 1, output_stage_tlv), |
271 | 291 | SOC_DOUBLE_R_TLV("LineR Line2 Bypass Playback Volume", | |
272 | SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL, | 292 | LINE2L_2_RLOPM_VOL, LINE2R_2_RLOPM_VOL, |
273 | DACR1_2_MONOLOPM_VOL, 0, 0x7f, 1), | 293 | 0, 118, 1, output_stage_tlv), |
294 | |||
295 | SOC_DOUBLE_R_TLV("Mono DAC Playback Volume", | ||
296 | DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL, | ||
297 | 0, 118, 1, output_stage_tlv), | ||
274 | SOC_SINGLE("Mono DAC Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), | 298 | SOC_SINGLE("Mono DAC Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), |
275 | SOC_DOUBLE_R("Mono PGA Bypass Playback Volume", PGAL_2_MONOLOPM_VOL, | 299 | SOC_DOUBLE_R_TLV("Mono PGA Bypass Playback Volume", |
276 | PGAR_2_MONOLOPM_VOL, 0, 0x7f, 1), | 300 | PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL, |
277 | SOC_DOUBLE_R("Mono Line2 Bypass Playback Volume", LINE2L_2_MONOLOPM_VOL, | 301 | 0, 118, 1, output_stage_tlv), |
278 | LINE2R_2_MONOLOPM_VOL, 0, 0x7f, 1), | 302 | SOC_DOUBLE_R_TLV("Mono Line2 Bypass Playback Volume", |
279 | 303 | LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, | |
280 | SOC_DOUBLE_R("HP DAC Playback Volume", DACL1_2_HPLOUT_VOL, | 304 | 0, 118, 1, output_stage_tlv), |
281 | DACR1_2_HPROUT_VOL, 0, 0x7f, 1), | 305 | |
306 | SOC_DOUBLE_R_TLV("HP DAC Playback Volume", | ||
307 | DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL, | ||
308 | 0, 118, 1, output_stage_tlv), | ||
282 | SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, | 309 | SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, |
283 | 0x01, 0), | 310 | 0x01, 0), |
284 | SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL, | 311 | SOC_DOUBLE_R_TLV("HP Right PGA Bypass Playback Volume", |
285 | PGAR_2_HPROUT_VOL, 0, 0x7f, 1), | 312 | PGAR_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL, |
286 | SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL, | 313 | 0, 118, 1, output_stage_tlv), |
287 | 0, 0x7f, 1), | 314 | SOC_SINGLE_TLV("HPL PGA Bypass Playback Volume", |
288 | SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL, | 315 | PGAL_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), |
289 | 0, 0x7f, 1), | 316 | SOC_SINGLE_TLV("HPR PGA Bypass Playback Volume", |
290 | SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL, | 317 | PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), |
291 | LINE2R_2_HPROUT_VOL, 0, 0x7f, 1), | 318 | SOC_DOUBLE_R_TLV("HP Line2 Bypass Playback Volume", |
292 | 319 | LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL, | |
293 | SOC_DOUBLE_R("HPCOM DAC Playback Volume", DACL1_2_HPLCOM_VOL, | 320 | 0, 118, 1, output_stage_tlv), |
294 | DACR1_2_HPRCOM_VOL, 0, 0x7f, 1), | 321 | |
322 | SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume", | ||
323 | DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL, | ||
324 | 0, 118, 1, output_stage_tlv), | ||
295 | SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, | 325 | SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, |
296 | 0x01, 0), | 326 | 0x01, 0), |
297 | SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL, | 327 | SOC_SINGLE_TLV("HPLCOM PGA Bypass Playback Volume", |
298 | 0, 0x7f, 1), | 328 | PGAL_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), |
299 | SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL, | 329 | SOC_SINGLE_TLV("HPRCOM PGA Bypass Playback Volume", |
300 | 0, 0x7f, 1), | 330 | PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), |
301 | SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL, | 331 | SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Playback Volume", |
302 | LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1), | 332 | LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL, |
333 | 0, 118, 1, output_stage_tlv), | ||
303 | 334 | ||
304 | /* | 335 | /* |
305 | * Note: enable Automatic input Gain Controller with care. It can | 336 | * Note: enable Automatic input Gain Controller with care. It can |
@@ -308,28 +339,13 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
308 | SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), | 339 | SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), |
309 | 340 | ||
310 | /* Input */ | 341 | /* Input */ |
311 | SOC_DOUBLE_R("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x7f, 0), | 342 | SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL, |
343 | 0, 119, 0, adc_tlv), | ||
312 | SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), | 344 | SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), |
313 | 345 | ||
314 | SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), | 346 | SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), |
315 | }; | 347 | }; |
316 | 348 | ||
317 | /* add non dapm controls */ | ||
318 | static int aic3x_add_controls(struct snd_soc_codec *codec) | ||
319 | { | ||
320 | int err, i; | ||
321 | |||
322 | for (i = 0; i < ARRAY_SIZE(aic3x_snd_controls); i++) { | ||
323 | err = snd_ctl_add(codec->card, | ||
324 | snd_soc_cnew(&aic3x_snd_controls[i], | ||
325 | codec, NULL)); | ||
326 | if (err < 0) | ||
327 | return err; | ||
328 | } | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* Left DAC Mux */ | 349 | /* Left DAC Mux */ |
334 | static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = | 350 | static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = |
335 | SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); | 351 | SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); |
@@ -746,7 +762,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, | |||
746 | { | 762 | { |
747 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 763 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
748 | struct snd_soc_device *socdev = rtd->socdev; | 764 | struct snd_soc_device *socdev = rtd->socdev; |
749 | struct snd_soc_codec *codec = socdev->codec; | 765 | struct snd_soc_codec *codec = socdev->card->codec; |
750 | struct aic3x_priv *aic3x = codec->private_data; | 766 | struct aic3x_priv *aic3x = codec->private_data; |
751 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; | 767 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; |
752 | u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; | 768 | u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; |
@@ -1072,6 +1088,13 @@ EXPORT_SYMBOL_GPL(aic3x_button_pressed); | |||
1072 | #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 1088 | #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1073 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) | 1089 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) |
1074 | 1090 | ||
1091 | static struct snd_soc_dai_ops aic3x_dai_ops = { | ||
1092 | .hw_params = aic3x_hw_params, | ||
1093 | .digital_mute = aic3x_mute, | ||
1094 | .set_sysclk = aic3x_set_dai_sysclk, | ||
1095 | .set_fmt = aic3x_set_dai_fmt, | ||
1096 | }; | ||
1097 | |||
1075 | struct snd_soc_dai aic3x_dai = { | 1098 | struct snd_soc_dai aic3x_dai = { |
1076 | .name = "tlv320aic3x", | 1099 | .name = "tlv320aic3x", |
1077 | .playback = { | 1100 | .playback = { |
@@ -1086,19 +1109,14 @@ struct snd_soc_dai aic3x_dai = { | |||
1086 | .channels_max = 2, | 1109 | .channels_max = 2, |
1087 | .rates = AIC3X_RATES, | 1110 | .rates = AIC3X_RATES, |
1088 | .formats = AIC3X_FORMATS,}, | 1111 | .formats = AIC3X_FORMATS,}, |
1089 | .ops = { | 1112 | .ops = &aic3x_dai_ops, |
1090 | .hw_params = aic3x_hw_params, | ||
1091 | .digital_mute = aic3x_mute, | ||
1092 | .set_sysclk = aic3x_set_dai_sysclk, | ||
1093 | .set_fmt = aic3x_set_dai_fmt, | ||
1094 | } | ||
1095 | }; | 1113 | }; |
1096 | EXPORT_SYMBOL_GPL(aic3x_dai); | 1114 | EXPORT_SYMBOL_GPL(aic3x_dai); |
1097 | 1115 | ||
1098 | static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) | 1116 | static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) |
1099 | { | 1117 | { |
1100 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1118 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1101 | struct snd_soc_codec *codec = socdev->codec; | 1119 | struct snd_soc_codec *codec = socdev->card->codec; |
1102 | 1120 | ||
1103 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1121 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1104 | 1122 | ||
@@ -1108,7 +1126,7 @@ static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) | |||
1108 | static int aic3x_resume(struct platform_device *pdev) | 1126 | static int aic3x_resume(struct platform_device *pdev) |
1109 | { | 1127 | { |
1110 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1128 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1111 | struct snd_soc_codec *codec = socdev->codec; | 1129 | struct snd_soc_codec *codec = socdev->card->codec; |
1112 | int i; | 1130 | int i; |
1113 | u8 data[2]; | 1131 | u8 data[2]; |
1114 | u8 *cache = codec->reg_cache; | 1132 | u8 *cache = codec->reg_cache; |
@@ -1131,7 +1149,7 @@ static int aic3x_resume(struct platform_device *pdev) | |||
1131 | */ | 1149 | */ |
1132 | static int aic3x_init(struct snd_soc_device *socdev) | 1150 | static int aic3x_init(struct snd_soc_device *socdev) |
1133 | { | 1151 | { |
1134 | struct snd_soc_codec *codec = socdev->codec; | 1152 | struct snd_soc_codec *codec = socdev->card->codec; |
1135 | struct aic3x_setup_data *setup = socdev->codec_data; | 1153 | struct aic3x_setup_data *setup = socdev->codec_data; |
1136 | int reg, ret = 0; | 1154 | int reg, ret = 0; |
1137 | 1155 | ||
@@ -1227,7 +1245,8 @@ static int aic3x_init(struct snd_soc_device *socdev) | |||
1227 | aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); | 1245 | aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); |
1228 | aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); | 1246 | aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); |
1229 | 1247 | ||
1230 | aic3x_add_controls(codec); | 1248 | snd_soc_add_controls(codec, aic3x_snd_controls, |
1249 | ARRAY_SIZE(aic3x_snd_controls)); | ||
1231 | aic3x_add_widgets(codec); | 1250 | aic3x_add_widgets(codec); |
1232 | ret = snd_soc_init_card(socdev); | 1251 | ret = snd_soc_init_card(socdev); |
1233 | if (ret < 0) { | 1252 | if (ret < 0) { |
@@ -1261,7 +1280,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1261 | const struct i2c_device_id *id) | 1280 | const struct i2c_device_id *id) |
1262 | { | 1281 | { |
1263 | struct snd_soc_device *socdev = aic3x_socdev; | 1282 | struct snd_soc_device *socdev = aic3x_socdev; |
1264 | struct snd_soc_codec *codec = socdev->codec; | 1283 | struct snd_soc_codec *codec = socdev->card->codec; |
1265 | int ret; | 1284 | int ret; |
1266 | 1285 | ||
1267 | i2c_set_clientdata(i2c, codec); | 1286 | i2c_set_clientdata(i2c, codec); |
@@ -1366,7 +1385,7 @@ static int aic3x_probe(struct platform_device *pdev) | |||
1366 | } | 1385 | } |
1367 | 1386 | ||
1368 | codec->private_data = aic3x; | 1387 | codec->private_data = aic3x; |
1369 | socdev->codec = codec; | 1388 | socdev->card->codec = codec; |
1370 | mutex_init(&codec->mutex); | 1389 | mutex_init(&codec->mutex); |
1371 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1390 | INIT_LIST_HEAD(&codec->dapm_widgets); |
1372 | INIT_LIST_HEAD(&codec->dapm_paths); | 1391 | INIT_LIST_HEAD(&codec->dapm_paths); |
@@ -1392,7 +1411,7 @@ static int aic3x_probe(struct platform_device *pdev) | |||
1392 | static int aic3x_remove(struct platform_device *pdev) | 1411 | static int aic3x_remove(struct platform_device *pdev) |
1393 | { | 1412 | { |
1394 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1413 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1395 | struct snd_soc_codec *codec = socdev->codec; | 1414 | struct snd_soc_codec *codec = socdev->card->codec; |
1396 | 1415 | ||
1397 | /* power down chip */ | 1416 | /* power down chip */ |
1398 | if (codec->control_data) | 1417 | if (codec->control_data) |