Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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
 26struct 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
 41static 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
 52static 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
 61static 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
 92static 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
106static 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
127static 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
148static 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
172static const char * const tas2764_ASI1_src[] = {
173	"I2C offset", "Left", "Right", "LeftRightDiv2",
174};
175
176static SOC_ENUM_SINGLE_DECL(
177	tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, TAS2764_TDM_CFG2_SCFG_SHIFT,
178	tas2764_ASI1_src);
179
180static const struct snd_kcontrol_new tas2764_asi1_mux =
181	SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum);
182
183static 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
210static const struct snd_kcontrol_new isense_switch =
211	SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1);
212static const struct snd_kcontrol_new vsense_switch =
213	SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 1, 1);
214
215static 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
229static 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
240static 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
249static 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
312static 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
349static 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
364static 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
424static 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
492static 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
506static 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
529static 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
584static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0);
585static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1);
586
587static const char * const tas2764_hpf_texts[] = {
588	"Disabled", "2 Hz", "50 Hz", "100 Hz", "200 Hz",
589	"400 Hz", "800 Hz"
590};
591
592static SOC_ENUM_SINGLE_DECL(
593	tas2764_hpf_enum, TAS2764_DC_BLK0,
594	TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts);
595
596static 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
604static 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
618static 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
631static 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
643static 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
654static 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
666static 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
700static 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
738static const struct i2c_device_id tas2764_i2c_id[] = {
739	{ "tas2764"},
740	{ }
741};
742MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id);
743
744#if defined(CONFIG_OF)
745static const struct of_device_id tas2764_of_match[] = {
746	{ .compatible = "ti,tas2764" },
747	{},
748};
749MODULE_DEVICE_TABLE(of, tas2764_of_match);
750#endif
751
752static 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};
760module_i2c_driver(tas2764_i2c_driver);
761
762MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
763MODULE_DESCRIPTION("TAS2764 I2C Smart Amplifier driver");
764MODULE_LICENSE("GPL v2");