Add regmap init and dac volume config
[tas2770sw-android/tas2770sw-android.git] / tas2770-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 **     tas2770-codec.c
15 **
16 ** Description:
17 **     ALSA SoC driver for TAS2770 20-W Digital Input Mono Class-D Audio Amplifier
18 **     with Speaker I/V Sense
19 **
20 ** =============================================================================
21 */
23 #ifdef CONFIG_TAS2770_CODEC
24 #define DEBUG
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 "tas2770.h"
48 #define TAS2770_MDELAY 0xFFFFFFFE
50 static int tas2770_set_slot(struct snd_soc_codec *codec, int slot_width);
52 static unsigned int tas2770_codec_read(struct snd_soc_codec *codec,
53                 unsigned int reg)
54 {
55         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
56         int nResult = 0;
57         unsigned int value;
58         nResult = tas2770_read(pTAS2770, reg);
60         if (nResult < 0)
61                 dev_err(pTAS2770->dev, "%s, ERROR, reg=0x%x, E=%d\n",
62                         __func__, reg, nResult);
63         else {
64                 value = nResult;
65                 dev_dbg(pTAS2770->dev, "%s, reg: 0x%x, value: 0x%x\n",
66                                 __func__, reg, value);
67         }
68         return nResult;
69 }
71 int tas2770_read(struct tas2770_priv *pTAS2770, unsigned int reg)
72 {
73         int nResult = 0;
74         struct i2c_msg msg_buf[2];
75         unsigned char data1, data2;
77         data2 = (unsigned char)reg;
78         msg_buf[0].addr = pTAS2770->mnAddr;
79         msg_buf[0].len = 1;
80         msg_buf[0].flags = 0;
81         msg_buf[0].buf = &data2;
83         msg_buf[1].addr = pTAS2770->mnAddr;
84         msg_buf[1].len = 1;
85         msg_buf[1].flags = I2C_M_RD;
86         msg_buf[1].buf = &data1;
88         mutex_lock(&pTAS2770->dev_lock);
89         nResult = i2c_transfer(pTAS2770->adapter, msg_buf, 2);
90         mutex_unlock(&pTAS2770->dev_lock);
92         if (nResult >= 0)
93                 return data1;
94         else
95                 return nResult;
96 }
99 static int tas2770_codec_write(struct snd_soc_codec *codec, unsigned int reg,
100                 unsigned int value)
102         int nResult = 0;
103         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
105         nResult = tas2770_write(pTAS2770, reg, value);
107         if (nResult < 0)
108                 dev_err(pTAS2770->dev, "%s, ERROR, reg=0x%x, E=%d\n",
109                         __func__, reg, nResult);
110         else
111                 dev_dbg(pTAS2770->dev, "%s, reg: 0x%x, 0x%x\n",
112                         __func__, reg, value);
113         return nResult;
116 int tas2770_write(struct tas2770_priv *pTAS2770,  unsigned int reg, unsigned int value)
118         int nResult = 0;
119         struct i2c_msg msg;
120         unsigned char data[2];
122         msg.addr = pTAS2770->mnAddr;
123         msg.len = 2;
124         msg.flags = 0;
125         msg.buf = data;
127         data[0] = (unsigned char)reg;
128         data[1] = (unsigned char)value;
130         mutex_lock(&pTAS2770->dev_lock);
131         nResult = i2c_transfer(pTAS2770->adapter, &msg, 1);
132         mutex_unlock(&pTAS2770->dev_lock);
134         return nResult;
137 static int tas2770_codec_suspend(struct snd_soc_codec *codec)
139         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
140         int ret = 0;
142         mutex_lock(&pTAS2770->codec_lock);
144         dev_dbg(pTAS2770->dev, "%s\n", __func__);
146         mutex_unlock(&pTAS2770->codec_lock);
147         return ret;
150 static int tas2770_codec_resume(struct snd_soc_codec *codec)
152         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
153         int ret = 0;
155         mutex_lock(&pTAS2770->codec_lock);
157         dev_dbg(pTAS2770->dev, "%s\n", __func__);
159         mutex_unlock(&pTAS2770->codec_lock);
160         return ret;
163 static const char * const tas2770_ASI1_src[] = {
164         "I2C offset", "Left", "Right", "LeftRightDiv2",
165 };
167 static SOC_ENUM_SINGLE_DECL(
168         tas2770_ASI1_src_enum, TAS2770_TDMConfigurationReg2,
169         4, tas2770_ASI1_src);
171 static const struct snd_kcontrol_new tas2770_asi1_mux =
172         SOC_DAPM_ENUM("ASI1 Source", tas2770_ASI1_src_enum);
175 static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
176                         struct snd_kcontrol *kcontrol, int event)
178         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
180         switch (event) {
181         case SND_SOC_DAPM_POST_PMU:
182                 snd_soc_update_bits(codec, TAS2770_PowerControl,
183                         TAS2770_PowerControl_OperationalMode10_Mask,
184                         TAS2770_PowerControl_OperationalMode10_Mute);
185                 break;
186         case SND_SOC_DAPM_PRE_PMD:
187                 snd_soc_update_bits(codec, TAS2770_PowerControl,
188                         TAS2770_PowerControl_OperationalMode10_Mask,
189                         TAS2770_PowerControl_OperationalMode10_Shutdown);
190                 break;
192         }
193         return 0;
197 static const struct snd_kcontrol_new isense_switch =
198         SOC_DAPM_SINGLE("Switch", TAS2770_PowerControl, 3, 1, 1);
199 static const struct snd_kcontrol_new vsense_switch =
200         SOC_DAPM_SINGLE("Switch", TAS2770_PowerControl, 2, 1, 1);
202 static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = {
203         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
204         SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0,
205                                 &tas2770_asi1_mux),
206         SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PowerControl, 3, 1,
207                         &isense_switch),
208         SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PowerControl, 2, 1,
209                         &vsense_switch),
210         SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2770_dac_event,
211         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
212         SND_SOC_DAPM_OUTPUT("OUT"),
213         SND_SOC_DAPM_SIGGEN("VMON"),
214         SND_SOC_DAPM_SIGGEN("IMON")
215 };
217 static const struct snd_soc_dapm_route tas2770_audio_map[] = {
218         {"ASI1 Sel", "I2C offset", "ASI1"},
219         {"ASI1 Sel", "Left", "ASI1"},
220         {"ASI1 Sel", "Right", "ASI1"},
221         {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
222         {"DAC", NULL, "ASI1 Sel"},
223         {"OUT", NULL, "DAC"},
224         {"ISENSE", "Switch", "IMON"},
225         {"VSENSE", "Switch", "VMON"},
226 };
229 static int tas2770_mute(struct snd_soc_dai *dai, int mute)
231         struct snd_soc_codec *codec = dai->codec;
232         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
233         dev_dbg(pTAS2770->dev, "%s\n", __func__);
235         mutex_lock(&pTAS2770->codec_lock);
236         if (mute) {
237                 snd_soc_update_bits(codec, TAS2770_PowerControl,
238                         TAS2770_PowerControl_OperationalMode10_Mask,
239                         TAS2770_PowerControl_OperationalMode10_Mute);
240         } else {
241                 snd_soc_update_bits(codec, TAS2770_PowerControl,
242                         TAS2770_PowerControl_OperationalMode10_Mask,
243                         TAS2770_PowerControl_OperationalMode10_Active);
244         }
245         mutex_unlock(&pTAS2770->codec_lock);
246         return 0;
249 static int tas2770_hw_params(struct snd_pcm_substream *substream,
250                 struct snd_pcm_hw_params *params,
251                 struct snd_soc_dai *dai)
253         struct snd_soc_codec *codec = dai->codec;
254         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
255         int ret = 0;
256         int slot_width_tmp = 16;
258         dev_dbg(pTAS2770->dev, "%s, format: %d\n", __func__,
259                 params_format(params));
261         switch (params_format(params)) {
262         case SNDRV_PCM_FORMAT_S16_LE:
263                 snd_soc_update_bits(codec,
264                         TAS2770_TDMConfigurationReg2,
265                         TAS2770_TDMConfigurationReg2_RXWLEN32_Mask,
266                         TAS2770_TDMConfigurationReg2_RXWLEN32_16Bits);
267                         pTAS2770->mnCh_size = 16;
268                         if (pTAS2770->mnSlot_width == 0)
269                                 slot_width_tmp = 16;
270                 break;
271         case SNDRV_PCM_FORMAT_S24_LE:
272                         snd_soc_update_bits(codec,
273                         TAS2770_TDMConfigurationReg2,
274                         TAS2770_TDMConfigurationReg2_RXWLEN32_Mask,
275                         TAS2770_TDMConfigurationReg2_RXWLEN32_24Bits);
276                         pTAS2770->mnCh_size = 24;
277                         if (pTAS2770->mnSlot_width == 0)
278                                 slot_width_tmp = 32;
279                 break;
280         case SNDRV_PCM_FORMAT_S32_LE:
281                         snd_soc_update_bits(codec,
282                         TAS2770_TDMConfigurationReg2,
283                         TAS2770_TDMConfigurationReg2_RXWLEN32_Mask,
284                         TAS2770_TDMConfigurationReg2_RXWLEN32_32Bits);
285                         pTAS2770->mnCh_size = 32;
286                         if (pTAS2770->mnSlot_width == 0)
287                                 slot_width_tmp = 32;
288                 break;
290         default:
291                 dev_dbg(pTAS2770->dev, "Not supported params format\n");
292                 return -EINVAL;
293         }
295         /* If machine driver did not call set slot width */
296         if (pTAS2770->mnSlot_width == 0)
297                 tas2770_set_slot(codec, slot_width_tmp);
299         dev_dbg(pTAS2770->dev, "mnCh_size: %d\n", pTAS2770->mnCh_size);
300         snd_soc_update_bits(codec,
301                 TAS2770_TDMConfigurationReg5,
302                 TAS2770_TDMConfigurationReg5_VSNSTX_Mask |
303                 TAS2770_TDMConfigurationReg5_VSNSSLOT50_Mask,
304                 TAS2770_TDMConfigurationReg5_VSNSTX_Enable |
305                 pTAS2770->mnVmon_slot_no);
306         snd_soc_update_bits(codec,
307                 TAS2770_TDMConfigurationReg6,
308                 TAS2770_TDMConfigurationReg6_ISNSTX_Mask |
309                 TAS2770_TDMConfigurationReg6_ISNSSLOT50_Mask,
310                 TAS2770_TDMConfigurationReg6_ISNSTX_Enable |
311                 pTAS2770->mnImon_slot_no);
313         dev_dbg(pTAS2770->dev, "%s, sample rate: %d\n", __func__,
314                 params_rate(params));
315         switch (params_rate(params)) {
316         case 48000:
317                         snd_soc_update_bits(codec,
318                                 TAS2770_TDMConfigurationReg0,
319                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_Mask,
320                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
321                         snd_soc_update_bits(codec,
322                                 TAS2770_TDMConfigurationReg0,
323                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_Mask,
324                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
325                         break;
326         case 44100:
327                         snd_soc_update_bits(codec,
328                                 TAS2770_TDMConfigurationReg0,
329                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_Mask,
330                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
331                         snd_soc_update_bits(codec,
332                                 TAS2770_TDMConfigurationReg0,
333                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_Mask,
334                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
335                         break;
336         case 96000:
337                         snd_soc_update_bits(codec,
338                                 TAS2770_TDMConfigurationReg0,
339                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_Mask,
340                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
341                         snd_soc_update_bits(codec,
342                                 TAS2770_TDMConfigurationReg0,
343                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_Mask,
344                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
345                         break;
346         case 19200:
347                         snd_soc_update_bits(codec,
348                                 TAS2770_TDMConfigurationReg0,
349                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_Mask,
350                                 TAS2770_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
351                         snd_soc_update_bits(codec,
352                                 TAS2770_TDMConfigurationReg0,
353                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_Mask,
354                                 TAS2770_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
355                         break;
356         default:
357                         dev_dbg(pTAS2770->dev, "%s, unsupported sample rate\n", __func__);
359         }
360         return ret;
363 static int tas2770_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
365         u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
366         struct snd_soc_codec *codec = dai->codec;
367         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
368         int ret = 0;
369         int value = 0;
371         dev_dbg(pTAS2770->dev, "%s, format=0x%x\n", __func__, fmt);
373         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
374         case SND_SOC_DAIFMT_CBS_CFS:
375                 asi_cfg_1 = 0x00;
376                 break;
377         default:
378                 dev_err(pTAS2770->dev, "ASI format master is not found\n");
379                 ret = -EINVAL;
380         }
382         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
383         case SND_SOC_DAIFMT_NB_NF:
384                 dev_dbg(pTAS2770->dev, "INV format: NBNF\n");
385                 asi_cfg_1 |= TAS2770_TDMConfigurationReg1_RXEDGE_Rising;
386                 break;
387         case SND_SOC_DAIFMT_IB_NF:
388                 dev_dbg(pTAS2770->dev, "INV format: IBNF\n");
389                 asi_cfg_1 |= TAS2770_TDMConfigurationReg1_RXEDGE_Falling;
390                 break;
391         default:
392                 dev_err(pTAS2770->dev, "ASI format Inverse is not found\n");
393                 ret = -EINVAL;
394         }
396         snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg1,
397                 TAS2770_TDMConfigurationReg1_RXEDGE_Mask,
398                 asi_cfg_1);
400         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
401         case (SND_SOC_DAIFMT_I2S):
402                 tdm_rx_start_slot = 1;
403                 break;
404         case (SND_SOC_DAIFMT_DSP_A):
405         case (SND_SOC_DAIFMT_DSP_B):
406                 tdm_rx_start_slot = 1;
407                 break;
408         case (SND_SOC_DAIFMT_LEFT_J):
409                 tdm_rx_start_slot = 0;
410                 break;
411         default:
412         dev_err(pTAS2770->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
413         ret = -EINVAL;
414                 break;
415         }
417         snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg1,
418                 TAS2770_TDMConfigurationReg1_RXOFFSET51_Mask,
419         (tdm_rx_start_slot << TAS2770_TDMConfigurationReg1_RXOFFSET51_Shift));
421         snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg3,
422                 TAS2770_TDMConfigurationReg3_RXSLOTLeft30_Mask,
423                 (pTAS2770->mnLeftSlot << TAS2770_TDMConfigurationReg3_RXSLOTLeft30_Shift));
424         snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg3,
425                 TAS2770_TDMConfigurationReg3_RXSLOTRight74_Mask,
426         (pTAS2770->mnRightSlot << TAS2770_TDMConfigurationReg3_RXSLOTRight74_Shift));
428         value = snd_soc_read(codec, TAS2770_TDMConfigurationReg3);
429         dev_dbg(pTAS2770->dev, "slot value: 0x%x", value);
431         return ret;
434 static int tas2770_set_slot(struct snd_soc_codec *codec, int slot_width)
436         int ret = 0;
437         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
439         switch (slot_width) {
440         case 16:
441         ret = snd_soc_update_bits(codec,
442                 TAS2770_TDMConfigurationReg2,
443                 TAS2770_TDMConfigurationReg2_RXSLEN10_Mask,
444                 TAS2770_TDMConfigurationReg2_RXSLEN10_16Bits);
445         break;
447         case 24:
448         ret = snd_soc_update_bits(codec,
449                 TAS2770_TDMConfigurationReg2,
450                 TAS2770_TDMConfigurationReg2_RXSLEN10_Mask,
451                 TAS2770_TDMConfigurationReg2_RXSLEN10_24Bits);
452         break;
454         case 32:
455         ret = snd_soc_update_bits(codec,
456                 TAS2770_TDMConfigurationReg2,
457                 TAS2770_TDMConfigurationReg2_RXSLEN10_Mask,
458                 TAS2770_TDMConfigurationReg2_RXSLEN10_32Bits);
459         break;
461         case 0:
462         /* Do not change slot width */
463         break;
465         default:
466                 dev_dbg(pTAS2770->dev, "slot width not supported");
467                 ret = -EINVAL;
468         }
470         if (ret >= 0)
471                 pTAS2770->mnSlot_width = slot_width;
473         return ret;
476 static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai,
477                 unsigned int tx_mask, unsigned int rx_mask,
478                 int slots, int slot_width)
480         int ret = 0;
481         struct snd_soc_codec *codec = dai->codec;
482         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
484         dev_dbg(pTAS2770->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
485                         __func__, tx_mask, rx_mask, slots, slot_width);
487         ret = tas2770_set_slot(codec, slot_width);
489         return ret;
492 static struct snd_soc_dai_ops tas2770_dai_ops = {
493         .digital_mute = tas2770_mute,
494         .hw_params  = tas2770_hw_params,
495         .set_fmt    = tas2770_set_dai_fmt,
496         .set_tdm_slot = tas2770_set_dai_tdm_slot,
497 };
499 #define TAS2770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
500                 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
502 #define TAS2770_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
503                                                 SNDRV_PCM_RATE_96000 |\
504                                                 SNDRV_PCM_RATE_192000\
505                                                 )
507 static struct snd_soc_dai_driver tas2770_dai_driver[] = {
508         {
509                 .name = "tas2770 ASI1",
510                 .id = 0,
511                 .playback = {
512                         .stream_name    = "ASI1 Playback",
513                         .channels_min   = 2,
514                         .channels_max   = 2,
515                         .rates      = TAS2770_RATES,
516                         .formats    = TAS2770_FORMATS,
517                 },
518                 .capture = {
519                         .stream_name    = "ASI1 Capture",
520                         .channels_min   = 0,
521                         .channels_max   = 2,
522                         .rates          = TAS2770_RATES,
523                         .formats    = TAS2770_FORMATS,
524                 },
525                 .ops = &tas2770_dai_ops,
526                 .symmetric_rates = 1,
527         },
528 };
530 static int tas2770_codec_probe(struct snd_soc_codec *codec)
532         struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec);
534         dev_err(pTAS2770->dev, "%s\n", __func__);
535         snd_soc_codec_init_regmap(codec, pTAS2770->regmap);
537         return 0;
540 static int tas2770_codec_remove(struct snd_soc_codec *codec)
542         return 0;
545 static DECLARE_TLV_DB_SCALE(tas2770_digital_tlv, 1100, 50, 0);
546 static DECLARE_TLV_DB_SCALE(tas2770_playback_volume, -10000, 50, 0);
548 static const struct snd_kcontrol_new tas2770_snd_controls[] = {
549         SOC_SINGLE_TLV("Amp Output Level", TAS2770_PlaybackConfigurationReg0,
550                 0, TAS2770_PlaybackConfigurationReg0_AmplifierLevel40_Mask, 0,
551                 tas2770_digital_tlv),
552         SOC_SINGLE_TLV("Playback Volume", TAS2770_PlaybackConfigurationReg2,
553                 0, TAS2770_PlaybackConfigurationReg2_DVCPCM70_Mask, 1,
554                 tas2770_playback_volume),
555 };
557 static struct snd_soc_codec_driver soc_codec_driver_tas2770 = {
558         .probe                  = tas2770_codec_probe,
559         .remove                 = tas2770_codec_remove,
560         .read                   = tas2770_codec_read,
561         .write                  = tas2770_codec_write,
562         .suspend                = tas2770_codec_suspend,
563         .resume                 = tas2770_codec_resume,
564         .component_driver = {
565                 .controls               = tas2770_snd_controls,
566                 .num_controls           = ARRAY_SIZE(tas2770_snd_controls),
567                 .dapm_widgets           = tas2770_dapm_widgets,
568                 .num_dapm_widgets       = ARRAY_SIZE(tas2770_dapm_widgets),
569                 .dapm_routes            = tas2770_audio_map,
570                 .num_dapm_routes        = ARRAY_SIZE(tas2770_audio_map),
571         },
572 };
574 int tas2770_register_codec(struct tas2770_priv *pTAS2770)
576         int nResult = 0;
578         dev_info(pTAS2770->dev, "%s, enter\n", __func__);
579         nResult = snd_soc_register_codec(pTAS2770->dev,
580                 &soc_codec_driver_tas2770,
581                 tas2770_dai_driver, ARRAY_SIZE(tas2770_dai_driver));
583         return nResult;
586 int tas2770_deregister_codec(struct tas2770_priv *pTAS2770)
588         snd_soc_unregister_codec(pTAS2770->dev);
590         return 0;
593 MODULE_AUTHOR("Texas Instruments Inc.");
594 MODULE_DESCRIPTION("TAS2770 ALSA SOC Smart Amplifier driver");
595 MODULE_LICENSE("GPL v2");
596 #endif /* CONFIG_TAS2770_CODEC */