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