1// SPDX-License-Identifier: GPL-2.0
2//
3// ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier
4//
5// Copyright (C) 2022 - 2023 Texas Instruments Incorporated
6// https://www.ti.com
7//
8// The TAS2563/TAS2781 driver implements a flexible and configurable
9// algo coefficient setting for one, two, or even multiple
10// TAS2563/TAS2781 chips.
11//
12// Author: Shenghao Ding <shenghao-ding@ti.com>
13// Author: Kevin Lu <kevin-lu@ti.com>
14//
15
16#include <linux/crc8.h>
17#include <linux/firmware.h>
18#include <linux/gpio/consumer.h>
19#include <linux/i2c.h>
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/module.h>
23#include <linux/of.h>
24#include <linux/of_gpio.h>
25#include <linux/of_irq.h>
26#include <linux/regmap.h>
27#include <linux/slab.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/tas2781.h>
31#include <sound/tlv.h>
32#include <sound/tas2781-tlv.h>
33
34static const struct i2c_device_id tasdevice_id[] = {
35 { "tas2563", TAS2563 },
36 { "tas2781", TAS2781 },
37 {}
38};
39MODULE_DEVICE_TABLE(i2c, tasdevice_id);
40
41#ifdef CONFIG_OF
42static const struct of_device_id tasdevice_of_match[] = {
43 { .compatible = "ti,tas2563" },
44 { .compatible = "ti,tas2781" },
45 {},
46};
47MODULE_DEVICE_TABLE(of, tasdevice_of_match);
48#endif
49
50/**
51 * tas2781_digital_getvol - get the volum control
52 * @kcontrol: control pointer
53 * @ucontrol: User data
54 * Customer Kcontrol for tas2781 is primarily for regmap booking, paging
55 * depends on internal regmap mechanism.
56 * tas2781 contains book and page two-level register map, especially
57 * book switching will set the register BXXP00R7F, after switching to the
58 * correct book, then leverage the mechanism for paging to access the
59 * register.
60 */
61static int tas2781_digital_getvol(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
63{
64 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
65 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
66 struct soc_mixer_control *mc =
67 (struct soc_mixer_control *)kcontrol->private_value;
68
69 return tasdevice_digital_getvol(tas_priv, ucontrol, mc);
70}
71
72static int tas2781_digital_putvol(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_value *ucontrol)
74{
75 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
76 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
77 struct soc_mixer_control *mc =
78 (struct soc_mixer_control *)kcontrol->private_value;
79
80 return tasdevice_digital_putvol(tas_priv, ucontrol, mc);
81}
82
83static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
84 struct snd_ctl_elem_value *ucontrol)
85{
86 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
87 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
88 struct soc_mixer_control *mc =
89 (struct soc_mixer_control *)kcontrol->private_value;
90
91 return tasdevice_amp_getvol(tas_priv, ucontrol, mc);
92}
93
94static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
95 struct snd_ctl_elem_value *ucontrol)
96{
97 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
98 struct tasdevice_priv *tas_priv =
99 snd_soc_component_get_drvdata(c: codec);
100 struct soc_mixer_control *mc =
101 (struct soc_mixer_control *)kcontrol->private_value;
102
103 return tasdevice_amp_putvol(tas_priv, ucontrol, mc);
104}
105
106static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
107 struct snd_ctl_elem_value *ucontrol)
108{
109 struct snd_soc_component *component =
110 snd_soc_kcontrol_component(kcontrol);
111 struct tasdevice_priv *tas_priv =
112 snd_soc_component_get_drvdata(c: component);
113
114 ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;
115 dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
116 tas_priv->force_fwload_status ? "ON" : "OFF");
117
118 return 0;
119}
120
121static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_value *ucontrol)
123{
124 struct snd_soc_component *component =
125 snd_soc_kcontrol_component(kcontrol);
126 struct tasdevice_priv *tas_priv =
127 snd_soc_component_get_drvdata(c: component);
128 bool change, val = (bool)ucontrol->value.integer.value[0];
129
130 if (tas_priv->force_fwload_status == val)
131 change = false;
132 else {
133 change = true;
134 tas_priv->force_fwload_status = val;
135 }
136 dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
137 tas_priv->force_fwload_status ? "ON" : "OFF");
138
139 return change;
140}
141
142static const struct snd_kcontrol_new tas2781_snd_controls[] = {
143 SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Gain", TAS2781_AMP_LEVEL,
144 1, 0, 20, 0, tas2781_amp_getvol,
145 tas2781_amp_putvol, amp_vol_tlv),
146 SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Gain", TAS2781_DVC_LVL,
147 0, 0, 200, 1, tas2781_digital_getvol,
148 tas2781_digital_putvol, dvc_tlv),
149 SOC_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,
150 tas2781_force_fwload_get, tas2781_force_fwload_put),
151};
152
153static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,
154 struct snd_ctl_elem_value *ucontrol)
155{
156 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
157 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
158 int ret = 0;
159
160 if (tas_priv->rcabin.profile_cfg_id !=
161 ucontrol->value.integer.value[0]) {
162 tas_priv->rcabin.profile_cfg_id =
163 ucontrol->value.integer.value[0];
164 ret = 1;
165 }
166
167 return ret;
168}
169
170static int tasdevice_info_programs(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_info *uinfo)
172{
173 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
174 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
175 struct tasdevice_fw *tas_fw = tas_priv->fmw;
176
177 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
178 uinfo->count = 1;
179 uinfo->value.integer.min = 0;
180 uinfo->value.integer.max = (int)tas_fw->nr_programs;
181
182 return 0;
183}
184
185static int tasdevice_info_configurations(
186 struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
187{
188 struct snd_soc_component *codec =
189 snd_soc_kcontrol_component(kcontrol);
190 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
191 struct tasdevice_fw *tas_fw = tas_priv->fmw;
192
193 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
194 uinfo->count = 1;
195 uinfo->value.integer.min = 0;
196 uinfo->value.integer.max = (int)tas_fw->nr_configurations - 1;
197
198 return 0;
199}
200
201static int tasdevice_info_profile(struct snd_kcontrol *kcontrol,
202 struct snd_ctl_elem_info *uinfo)
203{
204 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
205 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
206
207 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
208 uinfo->count = 1;
209 uinfo->value.integer.min = 0;
210 uinfo->value.integer.max = tas_priv->rcabin.ncfgs - 1;
211
212 return 0;
213}
214
215static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_value *ucontrol)
217{
218 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
219 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
220
221 ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id;
222
223 return 0;
224}
225
226static int tasdevice_create_control(struct tasdevice_priv *tas_priv)
227{
228 struct snd_kcontrol_new *prof_ctrls;
229 int nr_controls = 1;
230 int mix_index = 0;
231 int ret;
232 char *name;
233
234 prof_ctrls = devm_kcalloc(dev: tas_priv->dev, n: nr_controls,
235 size: sizeof(prof_ctrls[0]), GFP_KERNEL);
236 if (!prof_ctrls) {
237 ret = -ENOMEM;
238 goto out;
239 }
240
241 /* Create a mixer item for selecting the active profile */
242 name = devm_kzalloc(dev: tas_priv->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
243 GFP_KERNEL);
244 if (!name) {
245 ret = -ENOMEM;
246 goto out;
247 }
248 scnprintf(buf: name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, fmt: "Speaker Profile Id");
249 prof_ctrls[mix_index].name = name;
250 prof_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
251 prof_ctrls[mix_index].info = tasdevice_info_profile;
252 prof_ctrls[mix_index].get = tasdevice_get_profile_id;
253 prof_ctrls[mix_index].put = tasdevice_set_profile_id;
254 mix_index++;
255
256 ret = snd_soc_add_component_controls(component: tas_priv->codec,
257 controls: prof_ctrls, num_controls: nr_controls < mix_index ? nr_controls : mix_index);
258
259out:
260 return ret;
261}
262
263static int tasdevice_program_get(struct snd_kcontrol *kcontrol,
264 struct snd_ctl_elem_value *ucontrol)
265{
266 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
267 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
268
269 ucontrol->value.integer.value[0] = tas_priv->cur_prog;
270
271 return 0;
272}
273
274static int tasdevice_program_put(struct snd_kcontrol *kcontrol,
275 struct snd_ctl_elem_value *ucontrol)
276{
277 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
278 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
279 unsigned int nr_program = ucontrol->value.integer.value[0];
280 int ret = 0;
281
282 if (tas_priv->cur_prog != nr_program) {
283 tas_priv->cur_prog = nr_program;
284 ret = 1;
285 }
286
287 return ret;
288}
289
290static int tasdevice_configuration_get(struct snd_kcontrol *kcontrol,
291 struct snd_ctl_elem_value *ucontrol)
292{
293
294 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
295 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
296
297 ucontrol->value.integer.value[0] = tas_priv->cur_conf;
298
299 return 0;
300}
301
302static int tasdevice_configuration_put(
303 struct snd_kcontrol *kcontrol,
304 struct snd_ctl_elem_value *ucontrol)
305{
306 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
307 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
308 unsigned int nr_configuration = ucontrol->value.integer.value[0];
309 int ret = 0;
310
311 if (tas_priv->cur_conf != nr_configuration) {
312 tas_priv->cur_conf = nr_configuration;
313 ret = 1;
314 }
315
316 return ret;
317}
318
319static int tasdevice_dsp_create_ctrls(
320 struct tasdevice_priv *tas_priv)
321{
322 struct snd_kcontrol_new *dsp_ctrls;
323 char *prog_name, *conf_name;
324 int nr_controls = 2;
325 int mix_index = 0;
326 int ret;
327
328 /* Alloc kcontrol via devm_kzalloc, which don't manually
329 * free the kcontrol
330 */
331 dsp_ctrls = devm_kcalloc(dev: tas_priv->dev, n: nr_controls,
332 size: sizeof(dsp_ctrls[0]), GFP_KERNEL);
333 if (!dsp_ctrls) {
334 ret = -ENOMEM;
335 goto out;
336 }
337
338 /* Create a mixer item for selecting the active profile */
339 prog_name = devm_kzalloc(dev: tas_priv->dev,
340 SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL);
341 conf_name = devm_kzalloc(dev: tas_priv->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
342 GFP_KERNEL);
343 if (!prog_name || !conf_name) {
344 ret = -ENOMEM;
345 goto out;
346 }
347
348 scnprintf(buf: prog_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
349 fmt: "Speaker Program Id");
350 dsp_ctrls[mix_index].name = prog_name;
351 dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
352 dsp_ctrls[mix_index].info = tasdevice_info_programs;
353 dsp_ctrls[mix_index].get = tasdevice_program_get;
354 dsp_ctrls[mix_index].put = tasdevice_program_put;
355 mix_index++;
356
357 scnprintf(buf: conf_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
358 fmt: "Speaker Config Id");
359 dsp_ctrls[mix_index].name = conf_name;
360 dsp_ctrls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
361 dsp_ctrls[mix_index].info = tasdevice_info_configurations;
362 dsp_ctrls[mix_index].get = tasdevice_configuration_get;
363 dsp_ctrls[mix_index].put = tasdevice_configuration_put;
364 mix_index++;
365
366 ret = snd_soc_add_component_controls(component: tas_priv->codec, controls: dsp_ctrls,
367 num_controls: nr_controls < mix_index ? nr_controls : mix_index);
368
369out:
370 return ret;
371}
372
373static void tasdevice_fw_ready(const struct firmware *fmw,
374 void *context)
375{
376 struct tasdevice_priv *tas_priv = context;
377 int ret = 0;
378 int i;
379
380 mutex_lock(&tas_priv->codec_lock);
381
382 ret = tasdevice_rca_parser(context: tas_priv, fmw);
383 if (ret)
384 goto out;
385 tasdevice_create_control(tas_priv);
386
387 tasdevice_dsp_remove(context: tas_priv);
388 tasdevice_calbin_remove(context: tas_priv);
389 tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;
390 scnprintf(buf: tas_priv->coef_binaryname, size: 64, fmt: "%s_coef.bin",
391 tas_priv->dev_name);
392 ret = tasdevice_dsp_parser(context: tas_priv);
393 if (ret) {
394 dev_err(tas_priv->dev, "dspfw load %s error\n",
395 tas_priv->coef_binaryname);
396 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
397 goto out;
398 }
399 tasdevice_dsp_create_ctrls(tas_priv);
400
401 tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
402
403 /* If calibrated data occurs error, dsp will still works with default
404 * calibrated data inside algo.
405 */
406 for (i = 0; i < tas_priv->ndev; i++) {
407 scnprintf(buf: tas_priv->cal_binaryname[i], size: 64, fmt: "%s_cal_0x%02x.bin",
408 tas_priv->dev_name, tas_priv->tasdevice[i].dev_addr);
409 ret = tas2781_load_calibration(context: tas_priv,
410 file_name: tas_priv->cal_binaryname[i], i);
411 if (ret != 0)
412 dev_err(tas_priv->dev,
413 "%s: load %s error, default will effect\n",
414 __func__, tas_priv->cal_binaryname[i]);
415 }
416
417 tasdevice_prmg_calibdata_load(context: tas_priv, prm_no: 0);
418 tas_priv->cur_prog = 0;
419out:
420 if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
421 /*If DSP FW fail, kcontrol won't be created */
422 tasdevice_config_info_remove(context: tas_priv);
423 tasdevice_dsp_remove(context: tas_priv);
424 }
425 mutex_unlock(lock: &tas_priv->codec_lock);
426 if (fmw)
427 release_firmware(fw: fmw);
428}
429
430static int tasdevice_dapm_event(struct snd_soc_dapm_widget *w,
431 struct snd_kcontrol *kcontrol, int event)
432{
433 struct snd_soc_component *codec = snd_soc_dapm_to_component(dapm: w->dapm);
434 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
435 int state = 0;
436
437 /* Codec Lock Hold */
438 mutex_lock(&tas_priv->codec_lock);
439 if (event == SND_SOC_DAPM_PRE_PMD)
440 state = 1;
441 tasdevice_tuning_switch(context: tas_priv, state);
442 /* Codec Lock Release*/
443 mutex_unlock(lock: &tas_priv->codec_lock);
444
445 return 0;
446}
447
448static const struct snd_soc_dapm_widget tasdevice_dapm_widgets[] = {
449 SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0),
450 SND_SOC_DAPM_AIF_OUT_E("ASI OUT", "ASI Capture", 0, SND_SOC_NOPM,
451 0, 0, tasdevice_dapm_event,
452 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
453 SND_SOC_DAPM_SPK("SPK", tasdevice_dapm_event),
454 SND_SOC_DAPM_OUTPUT("OUT"),
455 SND_SOC_DAPM_INPUT("DMIC")
456};
457
458static const struct snd_soc_dapm_route tasdevice_audio_map[] = {
459 {"SPK", NULL, "ASI"},
460 {"OUT", NULL, "SPK"},
461 {"ASI OUT", NULL, "DMIC"}
462};
463
464static int tasdevice_startup(struct snd_pcm_substream *substream,
465 struct snd_soc_dai *dai)
466{
467 struct snd_soc_component *codec = dai->component;
468 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
469 int ret = 0;
470
471 if (tas_priv->fw_state != TASDEVICE_DSP_FW_ALL_OK) {
472 dev_err(tas_priv->dev, "DSP bin file not loaded\n");
473 ret = -EINVAL;
474 }
475
476 return ret;
477}
478
479static int tasdevice_hw_params(struct snd_pcm_substream *substream,
480 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
481{
482 struct tasdevice_priv *tas_priv = snd_soc_dai_get_drvdata(dai);
483 unsigned int slot_width;
484 unsigned int fsrate;
485 int bclk_rate;
486 int rc = 0;
487
488 fsrate = params_rate(p: params);
489 switch (fsrate) {
490 case 48000:
491 case 44100:
492 break;
493 default:
494 dev_err(tas_priv->dev, "%s: incorrect sample rate = %u\n",
495 __func__, fsrate);
496 rc = -EINVAL;
497 goto out;
498 }
499
500 slot_width = params_width(p: params);
501 switch (slot_width) {
502 case 16:
503 case 20:
504 case 24:
505 case 32:
506 break;
507 default:
508 dev_err(tas_priv->dev, "%s: incorrect slot width = %u\n",
509 __func__, slot_width);
510 rc = -EINVAL;
511 goto out;
512 }
513
514 bclk_rate = snd_soc_params_to_bclk(parms: params);
515 if (bclk_rate < 0) {
516 dev_err(tas_priv->dev, "%s: incorrect bclk rate = %d\n",
517 __func__, bclk_rate);
518 rc = bclk_rate;
519 goto out;
520 }
521
522out:
523 return rc;
524}
525
526static int tasdevice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
527 int clk_id, unsigned int freq, int dir)
528{
529 struct tasdevice_priv *tas_priv = snd_soc_dai_get_drvdata(dai: codec_dai);
530
531 tas_priv->sysclk = freq;
532
533 return 0;
534}
535
536static const struct snd_soc_dai_ops tasdevice_dai_ops = {
537 .startup = tasdevice_startup,
538 .hw_params = tasdevice_hw_params,
539 .set_sysclk = tasdevice_set_dai_sysclk,
540};
541
542static struct snd_soc_dai_driver tasdevice_dai_driver[] = {
543 {
544 .name = "tas2781_codec",
545 .id = 0,
546 .playback = {
547 .stream_name = "Playback",
548 .channels_min = 1,
549 .channels_max = 4,
550 .rates = TASDEVICE_RATES,
551 .formats = TASDEVICE_FORMATS,
552 },
553 .capture = {
554 .stream_name = "Capture",
555 .channels_min = 1,
556 .channels_max = 4,
557 .rates = TASDEVICE_RATES,
558 .formats = TASDEVICE_FORMATS,
559 },
560 .ops = &tasdevice_dai_ops,
561 .symmetric_rate = 1,
562 },
563};
564
565static int tasdevice_codec_probe(struct snd_soc_component *codec)
566{
567 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
568
569 return tascodec_init(tas_priv, codec, THIS_MODULE, cont: tasdevice_fw_ready);
570}
571
572static void tasdevice_deinit(void *context)
573{
574 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
575
576 tasdevice_config_info_remove(context: tas_priv);
577 tasdevice_dsp_remove(context: tas_priv);
578 tasdevice_calbin_remove(context: tas_priv);
579 tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;
580}
581
582static void tasdevice_codec_remove(
583 struct snd_soc_component *codec)
584{
585 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(c: codec);
586
587 tasdevice_deinit(context: tas_priv);
588}
589
590static const struct snd_soc_component_driver
591 soc_codec_driver_tasdevice = {
592 .probe = tasdevice_codec_probe,
593 .remove = tasdevice_codec_remove,
594 .controls = tas2781_snd_controls,
595 .num_controls = ARRAY_SIZE(tas2781_snd_controls),
596 .dapm_widgets = tasdevice_dapm_widgets,
597 .num_dapm_widgets = ARRAY_SIZE(tasdevice_dapm_widgets),
598 .dapm_routes = tasdevice_audio_map,
599 .num_dapm_routes = ARRAY_SIZE(tasdevice_audio_map),
600 .idle_bias_on = 1,
601 .endianness = 1,
602};
603
604static void tasdevice_parse_dt(struct tasdevice_priv *tas_priv)
605{
606 struct i2c_client *client = (struct i2c_client *)tas_priv->client;
607 unsigned int dev_addrs[TASDEVICE_MAX_CHANNELS];
608 int rc, i, ndev = 0;
609
610 if (tas_priv->isacpi) {
611 ndev = device_property_read_u32_array(dev: &client->dev,
612 propname: "ti,audio-slots", NULL, nval: 0);
613 if (ndev <= 0) {
614 ndev = 1;
615 dev_addrs[0] = client->addr;
616 } else {
617 ndev = (ndev < ARRAY_SIZE(dev_addrs))
618 ? ndev : ARRAY_SIZE(dev_addrs);
619 ndev = device_property_read_u32_array(dev: &client->dev,
620 propname: "ti,audio-slots", val: dev_addrs, nval: ndev);
621 }
622
623 tas_priv->irq_info.irq_gpio =
624 acpi_dev_gpio_irq_get(ACPI_COMPANION(&client->dev), index: 0);
625 } else {
626 struct device_node *np = tas_priv->dev->of_node;
627#ifdef CONFIG_OF
628 const __be32 *reg, *reg_end;
629 int len, sw, aw;
630
631 aw = of_n_addr_cells(np);
632 sw = of_n_size_cells(np);
633 if (sw == 0) {
634 reg = (const __be32 *)of_get_property(node: np,
635 name: "reg", lenp: &len);
636 reg_end = reg + len/sizeof(*reg);
637 ndev = 0;
638 do {
639 dev_addrs[ndev] = of_read_number(cell: reg, size: aw);
640 reg += aw;
641 ndev++;
642 } while (reg < reg_end);
643 } else {
644 ndev = 1;
645 dev_addrs[0] = client->addr;
646 }
647#else
648 ndev = 1;
649 dev_addrs[0] = client->addr;
650#endif
651 tas_priv->irq_info.irq_gpio = of_irq_get(dev: np, index: 0);
652 }
653 tas_priv->ndev = ndev;
654 for (i = 0; i < ndev; i++)
655 tas_priv->tasdevice[i].dev_addr = dev_addrs[i];
656
657 tas_priv->reset = devm_gpiod_get_optional(dev: &client->dev,
658 con_id: "reset-gpios", flags: GPIOD_OUT_HIGH);
659 if (IS_ERR(ptr: tas_priv->reset))
660 dev_err(tas_priv->dev, "%s Can't get reset GPIO\n",
661 __func__);
662
663 strcpy(p: tas_priv->dev_name, q: tasdevice_id[tas_priv->chip_id].name);
664
665 if (gpio_is_valid(number: tas_priv->irq_info.irq_gpio)) {
666 rc = gpio_request(gpio: tas_priv->irq_info.irq_gpio,
667 label: "AUDEV-IRQ");
668 if (!rc) {
669 gpio_direction_input(
670 gpio: tas_priv->irq_info.irq_gpio);
671
672 tas_priv->irq_info.irq =
673 gpio_to_irq(gpio: tas_priv->irq_info.irq_gpio);
674 } else
675 dev_err(tas_priv->dev, "%s: GPIO %d request error\n",
676 __func__, tas_priv->irq_info.irq_gpio);
677 } else
678 dev_err(tas_priv->dev,
679 "Looking up irq-gpio property failed %d\n",
680 tas_priv->irq_info.irq_gpio);
681}
682
683static int tasdevice_i2c_probe(struct i2c_client *i2c)
684{
685 const struct i2c_device_id *id = i2c_match_id(id: tasdevice_id, client: i2c);
686 const struct acpi_device_id *acpi_id;
687 struct tasdevice_priv *tas_priv;
688 int ret;
689
690 tas_priv = tasdevice_kzalloc(i2c);
691 if (!tas_priv)
692 return -ENOMEM;
693
694 dev_set_drvdata(dev: &i2c->dev, data: tas_priv);
695
696 if (ACPI_HANDLE(&i2c->dev)) {
697 acpi_id = acpi_match_device(ids: i2c->dev.driver->acpi_match_table,
698 dev: &i2c->dev);
699 if (!acpi_id) {
700 dev_err(&i2c->dev, "No driver data\n");
701 ret = -EINVAL;
702 goto err;
703 }
704 tas_priv->chip_id = acpi_id->driver_data;
705 tas_priv->isacpi = true;
706 } else {
707 tas_priv->chip_id = id ? id->driver_data : 0;
708 tas_priv->isacpi = false;
709 }
710
711 tasdevice_parse_dt(tas_priv);
712
713 ret = tasdevice_init(tas_priv);
714 if (ret)
715 goto err;
716
717 ret = devm_snd_soc_register_component(dev: tas_priv->dev,
718 component_driver: &soc_codec_driver_tasdevice,
719 dai_drv: tasdevice_dai_driver, ARRAY_SIZE(tasdevice_dai_driver));
720 if (ret) {
721 dev_err(tas_priv->dev, "%s: codec register error:0x%08x\n",
722 __func__, ret);
723 goto err;
724 }
725err:
726 if (ret < 0)
727 tasdevice_remove(tas_priv);
728 return ret;
729}
730
731static void tasdevice_i2c_remove(struct i2c_client *client)
732{
733 struct tasdevice_priv *tas_priv = i2c_get_clientdata(client);
734
735 tasdevice_remove(tas_priv);
736}
737
738#ifdef CONFIG_ACPI
739static const struct acpi_device_id tasdevice_acpi_match[] = {
740 { "TAS2781", TAS2781 },
741 {},
742};
743
744MODULE_DEVICE_TABLE(acpi, tasdevice_acpi_match);
745#endif
746
747static struct i2c_driver tasdevice_i2c_driver = {
748 .driver = {
749 .name = "tas2781-codec",
750 .of_match_table = of_match_ptr(tasdevice_of_match),
751#ifdef CONFIG_ACPI
752 .acpi_match_table = ACPI_PTR(tasdevice_acpi_match),
753#endif
754 },
755 .probe = tasdevice_i2c_probe,
756 .remove = tasdevice_i2c_remove,
757 .id_table = tasdevice_id,
758};
759
760module_i2c_driver(tasdevice_i2c_driver);
761
762MODULE_AUTHOR("Shenghao Ding <shenghao-ding@ti.com>");
763MODULE_AUTHOR("Kevin Lu <kevin-lu@ti.com>");
764MODULE_DESCRIPTION("ASoC TAS2781 Driver");
765MODULE_LICENSE("GPL");
766MODULE_IMPORT_NS(SND_SOC_TAS2781_FMWLIB);
767

source code of linux/sound/soc/codecs/tas2781-i2c.c