Change Magic Number for kernel 4.19 support
[tas2557sw-android/tas2557-android-driver.git] / tas2557-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 **     tas2557-codec.c
15 **
16 ** Description:
17 **     ALSA SoC driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier
18 **
19 ** =============================================================================
20 */
22 #ifdef CONFIG_TAS2557_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 <linux/syscalls.h>
39 #include <linux/fcntl.h>
40 #include <linux/uaccess.h>
41 #include <sound/core.h>
42 #include <sound/pcm.h>
43 #include <sound/pcm_params.h>
44 #include <sound/soc.h>
45 #include <sound/initval.h>
46 #include <sound/tlv.h>
48 #include "tas2557-core.h"
49 #include "tas2557-codec.h"
51 #define KCONTROL_CODEC
53 static unsigned int tas2557_codec_read(struct snd_soc_codec *pCodec,
54         unsigned int nRegister)
55 {
56         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
57         int ret = 0;
58         unsigned int Value = 0;
60         mutex_lock(&pTAS2557->codec_lock);
62         ret = pTAS2557->read(pTAS2557, nRegister, &Value);
63         if (ret < 0)
64                 dev_err(pTAS2557->dev, "%s, %d, ERROR happen=%d\n", __func__,
65                         __LINE__, ret);
66         else
67                 ret = Value;
69         mutex_unlock(&pTAS2557->codec_lock);
70         return ret;
71 }
73 static int tas2557_codec_write(struct snd_soc_codec *pCodec, unsigned int nRegister,
74         unsigned int nValue)
75 {
76         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
77         int ret = 0;
79         mutex_lock(&pTAS2557->codec_lock);
81         ret = pTAS2557->write(pTAS2557, nRegister, nValue);
83         mutex_unlock(&pTAS2557->codec_lock);
84         return ret;
85 }
87 static int tas2557_codec_suspend(struct snd_soc_codec *pCodec)
88 {
89         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
90         int ret = 0;
92         mutex_lock(&pTAS2557->codec_lock);
94         dev_dbg(pTAS2557->dev, "%s\n", __func__);
95         pTAS2557->runtime_suspend(pTAS2557);
97         mutex_unlock(&pTAS2557->codec_lock);
98         return ret;
99 }
101 static int tas2557_codec_resume(struct snd_soc_codec *pCodec)
103         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
104         int ret = 0;
106         mutex_lock(&pTAS2557->codec_lock);
108         dev_dbg(pTAS2557->dev, "%s\n", __func__);
109         pTAS2557->runtime_resume(pTAS2557);
111         mutex_unlock(&pTAS2557->codec_lock);
112         return ret;
115 static const struct snd_soc_dapm_widget tas2557_dapm_widgets[] = {
116         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
117         SND_SOC_DAPM_AIF_IN("ASI2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
118         SND_SOC_DAPM_AIF_IN("ASIM", "ASIM Playback", 0, SND_SOC_NOPM, 0, 0),
119         SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
121         SND_SOC_DAPM_OUT_DRV("ClassD", SND_SOC_NOPM, 0, 0, NULL, 0),
123         SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, NULL, 0),
124         SND_SOC_DAPM_SUPPLY("NDivider", SND_SOC_NOPM, 0, 0, NULL, 0),
126         SND_SOC_DAPM_OUTPUT("OUT")
127 };
129 static const struct snd_soc_dapm_route tas2557_audio_map[] = {
130         {"DAC", NULL, "ASI1"},
131         {"DAC", NULL, "ASI2"},
132         {"DAC", NULL, "ASIM"},
133         {"ClassD", NULL, "DAC"},
134         {"OUT", NULL, "ClassD"},
135         {"DAC", NULL, "PLL"},
136         {"DAC", NULL, "NDivider"},
137 };
139 static int tas2557_startup(struct snd_pcm_substream *substream,
140         struct snd_soc_dai *dai)
142         struct snd_soc_codec *codec = dai->codec;
143         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
145         dev_dbg(pTAS2557->dev, "%s\n", __func__);
146         return 0;
149 static void tas2557_shutdown(struct snd_pcm_substream *substream,
150         struct snd_soc_dai *dai)
152         struct snd_soc_codec *codec = dai->codec;
153         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
155         dev_dbg(pTAS2557->dev, "%s\n", __func__);
158 static int tas2557_mute(struct snd_soc_dai *dai, int mute)
160         struct snd_soc_codec *codec = dai->codec;
161         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
163         mutex_lock(&pTAS2557->codec_lock);
165         dev_dbg(pTAS2557->dev, "%s\n", __func__);
166         tas2557_enable(pTAS2557, !mute);
168         mutex_unlock(&pTAS2557->codec_lock);
169         return 0;
172 static int tas2557_set_dai_sysclk(struct snd_soc_dai *pDAI,
173         int nClkID, unsigned int nFreqency, int nDir)
175         struct snd_soc_codec *pCodec = pDAI->codec;
176         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
178         dev_dbg(pTAS2557->dev, "tas2557_set_dai_sysclk: freq = %u\n", nFreqency);
180         return 0;
183 static int tas2557_hw_params(struct snd_pcm_substream *pSubstream,
184         struct snd_pcm_hw_params *pParams, struct snd_soc_dai *pDAI)
186         struct snd_soc_codec *pCodec = pDAI->codec;
187         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
189         mutex_lock(&pTAS2557->codec_lock);
191         dev_dbg(pTAS2557->dev, "%s\n", __func__);
192 /* do bit rate setting during platform data */
193 /* tas2557_set_bit_rate(pTAS2557, channel_both, snd_pcm_format_width(params_format(pParams))); */
194         tas2557_set_sampling_rate(pTAS2557, params_rate(pParams));
196         mutex_unlock(&pTAS2557->codec_lock);
197         return 0;
200 static int tas2557_set_dai_fmt(struct snd_soc_dai *pDAI, unsigned int nFormat)
202         struct snd_soc_codec *codec = pDAI->codec;
203         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
205         dev_dbg(pTAS2557->dev, "%s\n", __func__);
206         return 0;
209 static int tas2557_prepare(struct snd_pcm_substream *pSubstream,
210         struct snd_soc_dai *pDAI)
212         struct snd_soc_codec *codec = pDAI->codec;
213         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
215         dev_dbg(pTAS2557->dev, "%s\n", __func__);
216         return 0;
219 static int tas2557_set_bias_level(struct snd_soc_codec *pCodec,
220         enum snd_soc_bias_level eLevel)
222         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
224         dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, eLevel);
225         return 0;
228 static int tas2557_codec_probe(struct snd_soc_codec *pCodec)
230         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
232         dev_dbg(pTAS2557->dev, "%s\n", __func__);
233         return 0;
236 static int tas2557_codec_remove(struct snd_soc_codec *pCodec)
238         return 0;
241 static int tas2557_power_ctrl_get(struct snd_kcontrol *pKcontrol,
242         struct snd_ctl_elem_value *pValue)
244 #ifdef KCONTROL_CODEC
245         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
246 #else
247         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
248 #endif
249         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
251         mutex_lock(&pTAS2557->codec_lock);
253         pValue->value.integer.value[0] = pTAS2557->mbPowerUp;
254         dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_get = %d\n",
255                 pTAS2557->mbPowerUp);
257         mutex_unlock(&pTAS2557->codec_lock);
258         return 0;
261 static int tas2557_power_ctrl_put(struct snd_kcontrol *pKcontrol,
262         struct snd_ctl_elem_value *pValue)
264 #ifdef KCONTROL_CODEC
265         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
266 #else
267         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
268 #endif
269         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
271         int nPowerOn = pValue->value.integer.value[0];
273         mutex_lock(&pTAS2557->codec_lock);
275         dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_put = %d\n", nPowerOn);
276         tas2557_enable(pTAS2557, (nPowerOn != 0));
278         mutex_unlock(&pTAS2557->codec_lock);
279         return 0;
282 static int tas2557_fs_get(struct snd_kcontrol *pKcontrol,
283         struct snd_ctl_elem_value *pValue)
285 #ifdef KCONTROL_CODEC
286         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
287 #else
288         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
289 #endif
290         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
291         int nFS = 48000;
293         mutex_lock(&pTAS2557->codec_lock);
295         if (pTAS2557->mpFirmware->mnConfigurations)
296                 nFS = pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration].mnSamplingRate;
297         pValue->value.integer.value[0] = nFS;
298         dev_dbg(pTAS2557->dev, "tas2557_fs_get = %d\n", nFS);
300         mutex_unlock(&pTAS2557->codec_lock);
301         return 0;
304 static int tas2557_fs_put(struct snd_kcontrol *pKcontrol,
305         struct snd_ctl_elem_value *pValue)
307 #ifdef KCONTROL_CODEC
308         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
309 #else
310         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
311 #endif
312         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
313         int ret = 0;
314         int nFS = pValue->value.integer.value[0];
316         mutex_lock(&pTAS2557->codec_lock);
318         dev_info(pTAS2557->dev, "tas2557_fs_put = %d\n", nFS);
319         ret = tas2557_set_sampling_rate(pTAS2557, nFS);
321         mutex_unlock(&pTAS2557->codec_lock);
322         return ret;
325 static int tas2557_Cali_get(struct snd_kcontrol *pKcontrol,
326         struct snd_ctl_elem_value *pValue)
328 #ifdef KCONTROL_CODEC
329         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
330 #else
331         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
332 #endif
333         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
334         bool ret = 0;
335         int prm_r0 = 0;
337         mutex_lock(&pTAS2557->codec_lock);
339         ret = tas2557_get_Cali_prm_r0(pTAS2557, &prm_r0);
340         if (ret)
341                 pValue->value.integer.value[0] = prm_r0;
344         mutex_unlock(&pTAS2557->codec_lock);
345         return 0;
348 static int tas2557_program_get(struct snd_kcontrol *pKcontrol,
349         struct snd_ctl_elem_value *pValue)
351 #ifdef KCONTROL_CODEC
352         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
353 #else
354         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
355 #endif
356         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
358         mutex_lock(&pTAS2557->codec_lock);
360         pValue->value.integer.value[0] = pTAS2557->mnCurrentProgram;
361         dev_dbg(pTAS2557->dev, "tas2557_program_get = %d\n",
362                 pTAS2557->mnCurrentProgram);
364         mutex_unlock(&pTAS2557->codec_lock);
365         return 0;
368 static int tas2557_program_put(struct snd_kcontrol *pKcontrol,
369         struct snd_ctl_elem_value *pValue)
371 #ifdef KCONTROL_CODEC
372         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
373 #else
374         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
375 #endif
376         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
377         unsigned int nProgram = pValue->value.integer.value[0];
378         int ret = 0, nConfiguration = -1;
380         mutex_lock(&pTAS2557->codec_lock);
382         if (nProgram == pTAS2557->mnCurrentProgram)
383                 nConfiguration = pTAS2557->mnCurrentConfiguration;
384         ret = tas2557_set_program(pTAS2557, nProgram, nConfiguration);
386         mutex_unlock(&pTAS2557->codec_lock);
387         return ret;
390 static int tas2557_configuration_get(struct snd_kcontrol *pKcontrol,
391         struct snd_ctl_elem_value *pValue)
393 #ifdef KCONTROL_CODEC
394         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
395 #else
396         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
397 #endif
398         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
400         mutex_lock(&pTAS2557->codec_lock);
402         pValue->value.integer.value[0] = pTAS2557->mnCurrentConfiguration;
403         dev_dbg(pTAS2557->dev, "tas2557_configuration_get = %d\n",
404                 pTAS2557->mnCurrentConfiguration);
406         mutex_unlock(&pTAS2557->codec_lock);
407         return 0;
410 static int tas2557_configuration_put(struct snd_kcontrol *pKcontrol,
411         struct snd_ctl_elem_value *pValue)
413 #ifdef KCONTROL_CODEC
414         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
415 #else
416         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
417 #endif
418         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
419         unsigned int nConfiguration = pValue->value.integer.value[0];
420         int ret = 0;
422         mutex_lock(&pTAS2557->codec_lock);
424         dev_info(pTAS2557->dev, "%s = %d\n", __func__, nConfiguration);
425         ret = tas2557_set_config(pTAS2557, nConfiguration);
427         mutex_unlock(&pTAS2557->codec_lock);
428         return ret;
431 static int tas2557_calibration_get(struct snd_kcontrol *pKcontrol,
432         struct snd_ctl_elem_value *pValue)
434 #ifdef KCONTROL_CODEC
435         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
436 #else
437         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
438 #endif
439         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
441         mutex_lock(&pTAS2557->codec_lock);
443         pValue->value.integer.value[0] = pTAS2557->mnCurrentCalibration;
444         dev_info(pTAS2557->dev,
445                 "tas2557_calibration_get = %d\n",
446                 pTAS2557->mnCurrentCalibration);
448         mutex_unlock(&pTAS2557->codec_lock);
449         return 0;
452 static int tas2557_calibration_put(struct snd_kcontrol *pKcontrol,
453         struct snd_ctl_elem_value *pValue)
455 #ifdef KCONTROL_CODEC
456         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
457 #else
458         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
459 #endif
460         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
461         unsigned int nCalibration = pValue->value.integer.value[0];
462         int ret = 0;
464         mutex_lock(&pTAS2557->codec_lock);
466         ret = tas2557_set_calibration(pTAS2557, nCalibration);
468         mutex_unlock(&pTAS2557->codec_lock);
469         return ret;
472 static const char * const classd_edge_text[] = {
473         "0 (50ns)",
474         "1 (40ns)",
475         "2 (29ns)",
476         "3 (25ns)",
477         "4 (14ns)",
478         "5 (13ns)",
479         "6 (12ns)",
480         "7 (11ns)",
481 };
483 static const struct soc_enum classd_edge_enum[] = {
484         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(classd_edge_text), classd_edge_text),
485 };
487 static int tas2557_edge_get(struct snd_kcontrol *pKcontrol,
488                         struct snd_ctl_elem_value *pValue)
490 #ifdef KCONTROL_CODEC
491         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
492 #else
493         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
494 #endif
495         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
496         mutex_lock(&pTAS2557->codec_lock);
498         pValue->value.integer.value[0] = pTAS2557->mnEdge;
500         mutex_unlock(&pTAS2557->codec_lock);
501         return 0;
503 static int tas2557_edge_put(struct snd_kcontrol *pKcontrol,
504                         struct snd_ctl_elem_value *pValue)
506 #ifdef KCONTROL_CODEC
507         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
508 #else
509         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
510 #endif
511         struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
512         unsigned int edge = pValue->value.integer.value[0];
514         mutex_lock(&pTAS2557->codec_lock);
516         dev_dbg(pTAS2557->dev, "%s, edge %d\n", __func__, edge);
517         pTAS2557->mnEdge = pValue->value.integer.value[0];
518         tas2557_update_edge(pTAS2557);
520         mutex_unlock(&pTAS2557->codec_lock);
521         return 0;
524 static const struct snd_kcontrol_new tas2557_snd_controls[] = {
525         SOC_SINGLE_EXT("PowerCtrl", SND_SOC_NOPM, 0, 0x0001, 0,
526                 tas2557_power_ctrl_get, tas2557_power_ctrl_put),
527         SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, tas2557_program_get,
528                 tas2557_program_put),
529         SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0,
530                 tas2557_configuration_get, tas2557_configuration_put),
531         SOC_SINGLE_EXT("FS", SND_SOC_NOPM, 8000, 48000, 0,
532                 tas2557_fs_get, tas2557_fs_put),
533         SOC_SINGLE_EXT("Get Cali_Re", SND_SOC_NOPM, 0, 0x7f000000, 0,
534                 tas2557_Cali_get, NULL),
535         SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0,
536                 tas2557_calibration_get, tas2557_calibration_put),
537         SOC_ENUM_EXT("TAS2557 ClassD Edge", classd_edge_enum[0],
538                 tas2557_edge_get, tas2557_edge_put),
539 };
541 static struct snd_soc_codec_driver soc_codec_driver_tas2557 = {
542         .probe = tas2557_codec_probe,
543         .remove = tas2557_codec_remove,
544         .read = tas2557_codec_read,
545         .write = tas2557_codec_write,
546         .suspend = tas2557_codec_suspend,
547         .resume = tas2557_codec_resume,
548         .set_bias_level = tas2557_set_bias_level,
549         .idle_bias_off = true,
550         .component_driver = {
551                 .controls = tas2557_snd_controls,
552                 .num_controls = ARRAY_SIZE(tas2557_snd_controls),
553                 .dapm_widgets = tas2557_dapm_widgets,
554                 .num_dapm_widgets = ARRAY_SIZE(tas2557_dapm_widgets),
555                 .dapm_routes = tas2557_audio_map,
556                 .num_dapm_routes = ARRAY_SIZE(tas2557_audio_map),
557         },
558 };
560 static struct snd_soc_dai_ops tas2557_dai_ops = {
561         .startup = tas2557_startup,
562         .shutdown = tas2557_shutdown,
563         .digital_mute = tas2557_mute,
564         .hw_params = tas2557_hw_params,
565         .prepare = tas2557_prepare,
566         .set_sysclk = tas2557_set_dai_sysclk,
567         .set_fmt = tas2557_set_dai_fmt,
568 };
570 #define TAS2557_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
571         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
572 static struct snd_soc_dai_driver tas2557_dai_driver[] = {
573         {
574                 .name = "tas2557 ASI1",
575                 .id = 0,
576                 .playback = {
577                                 .stream_name = "ASI1 Playback",
578                                 .channels_min = 2,
579                                 .channels_max = 2,
580                                 .rates = SNDRV_PCM_RATE_8000_192000,
581                                 .formats = TAS2557_FORMATS,
582                         },
583                 .ops = &tas2557_dai_ops,
584                 .symmetric_rates = 1,
585         },
586         {
587                 .name = "tas2557 ASI2",
588                 .id = 1,
589                 .playback = {
590                                 .stream_name = "ASI2 Playback",
591                                 .channels_min = 2,
592                                 .channels_max = 2,
593                                 .rates = SNDRV_PCM_RATE_8000_192000,
594                                 .formats = TAS2557_FORMATS,
595                         },
596                 .ops = &tas2557_dai_ops,
597                 .symmetric_rates = 1,
598         },
599         {
600                 .name = "tas2557 ASIM",
601                 .id = 2,
602                 .playback = {
603                                 .stream_name = "ASIM Playback",
604                                 .channels_min = 2,
605                                 .channels_max = 2,
606                                 .rates = SNDRV_PCM_RATE_8000_192000,
607                                 .formats = TAS2557_FORMATS,
608                         },
609                 .ops = &tas2557_dai_ops,
610                 .symmetric_rates = 1,
611         },
612 };
614 int tas2557_register_codec(struct tas2557_priv *pTAS2557)
616         int nResult = 0;
618         dev_info(pTAS2557->dev, "%s, enter\n", __func__);
619         nResult = snd_soc_register_codec(pTAS2557->dev,
620                 &soc_codec_driver_tas2557,
621                 tas2557_dai_driver, ARRAY_SIZE(tas2557_dai_driver));
622         return nResult;
625 int tas2557_deregister_codec(struct tas2557_priv *pTAS2557)
627         snd_soc_unregister_codec(pTAS2557->dev);
628         return 0;
631 MODULE_AUTHOR("Texas Instruments Inc.");
632 MODULE_DESCRIPTION("TAS2557 ALSA SOC Smart Amplifier driver");
633 MODULE_LICENSE("GPL v2");
634 #endif