aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/nau8825.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/nau8825.c')
-rw-r--r--sound/soc/codecs/nau8825.c169
1 files changed, 126 insertions, 43 deletions
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index c1b87c5800b1..1c8729984c2b 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -84,6 +84,7 @@ static const struct nau8825_fll_attr fll_pre_scalar[] = {
84 84
85static const struct reg_default nau8825_reg_defaults[] = { 85static const struct reg_default nau8825_reg_defaults[] = {
86 { NAU8825_REG_ENA_CTRL, 0x00ff }, 86 { NAU8825_REG_ENA_CTRL, 0x00ff },
87 { NAU8825_REG_IIC_ADDR_SET, 0x0 },
87 { NAU8825_REG_CLK_DIVIDER, 0x0050 }, 88 { NAU8825_REG_CLK_DIVIDER, 0x0050 },
88 { NAU8825_REG_FLL1, 0x0 }, 89 { NAU8825_REG_FLL1, 0x0 },
89 { NAU8825_REG_FLL2, 0x3126 }, 90 { NAU8825_REG_FLL2, 0x3126 },
@@ -158,8 +159,7 @@ static const struct reg_default nau8825_reg_defaults[] = {
158static bool nau8825_readable_reg(struct device *dev, unsigned int reg) 159static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
159{ 160{
160 switch (reg) { 161 switch (reg) {
161 case NAU8825_REG_ENA_CTRL: 162 case NAU8825_REG_ENA_CTRL ... NAU8825_REG_FLL_VCO_RSV:
162 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL: 163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL: 164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL:
165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL: 165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
@@ -184,8 +184,7 @@ static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg) 184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg)
185{ 185{
186 switch (reg) { 186 switch (reg) {
187 case NAU8825_REG_RESET ... NAU8825_REG_ENA_CTRL: 187 case NAU8825_REG_RESET ... NAU8825_REG_FLL_VCO_RSV:
188 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
189 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL: 188 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
190 case NAU8825_REG_INTERRUPT_MASK: 189 case NAU8825_REG_INTERRUPT_MASK:
191 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL: 190 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL:
@@ -227,10 +226,42 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
227static int nau8825_pump_event(struct snd_soc_dapm_widget *w, 226static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
228 struct snd_kcontrol *kcontrol, int event) 227 struct snd_kcontrol *kcontrol, int event)
229{ 228{
229 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
230 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
231
230 switch (event) { 232 switch (event) {
231 case SND_SOC_DAPM_POST_PMU: 233 case SND_SOC_DAPM_POST_PMU:
232 /* Prevent startup click by letting charge pump to ramp up */ 234 /* Prevent startup click by letting charge pump to ramp up */
233 msleep(10); 235 msleep(10);
236 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
237 NAU8825_JAMNODCLOW, NAU8825_JAMNODCLOW);
238 break;
239 case SND_SOC_DAPM_PRE_PMD:
240 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
241 NAU8825_JAMNODCLOW, 0);
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 return 0;
248}
249
250static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
251 struct snd_kcontrol *kcontrol, int event)
252{
253 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
254 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
255
256 switch (event) {
257 case SND_SOC_DAPM_PRE_PMU:
258 /* Disables the TESTDAC to let DAC signal pass through. */
259 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
260 NAU8825_BIAS_TESTDAC_EN, 0);
261 break;
262 case SND_SOC_DAPM_POST_PMD:
263 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
264 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
234 break; 265 break;
235 default: 266 default:
236 return -EINVAL; 267 return -EINVAL;
@@ -316,10 +347,10 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
316 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL, 347 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL,
317 NAU8825_SAR_ADC_EN_SFT, 0), 348 NAU8825_SAR_ADC_EN_SFT, 0),
318 349
319 SND_SOC_DAPM_DAC("ADACL", NULL, NAU8825_REG_RDAC, 12, 0), 350 SND_SOC_DAPM_PGA_S("ADACL", 2, NAU8825_REG_RDAC, 12, 0, NULL, 0),
320 SND_SOC_DAPM_DAC("ADACR", NULL, NAU8825_REG_RDAC, 13, 0), 351 SND_SOC_DAPM_PGA_S("ADACR", 2, NAU8825_REG_RDAC, 13, 0, NULL, 0),
321 SND_SOC_DAPM_SUPPLY("ADACL Clock", NAU8825_REG_RDAC, 8, 0, NULL, 0), 352 SND_SOC_DAPM_PGA_S("ADACL Clock", 3, NAU8825_REG_RDAC, 8, 0, NULL, 0),
322 SND_SOC_DAPM_SUPPLY("ADACR Clock", NAU8825_REG_RDAC, 9, 0, NULL, 0), 353 SND_SOC_DAPM_PGA_S("ADACR Clock", 3, NAU8825_REG_RDAC, 9, 0, NULL, 0),
323 354
324 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL, 355 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL,
325 NAU8825_ENABLE_DACR_SFT, 0), 356 NAU8825_ENABLE_DACR_SFT, 0),
@@ -330,29 +361,48 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
330 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux), 361 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux),
331 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux), 362 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux),
332 363
333 SND_SOC_DAPM_PGA("HP amp L", NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0), 364 SND_SOC_DAPM_PGA_S("HP amp L", 0,
334 SND_SOC_DAPM_PGA("HP amp R", NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0), 365 NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0),
335 SND_SOC_DAPM_SUPPLY("HP amp power", NAU8825_REG_CLASSG_CTRL, 0, 0, NULL, 366 SND_SOC_DAPM_PGA_S("HP amp R", 0,
336 0), 367 NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0),
337 368
338 SND_SOC_DAPM_SUPPLY("Charge Pump", NAU8825_REG_CHARGE_PUMP, 5, 0, 369 SND_SOC_DAPM_PGA_S("Charge Pump", 1, NAU8825_REG_CHARGE_PUMP, 5, 0,
339 nau8825_pump_event, SND_SOC_DAPM_POST_PMU), 370 nau8825_pump_event, SND_SOC_DAPM_POST_PMU |
371 SND_SOC_DAPM_PRE_PMD),
340 372
341 SND_SOC_DAPM_PGA("Output Driver R Stage 1", 373 SND_SOC_DAPM_PGA_S("Output Driver R Stage 1", 4,
342 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0), 374 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0),
343 SND_SOC_DAPM_PGA("Output Driver L Stage 1", 375 SND_SOC_DAPM_PGA_S("Output Driver L Stage 1", 4,
344 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0), 376 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0),
345 SND_SOC_DAPM_PGA("Output Driver R Stage 2", 377 SND_SOC_DAPM_PGA_S("Output Driver R Stage 2", 5,
346 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0), 378 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
347 SND_SOC_DAPM_PGA("Output Driver L Stage 2", 379 SND_SOC_DAPM_PGA_S("Output Driver L Stage 2", 5,
348 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0), 380 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
349 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 1, 381 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 6,
350 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0), 382 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
351 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 1, 383 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 6,
352 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0), 384 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
353 385
354 SND_SOC_DAPM_PGA_S("Output DACL", 2, NAU8825_REG_CHARGE_PUMP, 8, 1, NULL, 0), 386 SND_SOC_DAPM_PGA_S("Output DACL", 7,
355 SND_SOC_DAPM_PGA_S("Output DACR", 2, NAU8825_REG_CHARGE_PUMP, 9, 1, NULL, 0), 387 NAU8825_REG_CHARGE_PUMP, 8, 1, nau8825_output_dac_event,
388 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
389 SND_SOC_DAPM_PGA_S("Output DACR", 7,
390 NAU8825_REG_CHARGE_PUMP, 9, 1, nau8825_output_dac_event,
391 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
392
393 /* HPOL/R are ungrounded by disabling 16 Ohm pull-downs on playback */
394 SND_SOC_DAPM_PGA_S("HPOL Pulldown", 8,
395 NAU8825_REG_HSD_CTRL, 0, 1, NULL, 0),
396 SND_SOC_DAPM_PGA_S("HPOR Pulldown", 8,
397 NAU8825_REG_HSD_CTRL, 1, 1, NULL, 0),
398
399 /* High current HPOL/R boost driver */
400 SND_SOC_DAPM_PGA_S("HP Boost Driver", 9,
401 NAU8825_REG_BOOST, 9, 1, NULL, 0),
402
403 /* Class G operation control*/
404 SND_SOC_DAPM_PGA_S("Class G", 10,
405 NAU8825_REG_CLASSG_CTRL, 0, 0, NULL, 0),
356 406
357 SND_SOC_DAPM_OUTPUT("HPOL"), 407 SND_SOC_DAPM_OUTPUT("HPOL"),
358 SND_SOC_DAPM_OUTPUT("HPOR"), 408 SND_SOC_DAPM_OUTPUT("HPOR"),
@@ -375,24 +425,27 @@ static const struct snd_soc_dapm_route nau8825_dapm_routes[] = {
375 {"DACR Mux", "DACR", "DDACR"}, 425 {"DACR Mux", "DACR", "DDACR"},
376 {"HP amp L", NULL, "DACL Mux"}, 426 {"HP amp L", NULL, "DACL Mux"},
377 {"HP amp R", NULL, "DACR Mux"}, 427 {"HP amp R", NULL, "DACR Mux"},
378 {"HP amp L", NULL, "HP amp power"}, 428 {"Charge Pump", NULL, "HP amp L"},
379 {"HP amp R", NULL, "HP amp power"}, 429 {"Charge Pump", NULL, "HP amp R"},
380 {"ADACL", NULL, "HP amp L"}, 430 {"ADACL", NULL, "Charge Pump"},
381 {"ADACR", NULL, "HP amp R"}, 431 {"ADACR", NULL, "Charge Pump"},
382 {"ADACL", NULL, "ADACL Clock"}, 432 {"ADACL Clock", NULL, "ADACL"},
383 {"ADACR", NULL, "ADACR Clock"}, 433 {"ADACR Clock", NULL, "ADACR"},
384 {"Output Driver L Stage 1", NULL, "ADACL"}, 434 {"Output Driver L Stage 1", NULL, "ADACL Clock"},
385 {"Output Driver R Stage 1", NULL, "ADACR"}, 435 {"Output Driver R Stage 1", NULL, "ADACR Clock"},
386 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"}, 436 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"},
387 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"}, 437 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"},
388 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"}, 438 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"},
389 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"}, 439 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"},
390 {"Output DACL", NULL, "Output Driver L Stage 3"}, 440 {"Output DACL", NULL, "Output Driver L Stage 3"},
391 {"Output DACR", NULL, "Output Driver R Stage 3"}, 441 {"Output DACR", NULL, "Output Driver R Stage 3"},
392 {"HPOL", NULL, "Output DACL"}, 442 {"HPOL Pulldown", NULL, "Output DACL"},
393 {"HPOR", NULL, "Output DACR"}, 443 {"HPOR Pulldown", NULL, "Output DACR"},
394 {"HPOL", NULL, "Charge Pump"}, 444 {"HP Boost Driver", NULL, "HPOL Pulldown"},
395 {"HPOR", NULL, "Charge Pump"}, 445 {"HP Boost Driver", NULL, "HPOR Pulldown"},
446 {"Class G", NULL, "HP Boost Driver"},
447 {"HPOL", NULL, "Class G"},
448 {"HPOR", NULL, "Class G"},
396}; 449};
397 450
398static int nau8825_hw_params(struct snd_pcm_substream *substream, 451static int nau8825_hw_params(struct snd_pcm_substream *substream,
@@ -659,11 +712,10 @@ static int nau8825_jack_insert(struct nau8825 *nau8825)
659 break; 712 break;
660 } 713 }
661 714
662 if (type & SND_JACK_HEADPHONE) { 715 /* Leaving HPOL/R grounded after jack insert by default. They will be
663 /* Unground HPL/R */ 716 * ungrounded as part of the widget power up sequence at the beginning
664 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0x3, 0); 717 * of playback to reduce pop.
665 } 718 */
666
667 return type; 719 return type;
668} 720}
669 721
@@ -768,6 +820,8 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
768{ 820{
769 struct regmap *regmap = nau8825->regmap; 821 struct regmap *regmap = nau8825->regmap;
770 822
823 /* Latch IIC LSB value */
824 regmap_write(regmap, NAU8825_REG_IIC_ADDR_SET, 0x0001);
771 /* Enable Bias/Vmid */ 825 /* Enable Bias/Vmid */
772 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ, 826 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
773 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID); 827 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID);
@@ -780,10 +834,10 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
780 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT); 834 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT);
781 /* Disable Boost Driver, Automatic Short circuit protection enable */ 835 /* Disable Boost Driver, Automatic Short circuit protection enable */
782 regmap_update_bits(regmap, NAU8825_REG_BOOST, 836 regmap_update_bits(regmap, NAU8825_REG_BOOST,
783 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS | 837 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_DIS |
784 NAU8825_SHORT_SHUTDOWN_EN, 838 NAU8825_HP_BOOST_G_DIS | NAU8825_SHORT_SHUTDOWN_EN,
785 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS | 839 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_DIS |
786 NAU8825_SHORT_SHUTDOWN_EN); 840 NAU8825_HP_BOOST_G_DIS | NAU8825_SHORT_SHUTDOWN_EN);
787 841
788 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL, 842 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
789 NAU8825_JKDET_OUTPUT_EN, 843 NAU8825_JKDET_OUTPUT_EN,
@@ -822,6 +876,35 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
822 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128); 876 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128);
823 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1, 877 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
824 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128); 878 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128);
879 /* Disable DACR/L power */
880 regmap_update_bits(regmap, NAU8825_REG_CHARGE_PUMP,
881 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL,
882 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL);
883 /* Enable TESTDAC. This sets the analog DAC inputs to a '0' input
884 * signal to avoid any glitches due to power up transients in both
885 * the analog and digital DAC circuit.
886 */
887 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
888 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
889 /* CICCLP off */
890 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
891 NAU8825_DAC_CLIP_OFF, NAU8825_DAC_CLIP_OFF);
892
893 /* Class AB bias current to 2x, DAC Capacitor enable MSB/LSB */
894 regmap_update_bits(regmap, NAU8825_REG_ANALOG_CONTROL_2,
895 NAU8825_HP_NON_CLASSG_CURRENT_2xADJ |
896 NAU8825_DAC_CAPACITOR_MSB | NAU8825_DAC_CAPACITOR_LSB,
897 NAU8825_HP_NON_CLASSG_CURRENT_2xADJ |
898 NAU8825_DAC_CAPACITOR_MSB | NAU8825_DAC_CAPACITOR_LSB);
899 /* Class G timer 64ms */
900 regmap_update_bits(regmap, NAU8825_REG_CLASSG_CTRL,
901 NAU8825_CLASSG_TIMER_MASK,
902 0x20 << NAU8825_CLASSG_TIMER_SFT);
903 /* DAC clock delay 2ns, VREF */
904 regmap_update_bits(regmap, NAU8825_REG_RDAC,
905 NAU8825_RDAC_CLK_DELAY_MASK | NAU8825_RDAC_VREF_MASK,
906 (0x2 << NAU8825_RDAC_CLK_DELAY_SFT) |
907 (0x3 << NAU8825_RDAC_VREF_SFT));
825} 908}
826 909
827static const struct regmap_config nau8825_regmap_config = { 910static const struct regmap_config nau8825_regmap_config = {