1 // SPDX-License-Identifier: GPL-2.0-only
3 * tas5720.c - ALSA SoC Texas Instruments TAS5720 Mono Audio Amplifier
5 * Copyright (C)2015-2016 Texas Instruments Incorporated - http://www.ti.com
7 * Author: Andreas Dannenberg <dannenberg@ti.com>
10 #include <linux/module.h>
11 #include <linux/errno.h>
12 #include <linux/device.h>
13 #include <linux/i2c.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/slab.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/delay.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include <sound/soc.h>
23 #include <sound/soc-dapm.h>
24 #include <sound/tlv.h>
28 /* Define how often to check (and clear) the fault status register (in ms) */
29 #define TAS5720_FAULT_CHECK_INTERVAL 200
36 static const char * const tas5720_supply_names
[] = {
37 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */
38 "pvdd", /* Class-D amp and analog power supply (connected). */
41 #define TAS5720_NUM_SUPPLIES ARRAY_SIZE(tas5720_supply_names)
44 struct snd_soc_component
*component
;
45 struct regmap
*regmap
;
46 struct i2c_client
*tas5720_client
;
47 enum tas572x_type devtype
;
48 struct regulator_bulk_data supplies
[TAS5720_NUM_SUPPLIES
];
49 struct delayed_work fault_check_work
;
50 unsigned int last_fault
;
53 static int tas5720_hw_params(struct snd_pcm_substream
*substream
,
54 struct snd_pcm_hw_params
*params
,
55 struct snd_soc_dai
*dai
)
57 struct snd_soc_component
*component
= dai
->component
;
58 unsigned int rate
= params_rate(params
);
72 dev_err(component
->dev
, "unsupported sample rate: %u\n", rate
);
76 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL1_REG
,
77 TAS5720_SSZ_DS
, ssz_ds
);
79 dev_err(component
->dev
, "error setting sample rate: %d\n", ret
);
86 static int tas5720_set_dai_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
88 struct snd_soc_component
*component
= dai
->component
;
92 if ((fmt
& SND_SOC_DAIFMT_MASTER_MASK
) != SND_SOC_DAIFMT_CBS_CFS
) {
93 dev_vdbg(component
->dev
, "DAI Format master is not found\n");
97 switch (fmt
& (SND_SOC_DAIFMT_FORMAT_MASK
|
98 SND_SOC_DAIFMT_INV_MASK
)) {
99 case (SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
):
100 /* 1st data bit occur one BCLK cycle after the frame sync */
101 serial_format
= TAS5720_SAIF_I2S
;
103 case (SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_NB_NF
):
105 * Note that although the TAS5720 does not have a dedicated DSP
106 * mode it doesn't care about the LRCLK duty cycle during TDM
107 * operation. Therefore we can use the device's I2S mode with
108 * its delaying of the 1st data bit to receive DSP_A formatted
109 * data. See device datasheet for additional details.
111 serial_format
= TAS5720_SAIF_I2S
;
113 case (SND_SOC_DAIFMT_DSP_B
| SND_SOC_DAIFMT_NB_NF
):
115 * Similar to DSP_A, we can use the fact that the TAS5720 does
116 * not care about the LRCLK duty cycle during TDM to receive
117 * DSP_B formatted data in LEFTJ mode (no delaying of the 1st
120 serial_format
= TAS5720_SAIF_LEFTJ
;
122 case (SND_SOC_DAIFMT_LEFT_J
| SND_SOC_DAIFMT_NB_NF
):
123 /* No delay after the frame sync */
124 serial_format
= TAS5720_SAIF_LEFTJ
;
127 dev_vdbg(component
->dev
, "DAI Format is not found\n");
131 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL1_REG
,
132 TAS5720_SAIF_FORMAT_MASK
,
135 dev_err(component
->dev
, "error setting SAIF format: %d\n", ret
);
142 static int tas5720_set_dai_tdm_slot(struct snd_soc_dai
*dai
,
143 unsigned int tx_mask
, unsigned int rx_mask
,
144 int slots
, int slot_width
)
146 struct snd_soc_component
*component
= dai
->component
;
147 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
148 unsigned int first_slot
;
152 dev_err(component
->dev
, "tx masks must not be 0\n");
157 * Determine the first slot that is being requested. We will only
158 * use the first slot that is found since the TAS5720 is a mono
161 first_slot
= __ffs(tx_mask
);
163 if (first_slot
> 7) {
164 dev_err(component
->dev
, "slot selection out of bounds (%u)\n",
169 /* Enable manual TDM slot selection (instead of I2C ID based) */
170 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL1_REG
,
171 TAS5720_TDM_CFG_SRC
, TAS5720_TDM_CFG_SRC
);
173 goto error_snd_soc_component_update_bits
;
175 /* Configure the TDM slot to process audio from */
176 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL2_REG
,
177 TAS5720_TDM_SLOT_SEL_MASK
, first_slot
);
179 goto error_snd_soc_component_update_bits
;
181 /* Configure TDM slot width. This is only applicable to TAS5722. */
182 switch (tas5720
->devtype
) {
184 ret
= snd_soc_component_update_bits(component
, TAS5722_DIGITAL_CTRL2_REG
,
185 TAS5722_TDM_SLOT_16B
,
187 TAS5722_TDM_SLOT_16B
: 0);
189 goto error_snd_soc_component_update_bits
;
197 error_snd_soc_component_update_bits
:
198 dev_err(component
->dev
, "error configuring TDM mode: %d\n", ret
);
202 static int tas5720_mute(struct snd_soc_dai
*dai
, int mute
)
204 struct snd_soc_component
*component
= dai
->component
;
207 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL2_REG
,
208 TAS5720_MUTE
, mute
? TAS5720_MUTE
: 0);
210 dev_err(component
->dev
, "error (un-)muting device: %d\n", ret
);
217 static void tas5720_fault_check_work(struct work_struct
*work
)
219 struct tas5720_data
*tas5720
= container_of(work
, struct tas5720_data
,
220 fault_check_work
.work
);
221 struct device
*dev
= tas5720
->component
->dev
;
222 unsigned int curr_fault
;
225 ret
= regmap_read(tas5720
->regmap
, TAS5720_FAULT_REG
, &curr_fault
);
227 dev_err(dev
, "failed to read FAULT register: %d\n", ret
);
231 /* Check/handle all errors except SAIF clock errors */
232 curr_fault
&= TAS5720_OCE
| TAS5720_DCE
| TAS5720_OTE
;
235 * Only flag errors once for a given occurrence. This is needed as
236 * the TAS5720 will take time clearing the fault condition internally
237 * during which we don't want to bombard the system with the same
238 * error message over and over.
240 if ((curr_fault
& TAS5720_OCE
) && !(tas5720
->last_fault
& TAS5720_OCE
))
241 dev_crit(dev
, "experienced an over current hardware fault\n");
243 if ((curr_fault
& TAS5720_DCE
) && !(tas5720
->last_fault
& TAS5720_DCE
))
244 dev_crit(dev
, "experienced a DC detection fault\n");
246 if ((curr_fault
& TAS5720_OTE
) && !(tas5720
->last_fault
& TAS5720_OTE
))
247 dev_crit(dev
, "experienced an over temperature fault\n");
249 /* Store current fault value so we can detect any changes next time */
250 tas5720
->last_fault
= curr_fault
;
256 * Periodically toggle SDZ (shutdown bit) H->L->H to clear any latching
257 * faults as long as a fault condition persists. Always going through
258 * the full sequence no matter the first return value to minimizes
259 * chances for the device to end up in shutdown mode.
261 ret
= regmap_write_bits(tas5720
->regmap
, TAS5720_POWER_CTRL_REG
,
264 dev_err(dev
, "failed to write POWER_CTRL register: %d\n", ret
);
266 ret
= regmap_write_bits(tas5720
->regmap
, TAS5720_POWER_CTRL_REG
,
267 TAS5720_SDZ
, TAS5720_SDZ
);
269 dev_err(dev
, "failed to write POWER_CTRL register: %d\n", ret
);
272 /* Schedule the next fault check at the specified interval */
273 schedule_delayed_work(&tas5720
->fault_check_work
,
274 msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL
));
277 static int tas5720_codec_probe(struct snd_soc_component
*component
)
279 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
280 unsigned int device_id
, expected_device_id
;
283 tas5720
->component
= component
;
285 ret
= regulator_bulk_enable(ARRAY_SIZE(tas5720
->supplies
),
288 dev_err(component
->dev
, "failed to enable supplies: %d\n", ret
);
293 * Take a liberal approach to checking the device ID to allow the
294 * driver to be used even if the device ID does not match, however
295 * issue a warning if there is a mismatch.
297 ret
= regmap_read(tas5720
->regmap
, TAS5720_DEVICE_ID_REG
, &device_id
);
299 dev_err(component
->dev
, "failed to read device ID register: %d\n",
304 switch (tas5720
->devtype
) {
306 expected_device_id
= TAS5720_DEVICE_ID
;
309 expected_device_id
= TAS5722_DEVICE_ID
;
312 dev_err(component
->dev
, "unexpected private driver data\n");
316 if (device_id
!= expected_device_id
)
317 dev_warn(component
->dev
, "wrong device ID. expected: %u read: %u\n",
318 expected_device_id
, device_id
);
320 /* Set device to mute */
321 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL2_REG
,
322 TAS5720_MUTE
, TAS5720_MUTE
);
324 goto error_snd_soc_component_update_bits
;
327 * Enter shutdown mode - our default when not playing audio - to
328 * minimize current consumption. On the TAS5720 there is no real down
329 * side doing so as all device registers are preserved and the wakeup
330 * of the codec is rather quick which we do using a dapm widget.
332 ret
= snd_soc_component_update_bits(component
, TAS5720_POWER_CTRL_REG
,
335 goto error_snd_soc_component_update_bits
;
337 INIT_DELAYED_WORK(&tas5720
->fault_check_work
, tas5720_fault_check_work
);
341 error_snd_soc_component_update_bits
:
342 dev_err(component
->dev
, "error configuring device registers: %d\n", ret
);
345 regulator_bulk_disable(ARRAY_SIZE(tas5720
->supplies
),
350 static void tas5720_codec_remove(struct snd_soc_component
*component
)
352 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
355 cancel_delayed_work_sync(&tas5720
->fault_check_work
);
357 ret
= regulator_bulk_disable(ARRAY_SIZE(tas5720
->supplies
),
360 dev_err(component
->dev
, "failed to disable supplies: %d\n", ret
);
363 static int tas5720_dac_event(struct snd_soc_dapm_widget
*w
,
364 struct snd_kcontrol
*kcontrol
, int event
)
366 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
367 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
370 if (event
& SND_SOC_DAPM_POST_PMU
) {
371 /* Take TAS5720 out of shutdown mode */
372 ret
= snd_soc_component_update_bits(component
, TAS5720_POWER_CTRL_REG
,
373 TAS5720_SDZ
, TAS5720_SDZ
);
375 dev_err(component
->dev
, "error waking component: %d\n", ret
);
380 * Observe codec shutdown-to-active time. The datasheet only
381 * lists a nominal value however just use-it as-is without
382 * additional padding to minimize the delay introduced in
383 * starting to play audio (actually there is other setup done
384 * by the ASoC framework that will provide additional delays,
385 * so we should always be safe).
389 /* Turn on TAS5720 periodic fault checking/handling */
390 tas5720
->last_fault
= 0;
391 schedule_delayed_work(&tas5720
->fault_check_work
,
392 msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL
));
393 } else if (event
& SND_SOC_DAPM_PRE_PMD
) {
394 /* Disable TAS5720 periodic fault checking/handling */
395 cancel_delayed_work_sync(&tas5720
->fault_check_work
);
397 /* Place TAS5720 in shutdown mode to minimize current draw */
398 ret
= snd_soc_component_update_bits(component
, TAS5720_POWER_CTRL_REG
,
401 dev_err(component
->dev
, "error shutting down component: %d\n",
411 static int tas5720_suspend(struct snd_soc_component
*component
)
413 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
416 regcache_cache_only(tas5720
->regmap
, true);
417 regcache_mark_dirty(tas5720
->regmap
);
419 ret
= regulator_bulk_disable(ARRAY_SIZE(tas5720
->supplies
),
422 dev_err(component
->dev
, "failed to disable supplies: %d\n", ret
);
427 static int tas5720_resume(struct snd_soc_component
*component
)
429 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
432 ret
= regulator_bulk_enable(ARRAY_SIZE(tas5720
->supplies
),
435 dev_err(component
->dev
, "failed to enable supplies: %d\n", ret
);
439 regcache_cache_only(tas5720
->regmap
, false);
441 ret
= regcache_sync(tas5720
->regmap
);
443 dev_err(component
->dev
, "failed to sync regcache: %d\n", ret
);
450 #define tas5720_suspend NULL
451 #define tas5720_resume NULL
454 static bool tas5720_is_volatile_reg(struct device
*dev
, unsigned int reg
)
457 case TAS5720_DEVICE_ID_REG
:
458 case TAS5720_FAULT_REG
:
465 static const struct regmap_config tas5720_regmap_config
= {
469 .max_register
= TAS5720_MAX_REG
,
470 .cache_type
= REGCACHE_RBTREE
,
471 .volatile_reg
= tas5720_is_volatile_reg
,
474 static const struct regmap_config tas5722_regmap_config
= {
478 .max_register
= TAS5722_MAX_REG
,
479 .cache_type
= REGCACHE_RBTREE
,
480 .volatile_reg
= tas5720_is_volatile_reg
,
484 * DAC analog gain. There are four discrete values to select from, ranging
485 * from 19.2 dB to 26.3dB.
487 static const DECLARE_TLV_DB_RANGE(dac_analog_tlv
,
488 0x0, 0x0, TLV_DB_SCALE_ITEM(1920, 0, 0),
489 0x1, 0x1, TLV_DB_SCALE_ITEM(2070, 0, 0),
490 0x2, 0x2, TLV_DB_SCALE_ITEM(2350, 0, 0),
491 0x3, 0x3, TLV_DB_SCALE_ITEM(2630, 0, 0),
495 * DAC digital volumes. From -103.5 to 24 dB in 0.5 dB or 0.25 dB steps
496 * depending on the device. Note that setting the gain below -100 dB
497 * (register value <0x7) is effectively a MUTE as per device datasheet.
499 * Note that for the TAS5722 the digital volume controls are actually split
500 * over two registers, so we need custom getters/setters for access.
502 static DECLARE_TLV_DB_SCALE(tas5720_dac_tlv
, -10350, 50, 0);
503 static DECLARE_TLV_DB_SCALE(tas5722_dac_tlv
, -10350, 25, 0);
505 static int tas5722_volume_get(struct snd_kcontrol
*kcontrol
,
506 struct snd_ctl_elem_value
*ucontrol
)
508 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
511 snd_soc_component_read(component
, TAS5720_VOLUME_CTRL_REG
, &val
);
512 ucontrol
->value
.integer
.value
[0] = val
<< 1;
514 snd_soc_component_read(component
, TAS5722_DIGITAL_CTRL2_REG
, &val
);
515 ucontrol
->value
.integer
.value
[0] |= val
& TAS5722_VOL_CONTROL_LSB
;
520 static int tas5722_volume_set(struct snd_kcontrol
*kcontrol
,
521 struct snd_ctl_elem_value
*ucontrol
)
523 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
524 unsigned int sel
= ucontrol
->value
.integer
.value
[0];
526 snd_soc_component_write(component
, TAS5720_VOLUME_CTRL_REG
, sel
>> 1);
527 snd_soc_component_update_bits(component
, TAS5722_DIGITAL_CTRL2_REG
,
528 TAS5722_VOL_CONTROL_LSB
, sel
);
533 static const struct snd_kcontrol_new tas5720_snd_controls
[] = {
534 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
535 TAS5720_VOLUME_CTRL_REG
, 0, 0xff, 0, tas5720_dac_tlv
),
536 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG
,
537 TAS5720_ANALOG_GAIN_SHIFT
, 3, 0, dac_analog_tlv
),
540 static const struct snd_kcontrol_new tas5722_snd_controls
[] = {
541 SOC_SINGLE_EXT_TLV("Speaker Driver Playback Volume",
543 tas5722_volume_get
, tas5722_volume_set
,
545 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG
,
546 TAS5720_ANALOG_GAIN_SHIFT
, 3, 0, dac_analog_tlv
),
549 static const struct snd_soc_dapm_widget tas5720_dapm_widgets
[] = {
550 SND_SOC_DAPM_AIF_IN("DAC IN", "Playback", 0, SND_SOC_NOPM
, 0, 0),
551 SND_SOC_DAPM_DAC_E("DAC", NULL
, SND_SOC_NOPM
, 0, 0, tas5720_dac_event
,
552 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_PRE_PMD
),
553 SND_SOC_DAPM_OUTPUT("OUT")
556 static const struct snd_soc_dapm_route tas5720_audio_map
[] = {
557 { "DAC", NULL
, "DAC IN" },
558 { "OUT", NULL
, "DAC" },
561 static const struct snd_soc_component_driver soc_component_dev_tas5720
= {
562 .probe
= tas5720_codec_probe
,
563 .remove
= tas5720_codec_remove
,
564 .suspend
= tas5720_suspend
,
565 .resume
= tas5720_resume
,
566 .controls
= tas5720_snd_controls
,
567 .num_controls
= ARRAY_SIZE(tas5720_snd_controls
),
568 .dapm_widgets
= tas5720_dapm_widgets
,
569 .num_dapm_widgets
= ARRAY_SIZE(tas5720_dapm_widgets
),
570 .dapm_routes
= tas5720_audio_map
,
571 .num_dapm_routes
= ARRAY_SIZE(tas5720_audio_map
),
573 .use_pmdown_time
= 1,
575 .non_legacy_dai_naming
= 1,
578 static const struct snd_soc_component_driver soc_component_dev_tas5722
= {
579 .probe
= tas5720_codec_probe
,
580 .remove
= tas5720_codec_remove
,
581 .suspend
= tas5720_suspend
,
582 .resume
= tas5720_resume
,
583 .controls
= tas5722_snd_controls
,
584 .num_controls
= ARRAY_SIZE(tas5722_snd_controls
),
585 .dapm_widgets
= tas5720_dapm_widgets
,
586 .num_dapm_widgets
= ARRAY_SIZE(tas5720_dapm_widgets
),
587 .dapm_routes
= tas5720_audio_map
,
588 .num_dapm_routes
= ARRAY_SIZE(tas5720_audio_map
),
590 .use_pmdown_time
= 1,
592 .non_legacy_dai_naming
= 1,
595 /* PCM rates supported by the TAS5720 driver */
596 #define TAS5720_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
597 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
599 /* Formats supported by TAS5720 driver */
600 #define TAS5720_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\
601 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
603 static const struct snd_soc_dai_ops tas5720_speaker_dai_ops
= {
604 .hw_params
= tas5720_hw_params
,
605 .set_fmt
= tas5720_set_dai_fmt
,
606 .set_tdm_slot
= tas5720_set_dai_tdm_slot
,
607 .digital_mute
= tas5720_mute
,
611 * TAS5720 DAI structure
613 * Note that were are advertising .playback.channels_max = 2 despite this being
614 * a mono amplifier. The reason for that is that some serial ports such as TI's
615 * McASP module have a minimum number of channels (2) that they can output.
616 * Advertising more channels than we have will allow us to interface with such
617 * a serial port without really any negative side effects as the TAS5720 will
618 * simply ignore any extra channel(s) asides from the one channel that is
619 * configured to be played back.
621 static struct snd_soc_dai_driver tas5720_dai
[] = {
623 .name
= "tas5720-amplifier",
625 .stream_name
= "Playback",
628 .rates
= TAS5720_RATES
,
629 .formats
= TAS5720_FORMATS
,
631 .ops
= &tas5720_speaker_dai_ops
,
635 static int tas5720_probe(struct i2c_client
*client
,
636 const struct i2c_device_id
*id
)
638 struct device
*dev
= &client
->dev
;
639 struct tas5720_data
*data
;
640 const struct regmap_config
*regmap_config
;
644 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
648 data
->tas5720_client
= client
;
649 data
->devtype
= id
->driver_data
;
651 switch (id
->driver_data
) {
653 regmap_config
= &tas5720_regmap_config
;
656 regmap_config
= &tas5722_regmap_config
;
659 dev_err(dev
, "unexpected private driver data\n");
662 data
->regmap
= devm_regmap_init_i2c(client
, regmap_config
);
663 if (IS_ERR(data
->regmap
)) {
664 ret
= PTR_ERR(data
->regmap
);
665 dev_err(dev
, "failed to allocate register map: %d\n", ret
);
669 for (i
= 0; i
< ARRAY_SIZE(data
->supplies
); i
++)
670 data
->supplies
[i
].supply
= tas5720_supply_names
[i
];
672 ret
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(data
->supplies
),
675 dev_err(dev
, "failed to request supplies: %d\n", ret
);
679 dev_set_drvdata(dev
, data
);
681 switch (id
->driver_data
) {
683 ret
= devm_snd_soc_register_component(&client
->dev
,
684 &soc_component_dev_tas5720
,
686 ARRAY_SIZE(tas5720_dai
));
689 ret
= devm_snd_soc_register_component(&client
->dev
,
690 &soc_component_dev_tas5722
,
692 ARRAY_SIZE(tas5720_dai
));
695 dev_err(dev
, "unexpected private driver data\n");
699 dev_err(dev
, "failed to register component: %d\n", ret
);
706 static const struct i2c_device_id tas5720_id
[] = {
707 { "tas5720", TAS5720
},
708 { "tas5722", TAS5722
},
711 MODULE_DEVICE_TABLE(i2c
, tas5720_id
);
713 #if IS_ENABLED(CONFIG_OF)
714 static const struct of_device_id tas5720_of_match
[] = {
715 { .compatible
= "ti,tas5720", },
716 { .compatible
= "ti,tas5722", },
719 MODULE_DEVICE_TABLE(of
, tas5720_of_match
);
722 static struct i2c_driver tas5720_i2c_driver
= {
725 .of_match_table
= of_match_ptr(tas5720_of_match
),
727 .probe
= tas5720_probe
,
728 .id_table
= tas5720_id
,
731 module_i2c_driver(tas5720_i2c_driver
);
733 MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>");
734 MODULE_DESCRIPTION("TAS5720 Audio amplifier driver");
735 MODULE_LICENSE("GPL");