~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/nau8325.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 //
  3 // nau8325.c -- Nuvoton NAU8325 audio codec driver
  4 //
  5 // Copyright 2023 Nuvoton Technology Crop.
  6 // Author: Seven Lee <WTLI@nuvoton.com>
  7 //         David Lin <CTLIN0@nuvoton.com>
  8 //
  9 
 10 #include <linux/clk.h>
 11 #include <linux/delay.h>
 12 #include <linux/init.h>
 13 #include <linux/i2c.h>
 14 #include <linux/module.h>
 15 #include <linux/regmap.h>
 16 #include <linux/slab.h>
 17 #include <sound/core.h>
 18 #include <sound/initval.h>
 19 #include <sound/pcm.h>
 20 #include <sound/pcm_params.h>
 21 #include <sound/soc.h>
 22 #include <sound/tlv.h>
 23 #include "nau8325.h"
 24 
 25 /* Range of Master Clock MCLK (Hz) */
 26 #define MASTER_CLK_MAX 49152000
 27 #define MASTER_CLK_MIN 2048000
 28 
 29 /* scaling for MCLK source */
 30 #define CLK_PROC_BYPASS (-1)
 31 
 32 /* the maximum CLK_DAC */
 33 #define CLK_DA_AD_MAX 6144000
 34 
 35 /* from MCLK input */
 36 #define MCLK_SRC 4
 37 
 38 static const struct nau8325_src_attr mclk_n1_div[] = {
 39         { 1, 0x0 },
 40         { 2, 0x1 },
 41         { 3, 0x2 },
 42 };
 43 
 44 /* over sampling rate */
 45 static const struct nau8325_osr_attr osr_dac_sel[] = {
 46         { 64, 2 },      /* OSR 64, SRC 1/4 */
 47         { 256, 0 },     /* OSR 256, SRC 1 */
 48         { 128, 1 },     /* OSR 128, SRC 1/2 */
 49         { 0, 0 },
 50         { 32, 3 },      /* OSR 32, SRC 1/8 */
 51 };
 52 
 53 static const struct nau8325_src_attr mclk_n2_div[] = {
 54         { 0, 0x0 },
 55         { 1, 0x1 },
 56         { 2, 0x2 },
 57         { 3, 0x3 },
 58         { 4, 0x4 },
 59 };
 60 
 61 static const struct nau8325_src_attr mclk_n3_mult[] = {
 62         { 0, 0x1 },
 63         { 1, 0x2 },
 64         { 2, 0x3 },
 65         { 3, 0x4 },
 66 };
 67 
 68 /* Sample Rate and MCLK_SRC selections */
 69 static const struct nau8325_srate_attr target_srate_table[] = {
 70         /* { FS, range, max, { MCLK source }} */
 71         { 48000, 2, true, { 12288000, 19200000, 24000000 } },
 72         { 16000, 1, false, { 4096000, 6400000, 8000000 } },
 73         { 8000, 0, false, { 2048000, 3200000, 4000000 }},
 74         { 44100, 2, true, { 11289600, 17640000, 22050000 }},
 75         { 64000, 3, false, { 16384000, 25600000, 32000000 } },
 76         { 96000, 3, true, { 24576000, 38400000, 48000000 } },
 77         { 12000, 0, true, { 3072000, 4800000, 6000000 } },
 78         { 24000, 1, true, { 6144000, 9600000, 12000000 } },
 79         { 32000, 2, false, { 8192000, 12800000, 16000000 } },
 80 };
 81 
 82 static const struct reg_default nau8325_reg_defaults[] = {
 83         { NAU8325_R00_HARDWARE_RST, 0x0000 },
 84         { NAU8325_R01_SOFTWARE_RST, 0x0000 },
 85         { NAU8325_R03_CLK_CTRL, 0x0000 },
 86         { NAU8325_R04_ENA_CTRL, 0x0000 },
 87         { NAU8325_R05_INTERRUPT_CTRL, 0x007f },
 88         { NAU8325_R09_IRQOUT, 0x0000 },
 89         { NAU8325_R0A_IO_CTRL, 0x0000 },
 90         { NAU8325_R0B_PDM_CTRL, 0x0000 },
 91         { NAU8325_R0C_TDM_CTRL, 0x0000 },
 92         { NAU8325_R0D_I2S_PCM_CTRL1, 0x000a },
 93         { NAU8325_R0E_I2S_PCM_CTRL2, 0x0000 },
 94         { NAU8325_R0F_L_TIME_SLOT, 0x0000 },
 95         { NAU8325_R10_R_TIME_SLOT, 0x0000 },
 96         { NAU8325_R11_HPF_CTRL, 0x0000 },
 97         { NAU8325_R12_MUTE_CTRL, 0x0000 },
 98         { NAU8325_R13_DAC_VOLUME, 0xf3f3 },
 99         { NAU8325_R29_DAC_CTRL1, 0x0081 },
100         { NAU8325_R2A_DAC_CTRL2, 0x0000 },
101         { NAU8325_R2C_ALC_CTRL1, 0x000e },
102         { NAU8325_R2D_ALC_CTRL2, 0x8400 },
103         { NAU8325_R2E_ALC_CTRL3, 0x0000 },
104         { NAU8325_R2F_ALC_CTRL4, 0x003f },
105         { NAU8325_R40_CLK_DET_CTRL, 0xa801 },
106         { NAU8325_R50_MIXER_CTRL, 0x0000 },
107         { NAU8325_R55_MISC_CTRL, 0x0000 },
108         { NAU8325_R60_BIAS_ADJ, 0x0000 },
109         { NAU8325_R61_ANALOG_CONTROL_1, 0x0000 },
110         { NAU8325_R62_ANALOG_CONTROL_2, 0x0000 },
111         { NAU8325_R63_ANALOG_CONTROL_3, 0x0000 },
112         { NAU8325_R64_ANALOG_CONTROL_4, 0x0000 },
113         { NAU8325_R65_ANALOG_CONTROL_5, 0x0000 },
114         { NAU8325_R66_ANALOG_CONTROL_6, 0x0000 },
115         { NAU8325_R69_CLIP_CTRL, 0x0000 },
116         { NAU8325_R73_RDAC, 0x0008 },
117 };
118 
119 static bool nau8325_readable_reg(struct device *dev, unsigned int reg)
120 {
121         switch (reg) {
122         case NAU8325_R02_DEVICE_ID ... NAU8325_R06_INT_CLR_STATUS:
123         case NAU8325_R09_IRQOUT ... NAU8325_R13_DAC_VOLUME:
124         case NAU8325_R1D_DEBUG_READ1:
125         case NAU8325_R1F_DEBUG_READ2:
126         case NAU8325_R22_DEBUG_READ3:
127         case NAU8325_R29_DAC_CTRL1 ... NAU8325_R2A_DAC_CTRL2:
128         case NAU8325_R2C_ALC_CTRL1 ... NAU8325_R2F_ALC_CTRL4:
129         case NAU8325_R40_CLK_DET_CTRL:
130         case NAU8325_R49_TEST_STATUS ... NAU8325_R4A_ANALOG_READ:
131         case NAU8325_R50_MIXER_CTRL:
132         case NAU8325_R55_MISC_CTRL:
133         case NAU8325_R60_BIAS_ADJ ... NAU8325_R66_ANALOG_CONTROL_6:
134         case NAU8325_R69_CLIP_CTRL:
135         case NAU8325_R73_RDAC:
136                 return true;
137         default:
138                 return false;
139         }
140 }
141 
142 static bool nau8325_writeable_reg(struct device *dev, unsigned int reg)
143 {
144         switch (reg) {
145         case NAU8325_R00_HARDWARE_RST:
146         case NAU8325_R03_CLK_CTRL ... NAU8325_R06_INT_CLR_STATUS:
147         case NAU8325_R09_IRQOUT ... NAU8325_R13_DAC_VOLUME:
148         case NAU8325_R29_DAC_CTRL1 ... NAU8325_R2A_DAC_CTRL2:
149         case NAU8325_R2C_ALC_CTRL1 ... NAU8325_R2F_ALC_CTRL4:
150         case NAU8325_R40_CLK_DET_CTRL:
151         case NAU8325_R50_MIXER_CTRL:
152         case NAU8325_R55_MISC_CTRL:
153         case NAU8325_R60_BIAS_ADJ ... NAU8325_R66_ANALOG_CONTROL_6:
154         case NAU8325_R69_CLIP_CTRL:
155         case NAU8325_R73_RDAC:
156                 return true;
157         default:
158                 return false;
159         }
160 }
161 
162 static bool nau8325_volatile_reg(struct device *dev, unsigned int reg)
163 {
164         switch (reg) {
165         case NAU8325_R00_HARDWARE_RST ... NAU8325_R02_DEVICE_ID:
166         case NAU8325_R06_INT_CLR_STATUS:
167         case NAU8325_R1D_DEBUG_READ1:
168         case NAU8325_R1F_DEBUG_READ2:
169         case NAU8325_R22_DEBUG_READ3:
170         case NAU8325_R4A_ANALOG_READ:
171                 return true;
172         default:
173                 return false;
174         }
175 }
176 
177 static const char * const nau8325_dac_oversampl_texts[] = {
178         "64", "256", "128", "32",
179 };
180 
181 static const unsigned int nau8325_dac_oversampl_values[] = {
182         0, 1, 2, 4,
183 };
184 
185 static const struct soc_enum nau8325_dac_oversampl_enum =
186         SOC_VALUE_ENUM_SINGLE(NAU8325_R29_DAC_CTRL1,
187                               NAU8325_DAC_OVERSAMPLE_SFT, 0x7,
188                               ARRAY_SIZE(nau8325_dac_oversampl_texts),
189                               nau8325_dac_oversampl_texts,
190                               nau8325_dac_oversampl_values);
191 
192 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_vol_tlv, -8000, 600);
193 
194 static const struct snd_kcontrol_new nau8325_snd_controls[] = {
195         SOC_ENUM("DAC Oversampling Rate", nau8325_dac_oversampl_enum),
196         SOC_DOUBLE_TLV("Speaker Volume", NAU8325_R13_DAC_VOLUME,
197                        NAU8325_DAC_VOLUME_L_SFT, NAU8325_DAC_VOLUME_R_SFT,
198                        NAU8325_DAC_VOLUME_R_EN, 0, dac_vol_tlv),
199         SOC_SINGLE("ALC Max Gain", NAU8325_R2C_ALC_CTRL1,
200                    NAU8325_ALC_MAXGAIN_SFT, NAU8325_ALC_MAXGAIN_MAX, 0),
201         SOC_SINGLE("ALC Min Gain", NAU8325_R2C_ALC_CTRL1,
202                    NAU8325_ALC_MINGAIN_SFT, NAU8325_ALC_MINGAIN_MAX, 0),
203         SOC_SINGLE("ALC Decay Timer", NAU8325_R2D_ALC_CTRL2,
204                    NAU8325_ALC_DCY_SFT, NAU8325_ALC_DCY_MAX, 0),
205         SOC_SINGLE("ALC Attack Timer", NAU8325_R2D_ALC_CTRL2,
206                    NAU8325_ALC_ATK_SFT, NAU8325_ALC_ATK_MAX, 0),
207         SOC_SINGLE("ALC Hold Time", NAU8325_R2D_ALC_CTRL2,
208                    NAU8325_ALC_HLD_SFT, NAU8325_ALC_HLD_MAX, 0),
209         SOC_SINGLE("ALC Target Level", NAU8325_R2D_ALC_CTRL2,
210                    NAU8325_ALC_LVL_SFT, NAU8325_ALC_LVL_MAX, 0),
211         SOC_SINGLE("ALC Enable Switch", NAU8325_R2E_ALC_CTRL3,
212                    NAU8325_ALC_EN_SFT, 1, 0),
213 };
214 
215 static int nau8325_dac_event(struct snd_soc_dapm_widget *w,
216                              struct snd_kcontrol *kcontrol, int event)
217 {
218         struct snd_soc_component *component =
219                 snd_soc_dapm_to_component(w->dapm);
220         struct nau8325 *nau8325 = snd_soc_component_get_drvdata(component);
221 
222         switch (event) {
223         case SND_SOC_DAPM_POST_PMU:
224                 regmap_update_bits(nau8325->regmap, NAU8325_R12_MUTE_CTRL,
225                                    NAU8325_SOFT_MUTE, 0);
226                 msleep(30);
227                 break;
228         case SND_SOC_DAPM_PRE_PMD:
229                 /* Soft mute the output to prevent the pop noise. */
230                 regmap_update_bits(nau8325->regmap, NAU8325_R12_MUTE_CTRL,
231                                    NAU8325_SOFT_MUTE, NAU8325_SOFT_MUTE);
232                 msleep(30);
233                 break;
234         default:
235                 return -EINVAL;
236         }
237 
238         return 0;
239 }
240 
241 static int nau8325_powerup_event(struct snd_soc_dapm_widget *w,
242                                  struct snd_kcontrol *kcontrol, int event)
243 {
244         struct snd_soc_component *component =
245                 snd_soc_dapm_to_component(w->dapm);
246         struct nau8325 *nau8325 = snd_soc_component_get_drvdata(component);
247 
248         if (nau8325->clock_detection)
249                 return 0;
250 
251         switch (event) {
252         case SND_SOC_DAPM_POST_PMU:
253                 regmap_update_bits(nau8325->regmap, NAU8325_R40_CLK_DET_CTRL,
254                                    NAU8325_PWRUP_DFT, NAU8325_PWRUP_DFT);
255                 break;
256         case SND_SOC_DAPM_POST_PMD:
257                 regmap_update_bits(nau8325->regmap, NAU8325_R40_CLK_DET_CTRL,
258                                    NAU8325_PWRUP_DFT, 0);
259                 break;
260         default:
261                 return -EINVAL;
262         }
263 
264         return 0;
265 }
266 
267 static const struct snd_soc_dapm_widget nau8325_dapm_widgets[] = {
268         SND_SOC_DAPM_SUPPLY("Power Up", SND_SOC_NOPM, 0, 0,
269                             nau8325_powerup_event, SND_SOC_DAPM_POST_PMU |
270                             SND_SOC_DAPM_POST_PMD),
271         SND_SOC_DAPM_DAC_E("DACL", NULL, NAU8325_R04_ENA_CTRL,
272                            NAU8325_DAC_LEFT_CH_EN_SFT, 0, nau8325_dac_event,
273                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
274         SND_SOC_DAPM_DAC_E("DACR", NULL, NAU8325_R04_ENA_CTRL,
275                            NAU8325_DAC_RIGHT_CH_EN_SFT, 0, nau8325_dac_event,
276                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
277         SND_SOC_DAPM_AIF_IN("AIFRX", "Playback", 0, SND_SOC_NOPM, 0, 0),
278 
279         SND_SOC_DAPM_OUTPUT("SPKL"),
280         SND_SOC_DAPM_OUTPUT("SPKR"),
281 };
282 
283 static const struct snd_soc_dapm_route nau8325_dapm_routes[] = {
284         { "DACL", NULL, "Power Up" },
285         { "DACR", NULL, "Power Up" },
286 
287         { "DACL", NULL, "AIFRX" },
288         { "DACR", NULL, "AIFRX" },
289         { "SPKL", NULL, "DACL" },
290         { "SPKR", NULL, "DACR" },
291 };
292 
293 static int nau8325_srate_clk_apply(struct nau8325 *nau8325,
294                                    const struct nau8325_srate_attr *srate_table,
295                                    int n1_sel, int mclk_mult_sel, int n2_sel)
296 {
297         if (!srate_table || n2_sel < 0 || n2_sel >= ARRAY_SIZE(mclk_n2_div) ||
298             n1_sel < 0 || n1_sel >= ARRAY_SIZE(mclk_n1_div)) {
299                 dev_dbg(nau8325->dev, "The CLK isn't supported.");
300                 return -EINVAL;
301         }
302 
303         regmap_update_bits(nau8325->regmap, NAU8325_R40_CLK_DET_CTRL,
304                            NAU8325_REG_SRATE_MASK | NAU8325_REG_DIV_MAX,
305                            (srate_table->range << NAU8325_REG_SRATE_SFT) |
306                            (srate_table->max ? NAU8325_REG_DIV_MAX : 0));
307         regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL,
308                            NAU8325_MCLK_SRC_MASK, mclk_n2_div[n2_sel].val);
309         regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL,
310                            NAU8325_CLK_MUL_SRC_MASK,
311                            mclk_n1_div[n1_sel].val << NAU8325_CLK_MUL_SRC_SFT);
312 
313         if (mclk_mult_sel != CLK_PROC_BYPASS) {
314                 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL,
315                                    NAU8325_MCLK_SEL_MASK,
316                                    mclk_n3_mult[mclk_mult_sel].val <<
317                                    NAU8325_MCLK_SEL_SFT);
318         } else {
319                 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL,
320                                    NAU8325_MCLK_SEL_MASK, 0);
321         }
322 
323         switch (mclk_mult_sel) {
324         case 2:
325                 regmap_update_bits(nau8325->regmap, NAU8325_R65_ANALOG_CONTROL_5,
326                                    NAU8325_MCLK4XEN_EN, NAU8325_MCLK4XEN_EN);
327                 break;
328         case 3:
329                 regmap_update_bits(nau8325->regmap, NAU8325_R65_ANALOG_CONTROL_5,
330                                    NAU8325_MCLK4XEN_EN | NAU8325_MCLK8XEN_EN,
331                                    NAU8325_MCLK4XEN_EN | NAU8325_MCLK8XEN_EN);
332                 break;
333         default:
334                 regmap_update_bits(nau8325->regmap, NAU8325_R65_ANALOG_CONTROL_5,
335                                    NAU8325_MCLK4XEN_EN | NAU8325_MCLK8XEN_EN, 0);
336                 break;
337         }
338 
339         return 0;
340 }
341 
342 static int nau8325_clksrc_n2(struct nau8325 *nau8325,
343                              const struct nau8325_srate_attr *srate_table,
344                              int mclk, int *n2_sel)
345 {
346         int i, mclk_src, ratio;
347 
348         ratio = NAU8325_MCLK_FS_RATIO_NUM;
349         for (i = 0; i < ARRAY_SIZE(mclk_n2_div); i++) {
350                 mclk_src = mclk >> mclk_n2_div[i].param;
351                 if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_256] == mclk_src) {
352                         ratio = NAU8325_MCLK_FS_RATIO_256;
353                         break;
354                 } else if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_400] == mclk_src) {
355                         ratio = NAU8325_MCLK_FS_RATIO_400;
356                         break;
357                 } else if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_500] == mclk_src) {
358                         ratio = NAU8325_MCLK_FS_RATIO_500;
359                         break;
360                 }
361         }
362         if (ratio != NAU8325_MCLK_FS_RATIO_NUM)
363                 *n2_sel = i;
364 
365         return ratio;
366 }
367 
368 static const struct nau8325_srate_attr *target_srate_attribute(int srate)
369 {
370         int i;
371 
372         for (i = 0; i < ARRAY_SIZE(target_srate_table); i++)
373                 if (target_srate_table[i].fs == srate)
374                         break;
375 
376         if (i == ARRAY_SIZE(target_srate_table))
377                 goto proc_err;
378 
379         return &target_srate_table[i];
380 
381 proc_err:
382         return NULL;
383 }
384 
385 static int nau8325_clksrc_choose(struct nau8325 *nau8325,
386                                  const struct nau8325_srate_attr **srate_table,
387                                  int *n1_sel, int *mult_sel, int *n2_sel)
388 {
389         int i, j, mclk, mclk_max, ratio, ratio_sel, n2_max;
390 
391         if (!nau8325->mclk || !nau8325->fs)
392                 goto proc_err;
393 
394         /* select sampling rate and MCLK_SRC */
395         *srate_table = target_srate_attribute(nau8325->fs);
396         if (!*srate_table)
397                 goto proc_err;
398 
399         /* First check clock from MCLK directly, decide N2 for MCLK_SRC.
400          * If not good, consider 1/N1 and Multiplier.
401          */
402         ratio = nau8325_clksrc_n2(nau8325, *srate_table, nau8325->mclk, n2_sel);
403         if (ratio != NAU8325_MCLK_FS_RATIO_NUM) {
404                 *n1_sel = 0;
405                 *mult_sel = CLK_PROC_BYPASS;
406                 *n2_sel = MCLK_SRC;
407                 goto proc_done;
408         }
409 
410         /* Get MCLK_SRC through 1/N, Multiplier, and then 1/N2. */
411         mclk_max = 0;
412         for (i = 0; i < ARRAY_SIZE(mclk_n1_div); i++) {
413                 for (j = 0; j < ARRAY_SIZE(mclk_n3_mult); j++) {
414                         mclk = nau8325->mclk << mclk_n3_mult[j].param;
415                         mclk = mclk / mclk_n1_div[i].param;
416                         ratio = nau8325_clksrc_n2(nau8325,
417                                                   *srate_table, mclk, n2_sel);
418                         if (ratio != NAU8325_MCLK_FS_RATIO_NUM &&
419                             (mclk_max < mclk || i > *n1_sel)) {
420                                 mclk_max = mclk;
421                                 n2_max = *n2_sel;
422                                 *n1_sel = i;
423                                 *mult_sel = j;
424                                 ratio_sel = ratio;
425                                         goto proc_done;
426                         }
427                 }
428         }
429         if (mclk_max) {
430                 *n2_sel = n2_max;
431                 ratio = ratio_sel;
432                 goto proc_done;
433         }
434 
435 proc_err:
436         dev_dbg(nau8325->dev, "The MCLK %d is invalid. It can't get MCLK_SRC of 256/400/500 FS (%d)",
437                 nau8325->mclk, nau8325->fs);
438         return -EINVAL;
439 proc_done:
440         dev_dbg(nau8325->dev, "nau8325->fs=%d,range=0x%x, %s, (n1,mu,n2,dmu):(%d,%d,%d), MCLK_SRC=%uHz (%d)",
441                 nau8325->fs, (*srate_table)->range,
442                 (*srate_table)->max ? "MAX" : "MIN",
443                 *n1_sel == CLK_PROC_BYPASS ?
444                 CLK_PROC_BYPASS : mclk_n1_div[*n1_sel].param,
445                 *mult_sel == CLK_PROC_BYPASS ?
446                 CLK_PROC_BYPASS : 1 << mclk_n3_mult[*mult_sel].param,
447                 1 << mclk_n2_div[*n2_sel].param,
448                 (*srate_table)->mclk_src[ratio],
449                 (*srate_table)->mclk_src[ratio] / nau8325->fs);
450 
451         return 0;
452 }
453 
454 static int nau8325_clock_config(struct nau8325 *nau8325)
455 {
456         const struct nau8325_srate_attr *srate_table;
457         int ret, n1_sel, mult_sel, n2_sel;
458 
459         ret = nau8325_clksrc_choose(nau8325, &srate_table,
460                                     &n1_sel, &mult_sel, &n2_sel);
461         if (ret)
462                 goto err;
463 
464         ret = nau8325_srate_clk_apply(nau8325, srate_table,
465                                       n1_sel, mult_sel, n2_sel);
466         if (ret)
467                 goto err;
468 
469         return 0;
470 err:
471         return ret;
472 }
473 
474 static const struct nau8325_osr_attr *nau8325_get_osr(struct nau8325 *nau8325)
475 {
476         unsigned int osr;
477 
478         regmap_read(nau8325->regmap, NAU8325_R29_DAC_CTRL1, &osr);
479         osr &= NAU8325_DAC_OVERSAMPLE_MASK;
480         if (osr >= ARRAY_SIZE(osr_dac_sel))
481                 return NULL;
482 
483         return &osr_dac_sel[osr];
484 }
485 
486 static int nau8325_dai_startup(struct snd_pcm_substream *substream,
487                                struct snd_soc_dai *dai)
488 {
489         struct snd_soc_component *component = dai->component;
490         struct nau8325 *nau8325 = snd_soc_component_get_drvdata(component);
491         const struct nau8325_osr_attr *osr;
492 
493         osr = nau8325_get_osr(nau8325);
494         if (!osr || !osr->osr)
495                 return -EINVAL;
496 
497         return snd_pcm_hw_constraint_minmax(substream->runtime,
498                                             SNDRV_PCM_HW_PARAM_RATE,
499                                             0, CLK_DA_AD_MAX / osr->osr);
500 }
501 
502 static int nau8325_hw_params(struct snd_pcm_substream *substream,
503                              struct snd_pcm_hw_params *params,
504                              struct snd_soc_dai *dai)
505 {
506         struct snd_soc_component *component = dai->component;
507         struct nau8325 *nau8325 = snd_soc_component_get_drvdata(component);
508         unsigned int val_len = 0;
509         const struct nau8325_osr_attr *osr;
510         int ret;
511 
512         nau8325->fs = params_rate(params);
513         osr = nau8325_get_osr(nau8325);
514         if (!osr || !osr->osr || nau8325->fs * osr->osr > CLK_DA_AD_MAX) {
515                 ret = -EINVAL;
516                 goto err;
517         }
518         regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL,
519                            NAU8325_CLK_DAC_SRC_MASK,
520                            osr->clk_src << NAU8325_CLK_DAC_SRC_SFT);
521 
522         ret = nau8325_clock_config(nau8325);
523         if (ret)
524                 goto err;
525 
526         switch (params_width(params)) {
527         case 16:
528                 val_len |= NAU8325_I2S_DL_16;
529                 break;
530         case 20:
531                 val_len |= NAU8325_I2S_DL_20;
532                 break;
533         case 24:
534                 val_len |= NAU8325_I2S_DL_24;
535                 break;
536         case 32:
537                 val_len |= NAU8325_I2S_DL_32;
538                 break;
539         default:
540                 ret = -EINVAL;
541                 goto err;
542         }
543 
544         regmap_update_bits(nau8325->regmap, NAU8325_R0D_I2S_PCM_CTRL1,
545                            NAU8325_I2S_DL_MASK, val_len);
546 
547         return 0;
548 
549 err:
550         return ret;
551 }
552 
553 static int nau8325_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
554 {
555         struct snd_soc_component *component = dai->component;
556         struct nau8325 *nau8325 = snd_soc_component_get_drvdata(component);
557         unsigned int ctrl1_val = 0;
558 
559         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
560         case SND_SOC_DAIFMT_CBC_CFC:
561                 break;
562         default:
563                 return -EINVAL;
564         }
565 
566         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
567         case SND_SOC_DAIFMT_NB_NF:
568                 break;
569         case SND_SOC_DAIFMT_IB_NF:
570                 ctrl1_val |= NAU8325_I2S_BP_INV;
571                 break;
572         default:
573                 return -EINVAL;
574         }
575 
576         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
577         case SND_SOC_DAIFMT_I2S:
578                 ctrl1_val |= NAU8325_I2S_DF_I2S;
579                 break;
580         case SND_SOC_DAIFMT_LEFT_J:
581                 ctrl1_val |= NAU8325_I2S_DF_LEFT;
582                 break;
583         case SND_SOC_DAIFMT_RIGHT_J:
584                 ctrl1_val |= NAU8325_I2S_DF_RIGTH;
585                 break;
586         case SND_SOC_DAIFMT_DSP_A:
587                 ctrl1_val |= NAU8325_I2S_DF_PCM_AB;
588                 break;
589         case SND_SOC_DAIFMT_DSP_B:
590                 ctrl1_val |= NAU8325_I2S_DF_PCM_AB;
591                 ctrl1_val |= NAU8325_I2S_PCMB_EN;
592                 break;
593         default:
594                 return -EINVAL;
595         }
596 
597         regmap_update_bits(nau8325->regmap, NAU8325_R0D_I2S_PCM_CTRL1,
598                            NAU8325_I2S_DF_MASK | NAU8325_I2S_BP_MASK |
599                            NAU8325_I2S_PCMB_EN, ctrl1_val);
600 
601         return 0;
602 }
603 
604 static int nau8325_set_sysclk(struct snd_soc_component *component, int clk_id,
605                               int source, unsigned int freq, int dir)
606 {
607         struct nau8325 *nau8325 = snd_soc_component_get_drvdata(component);
608 
609         if (freq < MASTER_CLK_MIN || freq > MASTER_CLK_MAX) {
610                 dev_dbg(nau8325->dev, "MCLK exceeds the range, MCLK:%d", freq);
611                 return -EINVAL;
612         }
613 
614         nau8325->mclk = freq;
615         dev_dbg(nau8325->dev, "MCLK %dHz", nau8325->mclk);
616 
617         return 0;
618 }
619 
620 static const struct snd_soc_component_driver nau8325_component_driver = {
621         .set_sysclk = nau8325_set_sysclk,
622         .suspend_bias_off = true,
623         .controls = nau8325_snd_controls,
624         .num_controls = ARRAY_SIZE(nau8325_snd_controls),
625         .dapm_widgets = nau8325_dapm_widgets,
626         .num_dapm_widgets = ARRAY_SIZE(nau8325_dapm_widgets),
627         .dapm_routes = nau8325_dapm_routes,
628         .num_dapm_routes = ARRAY_SIZE(nau8325_dapm_routes),
629 };
630 
631 static const struct snd_soc_dai_ops nau8325_dai_ops = {
632         .startup = nau8325_dai_startup,
633         .hw_params = nau8325_hw_params,
634         .set_fmt = nau8325_set_fmt,
635 };
636 
637 #define NAU8325_RATES SNDRV_PCM_RATE_8000_96000
638 #define NAU8325_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
639          | SNDRV_PCM_FMTBIT_S24_3LE)
640 
641 static struct snd_soc_dai_driver nau8325_dai = {
642         .name = NAU8325_CODEC_DAI,
643         .playback = {
644                 .stream_name = "Playback",
645                 .channels_min = 1,
646                 .channels_max = 2,
647                 .rates = NAU8325_RATES,
648                 .formats = NAU8325_FORMATS,
649         },
650         .ops = &nau8325_dai_ops,
651 };
652 
653 static const struct regmap_config nau8325_regmap_config = {
654         .reg_bits = NAU8325_REG_ADDR_LEN,
655         .val_bits = NAU8325_REG_DATA_LEN,
656 
657         .max_register = NAU8325_REG_MAX,
658         .readable_reg = nau8325_readable_reg,
659         .writeable_reg = nau8325_writeable_reg,
660         .volatile_reg = nau8325_volatile_reg,
661 
662         .cache_type = REGCACHE_RBTREE,
663         .reg_defaults = nau8325_reg_defaults,
664         .num_reg_defaults = ARRAY_SIZE(nau8325_reg_defaults),
665 };
666 
667 static void nau8325_reset_chip(struct regmap *regmap)
668 {
669         regmap_write(regmap, NAU8325_R00_HARDWARE_RST, 0x0001);
670         regmap_write(regmap, NAU8325_R00_HARDWARE_RST, 0x0000);
671 }
672 
673 static void nau8325_init_regs(struct nau8325 *nau8325)
674 {
675         struct regmap *regmap = nau8325->regmap;
676         struct device *dev = nau8325->dev;
677 
678         /* set ALC parameters */
679         regmap_update_bits(regmap, NAU8325_R2C_ALC_CTRL1,
680                            NAU8325_ALC_MAXGAIN_MASK,
681                            0x7 << NAU8325_ALC_MAXGAIN_SFT);
682         regmap_update_bits(regmap, NAU8325_R2D_ALC_CTRL2,
683                            NAU8325_ALC_DCY_MASK | NAU8325_ALC_ATK_MASK |
684                            NAU8325_ALC_HLD_MASK, (0x5 << NAU8325_ALC_DCY_SFT) |
685                            (0x3 << NAU8325_ALC_ATK_SFT) |
686                            (0x5 << NAU8325_ALC_HLD_SFT));
687         /* Enable ALC to avoid signal distortion when battery low. */
688         if (nau8325->alc_enable)
689                 regmap_update_bits(regmap, NAU8325_R2E_ALC_CTRL3,
690                                    NAU8325_ALC_EN, NAU8325_ALC_EN);
691         if (nau8325->clock_detection)
692                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
693                                    NAU8325_CLKPWRUP_DIS |
694                                    NAU8325_PWRUP_DFT, 0);
695         else
696                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
697                                    NAU8325_CLKPWRUP_DIS | NAU8325_PWRUP_DFT,
698                                    NAU8325_CLKPWRUP_DIS);
699         if (nau8325->clock_det_data)
700                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
701                                    NAU8325_APWRUP_EN, NAU8325_APWRUP_EN);
702         else
703                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
704                                    NAU8325_APWRUP_EN, 0);
705 
706         /* DAC Reference Voltage Setting */
707         switch (nau8325->dac_vref_microvolt) {
708         case 1800000:
709                 regmap_update_bits(regmap, NAU8325_R73_RDAC,
710                         NAU8325_DACVREFSEL_MASK, 0 << NAU8325_DACVREFSEL_SFT);
711                 break;
712         case 2700000:
713                 regmap_update_bits(regmap, NAU8325_R73_RDAC,
714                         NAU8325_DACVREFSEL_MASK, 1 << NAU8325_DACVREFSEL_SFT);
715                 break;
716         case 2880000:
717                 regmap_update_bits(regmap, NAU8325_R73_RDAC,
718                         NAU8325_DACVREFSEL_MASK, 2 << NAU8325_DACVREFSEL_SFT);
719                 break;
720         case 3060000:
721                 regmap_update_bits(regmap, NAU8325_R73_RDAC,
722                         NAU8325_DACVREFSEL_MASK, 3 << NAU8325_DACVREFSEL_SFT);
723                 break;
724         default:
725                 dev_dbg(dev, "Invalid dac-vref-microvolt %d", nau8325->dac_vref_microvolt);
726 
727         }
728 
729         /* DAC Reference Voltage Decoupling Capacitors. */
730         regmap_update_bits(regmap, NAU8325_R63_ANALOG_CONTROL_3,
731                            NAU8325_CLASSD_COARSE_GAIN_MASK, 0x4);
732         /* Auto-Att Min Gain 0dB, Class-D N Driver Slew Rate -25%. */
733         regmap_update_bits(regmap, NAU8325_R64_ANALOG_CONTROL_4,
734                            NAU8325_CLASSD_SLEWN_MASK, 0x7);
735 
736         /* VMID Tieoff (VMID Resistor Selection) */
737         switch (nau8325->vref_impedance_ohms) {
738         case 0:
739                 regmap_update_bits(regmap, NAU8325_R60_BIAS_ADJ,
740                         NAU8325_BIAS_VMID_SEL_MASK, 0 << NAU8325_BIAS_VMID_SEL_SFT);
741                 break;
742         case 25000:
743                 regmap_update_bits(regmap, NAU8325_R60_BIAS_ADJ,
744                         NAU8325_BIAS_VMID_SEL_MASK, 1 << NAU8325_BIAS_VMID_SEL_SFT);
745                 break;
746         case 125000:
747                 regmap_update_bits(regmap, NAU8325_R60_BIAS_ADJ,
748                         NAU8325_BIAS_VMID_SEL_MASK, 2 << NAU8325_BIAS_VMID_SEL_SFT);
749                 break;
750         case 2500:
751                 regmap_update_bits(regmap, NAU8325_R60_BIAS_ADJ,
752                         NAU8325_BIAS_VMID_SEL_MASK, 3 << NAU8325_BIAS_VMID_SEL_SFT);
753                 break;
754         default:
755                 dev_dbg(dev, "Invalid vref-impedance-ohms %d", nau8325->vref_impedance_ohms);
756         }
757 
758 
759         /* enable VMID, BIAS, DAC, DCA CLOCK, Voltage/Current Amps
760          */
761         regmap_update_bits(regmap, NAU8325_R61_ANALOG_CONTROL_1,
762                 NAU8325_DACEN_MASK | NAU8325_DACCLKEN_MASK |
763                 NAU8325_DACEN_R_MASK | NAU8325_DACCLKEN_R_MASK |
764                 NAU8325_CLASSDEN_MASK | NAU8325_VMDFSTENB_MASK |
765                 NAU8325_BIASEN_MASK | NAU8325_VMIDEN_MASK,
766                 (0x1 << NAU8325_DACEN_SFT) |
767                 (0x1 << NAU8325_DACCLKEN_SFT) |
768                 (0x1 << NAU8325_DACEN_R_SFT) |
769                 (0x1 << NAU8325_DACCLKEN_R_SFT) |
770                 (0x1 << NAU8325_CLASSDEN_SFT) |
771                 (0x1 << NAU8325_VMDFSTENB_SFT) |
772                 (0x1 << NAU8325_BIASEN_SFT) | 0x3);
773 
774         /* Enable ALC to avoid signal distortion when battery low. */
775         if (nau8325->alc_enable)
776                 regmap_update_bits(regmap, NAU8325_R2E_ALC_CTRL3,
777                                 NAU8325_ALC_EN, NAU8325_ALC_EN);
778         if (nau8325->clock_det_data)
779                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
780                                 NAU8325_APWRUP_EN, NAU8325_APWRUP_EN);
781         else
782                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
783                                 NAU8325_APWRUP_EN, 0);
784         if (nau8325->clock_detection)
785                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
786                                 NAU8325_CLKPWRUP_DIS |
787                                 NAU8325_PWRUP_DFT, 0);
788         else
789                 regmap_update_bits(regmap, NAU8325_R40_CLK_DET_CTRL,
790                                 NAU8325_CLKPWRUP_DIS | NAU8325_PWRUP_DFT,
791                                 NAU8325_CLKPWRUP_DIS);
792         regmap_update_bits(regmap, NAU8325_R29_DAC_CTRL1,
793                 NAU8325_DAC_OVERSAMPLE_MASK,
794                 NAU8325_DAC_OVERSAMPLE_128);
795 }
796 
797 static void nau8325_print_device_properties(struct nau8325 *nau8325)
798 {
799         struct device *dev = nau8325->dev;
800 
801         dev_dbg(dev, "vref-impedance-ohms:     %d", nau8325->vref_impedance_ohms);
802         dev_dbg(dev, "dac-vref-microvolt:      %d", nau8325->dac_vref_microvolt);
803         dev_dbg(dev, "alc-enable:              %d", nau8325->alc_enable);
804         dev_dbg(dev, "clock-det-data:          %d", nau8325->clock_det_data);
805         dev_dbg(dev, "clock-detection-disable: %d", nau8325->clock_detection);
806 }
807 
808 static int nau8325_read_device_properties(struct device *dev,
809                                           struct nau8325 *nau8325)
810 {
811         int ret;
812 
813         nau8325->alc_enable =
814                 device_property_read_bool(dev, "nuvoton,alc-enable");
815         nau8325->clock_det_data =
816                 device_property_read_bool(dev, "nuvoton,clock-det-data");
817         nau8325->clock_detection =
818                 !device_property_read_bool(dev, "nuvoton,clock-detection-disable");
819 
820         ret = device_property_read_u32(dev, "nuvoton,vref-impedance-ohms",
821                                        &nau8325->vref_impedance_ohms);
822         if (ret)
823                 nau8325->vref_impedance_ohms = 125000;
824         ret = device_property_read_u32(dev, "nuvoton,dac-vref-microvolt",
825                                        &nau8325->dac_vref_microvolt);
826         if (ret)
827                 nau8325->dac_vref_microvolt = 2880000;
828 
829         return 0;
830 }
831 
832 static int nau8325_i2c_probe(struct i2c_client *i2c,
833                              const struct i2c_device_id *id)
834 {
835         struct device *dev = &i2c->dev;
836         struct nau8325 *nau8325 = dev_get_platdata(dev);
837         int ret, value;
838 
839         if (!nau8325) {
840                 nau8325 = devm_kzalloc(dev, sizeof(*nau8325), GFP_KERNEL);
841                 if (!nau8325) {
842                         ret = -ENOMEM;
843                         goto err;
844                 }
845                 ret = nau8325_read_device_properties(dev, nau8325);
846                 if (ret)
847                         goto err;
848         }
849         i2c_set_clientdata(i2c, nau8325);
850 
851         nau8325->regmap = devm_regmap_init_i2c(i2c, &nau8325_regmap_config);
852         if (IS_ERR(nau8325->regmap)) {
853                 ret = PTR_ERR(nau8325->regmap);
854                 goto err;
855         }
856         nau8325->dev = dev;
857         nau8325_print_device_properties(nau8325);
858 
859         nau8325_reset_chip(nau8325->regmap);
860         ret = regmap_read(nau8325->regmap, NAU8325_R02_DEVICE_ID, &value);
861         if (ret) {
862                 dev_dbg(dev, "Failed to read device id (%d)", ret);
863                 goto err;
864         }
865         nau8325_init_regs(nau8325);
866 
867         ret = devm_snd_soc_register_component(dev, &nau8325_component_driver,
868                                               &nau8325_dai, 1);
869 err:
870         return ret;
871 }
872 
873 static const struct i2c_device_id nau8325_i2c_ids[] = {
874         { "nau8325" },
875         { }
876 };
877 MODULE_DEVICE_TABLE(i2c, nau8325_i2c_ids);
878 
879 #ifdef CONFIG_OF
880 static const struct of_device_id nau8325_of_ids[] = {
881         { .compatible = "nuvoton,nau8325", },
882         {}
883 };
884 MODULE_DEVICE_TABLE(of, nau8325_of_ids);
885 #endif
886 
887 static struct i2c_driver nau8325_i2c_driver = {
888         .driver = {
889                 .name = "nau8325",
890                 .of_match_table = of_match_ptr(nau8325_of_ids),
891         },
892         .probe = nau8325_i2c_probe,
893         .id_table = nau8325_i2c_ids,
894 };
895 module_i2c_driver(nau8325_i2c_driver);
896 
897 MODULE_DESCRIPTION("ASoC NAU8325 driver");
898 MODULE_AUTHOR("Seven Lee <WTLI@nuvoton.com>");
899 MODULE_AUTHOR("David Lin <CTLIN0@nuvoton.com>");
900 MODULE_LICENSE("GPL");
901 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php