.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/sound/soc/codecs/tlv320aic32x4.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * Author: Javier Martin <javier.martin@vista-silicon.com> |
---|
7 | 8 | * |
---|
8 | 9 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License as published by |
---|
12 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
13 | | - * (at your option) any later version. |
---|
14 | | - * |
---|
15 | | - * This program is distributed in the hope that it will be useful, |
---|
16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - * GNU General Public License for more details. |
---|
19 | | - * |
---|
20 | | - * You should have received a copy of the GNU General Public License |
---|
21 | | - * along with this program; if not, write to the Free Software |
---|
22 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
---|
23 | | - * MA 02110-1301, USA. |
---|
24 | 10 | */ |
---|
25 | 11 | |
---|
26 | 12 | #include <linux/module.h> |
---|
.. | .. |
---|
33 | 19 | #include <linux/cdev.h> |
---|
34 | 20 | #include <linux/slab.h> |
---|
35 | 21 | #include <linux/clk.h> |
---|
| 22 | +#include <linux/of_clk.h> |
---|
36 | 23 | #include <linux/regulator/consumer.h> |
---|
37 | 24 | |
---|
38 | 25 | #include <sound/tlv320aic32x4.h> |
---|
.. | .. |
---|
46 | 33 | |
---|
47 | 34 | #include "tlv320aic32x4.h" |
---|
48 | 35 | |
---|
49 | | -struct aic32x4_rate_divs { |
---|
50 | | - u32 mclk; |
---|
51 | | - u32 rate; |
---|
52 | | - u8 p_val; |
---|
53 | | - u8 pll_j; |
---|
54 | | - u16 pll_d; |
---|
55 | | - u16 dosr; |
---|
56 | | - u8 ndac; |
---|
57 | | - u8 mdac; |
---|
58 | | - u8 aosr; |
---|
59 | | - u8 nadc; |
---|
60 | | - u8 madc; |
---|
61 | | - u8 blck_N; |
---|
62 | | -}; |
---|
63 | | - |
---|
64 | 36 | struct aic32x4_priv { |
---|
65 | 37 | struct regmap *regmap; |
---|
66 | | - u32 sysclk; |
---|
67 | 38 | u32 power_cfg; |
---|
68 | 39 | u32 micpga_routing; |
---|
69 | 40 | bool swapdacs; |
---|
70 | 41 | int rstn_gpio; |
---|
71 | | - struct clk *mclk; |
---|
| 42 | + const char *mclk_name; |
---|
72 | 43 | |
---|
73 | 44 | struct regulator *supply_ldo; |
---|
74 | 45 | struct regulator *supply_iov; |
---|
.. | .. |
---|
79 | 50 | struct device *dev; |
---|
80 | 51 | }; |
---|
81 | 52 | |
---|
| 53 | +static int aic32x4_reset_adc(struct snd_soc_dapm_widget *w, |
---|
| 54 | + struct snd_kcontrol *kcontrol, int event) |
---|
| 55 | +{ |
---|
| 56 | + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
| 57 | + u32 adc_reg; |
---|
| 58 | + |
---|
| 59 | + /* |
---|
| 60 | + * Workaround: the datasheet does not mention a required programming |
---|
| 61 | + * sequence but experiments show the ADC needs to be reset after each |
---|
| 62 | + * capture to avoid audible artifacts. |
---|
| 63 | + */ |
---|
| 64 | + switch (event) { |
---|
| 65 | + case SND_SOC_DAPM_POST_PMD: |
---|
| 66 | + adc_reg = snd_soc_component_read(component, AIC32X4_ADCSETUP); |
---|
| 67 | + snd_soc_component_write(component, AIC32X4_ADCSETUP, adc_reg | |
---|
| 68 | + AIC32X4_LADC_EN | AIC32X4_RADC_EN); |
---|
| 69 | + snd_soc_component_write(component, AIC32X4_ADCSETUP, adc_reg); |
---|
| 70 | + break; |
---|
| 71 | + } |
---|
| 72 | + return 0; |
---|
| 73 | +}; |
---|
| 74 | + |
---|
| 75 | +static int mic_bias_event(struct snd_soc_dapm_widget *w, |
---|
| 76 | + struct snd_kcontrol *kcontrol, int event) |
---|
| 77 | +{ |
---|
| 78 | + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
| 79 | + |
---|
| 80 | + switch (event) { |
---|
| 81 | + case SND_SOC_DAPM_POST_PMU: |
---|
| 82 | + /* Change Mic Bias Registor */ |
---|
| 83 | + snd_soc_component_update_bits(component, AIC32X4_MICBIAS, |
---|
| 84 | + AIC32x4_MICBIAS_MASK, |
---|
| 85 | + AIC32X4_MICBIAS_LDOIN | |
---|
| 86 | + AIC32X4_MICBIAS_2075V); |
---|
| 87 | + printk(KERN_DEBUG "%s: Mic Bias will be turned ON\n", __func__); |
---|
| 88 | + break; |
---|
| 89 | + case SND_SOC_DAPM_PRE_PMD: |
---|
| 90 | + snd_soc_component_update_bits(component, AIC32X4_MICBIAS, |
---|
| 91 | + AIC32x4_MICBIAS_MASK, 0); |
---|
| 92 | + printk(KERN_DEBUG "%s: Mic Bias will be turned OFF\n", |
---|
| 93 | + __func__); |
---|
| 94 | + break; |
---|
| 95 | + } |
---|
| 96 | + |
---|
| 97 | + return 0; |
---|
| 98 | +} |
---|
| 99 | + |
---|
| 100 | + |
---|
82 | 101 | static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol, |
---|
83 | 102 | struct snd_ctl_elem_value *ucontrol) |
---|
84 | 103 | { |
---|
85 | 104 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
86 | 105 | u8 val; |
---|
87 | 106 | |
---|
88 | | - val = snd_soc_component_read32(component, AIC32X4_DINCTL); |
---|
| 107 | + val = snd_soc_component_read(component, AIC32X4_DINCTL); |
---|
89 | 108 | |
---|
90 | 109 | ucontrol->value.integer.value[0] = (val & 0x01); |
---|
91 | 110 | |
---|
.. | .. |
---|
99 | 118 | u8 val; |
---|
100 | 119 | u8 gpio_check; |
---|
101 | 120 | |
---|
102 | | - val = snd_soc_component_read32(component, AIC32X4_DOUTCTL); |
---|
| 121 | + val = snd_soc_component_read(component, AIC32X4_DOUTCTL); |
---|
103 | 122 | gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED); |
---|
104 | 123 | if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) { |
---|
105 | 124 | printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n", |
---|
.. | .. |
---|
126 | 145 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
127 | 146 | u8 val; |
---|
128 | 147 | |
---|
129 | | - val = snd_soc_component_read32(component, AIC32X4_SCLKCTL); |
---|
| 148 | + val = snd_soc_component_read(component, AIC32X4_SCLKCTL); |
---|
130 | 149 | |
---|
131 | 150 | ucontrol->value.integer.value[0] = (val & 0x01); |
---|
132 | 151 | |
---|
.. | .. |
---|
140 | 159 | u8 val; |
---|
141 | 160 | u8 gpio_check; |
---|
142 | 161 | |
---|
143 | | - val = snd_soc_component_read32(component, AIC32X4_MISOCTL); |
---|
| 162 | + val = snd_soc_component_read(component, AIC32X4_MISOCTL); |
---|
144 | 163 | gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED); |
---|
145 | 164 | if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) { |
---|
146 | 165 | printk(KERN_ERR "%s: MFP4 is not configure as a GPIO output\n", |
---|
.. | .. |
---|
167 | 186 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
168 | 187 | u8 val; |
---|
169 | 188 | |
---|
170 | | - val = snd_soc_component_read32(component, AIC32X4_GPIOCTL); |
---|
| 189 | + val = snd_soc_component_read(component, AIC32X4_GPIOCTL); |
---|
171 | 190 | ucontrol->value.integer.value[0] = ((val & 0x2) >> 1); |
---|
172 | 191 | |
---|
173 | 192 | return 0; |
---|
.. | .. |
---|
180 | 199 | u8 val; |
---|
181 | 200 | u8 gpio_check; |
---|
182 | 201 | |
---|
183 | | - val = snd_soc_component_read32(component, AIC32X4_GPIOCTL); |
---|
| 202 | + val = snd_soc_component_read(component, AIC32X4_GPIOCTL); |
---|
184 | 203 | gpio_check = (val & AIC32X4_MFP5_GPIO_OUTPUT); |
---|
185 | 204 | if (gpio_check != AIC32X4_MFP5_GPIO_OUTPUT) { |
---|
186 | 205 | printk(KERN_ERR "%s: MFP5 is not configure as a GPIO output\n", |
---|
.. | .. |
---|
231 | 250 | /* -12dB min, 0.5dB steps */ |
---|
232 | 251 | static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0); |
---|
233 | 252 | |
---|
| 253 | +static const char * const lo_cm_text[] = { |
---|
| 254 | + "Full Chip", "1.65V", |
---|
| 255 | +}; |
---|
| 256 | + |
---|
| 257 | +static SOC_ENUM_SINGLE_DECL(lo_cm_enum, AIC32X4_CMMODE, 3, lo_cm_text); |
---|
| 258 | + |
---|
| 259 | +static const char * const ptm_text[] = { |
---|
| 260 | + "P3", "P2", "P1", |
---|
| 261 | +}; |
---|
| 262 | + |
---|
| 263 | +static SOC_ENUM_SINGLE_DECL(l_ptm_enum, AIC32X4_LPLAYBACK, 2, ptm_text); |
---|
| 264 | +static SOC_ENUM_SINGLE_DECL(r_ptm_enum, AIC32X4_RPLAYBACK, 2, ptm_text); |
---|
| 265 | + |
---|
234 | 266 | static const struct snd_kcontrol_new aic32x4_snd_controls[] = { |
---|
235 | 267 | SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, |
---|
236 | 268 | AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm), |
---|
| 269 | + SOC_ENUM("DAC Left Playback PowerTune Switch", l_ptm_enum), |
---|
| 270 | + SOC_ENUM("DAC Right Playback PowerTune Switch", r_ptm_enum), |
---|
237 | 271 | SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, |
---|
238 | 272 | AIC32X4_HPRGAIN, 0, -0x6, 0x1d, 5, 0, |
---|
239 | 273 | tlv_driver_gain), |
---|
.. | .. |
---|
244 | 278 | AIC32X4_HPRGAIN, 6, 0x01, 1), |
---|
245 | 279 | SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, |
---|
246 | 280 | AIC32X4_LORGAIN, 6, 0x01, 1), |
---|
| 281 | + SOC_ENUM("LO Playback Common Mode Switch", lo_cm_enum), |
---|
247 | 282 | SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL, |
---|
248 | 283 | AIC32X4_RMICPGAVOL, 7, 0x01, 1), |
---|
249 | 284 | |
---|
.. | .. |
---|
277 | 312 | 0, 0x1F, 0), |
---|
278 | 313 | SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7, |
---|
279 | 314 | 0, 0x0F, 0), |
---|
280 | | -}; |
---|
281 | | - |
---|
282 | | -static const struct aic32x4_rate_divs aic32x4_divs[] = { |
---|
283 | | - /* 8k rate */ |
---|
284 | | - {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24}, |
---|
285 | | - {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24}, |
---|
286 | | - {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24}, |
---|
287 | | - /* 11.025k rate */ |
---|
288 | | - {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16}, |
---|
289 | | - {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16}, |
---|
290 | | - /* 16k rate */ |
---|
291 | | - {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12}, |
---|
292 | | - {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12}, |
---|
293 | | - {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12}, |
---|
294 | | - /* 22.05k rate */ |
---|
295 | | - {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8}, |
---|
296 | | - {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8}, |
---|
297 | | - {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8}, |
---|
298 | | - /* 32k rate */ |
---|
299 | | - {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6}, |
---|
300 | | - {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6}, |
---|
301 | | - /* 44.1k rate */ |
---|
302 | | - {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4}, |
---|
303 | | - {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4}, |
---|
304 | | - {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4}, |
---|
305 | | - /* 48k rate */ |
---|
306 | | - {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4}, |
---|
307 | | - {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4}, |
---|
308 | | - {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}, |
---|
309 | | - |
---|
310 | | - /* 96k rate */ |
---|
311 | | - {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1}, |
---|
312 | 315 | }; |
---|
313 | 316 | |
---|
314 | 317 | static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { |
---|
.. | .. |
---|
365 | 368 | SOC_DAPM_ENUM("IN3_R L- Switch", in3r_lpga_n_enum), |
---|
366 | 369 | }; |
---|
367 | 370 | |
---|
368 | | -/* Right mixer pins */ |
---|
| 371 | +/* Right mixer pins */ |
---|
369 | 372 | static SOC_ENUM_SINGLE_DECL(in1r_rpga_p_enum, AIC32X4_RMICPGAPIN, 6, resistor_text); |
---|
370 | 373 | static SOC_ENUM_SINGLE_DECL(in2r_rpga_p_enum, AIC32X4_RMICPGAPIN, 4, resistor_text); |
---|
371 | 374 | static SOC_ENUM_SINGLE_DECL(in3r_rpga_p_enum, AIC32X4_RMICPGAPIN, 2, resistor_text); |
---|
.. | .. |
---|
450 | 453 | SND_SOC_DAPM_MUX("IN3_R to Left Mixer Negative Resistor", SND_SOC_NOPM, 0, 0, |
---|
451 | 454 | in3r_to_lmixer_controls), |
---|
452 | 455 | |
---|
453 | | - SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0), |
---|
| 456 | + SND_SOC_DAPM_SUPPLY("Mic Bias", AIC32X4_MICBIAS, 6, 0, mic_bias_event, |
---|
| 457 | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
---|
| 458 | + |
---|
| 459 | + SND_SOC_DAPM_POST("ADC Reset", aic32x4_reset_adc), |
---|
454 | 460 | |
---|
455 | 461 | SND_SOC_DAPM_OUTPUT("HPL"), |
---|
456 | 462 | SND_SOC_DAPM_OUTPUT("HPR"), |
---|
.. | .. |
---|
567 | 573 | static const struct regmap_range_cfg aic32x4_regmap_pages[] = { |
---|
568 | 574 | { |
---|
569 | 575 | .selector_reg = 0, |
---|
570 | | - .selector_mask = 0xff, |
---|
| 576 | + .selector_mask = 0xff, |
---|
571 | 577 | .window_start = 0, |
---|
572 | 578 | .window_len = 128, |
---|
573 | 579 | .range_min = 0, |
---|
574 | | - .range_max = AIC32X4_RMICPGAVOL, |
---|
| 580 | + .range_max = AIC32X4_REFPOWERUP, |
---|
575 | 581 | }, |
---|
576 | 582 | }; |
---|
577 | 583 | |
---|
578 | 584 | const struct regmap_config aic32x4_regmap_config = { |
---|
579 | | - .max_register = AIC32X4_RMICPGAVOL, |
---|
| 585 | + .max_register = AIC32X4_REFPOWERUP, |
---|
580 | 586 | .ranges = aic32x4_regmap_pages, |
---|
581 | 587 | .num_ranges = ARRAY_SIZE(aic32x4_regmap_pages), |
---|
582 | 588 | }; |
---|
583 | 589 | EXPORT_SYMBOL(aic32x4_regmap_config); |
---|
584 | 590 | |
---|
585 | | -static inline int aic32x4_get_divs(int mclk, int rate) |
---|
586 | | -{ |
---|
587 | | - int i; |
---|
588 | | - |
---|
589 | | - for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) { |
---|
590 | | - if ((aic32x4_divs[i].rate == rate) |
---|
591 | | - && (aic32x4_divs[i].mclk == mclk)) { |
---|
592 | | - return i; |
---|
593 | | - } |
---|
594 | | - } |
---|
595 | | - printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n"); |
---|
596 | | - return -EINVAL; |
---|
597 | | -} |
---|
598 | | - |
---|
599 | 591 | static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
---|
600 | 592 | int clk_id, unsigned int freq, int dir) |
---|
601 | 593 | { |
---|
602 | 594 | struct snd_soc_component *component = codec_dai->component; |
---|
603 | | - struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); |
---|
| 595 | + struct clk *mclk; |
---|
| 596 | + struct clk *pll; |
---|
604 | 597 | |
---|
605 | | - switch (freq) { |
---|
606 | | - case 12000000: |
---|
607 | | - case 24000000: |
---|
608 | | - case 25000000: |
---|
609 | | - aic32x4->sysclk = freq; |
---|
610 | | - return 0; |
---|
611 | | - } |
---|
612 | | - printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n"); |
---|
613 | | - return -EINVAL; |
---|
| 598 | + pll = devm_clk_get(component->dev, "pll"); |
---|
| 599 | + if (IS_ERR(pll)) |
---|
| 600 | + return PTR_ERR(pll); |
---|
| 601 | + |
---|
| 602 | + mclk = clk_get_parent(pll); |
---|
| 603 | + |
---|
| 604 | + return clk_set_rate(mclk, freq); |
---|
614 | 605 | } |
---|
615 | 606 | |
---|
616 | 607 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
---|
.. | .. |
---|
660 | 651 | } |
---|
661 | 652 | |
---|
662 | 653 | snd_soc_component_update_bits(component, AIC32X4_IFACE1, |
---|
663 | | - AIC32X4_IFACE1_DATATYPE_MASK | |
---|
664 | | - AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); |
---|
| 654 | + AIC32X4_IFACE1_DATATYPE_MASK | |
---|
| 655 | + AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); |
---|
665 | 656 | snd_soc_component_update_bits(component, AIC32X4_IFACE2, |
---|
666 | | - AIC32X4_DATA_OFFSET_MASK, iface_reg_2); |
---|
| 657 | + AIC32X4_DATA_OFFSET_MASK, iface_reg_2); |
---|
667 | 658 | snd_soc_component_update_bits(component, AIC32X4_IFACE3, |
---|
668 | | - AIC32X4_BCLKINV_MASK, iface_reg_3); |
---|
| 659 | + AIC32X4_BCLKINV_MASK, iface_reg_3); |
---|
669 | 660 | |
---|
670 | 661 | return 0; |
---|
671 | 662 | } |
---|
672 | 663 | |
---|
| 664 | +static int aic32x4_set_aosr(struct snd_soc_component *component, u8 aosr) |
---|
| 665 | +{ |
---|
| 666 | + return snd_soc_component_write(component, AIC32X4_AOSR, aosr); |
---|
| 667 | +} |
---|
| 668 | + |
---|
| 669 | +static int aic32x4_set_dosr(struct snd_soc_component *component, u16 dosr) |
---|
| 670 | +{ |
---|
| 671 | + snd_soc_component_write(component, AIC32X4_DOSRMSB, dosr >> 8); |
---|
| 672 | + snd_soc_component_write(component, AIC32X4_DOSRLSB, |
---|
| 673 | + (dosr & 0xff)); |
---|
| 674 | + |
---|
| 675 | + return 0; |
---|
| 676 | +} |
---|
| 677 | + |
---|
| 678 | +static int aic32x4_set_processing_blocks(struct snd_soc_component *component, |
---|
| 679 | + u8 r_block, u8 p_block) |
---|
| 680 | +{ |
---|
| 681 | + if (r_block > 18 || p_block > 25) |
---|
| 682 | + return -EINVAL; |
---|
| 683 | + |
---|
| 684 | + snd_soc_component_write(component, AIC32X4_ADCSPB, r_block); |
---|
| 685 | + snd_soc_component_write(component, AIC32X4_DACSPB, p_block); |
---|
| 686 | + |
---|
| 687 | + return 0; |
---|
| 688 | +} |
---|
| 689 | + |
---|
| 690 | +static int aic32x4_setup_clocks(struct snd_soc_component *component, |
---|
| 691 | + unsigned int sample_rate, unsigned int channels, |
---|
| 692 | + unsigned int bit_depth) |
---|
| 693 | +{ |
---|
| 694 | + u8 aosr; |
---|
| 695 | + u16 dosr; |
---|
| 696 | + u8 adc_resource_class, dac_resource_class; |
---|
| 697 | + u8 madc, nadc, mdac, ndac, max_nadc, min_mdac, max_ndac; |
---|
| 698 | + u8 dosr_increment; |
---|
| 699 | + u16 max_dosr, min_dosr; |
---|
| 700 | + unsigned long adc_clock_rate, dac_clock_rate; |
---|
| 701 | + int ret; |
---|
| 702 | + |
---|
| 703 | + struct clk_bulk_data clocks[] = { |
---|
| 704 | + { .id = "pll" }, |
---|
| 705 | + { .id = "nadc" }, |
---|
| 706 | + { .id = "madc" }, |
---|
| 707 | + { .id = "ndac" }, |
---|
| 708 | + { .id = "mdac" }, |
---|
| 709 | + { .id = "bdiv" }, |
---|
| 710 | + }; |
---|
| 711 | + ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); |
---|
| 712 | + if (ret) |
---|
| 713 | + return ret; |
---|
| 714 | + |
---|
| 715 | + if (sample_rate <= 48000) { |
---|
| 716 | + aosr = 128; |
---|
| 717 | + adc_resource_class = 6; |
---|
| 718 | + dac_resource_class = 8; |
---|
| 719 | + dosr_increment = 8; |
---|
| 720 | + aic32x4_set_processing_blocks(component, 1, 1); |
---|
| 721 | + } else if (sample_rate <= 96000) { |
---|
| 722 | + aosr = 64; |
---|
| 723 | + adc_resource_class = 6; |
---|
| 724 | + dac_resource_class = 8; |
---|
| 725 | + dosr_increment = 4; |
---|
| 726 | + aic32x4_set_processing_blocks(component, 1, 9); |
---|
| 727 | + } else if (sample_rate == 192000) { |
---|
| 728 | + aosr = 32; |
---|
| 729 | + adc_resource_class = 3; |
---|
| 730 | + dac_resource_class = 4; |
---|
| 731 | + dosr_increment = 2; |
---|
| 732 | + aic32x4_set_processing_blocks(component, 13, 19); |
---|
| 733 | + } else { |
---|
| 734 | + dev_err(component->dev, "Sampling rate not supported\n"); |
---|
| 735 | + return -EINVAL; |
---|
| 736 | + } |
---|
| 737 | + |
---|
| 738 | + madc = DIV_ROUND_UP((32 * adc_resource_class), aosr); |
---|
| 739 | + max_dosr = (AIC32X4_MAX_DOSR_FREQ / sample_rate / dosr_increment) * |
---|
| 740 | + dosr_increment; |
---|
| 741 | + min_dosr = (AIC32X4_MIN_DOSR_FREQ / sample_rate / dosr_increment) * |
---|
| 742 | + dosr_increment; |
---|
| 743 | + max_nadc = AIC32X4_MAX_CODEC_CLKIN_FREQ / (madc * aosr * sample_rate); |
---|
| 744 | + |
---|
| 745 | + for (nadc = max_nadc; nadc > 0; --nadc) { |
---|
| 746 | + adc_clock_rate = nadc * madc * aosr * sample_rate; |
---|
| 747 | + for (dosr = max_dosr; dosr >= min_dosr; |
---|
| 748 | + dosr -= dosr_increment) { |
---|
| 749 | + min_mdac = DIV_ROUND_UP((32 * dac_resource_class), dosr); |
---|
| 750 | + max_ndac = AIC32X4_MAX_CODEC_CLKIN_FREQ / |
---|
| 751 | + (min_mdac * dosr * sample_rate); |
---|
| 752 | + for (mdac = min_mdac; mdac <= 128; ++mdac) { |
---|
| 753 | + for (ndac = max_ndac; ndac > 0; --ndac) { |
---|
| 754 | + dac_clock_rate = ndac * mdac * dosr * |
---|
| 755 | + sample_rate; |
---|
| 756 | + if (dac_clock_rate == adc_clock_rate) { |
---|
| 757 | + if (clk_round_rate(clocks[0].clk, dac_clock_rate) == 0) |
---|
| 758 | + continue; |
---|
| 759 | + |
---|
| 760 | + clk_set_rate(clocks[0].clk, |
---|
| 761 | + dac_clock_rate); |
---|
| 762 | + |
---|
| 763 | + clk_set_rate(clocks[1].clk, |
---|
| 764 | + sample_rate * aosr * |
---|
| 765 | + madc); |
---|
| 766 | + clk_set_rate(clocks[2].clk, |
---|
| 767 | + sample_rate * aosr); |
---|
| 768 | + aic32x4_set_aosr(component, |
---|
| 769 | + aosr); |
---|
| 770 | + |
---|
| 771 | + clk_set_rate(clocks[3].clk, |
---|
| 772 | + sample_rate * dosr * |
---|
| 773 | + mdac); |
---|
| 774 | + clk_set_rate(clocks[4].clk, |
---|
| 775 | + sample_rate * dosr); |
---|
| 776 | + aic32x4_set_dosr(component, |
---|
| 777 | + dosr); |
---|
| 778 | + |
---|
| 779 | + clk_set_rate(clocks[5].clk, |
---|
| 780 | + sample_rate * channels * |
---|
| 781 | + bit_depth); |
---|
| 782 | + |
---|
| 783 | + return 0; |
---|
| 784 | + } |
---|
| 785 | + } |
---|
| 786 | + } |
---|
| 787 | + } |
---|
| 788 | + } |
---|
| 789 | + |
---|
| 790 | + dev_err(component->dev, |
---|
| 791 | + "Could not set clocks to support sample rate.\n"); |
---|
| 792 | + return -EINVAL; |
---|
| 793 | +} |
---|
| 794 | + |
---|
673 | 795 | static int aic32x4_hw_params(struct snd_pcm_substream *substream, |
---|
674 | | - struct snd_pcm_hw_params *params, |
---|
675 | | - struct snd_soc_dai *dai) |
---|
| 796 | + struct snd_pcm_hw_params *params, |
---|
| 797 | + struct snd_soc_dai *dai) |
---|
676 | 798 | { |
---|
677 | 799 | struct snd_soc_component *component = dai->component; |
---|
678 | 800 | struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); |
---|
679 | 801 | u8 iface1_reg = 0; |
---|
680 | 802 | u8 dacsetup_reg = 0; |
---|
681 | | - int i; |
---|
682 | 803 | |
---|
683 | | - i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params)); |
---|
684 | | - if (i < 0) { |
---|
685 | | - printk(KERN_ERR "aic32x4: sampling rate not supported\n"); |
---|
686 | | - return i; |
---|
687 | | - } |
---|
| 804 | + aic32x4_setup_clocks(component, params_rate(params), |
---|
| 805 | + params_channels(params), |
---|
| 806 | + params_physical_width(params)); |
---|
688 | 807 | |
---|
689 | | - /* MCLK as PLL_CLKIN */ |
---|
690 | | - snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK, |
---|
691 | | - AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT); |
---|
692 | | - /* PLL as CODEC_CLKIN */ |
---|
693 | | - snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK, |
---|
694 | | - AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); |
---|
695 | | - /* DAC_MOD_CLK as BDIV_CLKIN */ |
---|
696 | | - snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, |
---|
697 | | - AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); |
---|
698 | | - |
---|
699 | | - /* We will fix R value to 1 and will make P & J=K.D as variable */ |
---|
700 | | - snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01); |
---|
701 | | - |
---|
702 | | - /* PLL P value */ |
---|
703 | | - snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK, |
---|
704 | | - aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT); |
---|
705 | | - |
---|
706 | | - /* PLL J value */ |
---|
707 | | - snd_soc_component_write(component, AIC32X4_PLLJ, aic32x4_divs[i].pll_j); |
---|
708 | | - |
---|
709 | | - /* PLL D value */ |
---|
710 | | - snd_soc_component_write(component, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8)); |
---|
711 | | - snd_soc_component_write(component, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff)); |
---|
712 | | - |
---|
713 | | - /* NDAC divider value */ |
---|
714 | | - snd_soc_component_update_bits(component, AIC32X4_NDAC, |
---|
715 | | - AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); |
---|
716 | | - |
---|
717 | | - /* MDAC divider value */ |
---|
718 | | - snd_soc_component_update_bits(component, AIC32X4_MDAC, |
---|
719 | | - AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); |
---|
720 | | - |
---|
721 | | - /* DOSR MSB & LSB values */ |
---|
722 | | - snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); |
---|
723 | | - snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); |
---|
724 | | - |
---|
725 | | - /* NADC divider value */ |
---|
726 | | - snd_soc_component_update_bits(component, AIC32X4_NADC, |
---|
727 | | - AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); |
---|
728 | | - |
---|
729 | | - /* MADC divider value */ |
---|
730 | | - snd_soc_component_update_bits(component, AIC32X4_MADC, |
---|
731 | | - AIC32X4_MADC_MASK, aic32x4_divs[i].madc); |
---|
732 | | - |
---|
733 | | - /* AOSR value */ |
---|
734 | | - snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); |
---|
735 | | - |
---|
736 | | - /* BCLK N divider */ |
---|
737 | | - snd_soc_component_update_bits(component, AIC32X4_BCLKN, |
---|
738 | | - AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); |
---|
739 | | - |
---|
740 | | - switch (params_width(params)) { |
---|
| 808 | + switch (params_physical_width(params)) { |
---|
741 | 809 | case 16: |
---|
742 | 810 | iface1_reg |= (AIC32X4_WORD_LEN_16BITS << |
---|
743 | | - AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
| 811 | + AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
744 | 812 | break; |
---|
745 | 813 | case 20: |
---|
746 | 814 | iface1_reg |= (AIC32X4_WORD_LEN_20BITS << |
---|
747 | | - AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
| 815 | + AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
748 | 816 | break; |
---|
749 | 817 | case 24: |
---|
750 | 818 | iface1_reg |= (AIC32X4_WORD_LEN_24BITS << |
---|
751 | | - AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
| 819 | + AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
752 | 820 | break; |
---|
753 | 821 | case 32: |
---|
754 | 822 | iface1_reg |= (AIC32X4_WORD_LEN_32BITS << |
---|
755 | | - AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
| 823 | + AIC32X4_IFACE1_DATALEN_SHIFT); |
---|
756 | 824 | break; |
---|
757 | 825 | } |
---|
758 | 826 | snd_soc_component_update_bits(component, AIC32X4_IFACE1, |
---|
759 | | - AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); |
---|
| 827 | + AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); |
---|
760 | 828 | |
---|
761 | 829 | if (params_channels(params) == 1) { |
---|
762 | 830 | dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN; |
---|
.. | .. |
---|
767 | 835 | dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN; |
---|
768 | 836 | } |
---|
769 | 837 | snd_soc_component_update_bits(component, AIC32X4_DACSETUP, |
---|
770 | | - AIC32X4_DAC_CHAN_MASK, dacsetup_reg); |
---|
| 838 | + AIC32X4_DAC_CHAN_MASK, dacsetup_reg); |
---|
771 | 839 | |
---|
772 | 840 | return 0; |
---|
773 | 841 | } |
---|
774 | 842 | |
---|
775 | | -static int aic32x4_mute(struct snd_soc_dai *dai, int mute) |
---|
| 843 | +static int aic32x4_mute(struct snd_soc_dai *dai, int mute, int direction) |
---|
776 | 844 | { |
---|
777 | 845 | struct snd_soc_component *component = dai->component; |
---|
778 | 846 | |
---|
779 | 847 | snd_soc_component_update_bits(component, AIC32X4_DACMUTE, |
---|
780 | | - AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); |
---|
| 848 | + AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); |
---|
781 | 849 | |
---|
782 | 850 | return 0; |
---|
783 | 851 | } |
---|
.. | .. |
---|
785 | 853 | static int aic32x4_set_bias_level(struct snd_soc_component *component, |
---|
786 | 854 | enum snd_soc_bias_level level) |
---|
787 | 855 | { |
---|
788 | | - struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); |
---|
789 | 856 | int ret; |
---|
| 857 | + |
---|
| 858 | + struct clk_bulk_data clocks[] = { |
---|
| 859 | + { .id = "madc" }, |
---|
| 860 | + { .id = "mdac" }, |
---|
| 861 | + { .id = "bdiv" }, |
---|
| 862 | + }; |
---|
| 863 | + |
---|
| 864 | + ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); |
---|
| 865 | + if (ret) |
---|
| 866 | + return ret; |
---|
790 | 867 | |
---|
791 | 868 | switch (level) { |
---|
792 | 869 | case SND_SOC_BIAS_ON: |
---|
793 | | - /* Switch on master clock */ |
---|
794 | | - ret = clk_prepare_enable(aic32x4->mclk); |
---|
| 870 | + ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks); |
---|
795 | 871 | if (ret) { |
---|
796 | | - dev_err(component->dev, "Failed to enable master clock\n"); |
---|
| 872 | + dev_err(component->dev, "Failed to enable clocks\n"); |
---|
797 | 873 | return ret; |
---|
798 | 874 | } |
---|
799 | | - |
---|
800 | | - /* Switch on PLL */ |
---|
801 | | - snd_soc_component_update_bits(component, AIC32X4_PLLPR, |
---|
802 | | - AIC32X4_PLLEN, AIC32X4_PLLEN); |
---|
803 | | - |
---|
804 | | - /* Switch on NDAC Divider */ |
---|
805 | | - snd_soc_component_update_bits(component, AIC32X4_NDAC, |
---|
806 | | - AIC32X4_NDACEN, AIC32X4_NDACEN); |
---|
807 | | - |
---|
808 | | - /* Switch on MDAC Divider */ |
---|
809 | | - snd_soc_component_update_bits(component, AIC32X4_MDAC, |
---|
810 | | - AIC32X4_MDACEN, AIC32X4_MDACEN); |
---|
811 | | - |
---|
812 | | - /* Switch on NADC Divider */ |
---|
813 | | - snd_soc_component_update_bits(component, AIC32X4_NADC, |
---|
814 | | - AIC32X4_NADCEN, AIC32X4_NADCEN); |
---|
815 | | - |
---|
816 | | - /* Switch on MADC Divider */ |
---|
817 | | - snd_soc_component_update_bits(component, AIC32X4_MADC, |
---|
818 | | - AIC32X4_MADCEN, AIC32X4_MADCEN); |
---|
819 | | - |
---|
820 | | - /* Switch on BCLK_N Divider */ |
---|
821 | | - snd_soc_component_update_bits(component, AIC32X4_BCLKN, |
---|
822 | | - AIC32X4_BCLKEN, AIC32X4_BCLKEN); |
---|
823 | 875 | break; |
---|
824 | 876 | case SND_SOC_BIAS_PREPARE: |
---|
825 | 877 | break; |
---|
.. | .. |
---|
828 | 880 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) |
---|
829 | 881 | break; |
---|
830 | 882 | |
---|
831 | | - /* Switch off BCLK_N Divider */ |
---|
832 | | - snd_soc_component_update_bits(component, AIC32X4_BCLKN, |
---|
833 | | - AIC32X4_BCLKEN, 0); |
---|
834 | | - |
---|
835 | | - /* Switch off MADC Divider */ |
---|
836 | | - snd_soc_component_update_bits(component, AIC32X4_MADC, |
---|
837 | | - AIC32X4_MADCEN, 0); |
---|
838 | | - |
---|
839 | | - /* Switch off NADC Divider */ |
---|
840 | | - snd_soc_component_update_bits(component, AIC32X4_NADC, |
---|
841 | | - AIC32X4_NADCEN, 0); |
---|
842 | | - |
---|
843 | | - /* Switch off MDAC Divider */ |
---|
844 | | - snd_soc_component_update_bits(component, AIC32X4_MDAC, |
---|
845 | | - AIC32X4_MDACEN, 0); |
---|
846 | | - |
---|
847 | | - /* Switch off NDAC Divider */ |
---|
848 | | - snd_soc_component_update_bits(component, AIC32X4_NDAC, |
---|
849 | | - AIC32X4_NDACEN, 0); |
---|
850 | | - |
---|
851 | | - /* Switch off PLL */ |
---|
852 | | - snd_soc_component_update_bits(component, AIC32X4_PLLPR, |
---|
853 | | - AIC32X4_PLLEN, 0); |
---|
854 | | - |
---|
855 | | - /* Switch off master clock */ |
---|
856 | | - clk_disable_unprepare(aic32x4->mclk); |
---|
| 883 | + clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); |
---|
857 | 884 | break; |
---|
858 | 885 | case SND_SOC_BIAS_OFF: |
---|
859 | 886 | break; |
---|
.. | .. |
---|
861 | 888 | return 0; |
---|
862 | 889 | } |
---|
863 | 890 | |
---|
864 | | -#define AIC32X4_RATES SNDRV_PCM_RATE_8000_96000 |
---|
865 | | -#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ |
---|
866 | | - | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) |
---|
| 891 | +#define AIC32X4_RATES SNDRV_PCM_RATE_8000_192000 |
---|
| 892 | +#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ |
---|
| 893 | + | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE \ |
---|
| 894 | + | SNDRV_PCM_FMTBIT_S32_LE) |
---|
867 | 895 | |
---|
868 | 896 | static const struct snd_soc_dai_ops aic32x4_ops = { |
---|
869 | 897 | .hw_params = aic32x4_hw_params, |
---|
870 | | - .digital_mute = aic32x4_mute, |
---|
| 898 | + .mute_stream = aic32x4_mute, |
---|
871 | 899 | .set_fmt = aic32x4_set_dai_fmt, |
---|
872 | 900 | .set_sysclk = aic32x4_set_dai_sysclk, |
---|
| 901 | + .no_capture_mute = 1, |
---|
873 | 902 | }; |
---|
874 | 903 | |
---|
875 | 904 | static struct snd_soc_dai_driver aic32x4_dai = { |
---|
876 | 905 | .name = "tlv320aic32x4-hifi", |
---|
877 | 906 | .playback = { |
---|
878 | | - .stream_name = "Playback", |
---|
879 | | - .channels_min = 1, |
---|
880 | | - .channels_max = 2, |
---|
881 | | - .rates = AIC32X4_RATES, |
---|
882 | | - .formats = AIC32X4_FORMATS,}, |
---|
| 907 | + .stream_name = "Playback", |
---|
| 908 | + .channels_min = 1, |
---|
| 909 | + .channels_max = 2, |
---|
| 910 | + .rates = AIC32X4_RATES, |
---|
| 911 | + .formats = AIC32X4_FORMATS,}, |
---|
883 | 912 | .capture = { |
---|
884 | | - .stream_name = "Capture", |
---|
885 | | - .channels_min = 1, |
---|
886 | | - .channels_max = 2, |
---|
887 | | - .rates = AIC32X4_RATES, |
---|
888 | | - .formats = AIC32X4_FORMATS,}, |
---|
| 913 | + .stream_name = "Capture", |
---|
| 914 | + .channels_min = 1, |
---|
| 915 | + .channels_max = 8, |
---|
| 916 | + .rates = AIC32X4_RATES, |
---|
| 917 | + .formats = AIC32X4_FORMATS,}, |
---|
889 | 918 | .ops = &aic32x4_ops, |
---|
890 | 919 | .symmetric_rates = 1, |
---|
891 | 920 | }; |
---|
.. | .. |
---|
898 | 927 | /* MFP1 */ |
---|
899 | 928 | if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) { |
---|
900 | 929 | snd_soc_component_write(component, AIC32X4_DINCTL, |
---|
901 | | - aic32x4->setup->gpio_func[0]); |
---|
| 930 | + aic32x4->setup->gpio_func[0]); |
---|
902 | 931 | snd_soc_add_component_controls(component, aic32x4_mfp1, |
---|
903 | 932 | ARRAY_SIZE(aic32x4_mfp1)); |
---|
904 | 933 | } |
---|
.. | .. |
---|
906 | 935 | /* MFP2 */ |
---|
907 | 936 | if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) { |
---|
908 | 937 | snd_soc_component_write(component, AIC32X4_DOUTCTL, |
---|
909 | | - aic32x4->setup->gpio_func[1]); |
---|
| 938 | + aic32x4->setup->gpio_func[1]); |
---|
910 | 939 | snd_soc_add_component_controls(component, aic32x4_mfp2, |
---|
911 | 940 | ARRAY_SIZE(aic32x4_mfp2)); |
---|
912 | 941 | } |
---|
.. | .. |
---|
914 | 943 | /* MFP3 */ |
---|
915 | 944 | if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) { |
---|
916 | 945 | snd_soc_component_write(component, AIC32X4_SCLKCTL, |
---|
917 | | - aic32x4->setup->gpio_func[2]); |
---|
| 946 | + aic32x4->setup->gpio_func[2]); |
---|
918 | 947 | snd_soc_add_component_controls(component, aic32x4_mfp3, |
---|
919 | 948 | ARRAY_SIZE(aic32x4_mfp3)); |
---|
920 | 949 | } |
---|
.. | .. |
---|
922 | 951 | /* MFP4 */ |
---|
923 | 952 | if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) { |
---|
924 | 953 | snd_soc_component_write(component, AIC32X4_MISOCTL, |
---|
925 | | - aic32x4->setup->gpio_func[3]); |
---|
| 954 | + aic32x4->setup->gpio_func[3]); |
---|
926 | 955 | snd_soc_add_component_controls(component, aic32x4_mfp4, |
---|
927 | 956 | ARRAY_SIZE(aic32x4_mfp4)); |
---|
928 | 957 | } |
---|
.. | .. |
---|
930 | 959 | /* MFP5 */ |
---|
931 | 960 | if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) { |
---|
932 | 961 | snd_soc_component_write(component, AIC32X4_GPIOCTL, |
---|
933 | | - aic32x4->setup->gpio_func[4]); |
---|
| 962 | + aic32x4->setup->gpio_func[4]); |
---|
934 | 963 | snd_soc_add_component_controls(component, aic32x4_mfp5, |
---|
935 | 964 | ARRAY_SIZE(aic32x4_mfp5)); |
---|
936 | 965 | } |
---|
.. | .. |
---|
940 | 969 | { |
---|
941 | 970 | struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); |
---|
942 | 971 | u32 tmp_reg; |
---|
| 972 | + int ret; |
---|
943 | 973 | |
---|
944 | | - if (gpio_is_valid(aic32x4->rstn_gpio)) { |
---|
945 | | - ndelay(10); |
---|
946 | | - gpio_set_value(aic32x4->rstn_gpio, 1); |
---|
947 | | - } |
---|
| 974 | + struct clk_bulk_data clocks[] = { |
---|
| 975 | + { .id = "codec_clkin" }, |
---|
| 976 | + { .id = "pll" }, |
---|
| 977 | + { .id = "bdiv" }, |
---|
| 978 | + { .id = "mdac" }, |
---|
| 979 | + }; |
---|
948 | 980 | |
---|
949 | | - snd_soc_component_write(component, AIC32X4_RESET, 0x01); |
---|
| 981 | + ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); |
---|
| 982 | + if (ret) |
---|
| 983 | + return ret; |
---|
950 | 984 | |
---|
951 | 985 | if (aic32x4->setup) |
---|
952 | 986 | aic32x4_setup_gpios(component); |
---|
953 | 987 | |
---|
| 988 | + clk_set_parent(clocks[0].clk, clocks[1].clk); |
---|
| 989 | + clk_set_parent(clocks[2].clk, clocks[3].clk); |
---|
| 990 | + |
---|
954 | 991 | /* Power platform configuration */ |
---|
955 | 992 | if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { |
---|
956 | | - snd_soc_component_write(component, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN | |
---|
957 | | - AIC32X4_MICBIAS_2075V); |
---|
| 993 | + snd_soc_component_write(component, AIC32X4_MICBIAS, |
---|
| 994 | + AIC32X4_MICBIAS_LDOIN | AIC32X4_MICBIAS_2075V); |
---|
958 | 995 | } |
---|
959 | 996 | if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) |
---|
960 | 997 | snd_soc_component_write(component, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); |
---|
.. | .. |
---|
963 | 1000 | AIC32X4_LDOCTLEN : 0; |
---|
964 | 1001 | snd_soc_component_write(component, AIC32X4_LDOCTL, tmp_reg); |
---|
965 | 1002 | |
---|
966 | | - tmp_reg = snd_soc_component_read32(component, AIC32X4_CMMODE); |
---|
| 1003 | + tmp_reg = snd_soc_component_read(component, AIC32X4_CMMODE); |
---|
967 | 1004 | if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) |
---|
968 | 1005 | tmp_reg |= AIC32X4_LDOIN_18_36; |
---|
969 | 1006 | if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) |
---|
.. | .. |
---|
989 | 1026 | * and down for the first capture to work properly. It seems related to |
---|
990 | 1027 | * a HW BUG or some kind of behavior not documented in the datasheet. |
---|
991 | 1028 | */ |
---|
992 | | - tmp_reg = snd_soc_component_read32(component, AIC32X4_ADCSETUP); |
---|
| 1029 | + tmp_reg = snd_soc_component_read(component, AIC32X4_ADCSETUP); |
---|
993 | 1030 | snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg | |
---|
994 | 1031 | AIC32X4_LADC_EN | AIC32X4_RADC_EN); |
---|
995 | 1032 | snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg); |
---|
| 1033 | + |
---|
| 1034 | + /* |
---|
| 1035 | + * Enable the fast charging feature and ensure the needed 40ms ellapsed |
---|
| 1036 | + * before using the analog circuits. |
---|
| 1037 | + */ |
---|
| 1038 | + snd_soc_component_write(component, AIC32X4_REFPOWERUP, |
---|
| 1039 | + AIC32X4_REFPOWERUP_40MS); |
---|
| 1040 | + msleep(40); |
---|
996 | 1041 | |
---|
997 | 1042 | return 0; |
---|
998 | 1043 | } |
---|
.. | .. |
---|
1017 | 1062 | struct device_node *np) |
---|
1018 | 1063 | { |
---|
1019 | 1064 | struct aic32x4_setup_data *aic32x4_setup; |
---|
| 1065 | + int ret; |
---|
1020 | 1066 | |
---|
1021 | 1067 | aic32x4_setup = devm_kzalloc(aic32x4->dev, sizeof(*aic32x4_setup), |
---|
1022 | 1068 | GFP_KERNEL); |
---|
1023 | 1069 | if (!aic32x4_setup) |
---|
1024 | 1070 | return -ENOMEM; |
---|
| 1071 | + |
---|
| 1072 | + ret = of_property_match_string(np, "clock-names", "mclk"); |
---|
| 1073 | + if (ret < 0) |
---|
| 1074 | + return -EINVAL; |
---|
| 1075 | + aic32x4->mclk_name = of_clk_get_parent_name(np, ret); |
---|
1025 | 1076 | |
---|
1026 | 1077 | aic32x4->swapdacs = false; |
---|
1027 | 1078 | aic32x4->micpga_routing = 0; |
---|
.. | .. |
---|
1077 | 1128 | return PTR_ERR(aic32x4->supply_av); |
---|
1078 | 1129 | } |
---|
1079 | 1130 | } else { |
---|
1080 | | - if (IS_ERR(aic32x4->supply_dv) && |
---|
1081 | | - PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER) |
---|
| 1131 | + if (PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER) |
---|
1082 | 1132 | return -EPROBE_DEFER; |
---|
1083 | | - if (IS_ERR(aic32x4->supply_av) && |
---|
1084 | | - PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER) |
---|
| 1133 | + if (PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER) |
---|
1085 | 1134 | return -EPROBE_DEFER; |
---|
1086 | 1135 | } |
---|
1087 | 1136 | |
---|
.. | .. |
---|
1144 | 1193 | return PTR_ERR(regmap); |
---|
1145 | 1194 | |
---|
1146 | 1195 | aic32x4 = devm_kzalloc(dev, sizeof(struct aic32x4_priv), |
---|
1147 | | - GFP_KERNEL); |
---|
| 1196 | + GFP_KERNEL); |
---|
1148 | 1197 | if (aic32x4 == NULL) |
---|
1149 | 1198 | return -ENOMEM; |
---|
1150 | 1199 | |
---|
.. | .. |
---|
1156 | 1205 | aic32x4->swapdacs = pdata->swapdacs; |
---|
1157 | 1206 | aic32x4->micpga_routing = pdata->micpga_routing; |
---|
1158 | 1207 | aic32x4->rstn_gpio = pdata->rstn_gpio; |
---|
| 1208 | + aic32x4->mclk_name = "mclk"; |
---|
1159 | 1209 | } else if (np) { |
---|
1160 | 1210 | ret = aic32x4_parse_dt(aic32x4, np); |
---|
1161 | 1211 | if (ret) { |
---|
.. | .. |
---|
1167 | 1217 | aic32x4->swapdacs = false; |
---|
1168 | 1218 | aic32x4->micpga_routing = 0; |
---|
1169 | 1219 | aic32x4->rstn_gpio = -1; |
---|
1170 | | - } |
---|
1171 | | - |
---|
1172 | | - aic32x4->mclk = devm_clk_get(dev, "mclk"); |
---|
1173 | | - if (IS_ERR(aic32x4->mclk)) { |
---|
1174 | | - dev_err(dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n"); |
---|
1175 | | - return PTR_ERR(aic32x4->mclk); |
---|
| 1220 | + aic32x4->mclk_name = "mclk"; |
---|
1176 | 1221 | } |
---|
1177 | 1222 | |
---|
1178 | 1223 | if (gpio_is_valid(aic32x4->rstn_gpio)) { |
---|
.. | .. |
---|
1188 | 1233 | return ret; |
---|
1189 | 1234 | } |
---|
1190 | 1235 | |
---|
| 1236 | + if (gpio_is_valid(aic32x4->rstn_gpio)) { |
---|
| 1237 | + ndelay(10); |
---|
| 1238 | + gpio_set_value_cansleep(aic32x4->rstn_gpio, 1); |
---|
| 1239 | + mdelay(1); |
---|
| 1240 | + } |
---|
| 1241 | + |
---|
| 1242 | + ret = regmap_write(regmap, AIC32X4_RESET, 0x01); |
---|
| 1243 | + if (ret) |
---|
| 1244 | + goto err_disable_regulators; |
---|
| 1245 | + |
---|
| 1246 | + ret = aic32x4_register_clocks(dev, aic32x4->mclk_name); |
---|
| 1247 | + if (ret) |
---|
| 1248 | + goto err_disable_regulators; |
---|
| 1249 | + |
---|
1191 | 1250 | ret = devm_snd_soc_register_component(dev, |
---|
1192 | 1251 | &soc_component_dev_aic32x4, &aic32x4_dai, 1); |
---|
1193 | 1252 | if (ret) { |
---|
1194 | 1253 | dev_err(dev, "Failed to register component\n"); |
---|
1195 | | - aic32x4_disable_regulators(aic32x4); |
---|
1196 | | - return ret; |
---|
| 1254 | + goto err_disable_regulators; |
---|
1197 | 1255 | } |
---|
1198 | 1256 | |
---|
1199 | 1257 | return 0; |
---|
| 1258 | + |
---|
| 1259 | +err_disable_regulators: |
---|
| 1260 | + aic32x4_disable_regulators(aic32x4); |
---|
| 1261 | + |
---|
| 1262 | + return ret; |
---|
1200 | 1263 | } |
---|
1201 | 1264 | EXPORT_SYMBOL(aic32x4_probe); |
---|
1202 | 1265 | |
---|