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