~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/tas2781-i2c.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php