aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8903.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r--sound/soc/codecs/wm8903.c222
1 files changed, 114 insertions, 108 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 622b60238a82..987476a5895f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -29,9 +29,9 @@
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 32#include <sound/initval.h>
34#include <sound/wm8903.h> 33#include <sound/wm8903.h>
34#include <trace/events/asoc.h>
35 35
36#include "wm8903.h" 36#include "wm8903.h"
37 37
@@ -214,15 +214,14 @@ static u16 wm8903_reg_defaults[] = {
214 214
215struct wm8903_priv { 215struct wm8903_priv {
216 216
217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
218
219 int sysclk; 217 int sysclk;
220 int irq; 218 int irq;
221 219
222 /* Reference counts */ 220 int fs;
221 int deemph;
222
223 /* Reference count */
223 int class_w_users; 224 int class_w_users;
224 int playback_active;
225 int capture_active;
226 225
227 struct completion wseq; 226 struct completion wseq;
228 227
@@ -231,9 +230,6 @@ struct wm8903_priv {
231 int mic_short; 230 int mic_short;
232 int mic_last_report; 231 int mic_last_report;
233 int mic_delay; 232 int mic_delay;
234
235 struct snd_pcm_substream *master_substream;
236 struct snd_pcm_substream *slave_substream;
237}; 233};
238 234
239static int wm8903_volatile_register(unsigned int reg) 235static int wm8903_volatile_register(unsigned int reg)
@@ -463,6 +459,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
463 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 459 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
464 460
465 461
462static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
463
464static int wm8903_set_deemph(struct snd_soc_codec *codec)
465{
466 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
467 int val, i, best;
468
469 /* If we're using deemphasis select the nearest available sample
470 * rate.
471 */
472 if (wm8903->deemph) {
473 best = 1;
474 for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
475 if (abs(wm8903_deemph[i] - wm8903->fs) <
476 abs(wm8903_deemph[best] - wm8903->fs))
477 best = i;
478 }
479
480 val = best << WM8903_DEEMPH_SHIFT;
481 } else {
482 best = 0;
483 val = 0;
484 }
485
486 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
487 best, wm8903_deemph[best]);
488
489 return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
490 WM8903_DEEMPH_MASK, val);
491}
492
493static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495{
496 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
497 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
498
499 ucontrol->value.enumerated.item[0] = wm8903->deemph;
500
501 return 0;
502}
503
504static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_value *ucontrol)
506{
507 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
509 int deemph = ucontrol->value.enumerated.item[0];
510 int ret = 0;
511
512 if (deemph > 1)
513 return -EINVAL;
514
515 mutex_lock(&codec->mutex);
516 if (wm8903->deemph != deemph) {
517 wm8903->deemph = deemph;
518
519 wm8903_set_deemph(codec);
520
521 ret = 1;
522 }
523 mutex_unlock(&codec->mutex);
524
525 return ret;
526}
527
466/* ALSA can only do steps of .01dB */ 528/* ALSA can only do steps of .01dB */
467static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 529static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
468 530
@@ -475,6 +537,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
475static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); 537static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
476static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); 538static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
477 539
540static const char *hpf_mode_text[] = {
541 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
542};
543
544static const struct soc_enum hpf_mode =
545 SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
546
547static const char *osr_text[] = {
548 "Low power", "High performance"
549};
550
551static const struct soc_enum adc_osr =
552 SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);
553
554static const struct soc_enum dac_osr =
555 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);
556
478static const char *drc_slope_text[] = { 557static const char *drc_slope_text[] = {
479 "1", "1/2", "1/4", "1/8", "1/16", "0" 558 "1", "1/2", "1/4", "1/8", "1/16", "0"
480}; 559};
@@ -537,13 +616,6 @@ static const char *mute_mode_text[] = {
537static const struct soc_enum mute_mode = 616static const struct soc_enum mute_mode =
538 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); 617 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
539 618
540static const char *dac_deemphasis_text[] = {
541 "Disabled", "32kHz", "44.1kHz", "48kHz"
542};
543
544static const struct soc_enum dac_deemphasis =
545 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
546
547static const char *companding_text[] = { 619static const char *companding_text[] = {
548 "ulaw", "alaw" 620 "ulaw", "alaw"
549}; 621};
@@ -613,6 +685,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
613 6, 1, 0), 685 6, 1, 0),
614 686
615/* ADCs */ 687/* ADCs */
688SOC_ENUM("ADC OSR", adc_osr),
689SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
690SOC_ENUM("HPF Mode", hpf_mode),
616SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 691SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
617SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 692SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
618SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 693SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
@@ -642,14 +717,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
642 12, 0, digital_sidetone_tlv), 717 12, 0, digital_sidetone_tlv),
643 718
644/* DAC */ 719/* DAC */
720SOC_ENUM("DAC OSR", dac_osr),
645SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, 721SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
646 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), 722 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
647SOC_ENUM("DAC Soft Mute Rate", soft_mute), 723SOC_ENUM("DAC Soft Mute Rate", soft_mute),
648SOC_ENUM("DAC Mute Mode", mute_mode), 724SOC_ENUM("DAC Mute Mode", mute_mode),
649SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), 725SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
650SOC_ENUM("DAC De-emphasis", dac_deemphasis),
651SOC_ENUM("DAC Companding Mode", dac_companding), 726SOC_ENUM("DAC Companding Mode", dac_companding),
652SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), 727SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
728SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
729 wm8903_get_deemph, wm8903_put_deemph),
653 730
654/* Headphones */ 731/* Headphones */
655SOC_DOUBLE_R("Headphone Switch", 732SOC_DOUBLE_R("Headphone Switch",
@@ -923,10 +1000,11 @@ static const struct snd_soc_dapm_route intercon[] = {
923 1000
924static int wm8903_add_widgets(struct snd_soc_codec *codec) 1001static int wm8903_add_widgets(struct snd_soc_codec *codec)
925{ 1002{
926 snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, 1003 struct snd_soc_dapm_context *dapm = &codec->dapm;
927 ARRAY_SIZE(wm8903_dapm_widgets));
928 1004
929 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1005 snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
1006 ARRAY_SIZE(wm8903_dapm_widgets));
1007 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
930 1008
931 return 0; 1009 return 0;
932} 1010}
@@ -934,7 +1012,7 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
934static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1012static int wm8903_set_bias_level(struct snd_soc_codec *codec,
935 enum snd_soc_bias_level level) 1013 enum snd_soc_bias_level level)
936{ 1014{
937 u16 reg, reg2; 1015 u16 reg;
938 1016
939 switch (level) { 1017 switch (level) {
940 case SND_SOC_BIAS_ON: 1018 case SND_SOC_BIAS_ON:
@@ -946,7 +1024,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
946 break; 1024 break;
947 1025
948 case SND_SOC_BIAS_STANDBY: 1026 case SND_SOC_BIAS_STANDBY:
949 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1027 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
950 snd_soc_write(codec, WM8903_CLOCK_RATES_2, 1028 snd_soc_write(codec, WM8903_CLOCK_RATES_2,
951 WM8903_CLK_SYS_ENA); 1029 WM8903_CLK_SYS_ENA);
952 1030
@@ -958,23 +1036,15 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
958 wm8903_run_sequence(codec, 0); 1036 wm8903_run_sequence(codec, 0);
959 wm8903_sync_reg_cache(codec, codec->reg_cache); 1037 wm8903_sync_reg_cache(codec, codec->reg_cache);
960 1038
961 /* Enable low impedence charge pump output */
962 reg = snd_soc_read(codec,
963 WM8903_CONTROL_INTERFACE_TEST_1);
964 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
965 reg | WM8903_TEST_KEY);
966 reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1);
967 snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1,
968 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
969 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
970 reg);
971
972 /* By default no bypass paths are enabled so 1039 /* By default no bypass paths are enabled so
973 * enable Class W support. 1040 * enable Class W support.
974 */ 1041 */
975 dev_dbg(codec->dev, "Enabling Class W\n"); 1042 dev_dbg(codec->dev, "Enabling Class W\n");
976 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 1043 snd_soc_update_bits(codec, WM8903_CLASS_W_0,
977 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 1044 WM8903_CP_DYN_FREQ |
1045 WM8903_CP_DYN_V,
1046 WM8903_CP_DYN_FREQ |
1047 WM8903_CP_DYN_V);
978 } 1048 }
979 1049
980 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1050 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
@@ -991,7 +1061,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
991 break; 1061 break;
992 } 1062 }
993 1063
994 codec->bias_level = level; 1064 codec->dapm.bias_level = level;
995 1065
996 return 0; 1066 return 0;
997} 1067}
@@ -1222,58 +1292,6 @@ static struct {
1222 { 0, 0 }, 1292 { 0, 0 },
1223}; 1293};
1224 1294
1225static int wm8903_startup(struct snd_pcm_substream *substream,
1226 struct snd_soc_dai *dai)
1227{
1228 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1229 struct snd_soc_codec *codec = rtd->codec;
1230 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1231 struct snd_pcm_runtime *master_runtime;
1232
1233 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1234 wm8903->playback_active++;
1235 else
1236 wm8903->capture_active++;
1237
1238 /* The DAI has shared clocks so if we already have a playback or
1239 * capture going then constrain this substream to match it.
1240 */
1241 if (wm8903->master_substream) {
1242 master_runtime = wm8903->master_substream->runtime;
1243
1244 dev_dbg(codec->dev, "Constraining to %d bits\n",
1245 master_runtime->sample_bits);
1246
1247 snd_pcm_hw_constraint_minmax(substream->runtime,
1248 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1249 master_runtime->sample_bits,
1250 master_runtime->sample_bits);
1251
1252 wm8903->slave_substream = substream;
1253 } else
1254 wm8903->master_substream = substream;
1255
1256 return 0;
1257}
1258
1259static void wm8903_shutdown(struct snd_pcm_substream *substream,
1260 struct snd_soc_dai *dai)
1261{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_codec *codec = rtd->codec;
1264 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1265
1266 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1267 wm8903->playback_active--;
1268 else
1269 wm8903->capture_active--;
1270
1271 if (wm8903->master_substream == substream)
1272 wm8903->master_substream = wm8903->slave_substream;
1273
1274 wm8903->slave_substream = NULL;
1275}
1276
1277static int wm8903_hw_params(struct snd_pcm_substream *substream, 1295static int wm8903_hw_params(struct snd_pcm_substream *substream,
1278 struct snd_pcm_hw_params *params, 1296 struct snd_pcm_hw_params *params,
1279 struct snd_soc_dai *dai) 1297 struct snd_soc_dai *dai)
@@ -1298,11 +1316,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1298 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); 1316 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
1299 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 1317 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1300 1318
1301 if (substream == wm8903->slave_substream) {
1302 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
1303 return 0;
1304 }
1305
1306 /* Enable sloping stopband filter for low sample rates */ 1319 /* Enable sloping stopband filter for low sample rates */
1307 if (fs <= 24000) 1320 if (fs <= 24000)
1308 dac_digital1 |= WM8903_DAC_SB_FILT; 1321 dac_digital1 |= WM8903_DAC_SB_FILT;
@@ -1320,19 +1333,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 } 1333 }
1321 } 1334 }
1322 1335
1323 /* Constraints should stop us hitting this but let's make sure */
1324 if (wm8903->capture_active)
1325 switch (sample_rates[dsp_config].rate) {
1326 case 88200:
1327 case 96000:
1328 dev_err(codec->dev, "%dHz unsupported by ADC\n",
1329 fs);
1330 return -EINVAL;
1331
1332 default:
1333 break;
1334 }
1335
1336 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); 1336 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1337 clock1 &= ~WM8903_SAMPLE_RATE_MASK; 1337 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1338 clock1 |= sample_rates[dsp_config].value; 1338 clock1 |= sample_rates[dsp_config].value;
@@ -1428,6 +1428,9 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1428 aif2 |= bclk_divs[bclk_div].div; 1428 aif2 |= bclk_divs[bclk_div].div;
1429 aif3 |= bclk / fs; 1429 aif3 |= bclk / fs;
1430 1430
1431 wm8903->fs = params_rate(params);
1432 wm8903_set_deemph(codec);
1433
1431 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); 1434 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
1432 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); 1435 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
1433 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1436 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
@@ -1521,6 +1524,11 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1521 mic_report = wm8903->mic_last_report; 1524 mic_report = wm8903->mic_last_report;
1522 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); 1525 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
1523 1526
1527#ifndef CONFIG_SND_SOC_WM8903_MODULE
1528 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
1529 trace_snd_soc_jack_irq(dev_name(codec->dev));
1530#endif
1531
1524 if (int_val & WM8903_MICSHRT_EINT) { 1532 if (int_val & WM8903_MICSHRT_EINT) {
1525 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); 1533 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
1526 1534
@@ -1571,8 +1579,6 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1571 SNDRV_PCM_FMTBIT_S24_LE) 1579 SNDRV_PCM_FMTBIT_S24_LE)
1572 1580
1573static struct snd_soc_dai_ops wm8903_dai_ops = { 1581static struct snd_soc_dai_ops wm8903_dai_ops = {
1574 .startup = wm8903_startup,
1575 .shutdown = wm8903_shutdown,
1576 .hw_params = wm8903_hw_params, 1582 .hw_params = wm8903_hw_params,
1577 .digital_mute = wm8903_digital_mute, 1583 .digital_mute = wm8903_digital_mute,
1578 .set_fmt = wm8903_set_dai_fmt, 1584 .set_fmt = wm8903_set_dai_fmt,