xref: /openbmc/linux/sound/soc/codecs/tas2780.c (revision 4e9a429a)
1 // SPDX-License-Identifier: GPL-2.0
2 // Driver for the Texas Instruments TAS2780 Mono
3 //		Audio amplifier
4 // Copyright (C) 2022 Texas Instruments Inc.
5 
6 #include <linux/module.h>
7 #include <linux/err.h>
8 #include <linux/pm.h>
9 #include <linux/i2c.h>
10 #include <linux/gpio.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/regmap.h>
13 #include <linux/of.h>
14 #include <linux/of_gpio.h>
15 #include <sound/soc.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/tlv.h>
19 
20 #include "tas2780.h"
21 
22 struct tas2780_priv {
23 	struct snd_soc_component *component;
24 	struct gpio_desc *reset_gpio;
25 	struct regmap *regmap;
26 	struct device *dev;
27 	int v_sense_slot;
28 	int i_sense_slot;
29 };
30 
tas2780_reset(struct tas2780_priv * tas2780)31 static void tas2780_reset(struct tas2780_priv *tas2780)
32 {
33 	int ret = 0;
34 
35 	if (tas2780->reset_gpio) {
36 		gpiod_set_value_cansleep(tas2780->reset_gpio, 0);
37 		usleep_range(2000, 2050);
38 		gpiod_set_value_cansleep(tas2780->reset_gpio, 1);
39 		usleep_range(2000, 2050);
40 	}
41 
42 	ret = snd_soc_component_write(tas2780->component, TAS2780_SW_RST,
43 				TAS2780_RST);
44 	if (ret)
45 		dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n",
46 			__func__, ret);
47 }
48 
49 #ifdef CONFIG_PM
tas2780_codec_suspend(struct snd_soc_component * component)50 static int tas2780_codec_suspend(struct snd_soc_component *component)
51 {
52 	struct tas2780_priv *tas2780 =
53 		snd_soc_component_get_drvdata(component);
54 	int ret = 0;
55 
56 	ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL,
57 		TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_SHUTDOWN);
58 	if (ret < 0) {
59 		dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n",
60 			__func__, ret);
61 		goto err;
62 	}
63 	ret = 0;
64 	regcache_cache_only(tas2780->regmap, true);
65 	regcache_mark_dirty(tas2780->regmap);
66 err:
67 	return ret;
68 }
69 
tas2780_codec_resume(struct snd_soc_component * component)70 static int tas2780_codec_resume(struct snd_soc_component *component)
71 {
72 	struct tas2780_priv *tas2780 =
73 		snd_soc_component_get_drvdata(component);
74 	int ret = 0;
75 
76 	ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL,
77 		TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_ACTIVE);
78 
79 	if (ret < 0) {
80 		dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n",
81 			__func__, ret);
82 		goto err;
83 	}
84 	ret = 0;
85 	regcache_cache_only(tas2780->regmap, false);
86 	ret = regcache_sync(tas2780->regmap);
87 err:
88 	return ret;
89 }
90 #endif
91 
92 static const char * const tas2780_ASI1_src[] = {
93 	"I2C offset", "Left", "Right", "LeftRightDiv2",
94 };
95 
96 static SOC_ENUM_SINGLE_DECL(
97 	tas2780_ASI1_src_enum, TAS2780_TDM_CFG2, 4, tas2780_ASI1_src);
98 
99 static const struct snd_kcontrol_new tas2780_asi1_mux =
100 	SOC_DAPM_ENUM("ASI1 Source", tas2780_ASI1_src_enum);
101 
102 static const struct snd_kcontrol_new isense_switch =
103 	SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL,
104 			TAS2780_ISENSE_POWER_EN, 1, 1);
105 static const struct snd_kcontrol_new vsense_switch =
106 	SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL,
107 			TAS2780_VSENSE_POWER_EN, 1, 1);
108 
109 static const struct snd_soc_dapm_widget tas2780_dapm_widgets[] = {
110 	SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
111 	SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2780_asi1_mux),
112 	SND_SOC_DAPM_SWITCH("ISENSE", TAS2780_PWR_CTRL,
113 		TAS2780_ISENSE_POWER_EN, 1, &isense_switch),
114 	SND_SOC_DAPM_SWITCH("VSENSE", TAS2780_PWR_CTRL,
115 		TAS2780_VSENSE_POWER_EN, 1, &vsense_switch),
116 	SND_SOC_DAPM_OUTPUT("OUT"),
117 	SND_SOC_DAPM_SIGGEN("VMON"),
118 	SND_SOC_DAPM_SIGGEN("IMON")
119 };
120 
121 static const struct snd_soc_dapm_route tas2780_audio_map[] = {
122 	{"ASI1 Sel", "I2C offset", "ASI1"},
123 	{"ASI1 Sel", "Left", "ASI1"},
124 	{"ASI1 Sel", "Right", "ASI1"},
125 	{"ASI1 Sel", "LeftRightDiv2", "ASI1"},
126 	{"OUT", NULL, "ASI1 Sel"},
127 	{"ISENSE", "Switch", "IMON"},
128 	{"VSENSE", "Switch", "VMON"},
129 };
130 
tas2780_mute(struct snd_soc_dai * dai,int mute,int direction)131 static int tas2780_mute(struct snd_soc_dai *dai, int mute, int direction)
132 {
133 	struct snd_soc_component *component = dai->component;
134 	struct tas2780_priv *tas2780 =
135 		snd_soc_component_get_drvdata(component);
136 	int ret = 0;
137 
138 	ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL,
139 		TAS2780_PWR_CTRL_MASK,
140 		mute ? TAS2780_PWR_CTRL_MUTE : 0);
141 	if (ret < 0) {
142 		dev_err(tas2780->dev, "%s: Failed to set powercontrol\n",
143 			__func__);
144 		goto err;
145 	}
146 	ret = 0;
147 err:
148 	return ret;
149 }
150 
tas2780_set_bitwidth(struct tas2780_priv * tas2780,int bitwidth)151 static int tas2780_set_bitwidth(struct tas2780_priv *tas2780, int bitwidth)
152 {
153 	struct snd_soc_component *component = tas2780->component;
154 	int sense_en;
155 	int val;
156 	int ret;
157 	int slot_size;
158 
159 	switch (bitwidth) {
160 	case SNDRV_PCM_FORMAT_S16_LE:
161 		ret = snd_soc_component_update_bits(component,
162 			TAS2780_TDM_CFG2,
163 			TAS2780_TDM_CFG2_RXW_MASK,
164 			TAS2780_TDM_CFG2_RXW_16BITS);
165 		slot_size = TAS2780_TDM_CFG2_RXS_16BITS;
166 		break;
167 	case SNDRV_PCM_FORMAT_S24_LE:
168 		ret = snd_soc_component_update_bits(component,
169 			TAS2780_TDM_CFG2,
170 			TAS2780_TDM_CFG2_RXW_MASK,
171 			TAS2780_TDM_CFG2_RXW_24BITS);
172 		slot_size = TAS2780_TDM_CFG2_RXS_24BITS;
173 		break;
174 	case SNDRV_PCM_FORMAT_S32_LE:
175 		ret = snd_soc_component_update_bits(component,
176 			TAS2780_TDM_CFG2,
177 			TAS2780_TDM_CFG2_RXW_MASK,
178 			TAS2780_TDM_CFG2_RXW_32BITS);
179 		slot_size = TAS2780_TDM_CFG2_RXS_32BITS;
180 		break;
181 
182 	default:
183 		ret = -EINVAL;
184 	}
185 
186 	if (ret < 0) {
187 		dev_err(tas2780->dev, "%s:errCode:0x%x set bitwidth error\n",
188 			__func__, ret);
189 		goto err;
190 	}
191 
192 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2,
193 		TAS2780_TDM_CFG2_RXS_MASK, slot_size);
194 	if (ret < 0) {
195 		dev_err(tas2780->dev,
196 			"%s:errCode:0x%x set RX slot size error\n",
197 			__func__, ret);
198 		goto err;
199 	}
200 
201 	val = snd_soc_component_read(tas2780->component, TAS2780_PWR_CTRL);
202 	if (val < 0) {
203 		dev_err(tas2780->dev, "%s:errCode:0x%x read PWR_CTRL error\n",
204 			__func__, val);
205 		ret = val;
206 		goto err;
207 	}
208 
209 	if (val & (1 << TAS2780_VSENSE_POWER_EN))
210 		sense_en = 0;
211 	else
212 		sense_en = TAS2780_TDM_CFG5_VSNS_ENABLE;
213 
214 	ret = snd_soc_component_update_bits(tas2780->component,
215 		TAS2780_TDM_CFG5, TAS2780_TDM_CFG5_VSNS_ENABLE, sense_en);
216 	if (ret < 0) {
217 		dev_err(tas2780->dev, "%s:errCode:0x%x enable vSNS error\n",
218 			__func__, ret);
219 		goto err;
220 	}
221 
222 	if (val & (1 << TAS2780_ISENSE_POWER_EN))
223 		sense_en = 0;
224 	else
225 		sense_en = TAS2780_TDM_CFG6_ISNS_ENABLE;
226 
227 	ret = snd_soc_component_update_bits(tas2780->component,
228 		TAS2780_TDM_CFG6, TAS2780_TDM_CFG6_ISNS_ENABLE, sense_en);
229 	if (ret < 0) {
230 		dev_err(tas2780->dev, "%s:errCode:0x%x enable iSNS error\n",
231 			__func__, ret);
232 		goto err;
233 	}
234 	ret = 0;
235 err:
236 	return ret;
237 }
238 
tas2780_set_samplerate(struct tas2780_priv * tas2780,int samplerate)239 static int tas2780_set_samplerate(
240 	struct tas2780_priv *tas2780, int samplerate)
241 {
242 	struct snd_soc_component *component = tas2780->component;
243 	int ramp_rate_val;
244 	int ret;
245 
246 	switch (samplerate) {
247 	case 48000:
248 		ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ |
249 				TAS2780_TDM_CFG0_44_1_48KHZ;
250 		break;
251 	case 44100:
252 		ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ |
253 				TAS2780_TDM_CFG0_44_1_48KHZ;
254 		break;
255 	case 96000:
256 		ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ |
257 				TAS2780_TDM_CFG0_88_2_96KHZ;
258 		break;
259 	case 88200:
260 		ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ |
261 				TAS2780_TDM_CFG0_88_2_96KHZ;
262 		break;
263 	default:
264 		return -EINVAL;
265 	}
266 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG0,
267 		TAS2780_TDM_CFG0_SMP_MASK | TAS2780_TDM_CFG0_MASK,
268 		ramp_rate_val);
269 	if (ret < 0) {
270 		dev_err(tas2780->dev,
271 			"%s:errCode:0x%x Failed to set ramp_rate_val\n",
272 			__func__, ret);
273 		goto err;
274 	}
275 	ret = 0;
276 err:
277 	return ret;
278 }
279 
tas2780_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)280 static int tas2780_hw_params(struct snd_pcm_substream *substream,
281 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
282 {
283 	struct snd_soc_component *component = dai->component;
284 	struct tas2780_priv *tas2780 =
285 		snd_soc_component_get_drvdata(component);
286 	int ret;
287 
288 	ret = tas2780_set_bitwidth(tas2780, params_format(params));
289 	if (ret < 0)
290 		return ret;
291 
292 	return tas2780_set_samplerate(tas2780, params_rate(params));
293 }
294 
tas2780_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)295 static int tas2780_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
296 {
297 	struct snd_soc_component *component = dai->component;
298 	struct tas2780_priv *tas2780 =
299 		snd_soc_component_get_drvdata(component);
300 	u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
301 	int iface;
302 	int ret = 0;
303 
304 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
305 	case SND_SOC_DAIFMT_NB_NF:
306 		asi_cfg_1 = TAS2780_TDM_CFG1_RX_RISING;
307 		break;
308 	case SND_SOC_DAIFMT_IB_NF:
309 		asi_cfg_1 = TAS2780_TDM_CFG1_RX_FALLING;
310 		break;
311 	default:
312 		dev_err(tas2780->dev, "ASI format Inverse is not found\n");
313 		return -EINVAL;
314 	}
315 
316 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1,
317 		TAS2780_TDM_CFG1_RX_MASK, asi_cfg_1);
318 	if (ret < 0) {
319 		dev_err(tas2780->dev,
320 			"%s:errCode:0x%x Failed to set asi_cfg_1\n",
321 			__func__, ret);
322 		goto err;
323 	}
324 
325 	if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
326 		|| ((fmt & SND_SOC_DAIFMT_FORMAT_MASK)
327 		== SND_SOC_DAIFMT_DSP_A)){
328 		iface = TAS2780_TDM_CFG2_SCFG_I2S;
329 		tdm_rx_start_slot = 1;
330 	} else {
331 		if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK)
332 			== SND_SOC_DAIFMT_DSP_B)
333 			|| ((fmt & SND_SOC_DAIFMT_FORMAT_MASK)
334 			== SND_SOC_DAIFMT_LEFT_J)) {
335 			iface = TAS2780_TDM_CFG2_SCFG_LEFT_J;
336 			tdm_rx_start_slot = 0;
337 		} else {
338 			dev_err(tas2780->dev,
339 				"%s:DAI Format is not found, fmt=0x%x\n",
340 				__func__, fmt);
341 			ret = -EINVAL;
342 			goto err;
343 		}
344 	}
345 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1,
346 		TAS2780_TDM_CFG1_MASK,
347 		(tdm_rx_start_slot << TAS2780_TDM_CFG1_51_SHIFT));
348 	if (ret < 0) {
349 		dev_err(tas2780->dev,
350 			"%s:errCode:0x%x Failed to set tdm_rx_start_slot\n",
351 			__func__, ret);
352 		goto err;
353 	}
354 
355 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2,
356 		TAS2780_TDM_CFG2_SCFG_MASK, iface);
357 	if (ret < 0) {
358 		dev_err(tas2780->dev, "%s:errCode:0x%x Failed to set iface\n",
359 			__func__, ret);
360 		goto err;
361 	}
362 	ret = 0;
363 err:
364 	return ret;
365 }
366 
tas2780_set_dai_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)367 static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai,
368 				unsigned int tx_mask,
369 				unsigned int rx_mask,
370 				int slots, int slot_width)
371 {
372 	struct snd_soc_component *component = dai->component;
373 	struct tas2780_priv *tas2780 =
374 		snd_soc_component_get_drvdata(component);
375 	int left_slot, right_slot;
376 	int slots_cfg;
377 	int slot_size;
378 	int ret = 0;
379 
380 	if (tx_mask == 0 || rx_mask != 0)
381 		return -EINVAL;
382 
383 	left_slot = __ffs(tx_mask);
384 	tx_mask &= ~(1 << left_slot);
385 	if (tx_mask == 0) {
386 		right_slot = left_slot;
387 	} else {
388 		right_slot = __ffs(tx_mask);
389 		tx_mask &= ~(1 << right_slot);
390 	}
391 
392 	if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
393 		return -EINVAL;
394 
395 	slots_cfg = (right_slot << TAS2780_TDM_CFG3_RXS_SHIFT) | left_slot;
396 	ret = snd_soc_component_write(component, TAS2780_TDM_CFG3, slots_cfg);
397 	if (ret) {
398 		dev_err(tas2780->dev,
399 			"%s:errCode:0x%x Failed to set slots_cfg\n",
400 			__func__, ret);
401 		goto err;
402 	}
403 
404 	switch (slot_width) {
405 	case 16:
406 		slot_size = TAS2780_TDM_CFG2_RXS_16BITS;
407 		break;
408 	case 24:
409 		slot_size = TAS2780_TDM_CFG2_RXS_24BITS;
410 		break;
411 	case 32:
412 		slot_size = TAS2780_TDM_CFG2_RXS_32BITS;
413 		break;
414 	default:
415 		ret = -EINVAL;
416 		goto err;
417 	}
418 
419 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2,
420 		TAS2780_TDM_CFG2_RXS_MASK, slot_size);
421 	if (ret < 0) {
422 		dev_err(tas2780->dev,
423 			"%s:errCode:0x%x Failed to set slot_size\n",
424 			__func__, ret);
425 		goto err;
426 	}
427 
428 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG5,
429 		TAS2780_TDM_CFG5_50_MASK, tas2780->v_sense_slot);
430 	if (ret < 0) {
431 		dev_err(tas2780->dev,
432 			"%s:errCode:0x%x Failed to set v_sense_slot\n",
433 			__func__, ret);
434 		goto err;
435 	}
436 
437 	ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG6,
438 		TAS2780_TDM_CFG6_50_MASK, tas2780->i_sense_slot);
439 	if (ret < 0) {
440 		dev_err(tas2780->dev,
441 			"%s:errCode:0x%x Failed to set i_sense_slot\n",
442 			__func__, ret);
443 		goto err;
444 	}
445 	ret = 0;
446 err:
447 	return ret;
448 }
449 
450 static const struct snd_soc_dai_ops tas2780_dai_ops = {
451 	.mute_stream = tas2780_mute,
452 	.hw_params  = tas2780_hw_params,
453 	.set_fmt    = tas2780_set_fmt,
454 	.set_tdm_slot = tas2780_set_dai_tdm_slot,
455 	.no_capture_mute = 1,
456 };
457 
458 #define TAS2780_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
459 			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
460 
461 #define TAS2780_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
462 		       SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200)
463 
464 static struct snd_soc_dai_driver tas2780_dai_driver[] = {
465 	{
466 		.name = "tas2780 ASI1",
467 		.id = 0,
468 		.playback = {
469 			.stream_name    = "ASI1 Playback",
470 			.channels_min   = 2,
471 			.channels_max   = 2,
472 			.rates      = TAS2780_RATES,
473 			.formats    = TAS2780_FORMATS,
474 		},
475 		.capture = {
476 			.stream_name    = "ASI1 Capture",
477 			.channels_min   = 1,
478 			.channels_max   = 2,
479 			.rates = TAS2780_RATES,
480 			.formats = TAS2780_FORMATS,
481 		},
482 		.ops = &tas2780_dai_ops,
483 		.symmetric_rate = 1,
484 	},
485 };
486 
tas2780_codec_probe(struct snd_soc_component * component)487 static int tas2780_codec_probe(struct snd_soc_component *component)
488 {
489 	struct tas2780_priv *tas2780 =
490 		snd_soc_component_get_drvdata(component);
491 	int ret = 0;
492 
493 	tas2780->component = component;
494 
495 	tas2780_reset(tas2780);
496 	ret = snd_soc_component_update_bits(component,
497 			TAS2780_IC_CFG, TAS2780_IC_CFG_MASK,
498 			TAS2780_IC_CFG_ENABLE);
499 	if (ret < 0)
500 		dev_err(tas2780->dev, "%s:errCode:0x%0x\n",
501 			__func__, ret);
502 
503 	return ret;
504 }
505 
506 static DECLARE_TLV_DB_SCALE(tas2780_digital_tlv, 1100, 50, 0);
507 static DECLARE_TLV_DB_SCALE(tas2780_playback_volume, -10000, 50, 0);
508 
509 static const struct snd_kcontrol_new tas2780_snd_controls[] = {
510 	SOC_SINGLE_TLV("Speaker Volume", TAS2780_DVC, 0,
511 		       TAS2780_DVC_MAX, 1, tas2780_playback_volume),
512 	SOC_SINGLE_TLV("Amp Gain Volume", TAS2780_CHNL_0, 0, 0x14, 0,
513 		       tas2780_digital_tlv),
514 };
515 
516 static const struct snd_soc_component_driver soc_component_driver_tas2780 = {
517 	.probe			= tas2780_codec_probe,
518 #ifdef CONFIG_PM
519 	.suspend		= tas2780_codec_suspend,
520 	.resume			= tas2780_codec_resume,
521 #endif
522 	.controls		= tas2780_snd_controls,
523 	.num_controls		= ARRAY_SIZE(tas2780_snd_controls),
524 	.dapm_widgets		= tas2780_dapm_widgets,
525 	.num_dapm_widgets	= ARRAY_SIZE(tas2780_dapm_widgets),
526 	.dapm_routes		= tas2780_audio_map,
527 	.num_dapm_routes	= ARRAY_SIZE(tas2780_audio_map),
528 	.idle_bias_on		= 1,
529 	.endianness		= 1,
530 };
531 
532 static const struct reg_default tas2780_reg_defaults[] = {
533 	{ TAS2780_PAGE, 0x00 },
534 	{ TAS2780_SW_RST, 0x00 },
535 	{ TAS2780_PWR_CTRL, 0x1a },
536 	{ TAS2780_DVC, 0x00 },
537 	{ TAS2780_CHNL_0, 0x00 },
538 	{ TAS2780_TDM_CFG0, 0x09 },
539 	{ TAS2780_TDM_CFG1, 0x02 },
540 	{ TAS2780_TDM_CFG2, 0x0a },
541 	{ TAS2780_TDM_CFG3, 0x10 },
542 	{ TAS2780_TDM_CFG5, 0x42 },
543 };
544 
545 static const struct regmap_range_cfg tas2780_regmap_ranges[] = {
546 	{
547 		.range_min = 0,
548 		.range_max = 1 * 128,
549 		.selector_reg = TAS2780_PAGE,
550 		.selector_mask = 0xff,
551 		.selector_shift = 0,
552 		.window_start = 0,
553 		.window_len = 128,
554 	},
555 };
556 
557 static const struct regmap_config tas2780_i2c_regmap = {
558 	.reg_bits = 8,
559 	.val_bits = 8,
560 	.reg_defaults = tas2780_reg_defaults,
561 	.num_reg_defaults = ARRAY_SIZE(tas2780_reg_defaults),
562 	.cache_type = REGCACHE_RBTREE,
563 	.ranges = tas2780_regmap_ranges,
564 	.num_ranges = ARRAY_SIZE(tas2780_regmap_ranges),
565 	.max_register = 1 * 128,
566 };
567 
tas2780_parse_dt(struct device * dev,struct tas2780_priv * tas2780)568 static int tas2780_parse_dt(struct device *dev, struct tas2780_priv *tas2780)
569 {
570 	int ret = 0;
571 
572 	tas2780->reset_gpio = devm_gpiod_get_optional(tas2780->dev, "reset",
573 		GPIOD_OUT_HIGH);
574 	if (IS_ERR(tas2780->reset_gpio)) {
575 		if (PTR_ERR(tas2780->reset_gpio) == -EPROBE_DEFER) {
576 			tas2780->reset_gpio = NULL;
577 			return -EPROBE_DEFER;
578 		}
579 	}
580 
581 	ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
582 		&tas2780->i_sense_slot);
583 	if (ret)
584 		tas2780->i_sense_slot = 0;
585 
586 	ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
587 		&tas2780->v_sense_slot);
588 	if (ret)
589 		tas2780->v_sense_slot = 2;
590 
591 	return 0;
592 }
593 
tas2780_i2c_probe(struct i2c_client * client)594 static int tas2780_i2c_probe(struct i2c_client *client)
595 {
596 	struct tas2780_priv *tas2780;
597 	int result;
598 
599 	tas2780 = devm_kzalloc(&client->dev, sizeof(struct tas2780_priv),
600 		GFP_KERNEL);
601 	if (!tas2780)
602 		return -ENOMEM;
603 	tas2780->dev = &client->dev;
604 	i2c_set_clientdata(client, tas2780);
605 	dev_set_drvdata(&client->dev, tas2780);
606 
607 	tas2780->regmap = devm_regmap_init_i2c(client, &tas2780_i2c_regmap);
608 	if (IS_ERR(tas2780->regmap)) {
609 		result = PTR_ERR(tas2780->regmap);
610 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
611 			result);
612 		return result;
613 	}
614 
615 	if (client->dev.of_node) {
616 		result = tas2780_parse_dt(&client->dev, tas2780);
617 		if (result) {
618 			dev_err(tas2780->dev,
619 				"%s: Failed to parse devicetree\n", __func__);
620 			return result;
621 		}
622 	}
623 
624 	return devm_snd_soc_register_component(tas2780->dev,
625 		&soc_component_driver_tas2780, tas2780_dai_driver,
626 		ARRAY_SIZE(tas2780_dai_driver));
627 }
628 
629 static const struct i2c_device_id tas2780_i2c_id[] = {
630 	{ "tas2780", 0},
631 	{ }
632 };
633 MODULE_DEVICE_TABLE(i2c, tas2780_i2c_id);
634 
635 #if defined(CONFIG_OF)
636 static const struct of_device_id tas2780_of_match[] = {
637 	{ .compatible = "ti,tas2780" },
638 	{},
639 };
640 MODULE_DEVICE_TABLE(of, tas2780_of_match);
641 #endif
642 
643 static struct i2c_driver tas2780_i2c_driver = {
644 	.driver = {
645 		.name   = "tas2780",
646 		.of_match_table = of_match_ptr(tas2780_of_match),
647 	},
648 	.probe      = tas2780_i2c_probe,
649 	.id_table   = tas2780_i2c_id,
650 };
651 module_i2c_driver(tas2780_i2c_driver);
652 
653 MODULE_AUTHOR("Raphael Xu <raphael-xu@ti.com>");
654 MODULE_DESCRIPTION("TAS2780 I2C Smart Amplifier driver");
655 MODULE_LICENSE("GPL");
656