]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - tas256xsw-android/tas2562-android-driver.git/blob - tas2562-codec.c
Add IRQ support
[tas256xsw-android/tas2562-android-driver.git] / tas2562-codec.c
1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016  Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.
12 **
13 ** File:
14 **     tas2562-codec.c
15 **
16 ** Description:
17 **     ALSA SoC driver for Texas Instruments TAS2562 High Performance 4W Smart
18 **     Amplifier
19 **
20 ** =============================================================================
21 */
23 #ifdef CONFIG_TAS2562_CODEC
24 #define DEBUG 5
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/pm.h>
30 #include <linux/i2c.h>
31 #include <linux/gpio.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/firmware.h>
34 #include <linux/regmap.h>
35 #include <linux/of.h>
36 #include <linux/of_gpio.h>
37 #include <linux/slab.h>
38 #include <sound/core.h>
39 #include <sound/pcm.h>
40 #include <sound/pcm_params.h>
41 #include <sound/soc.h>
42 #include <sound/initval.h>
43 #include <sound/tlv.h>
45 #include "tas2562.h"
48 #define TAS2562_MDELAY 0xFFFFFFFE
49 /* #define KCONTROL_CODEC */
51 static char pICN[] = {0x00, 0x03, 0x46, 0xdc};
52 static char const *iv_enable_text[] = {"Off", "On"};
53 static int tas2562iv_enable;
54 static const struct soc_enum tas2562_enum[] = {
55     SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(iv_enable_text), iv_enable_text),
56 };
57 static int tas2562_set_fmt(struct tas2562_priv *pTAS2562, unsigned int fmt);
59 static unsigned int tas2562_codec_read(struct snd_soc_codec *codec,
60                 unsigned int reg)
61 {
62         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
63         int nResult = 0;
64         unsigned int value = 0;
66         mutex_lock(&pTAS2562->dev_lock);
68         nResult = regmap_read(pTAS2562->regmap, reg, &value);
70         if (nResult < 0)
71                 dev_err(pTAS2562->dev, "%s, ERROR, reg=0x%x, E=%d\n",
72                         __func__, reg, nResult);
73         else
74                 dev_dbg(pTAS2562->dev, "%s, reg: 0x%x, value: 0x%x\n",
75                                 __func__, reg, value);
77         mutex_unlock(&pTAS2562->dev_lock);
79         if (nResult >= 0)
80                 return value;
81         else
82                 return nResult;
83 }
85 static int tas2562_iv_enable(struct tas2562_priv *pTAS2562, int enable)
86 {
87         int nResult;
89         if (enable) {
90                 pr_debug("%s: tas2562iv_enable \n", __func__);
91                 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
92                     TAS2562_PowerControl_ISNSPower_Mask |
93                     TAS2562_PowerControl_VSNSPower_Mask,
94                     TAS2562_PowerControl_VSNSPower_Active |
95                     TAS2562_PowerControl_ISNSPower_Active);
96         } else {
97                 pr_debug("%s: tas2562iv_disable \n", __func__);
98                 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
99                         TAS2562_PowerControl_ISNSPower_Mask |
100                         TAS2562_PowerControl_VSNSPower_Mask,
101                         TAS2562_PowerControl_VSNSPower_PoweredDown |
102                         TAS2562_PowerControl_ISNSPower_PoweredDown);
103         }
104         tas2562iv_enable = enable;
106         return nResult;
109 static int tas2562iv_put(struct snd_kcontrol *kcontrol,
110                                    struct snd_ctl_elem_value *ucontrol)
112     struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
113         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
114         int iv_enable = 0, nResult = 0;
116     if (codec == NULL) {
117                 pr_err("%s: codec is NULL \n",  __func__);
118                 return 0;
119     }
121     iv_enable = ucontrol->value.integer.value[0];
123         nResult = tas2562_iv_enable(pTAS2562, iv_enable);
125         pr_debug("%s: tas2562iv_enable = %d\n", __func__, tas2562iv_enable);
127         return nResult;
130 static int tas2562iv_get(struct snd_kcontrol *kcontrol,
131                                   struct snd_ctl_elem_value *ucontrol)
133    ucontrol->value.integer.value[0] = tas2562iv_enable;
134    return 0;
137 static const struct snd_kcontrol_new tas2562_controls[] = {
138 SOC_ENUM_EXT("TAS2562 IVSENSE ENABLE", tas2562_enum[0],
139                     tas2562iv_get, tas2562iv_put),
140 };
142 static int tas2562_codec_write(struct snd_soc_codec *codec, unsigned int reg,
143         unsigned int value)
145         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
147         int nResult = 0;
149         mutex_lock(&pTAS2562->dev_lock);
151         nResult = regmap_write(pTAS2562->regmap, reg, value);
152         if (nResult < 0)
153                 dev_err(pTAS2562->dev, "%s, ERROR, reg=0x%x, E=%d\n",
154                         __func__, reg, nResult);
155         else
156                 dev_dbg(pTAS2562->dev, "%s, reg: 0x%x, 0x%x\n",
157                         __func__, reg, value);
159         mutex_unlock(&pTAS2562->dev_lock);
161         return nResult;
166 static int tas2562_codec_suspend(struct snd_soc_codec *codec)
168         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
169         int ret = 0;
171         mutex_lock(&pTAS2562->codec_lock);
173         dev_dbg(pTAS2562->dev, "%s\n", __func__);
174         pTAS2562->runtime_suspend(pTAS2562);
176         mutex_unlock(&pTAS2562->codec_lock);
177         return ret;
180 static int tas2562_codec_resume(struct snd_soc_codec *codec)
182         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
183         int ret = 0;
185         mutex_lock(&pTAS2562->codec_lock);
187         dev_dbg(pTAS2562->dev, "%s\n", __func__);
188         pTAS2562->runtime_resume(pTAS2562);
190         mutex_unlock(&pTAS2562->codec_lock);
191         return ret;
194 static const struct snd_kcontrol_new tas2562_asi_controls[] = {
195         SOC_DAPM_SINGLE("Left", TAS2562_TDMConfigurationReg2,
196                 4, 1, 0),
197         SOC_DAPM_SINGLE("Right", TAS2562_TDMConfigurationReg2,
198                 4, 2, 0),
199         SOC_DAPM_SINGLE("LeftRightDiv2", TAS2562_TDMConfigurationReg2,
200                 4, 3, 0),
201 };
203 static int tas2562_set_power_state(struct tas2562_priv *pTAS2562, int state)
205         int nResult = 0;
206         /*unsigned int nValue;*/
208         dev_err(pTAS2562->dev, "set power state: %d\n", state);
210         switch (state) {
211         case TAS2562_POWER_ACTIVE:
212         //if set format was not called by asoc, then set it default
213                 if(pTAS2562->mnASIFormat == 0)
214                         pTAS2562->mnASIFormat = SND_SOC_DAIFMT_CBS_CFS
215                                 | SND_SOC_DAIFMT_IB_NF
216                                 | SND_SOC_DAIFMT_I2S;
217                 nResult = tas2562_set_fmt(pTAS2562, pTAS2562->mnASIFormat);
218                 if (nResult < 0)
219                         return nResult;
221                 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
222                         TAS2562_PowerControl_OperationalMode10_Mask,
223                         TAS2562_PowerControl_OperationalMode10_Active);
224                 if (nResult < 0)
225                         return nResult;
226                 pTAS2562->mbPowerUp = true;
227                 dev_info(pTAS2562->dev, "set ICN to -80dB\n");
228                 nResult = pTAS2562->bulk_write(pTAS2562, TAS2562_ICN_REG, pICN, 4);
229                 pTAS2562->mnPowerState = TAS2562_POWER_ACTIVE;
230         pTAS2562->enableIRQ(pTAS2562, true);
231                 break;
233         case TAS2562_POWER_MUTE:
234                 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
235                         TAS2562_PowerControl_OperationalMode10_Mask |
236                         TAS2562_PowerControl_ISNSPower_Mask |
237                         TAS2562_PowerControl_VSNSPower_Mask,
238                         TAS2562_PowerControl_OperationalMode10_Mute |
239                         TAS2562_PowerControl_VSNSPower_Active |
240                         TAS2562_PowerControl_ISNSPower_Active);
241                         pTAS2562->mbPowerUp = true;
242                         pTAS2562->mnPowerState = TAS2562_POWER_MUTE;
243                 break;
245         case TAS2562_POWER_SHUTDOWN:
246                 pTAS2562->enableIRQ(pTAS2562, false);
247                 if (hrtimer_active(&pTAS2562->mtimer))
248                 {
249                         dev_info(pTAS2562->dev, "cancel timer\n");
250                         hrtimer_cancel(&pTAS2562->mtimer);
251                 }
253                 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
254                         TAS2562_PowerControl_OperationalMode10_Mask,
255                         TAS2562_PowerControl_OperationalMode10_Shutdown);
256                         pTAS2562->mbPowerUp = false;
257                         pTAS2562->mnPowerState = TAS2562_POWER_SHUTDOWN;
258                 msleep(20);
260                 break;
262         default:
263                 dev_err(pTAS2562->dev, "wrong power state setting %d\n", state);
265         }
267         return nResult;
271 static int tas2562_dac_event(struct snd_soc_dapm_widget *w,
272                         struct snd_kcontrol *kcontrol, int event)
274         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
275         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
277         switch (event) {
278         case SND_SOC_DAPM_POST_PMU:
279                 tas2562_set_power_state(pTAS2562, TAS2562_POWER_ACTIVE);
280                 break;
281         case SND_SOC_DAPM_PRE_PMD:
282                 tas2562_set_power_state(pTAS2562, TAS2562_POWER_SHUTDOWN);
283                 break;
285         }
286         return 0;
290 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = {
291         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
292         SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture",  1, TAS2562_PowerControl, 2, 1),
293         SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture",  0, TAS2562_PowerControl, 3, 1),
294         SND_SOC_DAPM_MIXER("ASI1 Sel",
295                 TAS2562_TDMConfigurationReg2, 4, 0,
296                 &tas2562_asi_controls[0],
297                 ARRAY_SIZE(tas2562_asi_controls)),
298         SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event,
299         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
300         SND_SOC_DAPM_OUTPUT("OUT"),
301         SND_SOC_DAPM_SIGGEN("VMON"),
302         SND_SOC_DAPM_SIGGEN("IMON")
303 };
305 static const struct snd_soc_dapm_route tas2562_audio_map[] = {
306         {"ASI1 Sel", "Left", "ASI1"},
307         {"ASI1 Sel", "Right", "ASI1"},
308         {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
309         {"DAC", NULL, "ASI1 Sel"},
310         {"OUT", NULL, "DAC"},
311         /*{"VMON", NULL, "Voltage Sense"},
312         {"IMON", NULL, "Current Sense"},*/
313         {"Voltage Sense", NULL, "VMON"},
314         {"Current Sense", NULL, "IMON"},
315 };
318 static int tas2562_mute(struct snd_soc_dai *dai, int mute)
320         struct snd_soc_codec *codec = dai->codec;
321         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
323         dev_dbg(pTAS2562->dev, "%s, %d \n", __func__, mute);
325         mutex_lock(&pTAS2562->codec_lock);
326         if (mute) {
327                 tas2562_set_power_state(pTAS2562, TAS2562_POWER_SHUTDOWN);
328         } else {
329                 tas2562_set_power_state(pTAS2562, TAS2562_POWER_ACTIVE);
330         }
331         mutex_unlock(&pTAS2562->codec_lock);
332         return 0;
335 static int tas2562_slot_config(struct snd_soc_codec *codec, struct tas2562_priv *pTAS2562, int blr_clk_ratio)
337         int ret = 0;
338                 pTAS2562->update_bits(pTAS2562,
339                         TAS2562_TDMConfigurationReg5, 0xff, 0x42);
341                 pTAS2562->update_bits(pTAS2562,
342                         TAS2562_TDMConfigurationReg6, 0xff, 0x40);
344         return ret;
347 static int tas2562_set_slot(struct snd_soc_codec *codec, int slot_width)
349         int ret = 0;
350         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
352         switch (slot_width) {
353         case 16:
354         ret = pTAS2562->update_bits(pTAS2562,
355                 TAS2562_TDMConfigurationReg2,
356                 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
357                 TAS2562_TDMConfigurationReg2_RXSLEN10_16Bits);
358         break;
360         case 24:
361         ret = pTAS2562->update_bits(pTAS2562,
362                 TAS2562_TDMConfigurationReg2,
363                 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
364                 TAS2562_TDMConfigurationReg2_RXSLEN10_24Bits);
365         break;
367         case 32:
368         ret = pTAS2562->update_bits(pTAS2562,
369                 TAS2562_TDMConfigurationReg2,
370                 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
371                 TAS2562_TDMConfigurationReg2_RXSLEN10_32Bits);
372         break;
374         case 0:
375         /* Do not change slot width */
376         break;
378         default:
379                 dev_err(pTAS2562->dev, "slot width not supported");
380                 ret = -EINVAL;
381         }
383         if (ret >= 0)
384                 pTAS2562->mnSlot_width = slot_width;
386         return ret;
389 static int tas2562_set_bitwidth(struct tas2562_priv *pTAS2562, int bitwidth)
391         int slot_width_tmp = 16;
392         dev_info(pTAS2562->dev, "%s %d\n", __func__, bitwidth);
394         switch (bitwidth) {
395         case SNDRV_PCM_FORMAT_S16_LE:
396                         pTAS2562->update_bits(pTAS2562,
397                         TAS2562_TDMConfigurationReg2,
398                         TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
399                         TAS2562_TDMConfigurationReg2_RXWLEN32_16Bits);
400                         pTAS2562->mnCh_size = 16;
401                         if (pTAS2562->mnSlot_width == 0)
402                                 slot_width_tmp = 16;
403                 break;
404         case SNDRV_PCM_FORMAT_S24_LE:
405                         pTAS2562->update_bits(pTAS2562,
406                         TAS2562_TDMConfigurationReg2,
407                         TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
408                         TAS2562_TDMConfigurationReg2_RXWLEN32_24Bits);
409                         pTAS2562->mnCh_size = 24;
410                         if (pTAS2562->mnSlot_width == 0)
411                                 slot_width_tmp = 32;
412                 break;
413         case SNDRV_PCM_FORMAT_S32_LE:
414                         pTAS2562->update_bits(pTAS2562,
415                         TAS2562_TDMConfigurationReg2,
416                         TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
417                         TAS2562_TDMConfigurationReg2_RXWLEN32_32Bits);
418                         pTAS2562->mnCh_size = 32;
419                         if (pTAS2562->mnSlot_width == 0)
420                                 slot_width_tmp = 32;
421                 break;
423         default:
424                 dev_info(pTAS2562->dev, "Not supported params format\n");
425         }
427         /* If machine driver did not call set slot width */
428         if (pTAS2562->mnSlot_width == 0)
429                 tas2562_set_slot(pTAS2562->codec, slot_width_tmp);
431         dev_info(pTAS2562->dev, "mnCh_size: %d\n", pTAS2562->mnCh_size);
432         pTAS2562->mnPCMFormat = bitwidth;
434         return 0;
437 static int tas2562_set_samplerate(struct tas2562_priv *pTAS2562, int samplerate)
439         switch (samplerate) {
440         case 48000:
441                         pTAS2562->update_bits(pTAS2562,
442                                 TAS2562_TDMConfigurationReg0,
443                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
444                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
445                         pTAS2562->update_bits(pTAS2562,
446                                 TAS2562_TDMConfigurationReg0,
447                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
448                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
449                         break;
450         case 44100:
451                         pTAS2562->update_bits(pTAS2562,
452                                 TAS2562_TDMConfigurationReg0,
453                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
454                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
455                         pTAS2562->update_bits(pTAS2562,
456                                 TAS2562_TDMConfigurationReg0,
457                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
458                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
459                         break;
460         case 96000:
461                         pTAS2562->update_bits(pTAS2562,
462                                 TAS2562_TDMConfigurationReg0,
463                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
464                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
465                         pTAS2562->update_bits(pTAS2562,
466                                 TAS2562_TDMConfigurationReg0,
467                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
468                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
469                         break;
470         case 88200:
471                         pTAS2562->update_bits(pTAS2562,
472                                 TAS2562_TDMConfigurationReg0,
473                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
474                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
475                         pTAS2562->update_bits(pTAS2562,
476                                 TAS2562_TDMConfigurationReg0,
477                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
478                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
479                         break;
480         case 19200:
481                         pTAS2562->update_bits(pTAS2562,
482                                 TAS2562_TDMConfigurationReg0,
483                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
484                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
485                         pTAS2562->update_bits(pTAS2562,
486                                 TAS2562_TDMConfigurationReg0,
487                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
488                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
489                         break;
490         case 17640:
491                         pTAS2562->update_bits(pTAS2562,
492                                 TAS2562_TDMConfigurationReg0,
493                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
494                                 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
495                         pTAS2562->update_bits(pTAS2562,
496                                 TAS2562_TDMConfigurationReg0,
497                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
498                                 TAS2562_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
499                         break;
500         default:
501                         dev_info(pTAS2562->dev, "%s, unsupported sample rate, %d\n", __func__, samplerate);
503         }
505         pTAS2562->mnSamplingRate = samplerate;
506         return 0;
511 static int tas2562_hw_params(struct snd_pcm_substream *substream,
512                 struct snd_pcm_hw_params *params,
513                 struct snd_soc_dai *dai)
515         struct snd_soc_codec *codec = dai->codec;
516         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
517         int blr_clk_ratio;
518         int ret = 0;
520         dev_dbg(pTAS2562->dev, "%s, format: %d\n", __func__,
521                 params_format(params));
523         mutex_lock(&pTAS2562->codec_lock);
525         ret = tas2562_set_bitwidth(pTAS2562, params_format(params));
526         if(ret < 0)
527         {
528                 dev_info(pTAS2562->dev, "set bitwidth failed, %d\n", ret);
529                 goto ret;
530         }
532         blr_clk_ratio = params_channels(params) * pTAS2562->mnCh_size;
533         dev_info(pTAS2562->dev, "blr_clk_ratio: %d\n", blr_clk_ratio);
534         if(blr_clk_ratio != 0)
535                 tas2562_slot_config(pTAS2562->codec, pTAS2562, blr_clk_ratio);
537         dev_info(pTAS2562->dev, "%s, sample rate: %d\n", __func__,
538                 params_rate(params));
540         ret = tas2562_set_samplerate(pTAS2562, params_rate(params));
542 ret:
543         mutex_unlock(&pTAS2562->codec_lock);
544         return ret;
547 static int tas2562_set_fmt(struct tas2562_priv *pTAS2562, unsigned int fmt)
549         u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
550         int ret = 0;
552         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
553         case SND_SOC_DAIFMT_CBS_CFS:
554                 asi_cfg_1 = 0x00;
555                 break;
556         default:
557                 dev_err(pTAS2562->dev, "ASI format master is not found\n");
558                 ret = -EINVAL;
559         }
561         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
562         case SND_SOC_DAIFMT_NB_NF:
563                 dev_info(pTAS2562->dev, "INV format: NBNF\n");
564                 asi_cfg_1 |= TAS2562_TDMConfigurationReg1_RXEDGE_Rising;
565                 break;
566         case SND_SOC_DAIFMT_IB_NF:
567                 dev_info(pTAS2562->dev, "INV format: IBNF\n");
568                 asi_cfg_1 |= TAS2562_TDMConfigurationReg1_RXEDGE_Falling;
569                 break;
570         default:
571                 dev_err(pTAS2562->dev, "ASI format Inverse is not found\n");
572                 ret = -EINVAL;
573         }
575         pTAS2562->update_bits(pTAS2562, TAS2562_TDMConfigurationReg1,
576                 TAS2562_TDMConfigurationReg1_RXEDGE_Mask,
577                 asi_cfg_1);
579         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
580         case (SND_SOC_DAIFMT_I2S):
581                 tdm_rx_start_slot = 1;
582                 break;
583         case (SND_SOC_DAIFMT_DSP_A):
584         case (SND_SOC_DAIFMT_DSP_B):
585                 tdm_rx_start_slot = 1;
586                 break;
587         case (SND_SOC_DAIFMT_LEFT_J):
588                 tdm_rx_start_slot = 0;
589                 break;
590         default:
591         dev_err(pTAS2562->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
592         ret = -EINVAL;
593                 break;
594         }
596         pTAS2562->update_bits(pTAS2562, TAS2562_TDMConfigurationReg1,
597                 TAS2562_TDMConfigurationReg1_RXOFFSET51_Mask,
598                 (tdm_rx_start_slot << TAS2562_TDMConfigurationReg1_RXOFFSET51_Shift));
600         pTAS2562->mnASIFormat = fmt;
602         return 0;
605 static int tas2562_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
607         struct snd_soc_codec *codec = dai->codec;
608         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
609         int ret = 0;
611         dev_dbg(pTAS2562->dev, "%s, format=0x%x\n", __func__, fmt);
613         ret = tas2562_set_fmt(pTAS2562, fmt);
614         return ret;
617 static int tas2562_set_dai_tdm_slot(struct snd_soc_dai *dai,
618                 unsigned int tx_mask, unsigned int rx_mask,
619                 int slots, int slot_width)
621         int ret = 0;
622         struct snd_soc_codec *codec = dai->codec;
623         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
625         dev_dbg(pTAS2562->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
626                         __func__, tx_mask, rx_mask, slots, slot_width);
628         ret = tas2562_set_slot(codec, slot_width);
630         return ret;
633 static struct snd_soc_dai_ops tas2562_dai_ops = {
634         .digital_mute = tas2562_mute,
635         .hw_params  = tas2562_hw_params,
636         .set_fmt    = tas2562_set_dai_fmt,
637         .set_tdm_slot = tas2562_set_dai_tdm_slot,
638 };
640 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
641                 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
643 #define TAS2562_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 \
644                                                 SNDRV_PCM_RATE_88200 |\
645                                                 SNDRV_PCM_RATE_96000 |\
646                                                 SNDRV_PCM_RATE_176400 |\
647                                                 SNDRV_PCM_RATE_192000\
648                                                 )
650 static struct snd_soc_dai_driver tas2562_dai_driver[] = {
651         {
652                 .name = "tas2562 ASI1",
653                 .id = 0,
654                 .playback = {
655                         .stream_name    = "ASI1 Playback",
656                         .channels_min   = 2,
657                         .channels_max   = 2,
658                         .rates      = SNDRV_PCM_RATE_8000_192000,
659                         .formats    = TAS2562_FORMATS,
660                 },
661                 .capture = {
662                         .stream_name    = "ASI1 Capture",
663                         .channels_min   = 0,
664                         .channels_max   = 2,
665                         .rates          = SNDRV_PCM_RATE_8000_192000,
666                         .formats    = TAS2562_FORMATS,
667                 },
668                 .ops = &tas2562_dai_ops,
669                 .symmetric_rates = 1,
670         },
671 };
673 static int tas2562_codec_probe(struct snd_soc_codec *codec)
675         int ret;
676         struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
678         ret = snd_soc_add_codec_controls(codec, tas2562_controls,
679                                          ARRAY_SIZE(tas2562_controls));
680         if (ret < 0) {
681                 pr_err("%s: add_codec_controls failed, err %d\n",
682                         __func__, ret);
683                 return ret;
684         }
686         tas2562_iv_enable(pTAS2562, 1);
687         pTAS2562->codec = codec;
688         dev_err(pTAS2562->dev, "%s\n", __func__);
690         return 0;
693 static int tas2562_codec_remove(struct snd_soc_codec *codec)
695         return 0;
698 static DECLARE_TLV_DB_SCALE(tas2562_digital_tlv, 1100, 50, 0);
700 static const struct snd_kcontrol_new tas2562_snd_controls[] = {
701         SOC_SINGLE_TLV("Amp Output Level", TAS2562_PlaybackConfigurationReg0,
702                 0, 0x16, 0,
703                 tas2562_digital_tlv),
704 };
706 static struct snd_soc_codec_driver soc_codec_driver_tas2562 = {
707         .probe                  = tas2562_codec_probe,
708         .remove                 = tas2562_codec_remove,
709         .read                   = tas2562_codec_read,
710         .write                  = tas2562_codec_write,
711         .suspend                = tas2562_codec_suspend,
712         .resume                 = tas2562_codec_resume,
713         .component_driver = {
714         .controls               = tas2562_snd_controls,
715         .num_controls           = ARRAY_SIZE(tas2562_snd_controls),
716                 .dapm_widgets           = tas2562_dapm_widgets,
717                 .num_dapm_widgets       = ARRAY_SIZE(tas2562_dapm_widgets),
718                 .dapm_routes            = tas2562_audio_map,
719                 .num_dapm_routes        = ARRAY_SIZE(tas2562_audio_map),
720         },
721 };
723 int tas2562_register_codec(struct tas2562_priv *pTAS2562)
725         int nResult = 0;
727         dev_info(pTAS2562->dev, "%s, enter\n", __func__);
728         nResult = snd_soc_register_codec(pTAS2562->dev,
729                 &soc_codec_driver_tas2562,
730                 tas2562_dai_driver, ARRAY_SIZE(tas2562_dai_driver));
731         return nResult;
734 int tas2562_deregister_codec(struct tas2562_priv *pTAS2562)
736         snd_soc_unregister_codec(pTAS2562->dev);
738         return 0;
741 void tas2562_LoadConfig(struct tas2562_priv *pTAS2562)
743         int ret = 0;
745         if (hrtimer_active(&pTAS2562->mtimer))
746         {
747                 dev_info(pTAS2562->dev, "cancel timer\n");
748                 hrtimer_cancel(&pTAS2562->mtimer);
749         } else
750                 dev_info(pTAS2562->dev, "timer not active\n");
751                 
752         pTAS2562->hw_reset(pTAS2562);
753         pTAS2562->write(pTAS2562, TAS2562_SoftwareReset,
754                         TAS2562_SoftwareReset_SoftwareReset_Reset);
755     msleep(3);
757     pTAS2562->write(pTAS2562, TAS2562_MiscConfigurationReg0, 0xce);
759         ret = tas2562_set_slot(pTAS2562->codec, pTAS2562->mnSlot_width);
760         if (ret < 0)
761                 goto end;
763         ret = tas2562_set_fmt(pTAS2562, pTAS2562->mnASIFormat);
764         if (ret < 0)
765                 goto end;
767         ret = tas2562_set_bitwidth(pTAS2562, pTAS2562->mnPCMFormat);
768         if (ret < 0)
769                 goto end;
771         ret = tas2562_set_samplerate(pTAS2562, pTAS2562->mnSamplingRate);
772         if (ret < 0)
773                 goto end;
775         ret = tas2562_set_power_state(pTAS2562, pTAS2562->mnPowerState);
776         if (ret < 0)
777                 goto end;
779 end:
780 /* power up failed, restart later */
781         if (ret < 0)
782                 schedule_delayed_work(&pTAS2562->irq_work,
783                                 msecs_to_jiffies(1000));
786 MODULE_AUTHOR("Texas Instruments Inc.");
787 MODULE_DESCRIPTION("TAS2562 ALSA SOC Smart Amplifier driver");
788 MODULE_LICENSE("GPL v2");
789 #endif /* CONFIG_TAS2562_CODEC */