1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Driver for the Texas Instruments TAS2764 CODEC
4 // Copyright (C) 2020 Texas Instruments Inc.
5
6 #include <linux/module.h>
7 #include <linux/moduleparam.h>
8 #include <linux/err.h>
9 #include <linux/init.h>
10 #include <linux/delay.h>
11 #include <linux/pm.h>
12 #include <linux/i2c.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/regmap.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/slab.h>
19 #include <sound/soc.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include <sound/initval.h>
23 #include <sound/tlv.h>
24
25 #include "tas2764.h"
26
27 enum tas2764_devid {
28 DEVID_TAS2764 = 0,
29 DEVID_SN012776 = 1
30 };
31
32 struct tas2764_priv {
33 struct snd_soc_component *component;
34 struct gpio_desc *reset_gpio;
35 struct gpio_desc *sdz_gpio;
36 struct regmap *regmap;
37 struct device *dev;
38 int irq;
39 enum tas2764_devid devid;
40
41 int v_sense_slot;
42 int i_sense_slot;
43
44 bool dac_powered;
45 bool unmuted;
46 };
47
48 static const char *tas2764_int_ltch0_msgs[8] = {
49 "fault: over temperature", /* INT_LTCH0 & BIT(0) */
50 "fault: over current",
51 "fault: bad TDM clock",
52 "limiter active",
53 "fault: PVDD below limiter inflection point",
54 "fault: limiter max attenuation",
55 "fault: BOP infinite hold",
56 "fault: BOP mute", /* INT_LTCH0 & BIT(7) */
57 };
58
59 static const unsigned int tas2764_int_readout_regs[6] = {
60 TAS2764_INT_LTCH0,
61 TAS2764_INT_LTCH1,
62 TAS2764_INT_LTCH1_0,
63 TAS2764_INT_LTCH2,
64 TAS2764_INT_LTCH3,
65 TAS2764_INT_LTCH4,
66 };
67
tas2764_irq(int irq,void * data)68 static irqreturn_t tas2764_irq(int irq, void *data)
69 {
70 struct tas2764_priv *tas2764 = data;
71 u8 latched[6] = {0, 0, 0, 0, 0, 0};
72 int ret = IRQ_NONE;
73 int i;
74
75 for (i = 0; i < ARRAY_SIZE(latched); i++)
76 latched[i] = snd_soc_component_read(tas2764->component,
77 tas2764_int_readout_regs[i]);
78
79 for (i = 0; i < 8; i++) {
80 if (latched[0] & BIT(i)) {
81 dev_crit_ratelimited(tas2764->dev, "%s\n",
82 tas2764_int_ltch0_msgs[i]);
83 ret = IRQ_HANDLED;
84 }
85 }
86
87 if (latched[0]) {
88 dev_err_ratelimited(tas2764->dev, "other context to the fault: %02x,%02x,%02x,%02x,%02x",
89 latched[1], latched[2], latched[3], latched[4], latched[5]);
90 snd_soc_component_update_bits(tas2764->component,
91 TAS2764_INT_CLK_CFG,
92 TAS2764_INT_CLK_CFG_IRQZ_CLR,
93 TAS2764_INT_CLK_CFG_IRQZ_CLR);
94 }
95
96 return ret;
97 }
98
tas2764_reset(struct tas2764_priv * tas2764)99 static void tas2764_reset(struct tas2764_priv *tas2764)
100 {
101 if (tas2764->reset_gpio) {
102 gpiod_set_value_cansleep(tas2764->reset_gpio, 0);
103 msleep(20);
104 gpiod_set_value_cansleep(tas2764->reset_gpio, 1);
105 usleep_range(1000, 2000);
106 }
107
108 snd_soc_component_write(tas2764->component, TAS2764_SW_RST,
109 TAS2764_RST);
110 usleep_range(1000, 2000);
111 }
112
tas2764_update_pwr_ctrl(struct tas2764_priv * tas2764)113 static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764)
114 {
115 struct snd_soc_component *component = tas2764->component;
116 unsigned int val;
117 int ret;
118
119 if (tas2764->dac_powered)
120 val = tas2764->unmuted ?
121 TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE;
122 else
123 val = TAS2764_PWR_CTRL_SHUTDOWN;
124
125 ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
126 TAS2764_PWR_CTRL_MASK, val);
127 if (ret < 0)
128 return ret;
129
130 return 0;
131 }
132
133 #ifdef CONFIG_PM
tas2764_codec_suspend(struct snd_soc_component * component)134 static int tas2764_codec_suspend(struct snd_soc_component *component)
135 {
136 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
137 int ret;
138
139 ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
140 TAS2764_PWR_CTRL_MASK,
141 TAS2764_PWR_CTRL_SHUTDOWN);
142
143 if (ret < 0)
144 return ret;
145
146 if (tas2764->sdz_gpio)
147 gpiod_set_value_cansleep(tas2764->sdz_gpio, 0);
148
149 regcache_cache_only(tas2764->regmap, true);
150 regcache_mark_dirty(tas2764->regmap);
151
152 return 0;
153 }
154
tas2764_codec_resume(struct snd_soc_component * component)155 static int tas2764_codec_resume(struct snd_soc_component *component)
156 {
157 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
158 int ret;
159
160 if (tas2764->sdz_gpio) {
161 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1);
162 usleep_range(1000, 2000);
163 }
164
165 ret = tas2764_update_pwr_ctrl(tas2764);
166
167 if (ret < 0)
168 return ret;
169
170 regcache_cache_only(tas2764->regmap, false);
171
172 return regcache_sync(tas2764->regmap);
173 }
174 #else
175 #define tas2764_codec_suspend NULL
176 #define tas2764_codec_resume NULL
177 #endif
178
179 static const char * const tas2764_ASI1_src[] = {
180 "I2C offset", "Left", "Right", "LeftRightDiv2",
181 };
182
183 static SOC_ENUM_SINGLE_DECL(
184 tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, TAS2764_TDM_CFG2_SCFG_SHIFT,
185 tas2764_ASI1_src);
186
187 static const struct snd_kcontrol_new tas2764_asi1_mux =
188 SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum);
189
190 static const struct snd_kcontrol_new isense_switch =
191 SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1);
192 static const struct snd_kcontrol_new vsense_switch =
193 SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 1, 1);
194
195 static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = {
196 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
197 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2764_asi1_mux),
198 SND_SOC_DAPM_SWITCH("ISENSE", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN,
199 1, &isense_switch),
200 SND_SOC_DAPM_SWITCH("VSENSE", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN,
201 1, &vsense_switch),
202 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
203 SND_SOC_DAPM_OUTPUT("OUT"),
204 SND_SOC_DAPM_SIGGEN("VMON"),
205 SND_SOC_DAPM_SIGGEN("IMON")
206 };
207
208 static const struct snd_soc_dapm_route tas2764_audio_map[] = {
209 {"ASI1 Sel", "I2C offset", "ASI1"},
210 {"ASI1 Sel", "Left", "ASI1"},
211 {"ASI1 Sel", "Right", "ASI1"},
212 {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
213 {"DAC", NULL, "ASI1 Sel"},
214 {"OUT", NULL, "DAC"},
215 {"ISENSE", "Switch", "IMON"},
216 {"VSENSE", "Switch", "VMON"},
217 };
218
tas2764_mute(struct snd_soc_dai * dai,int mute,int direction)219 static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction)
220 {
221 struct tas2764_priv *tas2764 =
222 snd_soc_component_get_drvdata(dai->component);
223 int ret;
224
225 if (!mute) {
226 tas2764->dac_powered = true;
227 ret = tas2764_update_pwr_ctrl(tas2764);
228 if (ret)
229 return ret;
230 }
231
232 tas2764->unmuted = !mute;
233 ret = tas2764_update_pwr_ctrl(tas2764);
234 if (ret)
235 return ret;
236
237 if (mute) {
238 tas2764->dac_powered = false;
239 ret = tas2764_update_pwr_ctrl(tas2764);
240 if (ret)
241 return ret;
242 }
243
244 return 0;
245 }
246
tas2764_set_bitwidth(struct tas2764_priv * tas2764,int bitwidth)247 static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth)
248 {
249 struct snd_soc_component *component = tas2764->component;
250 int sense_en;
251 int val;
252 int ret;
253
254 switch (bitwidth) {
255 case SNDRV_PCM_FORMAT_S16_LE:
256 ret = snd_soc_component_update_bits(component,
257 TAS2764_TDM_CFG2,
258 TAS2764_TDM_CFG2_RXW_MASK,
259 TAS2764_TDM_CFG2_RXW_16BITS);
260 break;
261 case SNDRV_PCM_FORMAT_S24_LE:
262 ret = snd_soc_component_update_bits(component,
263 TAS2764_TDM_CFG2,
264 TAS2764_TDM_CFG2_RXW_MASK,
265 TAS2764_TDM_CFG2_RXW_24BITS);
266 break;
267 case SNDRV_PCM_FORMAT_S32_LE:
268 ret = snd_soc_component_update_bits(component,
269 TAS2764_TDM_CFG2,
270 TAS2764_TDM_CFG2_RXW_MASK,
271 TAS2764_TDM_CFG2_RXW_32BITS);
272 break;
273
274 default:
275 return -EINVAL;
276 }
277
278 if (ret < 0)
279 return ret;
280
281 val = snd_soc_component_read(tas2764->component, TAS2764_PWR_CTRL);
282 if (val < 0)
283 return val;
284
285 if (val & (1 << TAS2764_VSENSE_POWER_EN))
286 sense_en = 0;
287 else
288 sense_en = TAS2764_TDM_CFG5_VSNS_ENABLE;
289
290 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5,
291 TAS2764_TDM_CFG5_VSNS_ENABLE,
292 sense_en);
293 if (ret < 0)
294 return ret;
295
296 if (val & (1 << TAS2764_ISENSE_POWER_EN))
297 sense_en = 0;
298 else
299 sense_en = TAS2764_TDM_CFG6_ISNS_ENABLE;
300
301 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6,
302 TAS2764_TDM_CFG6_ISNS_ENABLE,
303 sense_en);
304 if (ret < 0)
305 return ret;
306
307 return 0;
308 }
309
tas2764_set_samplerate(struct tas2764_priv * tas2764,int samplerate)310 static int tas2764_set_samplerate(struct tas2764_priv *tas2764, int samplerate)
311 {
312 struct snd_soc_component *component = tas2764->component;
313 int ramp_rate_val;
314 int ret;
315
316 switch (samplerate) {
317 case 48000:
318 ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ |
319 TAS2764_TDM_CFG0_44_1_48KHZ;
320 break;
321 case 44100:
322 ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ |
323 TAS2764_TDM_CFG0_44_1_48KHZ;
324 break;
325 case 96000:
326 ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ |
327 TAS2764_TDM_CFG0_88_2_96KHZ;
328 break;
329 case 88200:
330 ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ |
331 TAS2764_TDM_CFG0_88_2_96KHZ;
332 break;
333 default:
334 return -EINVAL;
335 }
336
337 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0,
338 TAS2764_TDM_CFG0_SMP_MASK |
339 TAS2764_TDM_CFG0_MASK,
340 ramp_rate_val);
341 if (ret < 0)
342 return ret;
343
344 return 0;
345 }
346
tas2764_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)347 static int tas2764_hw_params(struct snd_pcm_substream *substream,
348 struct snd_pcm_hw_params *params,
349 struct snd_soc_dai *dai)
350 {
351 struct snd_soc_component *component = dai->component;
352 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
353 int ret;
354
355 ret = tas2764_set_bitwidth(tas2764, params_format(params));
356 if (ret < 0)
357 return ret;
358
359 return tas2764_set_samplerate(tas2764, params_rate(params));
360 }
361
tas2764_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)362 static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
363 {
364 struct snd_soc_component *component = dai->component;
365 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
366 u8 tdm_rx_start_slot = 0, asi_cfg_0 = 0, asi_cfg_1 = 0, asi_cfg_4 = 0;
367 int ret;
368
369 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
370 case SND_SOC_DAIFMT_NB_IF:
371 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
372 fallthrough;
373 case SND_SOC_DAIFMT_NB_NF:
374 asi_cfg_1 = TAS2764_TDM_CFG1_RX_RISING;
375 asi_cfg_4 = TAS2764_TDM_CFG4_TX_FALLING;
376 break;
377 case SND_SOC_DAIFMT_IB_IF:
378 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
379 fallthrough;
380 case SND_SOC_DAIFMT_IB_NF:
381 asi_cfg_1 = TAS2764_TDM_CFG1_RX_FALLING;
382 asi_cfg_4 = TAS2764_TDM_CFG4_TX_RISING;
383 break;
384 }
385
386 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
387 TAS2764_TDM_CFG1_RX_MASK,
388 asi_cfg_1);
389 if (ret < 0)
390 return ret;
391
392 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG4,
393 TAS2764_TDM_CFG4_TX_MASK,
394 asi_cfg_4);
395 if (ret < 0)
396 return ret;
397
398 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
399 case SND_SOC_DAIFMT_I2S:
400 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
401 fallthrough;
402 case SND_SOC_DAIFMT_DSP_A:
403 tdm_rx_start_slot = 1;
404 break;
405 case SND_SOC_DAIFMT_DSP_B:
406 case SND_SOC_DAIFMT_LEFT_J:
407 tdm_rx_start_slot = 0;
408 break;
409 default:
410 dev_err(tas2764->dev,
411 "DAI Format is not found, fmt=0x%x\n", fmt);
412 return -EINVAL;
413 }
414
415 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0,
416 TAS2764_TDM_CFG0_FRAME_START,
417 asi_cfg_0);
418 if (ret < 0)
419 return ret;
420
421 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
422 TAS2764_TDM_CFG1_MASK,
423 (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT));
424 if (ret < 0)
425 return ret;
426
427 return 0;
428 }
429
tas2764_set_dai_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)430 static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai,
431 unsigned int tx_mask,
432 unsigned int rx_mask,
433 int slots, int slot_width)
434 {
435 struct snd_soc_component *component = dai->component;
436 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
437 int left_slot, right_slot;
438 int slots_cfg;
439 int slot_size;
440 int ret;
441
442 if (tx_mask == 0 || rx_mask != 0)
443 return -EINVAL;
444
445 left_slot = __ffs(tx_mask);
446 tx_mask &= ~(1 << left_slot);
447 if (tx_mask == 0) {
448 right_slot = left_slot;
449 } else {
450 right_slot = __ffs(tx_mask);
451 tx_mask &= ~(1 << right_slot);
452 }
453
454 if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
455 return -EINVAL;
456
457 slots_cfg = (right_slot << TAS2764_TDM_CFG3_RXS_SHIFT) | left_slot;
458
459 ret = snd_soc_component_write(component, TAS2764_TDM_CFG3, slots_cfg);
460 if (ret)
461 return ret;
462
463 switch (slot_width) {
464 case 16:
465 slot_size = TAS2764_TDM_CFG2_RXS_16BITS;
466 break;
467 case 24:
468 slot_size = TAS2764_TDM_CFG2_RXS_24BITS;
469 break;
470 case 32:
471 slot_size = TAS2764_TDM_CFG2_RXS_32BITS;
472 break;
473 default:
474 return -EINVAL;
475 }
476
477 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG2,
478 TAS2764_TDM_CFG2_RXS_MASK,
479 slot_size);
480 if (ret < 0)
481 return ret;
482
483 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG5,
484 TAS2764_TDM_CFG5_50_MASK,
485 tas2764->v_sense_slot);
486 if (ret < 0)
487 return ret;
488
489 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG6,
490 TAS2764_TDM_CFG6_50_MASK,
491 tas2764->i_sense_slot);
492 if (ret < 0)
493 return ret;
494
495 return 0;
496 }
497
498 static const struct snd_soc_dai_ops tas2764_dai_ops = {
499 .mute_stream = tas2764_mute,
500 .hw_params = tas2764_hw_params,
501 .set_fmt = tas2764_set_fmt,
502 .set_tdm_slot = tas2764_set_dai_tdm_slot,
503 .no_capture_mute = 1,
504 };
505
506 #define TAS2764_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
507 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
508
509 #define TAS2764_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
510 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200)
511
512 static struct snd_soc_dai_driver tas2764_dai_driver[] = {
513 {
514 .name = "tas2764 ASI1",
515 .id = 0,
516 .playback = {
517 .stream_name = "ASI1 Playback",
518 .channels_min = 1,
519 .channels_max = 2,
520 .rates = TAS2764_RATES,
521 .formats = TAS2764_FORMATS,
522 },
523 .capture = {
524 .stream_name = "ASI1 Capture",
525 .channels_min = 0,
526 .channels_max = 2,
527 .rates = TAS2764_RATES,
528 .formats = TAS2764_FORMATS,
529 },
530 .ops = &tas2764_dai_ops,
531 .symmetric_rate = 1,
532 },
533 };
534
535 static uint8_t sn012776_bop_presets[] = {
536 0x01, 0x32, 0x02, 0x22, 0x83, 0x2d, 0x80, 0x02, 0x06,
537 0x32, 0x46, 0x30, 0x02, 0x06, 0x38, 0x40, 0x30, 0x02,
538 0x06, 0x3e, 0x37, 0x30, 0xff, 0xe6
539 };
540
541 static const struct regmap_config tas2764_i2c_regmap;
542
tas2764_codec_probe(struct snd_soc_component * component)543 static int tas2764_codec_probe(struct snd_soc_component *component)
544 {
545 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
546 int ret, i;
547
548 tas2764->component = component;
549
550 if (tas2764->sdz_gpio) {
551 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1);
552 usleep_range(1000, 2000);
553 }
554
555 tas2764_reset(tas2764);
556 regmap_reinit_cache(tas2764->regmap, &tas2764_i2c_regmap);
557
558 if (tas2764->irq) {
559 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0x00);
560 if (ret < 0)
561 return ret;
562
563 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK1, 0xff);
564 if (ret < 0)
565 return ret;
566
567 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK2, 0xff);
568 if (ret < 0)
569 return ret;
570
571 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK3, 0xff);
572 if (ret < 0)
573 return ret;
574
575 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK4, 0xff);
576 if (ret < 0)
577 return ret;
578
579 ret = devm_request_threaded_irq(tas2764->dev, tas2764->irq, NULL, tas2764_irq,
580 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
581 "tas2764", tas2764);
582 if (ret)
583 dev_warn(tas2764->dev, "failed to request IRQ: %d\n", ret);
584 }
585
586 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5,
587 TAS2764_TDM_CFG5_VSNS_ENABLE, 0);
588 if (ret < 0)
589 return ret;
590
591 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6,
592 TAS2764_TDM_CFG6_ISNS_ENABLE, 0);
593 if (ret < 0)
594 return ret;
595
596 switch (tas2764->devid) {
597 case DEVID_SN012776:
598 ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
599 TAS2764_PWR_CTRL_BOP_SRC,
600 TAS2764_PWR_CTRL_BOP_SRC);
601 if (ret < 0)
602 return ret;
603
604 for (i = 0; i < ARRAY_SIZE(sn012776_bop_presets); i++) {
605 ret = snd_soc_component_write(component,
606 TAS2764_BOP_CFG0 + i,
607 sn012776_bop_presets[i]);
608
609 if (ret < 0)
610 return ret;
611 }
612 break;
613 default:
614 break;
615 }
616
617 return 0;
618 }
619
620 static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0);
621 static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1);
622
623 static const char * const tas2764_hpf_texts[] = {
624 "Disabled", "2 Hz", "50 Hz", "100 Hz", "200 Hz",
625 "400 Hz", "800 Hz"
626 };
627
628 static SOC_ENUM_SINGLE_DECL(
629 tas2764_hpf_enum, TAS2764_DC_BLK0,
630 TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts);
631
632 static const struct snd_kcontrol_new tas2764_snd_controls[] = {
633 SOC_SINGLE_TLV("Speaker Volume", TAS2764_DVC, 0,
634 TAS2764_DVC_MAX, 1, tas2764_playback_volume),
635 SOC_SINGLE_TLV("Amp Gain Volume", TAS2764_CHNL_0, 1, 0x14, 0,
636 tas2764_digital_tlv),
637 SOC_ENUM("HPF Corner Frequency", tas2764_hpf_enum),
638 };
639
640 static const struct snd_soc_component_driver soc_component_driver_tas2764 = {
641 .probe = tas2764_codec_probe,
642 .suspend = tas2764_codec_suspend,
643 .resume = tas2764_codec_resume,
644 .controls = tas2764_snd_controls,
645 .num_controls = ARRAY_SIZE(tas2764_snd_controls),
646 .dapm_widgets = tas2764_dapm_widgets,
647 .num_dapm_widgets = ARRAY_SIZE(tas2764_dapm_widgets),
648 .dapm_routes = tas2764_audio_map,
649 .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map),
650 .idle_bias_on = 1,
651 .endianness = 1,
652 };
653
654 static const struct reg_default tas2764_reg_defaults[] = {
655 { TAS2764_PAGE, 0x00 },
656 { TAS2764_SW_RST, 0x00 },
657 { TAS2764_PWR_CTRL, 0x1a },
658 { TAS2764_DVC, 0x00 },
659 { TAS2764_CHNL_0, 0x28 },
660 { TAS2764_TDM_CFG0, 0x09 },
661 { TAS2764_TDM_CFG1, 0x02 },
662 { TAS2764_TDM_CFG2, 0x0a },
663 { TAS2764_TDM_CFG3, 0x10 },
664 { TAS2764_TDM_CFG5, 0x42 },
665 { TAS2764_INT_CLK_CFG, 0x19 },
666 };
667
668 static const struct regmap_range_cfg tas2764_regmap_ranges[] = {
669 {
670 .range_min = 0,
671 .range_max = 1 * 128,
672 .selector_reg = TAS2764_PAGE,
673 .selector_mask = 0xff,
674 .selector_shift = 0,
675 .window_start = 0,
676 .window_len = 128,
677 },
678 };
679
tas2764_volatile_register(struct device * dev,unsigned int reg)680 static bool tas2764_volatile_register(struct device *dev, unsigned int reg)
681 {
682 switch (reg) {
683 case TAS2764_SW_RST:
684 case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4:
685 case TAS2764_INT_CLK_CFG:
686 return true;
687 default:
688 return false;
689 }
690 }
691
692 static const struct regmap_config tas2764_i2c_regmap = {
693 .reg_bits = 8,
694 .val_bits = 8,
695 .volatile_reg = tas2764_volatile_register,
696 .reg_defaults = tas2764_reg_defaults,
697 .num_reg_defaults = ARRAY_SIZE(tas2764_reg_defaults),
698 .cache_type = REGCACHE_RBTREE,
699 .ranges = tas2764_regmap_ranges,
700 .num_ranges = ARRAY_SIZE(tas2764_regmap_ranges),
701 .max_register = 1 * 128,
702 };
703
tas2764_parse_dt(struct device * dev,struct tas2764_priv * tas2764)704 static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764)
705 {
706 int ret = 0;
707
708 tas2764->reset_gpio = devm_gpiod_get_optional(tas2764->dev, "reset",
709 GPIOD_OUT_HIGH);
710 if (IS_ERR(tas2764->reset_gpio)) {
711 if (PTR_ERR(tas2764->reset_gpio) == -EPROBE_DEFER) {
712 tas2764->reset_gpio = NULL;
713 return -EPROBE_DEFER;
714 }
715 }
716
717 tas2764->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
718 if (IS_ERR(tas2764->sdz_gpio)) {
719 if (PTR_ERR(tas2764->sdz_gpio) == -EPROBE_DEFER)
720 return -EPROBE_DEFER;
721
722 tas2764->sdz_gpio = NULL;
723 }
724
725 ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
726 &tas2764->i_sense_slot);
727 if (ret)
728 tas2764->i_sense_slot = 0;
729
730 ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
731 &tas2764->v_sense_slot);
732 if (ret)
733 tas2764->v_sense_slot = 2;
734
735 return 0;
736 }
737
tas2764_i2c_probe(struct i2c_client * client)738 static int tas2764_i2c_probe(struct i2c_client *client)
739 {
740 struct tas2764_priv *tas2764;
741 int result;
742
743 tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv),
744 GFP_KERNEL);
745 if (!tas2764)
746 return -ENOMEM;
747
748 tas2764->devid = (enum tas2764_devid)of_device_get_match_data(&client->dev);
749
750 tas2764->dev = &client->dev;
751 tas2764->irq = client->irq;
752 i2c_set_clientdata(client, tas2764);
753 dev_set_drvdata(&client->dev, tas2764);
754
755 tas2764->regmap = devm_regmap_init_i2c(client, &tas2764_i2c_regmap);
756 if (IS_ERR(tas2764->regmap)) {
757 result = PTR_ERR(tas2764->regmap);
758 dev_err(&client->dev, "Failed to allocate register map: %d\n",
759 result);
760 return result;
761 }
762
763 if (client->dev.of_node) {
764 result = tas2764_parse_dt(&client->dev, tas2764);
765 if (result) {
766 dev_err(tas2764->dev, "%s: Failed to parse devicetree\n",
767 __func__);
768 return result;
769 }
770 }
771
772 return devm_snd_soc_register_component(tas2764->dev,
773 &soc_component_driver_tas2764,
774 tas2764_dai_driver,
775 ARRAY_SIZE(tas2764_dai_driver));
776 }
777
778 static const struct i2c_device_id tas2764_i2c_id[] = {
779 { "tas2764"},
780 { }
781 };
782 MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id);
783
784 #if defined(CONFIG_OF)
785 static const struct of_device_id tas2764_of_match[] = {
786 { .compatible = "ti,tas2764", .data = (void *)DEVID_TAS2764 },
787 { .compatible = "ti,sn012776", .data = (void *)DEVID_SN012776 },
788 {},
789 };
790 MODULE_DEVICE_TABLE(of, tas2764_of_match);
791 #endif
792
793 static struct i2c_driver tas2764_i2c_driver = {
794 .driver = {
795 .name = "tas2764",
796 .of_match_table = of_match_ptr(tas2764_of_match),
797 },
798 .probe = tas2764_i2c_probe,
799 .id_table = tas2764_i2c_id,
800 };
801 module_i2c_driver(tas2764_i2c_driver);
802
803 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
804 MODULE_DESCRIPTION("TAS2764 I2C Smart Amplifier driver");
805 MODULE_LICENSE("GPL v2");
806