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

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/src4xxx.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
  2 //
  3 // TI SRC4xxx Audio Codec driver
  4 //
  5 // Copyright 2021-2022 Deqx Pty Ltd
  6 // Author: Matt Flax <flatmax@flatmax.com>
  7 
  8 #include <linux/module.h>
  9 
 10 #include <sound/soc.h>
 11 #include <sound/tlv.h>
 12 
 13 #include "src4xxx.h"
 14 
 15 struct src4xxx {
 16         struct regmap *regmap;
 17         bool master[2];
 18         int mclk_hz;
 19         struct device *dev;
 20 };
 21 
 22 enum {SRC4XXX_PORTA, SRC4XXX_PORTB};
 23 
 24 /* SRC attenuation */
 25 static const DECLARE_TLV_DB_SCALE(src_tlv, -12750, 50, 0);
 26 
 27 static const struct snd_kcontrol_new src4xxx_controls[] = {
 28         SOC_DOUBLE_R_TLV("SRC Volume",
 29                 SRC4XXX_SCR_CTL_30, SRC4XXX_SCR_CTL_31, 0, 255, 1, src_tlv),
 30 };
 31 
 32 /* I2S port control */
 33 static const char * const port_out_src_text[] = {
 34         "loopback", "other_port", "DIR", "SRC"
 35 };
 36 static SOC_ENUM_SINGLE_DECL(porta_out_src_enum, SRC4XXX_PORTA_CTL_03, 4,
 37         port_out_src_text);
 38 static SOC_ENUM_SINGLE_DECL(portb_out_src_enum, SRC4XXX_PORTB_CTL_05, 4,
 39         port_out_src_text);
 40 static const struct snd_kcontrol_new porta_out_control =
 41         SOC_DAPM_ENUM("Port A source select", porta_out_src_enum);
 42 static const struct snd_kcontrol_new portb_out_control =
 43         SOC_DAPM_ENUM("Port B source select", portb_out_src_enum);
 44 
 45 /* Digital audio transmitter control */
 46 static const char * const dit_mux_text[] = {"Port A", "Port B", "DIR", "SRC"};
 47 static SOC_ENUM_SINGLE_DECL(dit_mux_enum, SRC4XXX_TX_CTL_07, 3, dit_mux_text);
 48 static const struct snd_kcontrol_new dit_mux_control =
 49         SOC_DAPM_ENUM("DIT source", dit_mux_enum);
 50 
 51 /* SRC control */
 52 static const char * const src_in_text[] = {"Port A", "Port B", "DIR"};
 53 static SOC_ENUM_SINGLE_DECL(src_in_enum, SRC4XXX_SCR_CTL_2D, 0, src_in_text);
 54 static const struct snd_kcontrol_new src_in_control =
 55         SOC_DAPM_ENUM("SRC source select", src_in_enum);
 56 
 57 /* DIR control */
 58 static const char * const dir_in_text[] = {"Ch 1", "Ch 2", "Ch 3", "Ch 4"};
 59 static SOC_ENUM_SINGLE_DECL(dir_in_enum, SRC4XXX_RCV_CTL_0D, 0, dir_in_text);
 60 static const struct snd_kcontrol_new dir_in_control =
 61         SOC_DAPM_ENUM("Digital Input", dir_in_enum);
 62 
 63 static const struct snd_soc_dapm_widget src4xxx_dapm_widgets[] = {
 64         SND_SOC_DAPM_INPUT("loopback_A"),
 65         SND_SOC_DAPM_INPUT("other_port_A"),
 66         SND_SOC_DAPM_INPUT("DIR_A"),
 67         SND_SOC_DAPM_INPUT("SRC_A"),
 68         SND_SOC_DAPM_MUX("Port A source",
 69                 SND_SOC_NOPM, 0, 0, &porta_out_control),
 70 
 71         SND_SOC_DAPM_INPUT("loopback_B"),
 72         SND_SOC_DAPM_INPUT("other_port_B"),
 73         SND_SOC_DAPM_INPUT("DIR_B"),
 74         SND_SOC_DAPM_INPUT("SRC_B"),
 75         SND_SOC_DAPM_MUX("Port B source",
 76                 SND_SOC_NOPM, 0, 0, &portb_out_control),
 77 
 78         SND_SOC_DAPM_INPUT("Port_A"),
 79         SND_SOC_DAPM_INPUT("Port_B"),
 80         SND_SOC_DAPM_INPUT("DIR_"),
 81 
 82         /* Digital audio receivers and transmitters */
 83         SND_SOC_DAPM_OUTPUT("DIR_OUT"),
 84         SND_SOC_DAPM_OUTPUT("SRC_OUT"),
 85         SND_SOC_DAPM_MUX("DIT Out Src", SRC4XXX_PWR_RST_01,
 86                 SRC4XXX_ENABLE_DIT_SHIFT, 1, &dit_mux_control),
 87 
 88         /* Audio Interface */
 89         SND_SOC_DAPM_AIF_IN("AIF_A_RX", "Playback A", 0,
 90                 SRC4XXX_PWR_RST_01, SRC4XXX_ENABLE_PORT_A_SHIFT, 1),
 91         SND_SOC_DAPM_AIF_OUT("AIF_A_TX", "Capture A", 0,
 92                 SRC4XXX_PWR_RST_01, SRC4XXX_ENABLE_PORT_A_SHIFT, 1),
 93         SND_SOC_DAPM_AIF_IN("AIF_B_RX", "Playback B", 0,
 94                 SRC4XXX_PWR_RST_01, SRC4XXX_ENABLE_PORT_B_SHIFT, 1),
 95         SND_SOC_DAPM_AIF_OUT("AIF_B_TX", "Capture B", 0,
 96                 SRC4XXX_PWR_RST_01, SRC4XXX_ENABLE_PORT_B_SHIFT, 1),
 97 
 98         SND_SOC_DAPM_MUX("SRC source", SND_SOC_NOPM, 0, 0, &src_in_control),
 99 
100         SND_SOC_DAPM_INPUT("MCLK"),
101         SND_SOC_DAPM_INPUT("RXMCLKI"),
102         SND_SOC_DAPM_INPUT("RXMCLKO"),
103 
104         SND_SOC_DAPM_INPUT("RX1"),
105         SND_SOC_DAPM_INPUT("RX2"),
106         SND_SOC_DAPM_INPUT("RX3"),
107         SND_SOC_DAPM_INPUT("RX4"),
108         SND_SOC_DAPM_MUX("Digital Input", SRC4XXX_PWR_RST_01,
109                 SRC4XXX_ENABLE_DIR_SHIFT, 1, &dir_in_control),
110 };
111 
112 static const struct snd_soc_dapm_route src4xxx_audio_routes[] = {
113         /* I2S Input to Output Routing */
114         {"Port A source", "loopback", "loopback_A"},
115         {"Port A source", "other_port", "other_port_A"},
116         {"Port A source", "DIR", "DIR_A"},
117         {"Port A source", "SRC", "SRC_A"},
118         {"Port B source", "loopback", "loopback_B"},
119         {"Port B source", "other_port", "other_port_B"},
120         {"Port B source", "DIR", "DIR_B"},
121         {"Port B source", "SRC", "SRC_B"},
122         /* DIT muxing */
123         {"DIT Out Src", "Port A", "Capture A"},
124         {"DIT Out Src", "Port B", "Capture B"},
125         {"DIT Out Src", "DIR", "DIR_OUT"},
126         {"DIT Out Src", "SRC", "SRC_OUT"},
127 
128         /* SRC input selection */
129         {"SRC source", "Port A", "Port_A"},
130         {"SRC source", "Port B", "Port_B"},
131         {"SRC source", "DIR", "DIR_"},
132         /* SRC mclk selection */
133         {"SRC mclk source", "Master (MCLK)", "MCLK"},
134         {"SRC mclk source", "Master (RXCLKI)", "RXMCLKI"},
135         {"SRC mclk source", "Recovered receiver clk", "RXMCLKO"},
136         /* DIR input selection */
137         {"Digital Input", "Ch 1", "RX1"},
138         {"Digital Input", "Ch 2", "RX2"},
139         {"Digital Input", "Ch 3", "RX3"},
140         {"Digital Input", "Ch 4", "RX4"},
141 };
142 
143 
144 static const struct snd_soc_component_driver src4xxx_driver = {
145         .controls = src4xxx_controls,
146         .num_controls = ARRAY_SIZE(src4xxx_controls),
147 
148         .dapm_widgets = src4xxx_dapm_widgets,
149         .num_dapm_widgets = ARRAY_SIZE(src4xxx_dapm_widgets),
150         .dapm_routes = src4xxx_audio_routes,
151         .num_dapm_routes = ARRAY_SIZE(src4xxx_audio_routes),
152 };
153 
154 static int src4xxx_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
155 {
156         struct snd_soc_component *component = dai->component;
157         struct src4xxx *src4xxx = snd_soc_component_get_drvdata(component);
158         unsigned int ctrl;
159 
160         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
161         case SND_SOC_DAIFMT_CBM_CFM:
162                 ctrl = SRC4XXX_BUS_MASTER;
163                 src4xxx->master[dai->id] = true;
164                 break;
165         case SND_SOC_DAIFMT_CBS_CFS:
166                 ctrl = 0;
167                 src4xxx->master[dai->id] = false;
168                 break;
169         default:
170                 return -EINVAL;
171                 break;
172         }
173 
174         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
175         case SND_SOC_DAIFMT_I2S:
176                 ctrl |= SRC4XXX_BUS_I2S;
177                 break;
178         case SND_SOC_DAIFMT_LEFT_J:
179                 ctrl |= SRC4XXX_BUS_LEFT_J;
180                 break;
181         case SND_SOC_DAIFMT_RIGHT_J:
182                 ctrl |= SRC4XXX_BUS_RIGHT_J_24;
183                 break;
184         default:
185                 return -EINVAL;
186                 break;
187         }
188 
189         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
190         case SND_SOC_DAIFMT_NB_NF:
191                 break;
192         default:
193                 return -EINVAL;
194                 break;
195         }
196 
197         regmap_update_bits(src4xxx->regmap, SRC4XXX_BUS_FMT(dai->id),
198                 SRC4XXX_BUS_FMT_MS_MASK, ctrl);
199 
200         return 0;
201 }
202 
203 static int src4xxx_set_mclk_hz(struct snd_soc_dai *codec_dai,
204                 int clk_id, unsigned int freq, int dir)
205 {
206         struct snd_soc_component *component = codec_dai->component;
207         struct src4xxx *src4xxx = snd_soc_component_get_drvdata(component);
208 
209         dev_info(component->dev, "changing mclk rate from %d to %d Hz\n",
210                 src4xxx->mclk_hz, freq);
211         src4xxx->mclk_hz = freq;
212 
213         return 0;
214 }
215 
216 static int src4xxx_hw_params(struct snd_pcm_substream *substream,
217                         struct snd_pcm_hw_params *params,
218                         struct snd_soc_dai *dai)
219 {
220         struct snd_soc_component *component = dai->component;
221         struct src4xxx *src4xxx = snd_soc_component_get_drvdata(component);
222         unsigned int mclk_div;
223         int val, pj, jd, d;
224         int reg;
225         int ret;
226 
227         switch (dai->id) {
228         case SRC4XXX_PORTB:
229                 reg = SRC4XXX_PORTB_CTL_06;
230                 break;
231         default:
232                 reg = SRC4XXX_PORTA_CTL_04;
233                 break;
234         }
235 
236         if (src4xxx->master[dai->id]) {
237                 mclk_div = src4xxx->mclk_hz/params_rate(params);
238                 if (src4xxx->mclk_hz != mclk_div*params_rate(params)) {
239                         dev_err(component->dev,
240                                 "mclk %d / rate %d has a remainder.\n",
241                                 src4xxx->mclk_hz, params_rate(params));
242                         return -EINVAL;
243                 }
244 
245                 val = ((int)mclk_div - 128) / 128;
246                 if ((val < 0) | (val > 3)) {
247                         dev_err(component->dev,
248                                 "div register setting %d is out of range\n",
249                                 val);
250                         dev_err(component->dev,
251                                 "unsupported sample rate %d Hz for the master clock of %d Hz\n",
252                                 params_rate(params), src4xxx->mclk_hz);
253                         return -EINVAL;
254                 }
255 
256                 /* set the TX DIV */
257                 ret = regmap_update_bits(src4xxx->regmap,
258                         SRC4XXX_TX_CTL_07, SRC4XXX_TX_MCLK_DIV_MASK,
259                         val<<SRC4XXX_TX_MCLK_DIV_SHIFT);
260                 if (ret) {
261                         dev_err(component->dev,
262                                 "Couldn't set the TX's div register to %d << %d = 0x%x\n",
263                                 val, SRC4XXX_TX_MCLK_DIV_SHIFT,
264                                 val<<SRC4XXX_TX_MCLK_DIV_SHIFT);
265                         return ret;
266                 }
267 
268                 /* set the PLL for the digital receiver */
269                 switch (src4xxx->mclk_hz) {
270                 case 24576000:
271                         pj = 0x22;
272                         jd = 0x00;
273                         d = 0x00;
274                         break;
275                 case 22579200:
276                         pj = 0x22;
277                         jd = 0x1b;
278                         d = 0xa3;
279                         break;
280                 default:
281                         /* don't error out here,
282                          * other parts of the chip are still functional
283                          * Dummy initialize variables to avoid
284                          * -Wsometimes-uninitialized from clang.
285                          */
286                         dev_info(component->dev,
287                                 "Couldn't set the RCV PLL as this master clock rate is unknown. Chosen regmap values may not match real world values.\n");
288                         pj = 0x0;
289                         jd = 0xff;
290                         d = 0xff;
291                         break;
292                 }
293                 ret = regmap_write(src4xxx->regmap, SRC4XXX_RCV_PLL_0F, pj);
294                 if (ret < 0)
295                         dev_err(component->dev,
296                                 "Failed to update PLL register 0x%x\n",
297                                 SRC4XXX_RCV_PLL_0F);
298                 ret = regmap_write(src4xxx->regmap, SRC4XXX_RCV_PLL_10, jd);
299                 if (ret < 0)
300                         dev_err(component->dev,
301                                 "Failed to update PLL register 0x%x\n",
302                                 SRC4XXX_RCV_PLL_10);
303                 ret = regmap_write(src4xxx->regmap, SRC4XXX_RCV_PLL_11, d);
304                 if (ret < 0)
305                         dev_err(component->dev,
306                                 "Failed to update PLL register 0x%x\n",
307                                 SRC4XXX_RCV_PLL_11);
308 
309                 ret = regmap_update_bits(src4xxx->regmap,
310                         SRC4XXX_TX_CTL_07, SRC4XXX_TX_MCLK_DIV_MASK,
311                         val<<SRC4XXX_TX_MCLK_DIV_SHIFT);
312                 if (ret < 0) {
313                         dev_err(component->dev,
314                                 "Couldn't set the TX's div register to %d << %d = 0x%x\n",
315                                 val, SRC4XXX_TX_MCLK_DIV_SHIFT,
316                                 val<<SRC4XXX_TX_MCLK_DIV_SHIFT);
317                         return ret;
318                 }
319 
320                 return regmap_update_bits(src4xxx->regmap, reg,
321                                         SRC4XXX_MCLK_DIV_MASK, val);
322         } else {
323                 dev_info(dai->dev, "not setting up MCLK as not master\n");
324         }
325 
326         return 0;
327 };
328 
329 static const struct snd_soc_dai_ops src4xxx_dai_ops = {
330         .hw_params      = src4xxx_hw_params,
331         .set_sysclk     = src4xxx_set_mclk_hz,
332         .set_fmt        = src4xxx_set_dai_fmt,
333 };
334 
335 #define SRC4XXX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |      SNDRV_PCM_FMTBIT_S32_LE)
336 #define SRC4XXX_RATES (SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000|\
337                                 SNDRV_PCM_RATE_88200|\
338                                 SNDRV_PCM_RATE_96000|\
339                                 SNDRV_PCM_RATE_176400|\
340                                 SNDRV_PCM_RATE_192000)
341 
342 static struct snd_soc_dai_driver src4xxx_dai_driver[] = {
343         {
344                 .id = SRC4XXX_PORTA,
345                 .name = "src4xxx-portA",
346                 .playback = {
347                         .stream_name = "Playback A",
348                         .channels_min = 2,
349                         .channels_max = 2,
350                         .rates = SRC4XXX_RATES,
351                         .formats = SRC4XXX_FORMATS,
352                 },
353                 .capture = {
354                         .stream_name = "Capture A",
355                         .channels_min = 2,
356                         .channels_max = 2,
357                         .rates = SRC4XXX_RATES,
358                         .formats = SRC4XXX_FORMATS,
359                 },
360                 .ops = &src4xxx_dai_ops,
361         },
362         {
363                 .id = SRC4XXX_PORTB,
364                 .name = "src4xxx-portB",
365                 .playback = {
366                         .stream_name = "Playback B",
367                         .channels_min = 2,
368                         .channels_max = 2,
369                         .rates = SRC4XXX_RATES,
370                         .formats = SRC4XXX_FORMATS,
371                 },
372                 .capture = {
373                         .stream_name = "Capture B",
374                         .channels_min = 2,
375                         .channels_max = 2,
376                         .rates = SRC4XXX_RATES,
377                         .formats = SRC4XXX_FORMATS,
378                 },
379                 .ops = &src4xxx_dai_ops,
380         },
381 };
382 
383 static const struct reg_default src4xxx_reg_defaults[] = {
384         { SRC4XXX_PWR_RST_01,           0x00 }, /* all powered down intially */
385         { SRC4XXX_PORTA_CTL_03,         0x00 },
386         { SRC4XXX_PORTA_CTL_04,         0x00 },
387         { SRC4XXX_PORTB_CTL_05,         0x00 },
388         { SRC4XXX_PORTB_CTL_06,         0x00 },
389         { SRC4XXX_TX_CTL_07,            0x00 },
390         { SRC4XXX_TX_CTL_08,            0x00 },
391         { SRC4XXX_TX_CTL_09,            0x00 },
392         { SRC4XXX_SRC_DIT_IRQ_MSK_0B,   0x00 },
393         { SRC4XXX_SRC_DIT_IRQ_MODE_0C,  0x00 },
394         { SRC4XXX_RCV_CTL_0D,           0x00 },
395         { SRC4XXX_RCV_CTL_0E,           0x00 },
396         { SRC4XXX_RCV_PLL_0F,           0x00 }, /* not spec. in the datasheet */
397         { SRC4XXX_RCV_PLL_10,           0xff }, /* not spec. in the datasheet */
398         { SRC4XXX_RCV_PLL_11,           0xff }, /* not spec. in the datasheet */
399         { SRC4XXX_RVC_IRQ_MSK_16,       0x00 },
400         { SRC4XXX_RVC_IRQ_MSK_17,       0x00 },
401         { SRC4XXX_RVC_IRQ_MODE_18,      0x00 },
402         { SRC4XXX_RVC_IRQ_MODE_19,      0x00 },
403         { SRC4XXX_RVC_IRQ_MODE_1A,      0x00 },
404         { SRC4XXX_GPIO_1_1B,            0x00 },
405         { SRC4XXX_GPIO_2_1C,            0x00 },
406         { SRC4XXX_GPIO_3_1D,            0x00 },
407         { SRC4XXX_GPIO_4_1E,            0x00 },
408         { SRC4XXX_SCR_CTL_2D,           0x00 },
409         { SRC4XXX_SCR_CTL_2E,           0x00 },
410         { SRC4XXX_SCR_CTL_2F,           0x00 },
411         { SRC4XXX_SCR_CTL_30,           0x00 },
412         { SRC4XXX_SCR_CTL_31,           0x00 },
413 };
414 
415 int src4xxx_probe(struct device *dev, struct regmap *regmap,
416                         void (*switch_mode)(struct device *dev))
417 {
418         struct src4xxx *src4xxx;
419         int ret;
420 
421         if (IS_ERR(regmap))
422                 return PTR_ERR(regmap);
423 
424         src4xxx = devm_kzalloc(dev, sizeof(*src4xxx), GFP_KERNEL);
425         if (!src4xxx)
426                 return -ENOMEM;
427 
428         src4xxx->regmap = regmap;
429         src4xxx->dev = dev;
430         src4xxx->mclk_hz = 0; /* mclk has not been configured yet */
431         dev_set_drvdata(dev, src4xxx);
432 
433         ret = regmap_write(regmap, SRC4XXX_PWR_RST_01, SRC4XXX_RESET);
434         if (ret < 0)
435                 dev_err(dev, "Failed to issue reset: %d\n", ret);
436         usleep_range(1, 500); /* sleep for more then 500 ns */
437         ret = regmap_write(regmap, SRC4XXX_PWR_RST_01, SRC4XXX_POWER_DOWN);
438         if (ret < 0)
439                 dev_err(dev, "Failed to decommission reset: %d\n", ret);
440         usleep_range(500, 1000); /* sleep for 500 us or more */
441 
442         ret = regmap_update_bits(src4xxx->regmap, SRC4XXX_PWR_RST_01,
443                 SRC4XXX_POWER_ENABLE, SRC4XXX_POWER_ENABLE);
444         if (ret < 0)
445                 dev_err(dev, "Failed to port A and B : %d\n", ret);
446 
447         /* set receiver to use master clock (rcv mclk is most likely jittery) */
448         ret = regmap_update_bits(src4xxx->regmap, SRC4XXX_RCV_CTL_0D,
449                 SRC4XXX_RXCLK_MCLK,     SRC4XXX_RXCLK_MCLK);
450         if (ret < 0)
451                 dev_err(dev,
452                         "Failed to enable mclk as the PLL1 DIR reference : %d\n", ret);
453 
454         /* default to leaving the PLL2 running on loss of lock, divide by 8 */
455         ret = regmap_update_bits(src4xxx->regmap, SRC4XXX_RCV_CTL_0E,
456                 SRC4XXX_PLL2_DIV_8 | SRC4XXX_REC_MCLK_EN | SRC4XXX_PLL2_LOL,
457                 SRC4XXX_PLL2_DIV_8 | SRC4XXX_REC_MCLK_EN | SRC4XXX_PLL2_LOL);
458         if (ret < 0)
459                 dev_err(dev, "Failed to enable mclk rec and div : %d\n", ret);
460 
461         ret = devm_snd_soc_register_component(dev, &src4xxx_driver,
462                         src4xxx_dai_driver, ARRAY_SIZE(src4xxx_dai_driver));
463         if (ret == 0)
464                 dev_info(dev, "src4392 probe ok %d\n", ret);
465         return ret;
466 }
467 EXPORT_SYMBOL_GPL(src4xxx_probe);
468 
469 static bool src4xxx_volatile_register(struct device *dev, unsigned int reg)
470 {
471         switch (reg) {
472         case SRC4XXX_RES_00:
473         case SRC4XXX_GLOBAL_ITR_STS_02:
474         case SRC4XXX_SRC_DIT_STS_0A:
475         case SRC4XXX_NON_AUDIO_D_12:
476         case SRC4XXX_RVC_STS_13:
477         case SRC4XXX_RVC_STS_14:
478         case SRC4XXX_RVC_STS_15:
479         case SRC4XXX_SUB_CODE_1F:
480         case SRC4XXX_SUB_CODE_20:
481         case SRC4XXX_SUB_CODE_21:
482         case SRC4XXX_SUB_CODE_22:
483         case SRC4XXX_SUB_CODE_23:
484         case SRC4XXX_SUB_CODE_24:
485         case SRC4XXX_SUB_CODE_25:
486         case SRC4XXX_SUB_CODE_26:
487         case SRC4XXX_SUB_CODE_27:
488         case SRC4XXX_SUB_CODE_28:
489         case SRC4XXX_PC_PREAMBLE_HI_29:
490         case SRC4XXX_PC_PREAMBLE_LO_2A:
491         case SRC4XXX_PD_PREAMBLE_HI_2B:
492         case SRC4XXX_PC_PREAMBLE_LO_2C:
493         case SRC4XXX_IO_RATIO_32:
494         case SRC4XXX_IO_RATIO_33:
495                 return true;
496         }
497 
498         if (reg > SRC4XXX_IO_RATIO_33 && reg < SRC4XXX_PAGE_SEL_7F)
499                 return true;
500 
501         return false;
502 }
503 
504 const struct regmap_config src4xxx_regmap_config = {
505         .val_bits = 8,
506         .reg_bits = 8,
507         .max_register = SRC4XXX_IO_RATIO_33,
508 
509         .reg_defaults = src4xxx_reg_defaults,
510         .num_reg_defaults = ARRAY_SIZE(src4xxx_reg_defaults),
511         .volatile_reg = src4xxx_volatile_register,
512         .cache_type = REGCACHE_RBTREE,
513 };
514 EXPORT_SYMBOL_GPL(src4xxx_regmap_config);
515 
516 MODULE_DESCRIPTION("ASoC SRC4XXX CODEC driver");
517 MODULE_AUTHOR("Matt Flax <flatmax@flatmax.com>");
518 MODULE_LICENSE("GPL");
519 

~ [ 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