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 - https://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/regmap.h>
15 #include <linux/slab.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/delay.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/tlv.h>
27 /* Define how often to check (and clear) the fault status register (in ms) */
28 #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_CLOCK_PROVIDER_MASK
) != SND_SOC_DAIFMT_CBC_CFC
) {
93 dev_vdbg(component
->dev
, "DAI clocking invalid\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",
170 * Enable manual TDM slot selection (instead of I2C ID based).
171 * This is not applicable to TAS5720A-Q1.
173 switch (tas5720
->devtype
) {
177 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL1_REG
,
178 TAS5720_TDM_CFG_SRC
, TAS5720_TDM_CFG_SRC
);
180 goto error_snd_soc_component_update_bits
;
182 /* Configure the TDM slot to process audio from */
183 ret
= snd_soc_component_update_bits(component
, TAS5720_DIGITAL_CTRL2_REG
,
184 TAS5720_TDM_SLOT_SEL_MASK
, first_slot
);
186 goto error_snd_soc_component_update_bits
;
190 /* Configure TDM slot width. This is only applicable to TAS5722. */
191 switch (tas5720
->devtype
) {
193 ret
= snd_soc_component_update_bits(component
, TAS5722_DIGITAL_CTRL2_REG
,
194 TAS5722_TDM_SLOT_16B
,
196 TAS5722_TDM_SLOT_16B
: 0);
198 goto error_snd_soc_component_update_bits
;
206 error_snd_soc_component_update_bits
:
207 dev_err(component
->dev
, "error configuring TDM mode: %d\n", ret
);
211 static int tas5720_mute_soc_component(struct snd_soc_component
*component
, int mute
)
213 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
214 unsigned int reg
, mask
;
217 switch (tas5720
->devtype
) {
219 reg
= TAS5720_Q1_VOLUME_CTRL_CFG_REG
;
220 mask
= TAS5720_Q1_MUTE
;
223 reg
= TAS5720_DIGITAL_CTRL2_REG
;
228 ret
= snd_soc_component_update_bits(component
, reg
, mask
, mute
? mask
: 0);
230 dev_err(component
->dev
, "error (un-)muting device: %d\n", ret
);
237 static int tas5720_mute(struct snd_soc_dai
*dai
, int mute
, int direction
)
239 return tas5720_mute_soc_component(dai
->component
, mute
);
242 static void tas5720_fault_check_work(struct work_struct
*work
)
244 struct tas5720_data
*tas5720
= container_of(work
, struct tas5720_data
,
245 fault_check_work
.work
);
246 struct device
*dev
= tas5720
->component
->dev
;
247 unsigned int curr_fault
;
250 ret
= regmap_read(tas5720
->regmap
, TAS5720_FAULT_REG
, &curr_fault
);
252 dev_err(dev
, "failed to read FAULT register: %d\n", ret
);
256 /* Check/handle all errors except SAIF clock errors */
257 curr_fault
&= TAS5720_OCE
| TAS5720_DCE
| TAS5720_OTE
;
260 * Only flag errors once for a given occurrence. This is needed as
261 * the TAS5720 will take time clearing the fault condition internally
262 * during which we don't want to bombard the system with the same
263 * error message over and over.
265 if ((curr_fault
& TAS5720_OCE
) && !(tas5720
->last_fault
& TAS5720_OCE
))
266 dev_crit(dev
, "experienced an over current hardware fault\n");
268 if ((curr_fault
& TAS5720_DCE
) && !(tas5720
->last_fault
& TAS5720_DCE
))
269 dev_crit(dev
, "experienced a DC detection fault\n");
271 if ((curr_fault
& TAS5720_OTE
) && !(tas5720
->last_fault
& TAS5720_OTE
))
272 dev_crit(dev
, "experienced an over temperature fault\n");
274 /* Store current fault value so we can detect any changes next time */
275 tas5720
->last_fault
= curr_fault
;
281 * Periodically toggle SDZ (shutdown bit) H->L->H to clear any latching
282 * faults as long as a fault condition persists. Always going through
283 * the full sequence no matter the first return value to minimizes
284 * chances for the device to end up in shutdown mode.
286 ret
= regmap_write_bits(tas5720
->regmap
, TAS5720_POWER_CTRL_REG
,
289 dev_err(dev
, "failed to write POWER_CTRL register: %d\n", ret
);
291 ret
= regmap_write_bits(tas5720
->regmap
, TAS5720_POWER_CTRL_REG
,
292 TAS5720_SDZ
, TAS5720_SDZ
);
294 dev_err(dev
, "failed to write POWER_CTRL register: %d\n", ret
);
297 /* Schedule the next fault check at the specified interval */
298 schedule_delayed_work(&tas5720
->fault_check_work
,
299 msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL
));
302 static int tas5720_codec_probe(struct snd_soc_component
*component
)
304 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
305 unsigned int device_id
, expected_device_id
;
308 tas5720
->component
= component
;
310 ret
= regulator_bulk_enable(ARRAY_SIZE(tas5720
->supplies
),
313 dev_err(component
->dev
, "failed to enable supplies: %d\n", ret
);
318 * Take a liberal approach to checking the device ID to allow the
319 * driver to be used even if the device ID does not match, however
320 * issue a warning if there is a mismatch.
322 ret
= regmap_read(tas5720
->regmap
, TAS5720_DEVICE_ID_REG
, &device_id
);
324 dev_err(component
->dev
, "failed to read device ID register: %d\n",
329 switch (tas5720
->devtype
) {
331 expected_device_id
= TAS5720_DEVICE_ID
;
334 expected_device_id
= TAS5720A_Q1_DEVICE_ID
;
337 expected_device_id
= TAS5722_DEVICE_ID
;
340 dev_err(component
->dev
, "unexpected private driver data\n");
345 if (device_id
!= expected_device_id
)
346 dev_warn(component
->dev
, "wrong device ID. expected: %u read: %u\n",
347 expected_device_id
, device_id
);
349 /* Set device to mute */
350 ret
= tas5720_mute_soc_component(component
, 1);
352 goto error_snd_soc_component_update_bits
;
354 /* Set Bit 7 in TAS5720_ANALOG_CTRL_REG to 1 for TAS5720A_Q1 */
355 switch (tas5720
->devtype
) {
357 ret
= snd_soc_component_update_bits(component
, TAS5720_ANALOG_CTRL_REG
,
358 TAS5720_Q1_RESERVED7_BIT
,
359 TAS5720_Q1_RESERVED7_BIT
);
365 goto error_snd_soc_component_update_bits
;
368 * Enter shutdown mode - our default when not playing audio - to
369 * minimize current consumption. On the TAS5720 there is no real down
370 * side doing so as all device registers are preserved and the wakeup
371 * of the codec is rather quick which we do using a dapm widget.
373 ret
= snd_soc_component_update_bits(component
, TAS5720_POWER_CTRL_REG
,
376 goto error_snd_soc_component_update_bits
;
378 INIT_DELAYED_WORK(&tas5720
->fault_check_work
, tas5720_fault_check_work
);
382 error_snd_soc_component_update_bits
:
383 dev_err(component
->dev
, "error configuring device registers: %d\n", ret
);
386 regulator_bulk_disable(ARRAY_SIZE(tas5720
->supplies
),
391 static void tas5720_codec_remove(struct snd_soc_component
*component
)
393 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
396 cancel_delayed_work_sync(&tas5720
->fault_check_work
);
398 ret
= regulator_bulk_disable(ARRAY_SIZE(tas5720
->supplies
),
401 dev_err(component
->dev
, "failed to disable supplies: %d\n", ret
);
404 static int tas5720_dac_event(struct snd_soc_dapm_widget
*w
,
405 struct snd_kcontrol
*kcontrol
, int event
)
407 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
408 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
411 if (event
& SND_SOC_DAPM_POST_PMU
) {
412 /* Take TAS5720 out of shutdown mode */
413 ret
= snd_soc_component_update_bits(component
, TAS5720_POWER_CTRL_REG
,
414 TAS5720_SDZ
, TAS5720_SDZ
);
416 dev_err(component
->dev
, "error waking component: %d\n", ret
);
421 * Observe codec shutdown-to-active time. The datasheet only
422 * lists a nominal value however just use-it as-is without
423 * additional padding to minimize the delay introduced in
424 * starting to play audio (actually there is other setup done
425 * by the ASoC framework that will provide additional delays,
426 * so we should always be safe).
430 /* Turn on TAS5720 periodic fault checking/handling */
431 tas5720
->last_fault
= 0;
432 schedule_delayed_work(&tas5720
->fault_check_work
,
433 msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL
));
434 } else if (event
& SND_SOC_DAPM_PRE_PMD
) {
435 /* Disable TAS5720 periodic fault checking/handling */
436 cancel_delayed_work_sync(&tas5720
->fault_check_work
);
438 /* Place TAS5720 in shutdown mode to minimize current draw */
439 ret
= snd_soc_component_update_bits(component
, TAS5720_POWER_CTRL_REG
,
442 dev_err(component
->dev
, "error shutting down component: %d\n",
452 static int tas5720_suspend(struct snd_soc_component
*component
)
454 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
457 regcache_cache_only(tas5720
->regmap
, true);
458 regcache_mark_dirty(tas5720
->regmap
);
460 ret
= regulator_bulk_disable(ARRAY_SIZE(tas5720
->supplies
),
463 dev_err(component
->dev
, "failed to disable supplies: %d\n", ret
);
468 static int tas5720_resume(struct snd_soc_component
*component
)
470 struct tas5720_data
*tas5720
= snd_soc_component_get_drvdata(component
);
473 ret
= regulator_bulk_enable(ARRAY_SIZE(tas5720
->supplies
),
476 dev_err(component
->dev
, "failed to enable supplies: %d\n", ret
);
480 regcache_cache_only(tas5720
->regmap
, false);
482 ret
= regcache_sync(tas5720
->regmap
);
484 dev_err(component
->dev
, "failed to sync regcache: %d\n", ret
);
491 #define tas5720_suspend NULL
492 #define tas5720_resume NULL
495 static bool tas5720_is_volatile_reg(struct device
*dev
, unsigned int reg
)
498 case TAS5720_DEVICE_ID_REG
:
499 case TAS5720_FAULT_REG
:
506 static const struct regmap_config tas5720_regmap_config
= {
510 .max_register
= TAS5720_MAX_REG
,
511 .cache_type
= REGCACHE_RBTREE
,
512 .volatile_reg
= tas5720_is_volatile_reg
,
515 static const struct regmap_config tas5720a_q1_regmap_config
= {
519 .max_register
= TAS5720_MAX_REG
,
520 .cache_type
= REGCACHE_RBTREE
,
521 .volatile_reg
= tas5720_is_volatile_reg
,
524 static const struct regmap_config tas5722_regmap_config
= {
528 .max_register
= TAS5722_MAX_REG
,
529 .cache_type
= REGCACHE_RBTREE
,
530 .volatile_reg
= tas5720_is_volatile_reg
,
534 * DAC analog gain. There are four discrete values to select from, ranging
535 * from 19.2 dB to 26.3dB.
537 static const DECLARE_TLV_DB_RANGE(dac_analog_tlv
,
538 0x0, 0x0, TLV_DB_SCALE_ITEM(1920, 0, 0),
539 0x1, 0x1, TLV_DB_SCALE_ITEM(2070, 0, 0),
540 0x2, 0x2, TLV_DB_SCALE_ITEM(2350, 0, 0),
541 0x3, 0x3, TLV_DB_SCALE_ITEM(2630, 0, 0),
545 * DAC analog gain for TAS5720A-Q1. There are three discrete values to select from, ranging
546 * from 19.2 dB to 25.0dB.
548 static const DECLARE_TLV_DB_RANGE(dac_analog_tlv_a_q1
,
549 0x0, 0x0, TLV_DB_SCALE_ITEM(1920, 0, 0),
550 0x1, 0x1, TLV_DB_SCALE_ITEM(2260, 0, 0),
551 0x2, 0x2, TLV_DB_SCALE_ITEM(2500, 0, 0),
555 * DAC digital volumes. From -103.5 to 24 dB in 0.5 dB or 0.25 dB steps
556 * depending on the device. Note that setting the gain below -100 dB
557 * (register value <0x7) is effectively a MUTE as per device datasheet.
559 * Note that for the TAS5722 the digital volume controls are actually split
560 * over two registers, so we need custom getters/setters for access.
562 static DECLARE_TLV_DB_SCALE(tas5720_dac_tlv
, -10350, 50, 0);
563 static DECLARE_TLV_DB_SCALE(tas5722_dac_tlv
, -10350, 25, 0);
565 static int tas5722_volume_get(struct snd_kcontrol
*kcontrol
,
566 struct snd_ctl_elem_value
*ucontrol
)
568 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
571 val
= snd_soc_component_read(component
, TAS5720_VOLUME_CTRL_REG
);
572 ucontrol
->value
.integer
.value
[0] = val
<< 1;
574 val
= snd_soc_component_read(component
, TAS5722_DIGITAL_CTRL2_REG
);
575 ucontrol
->value
.integer
.value
[0] |= val
& TAS5722_VOL_CONTROL_LSB
;
580 static int tas5722_volume_set(struct snd_kcontrol
*kcontrol
,
581 struct snd_ctl_elem_value
*ucontrol
)
583 struct snd_soc_component
*component
= snd_soc_kcontrol_component(kcontrol
);
584 unsigned int sel
= ucontrol
->value
.integer
.value
[0];
586 snd_soc_component_write(component
, TAS5720_VOLUME_CTRL_REG
, sel
>> 1);
587 snd_soc_component_update_bits(component
, TAS5722_DIGITAL_CTRL2_REG
,
588 TAS5722_VOL_CONTROL_LSB
, sel
);
593 static const struct snd_kcontrol_new tas5720_snd_controls
[] = {
594 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
595 TAS5720_VOLUME_CTRL_REG
, 0, 0xff, 0, tas5720_dac_tlv
),
596 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG
,
597 TAS5720_ANALOG_GAIN_SHIFT
, 3, 0, dac_analog_tlv
),
600 static const struct snd_kcontrol_new tas5720a_q1_snd_controls
[] = {
601 SOC_DOUBLE_R_TLV("Speaker Driver Playback Volume",
602 TAS5720_Q1_VOLUME_CTRL_LEFT_REG
,
603 TAS5720_Q1_VOLUME_CTRL_RIGHT_REG
,
604 0, 0xff, 0, tas5720_dac_tlv
),
605 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG
,
606 TAS5720_ANALOG_GAIN_SHIFT
, 3, 0, dac_analog_tlv_a_q1
),
609 static const struct snd_kcontrol_new tas5722_snd_controls
[] = {
610 SOC_SINGLE_EXT_TLV("Speaker Driver Playback Volume",
612 tas5722_volume_get
, tas5722_volume_set
,
614 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG
,
615 TAS5720_ANALOG_GAIN_SHIFT
, 3, 0, dac_analog_tlv
),
618 static const struct snd_soc_dapm_widget tas5720_dapm_widgets
[] = {
619 SND_SOC_DAPM_AIF_IN("DAC IN", "Playback", 0, SND_SOC_NOPM
, 0, 0),
620 SND_SOC_DAPM_DAC_E("DAC", NULL
, SND_SOC_NOPM
, 0, 0, tas5720_dac_event
,
621 SND_SOC_DAPM_POST_PMU
| SND_SOC_DAPM_PRE_PMD
),
622 SND_SOC_DAPM_OUTPUT("OUT")
625 static const struct snd_soc_dapm_route tas5720_audio_map
[] = {
626 { "DAC", NULL
, "DAC IN" },
627 { "OUT", NULL
, "DAC" },
630 static const struct snd_soc_component_driver soc_component_dev_tas5720
= {
631 .probe
= tas5720_codec_probe
,
632 .remove
= tas5720_codec_remove
,
633 .suspend
= tas5720_suspend
,
634 .resume
= tas5720_resume
,
635 .controls
= tas5720_snd_controls
,
636 .num_controls
= ARRAY_SIZE(tas5720_snd_controls
),
637 .dapm_widgets
= tas5720_dapm_widgets
,
638 .num_dapm_widgets
= ARRAY_SIZE(tas5720_dapm_widgets
),
639 .dapm_routes
= tas5720_audio_map
,
640 .num_dapm_routes
= ARRAY_SIZE(tas5720_audio_map
),
642 .use_pmdown_time
= 1,
646 static const struct snd_soc_component_driver soc_component_dev_tas5720_a_q1
= {
647 .probe
= tas5720_codec_probe
,
648 .remove
= tas5720_codec_remove
,
649 .suspend
= tas5720_suspend
,
650 .resume
= tas5720_resume
,
651 .controls
= tas5720a_q1_snd_controls
,
652 .num_controls
= ARRAY_SIZE(tas5720a_q1_snd_controls
),
653 .dapm_widgets
= tas5720_dapm_widgets
,
654 .num_dapm_widgets
= ARRAY_SIZE(tas5720_dapm_widgets
),
655 .dapm_routes
= tas5720_audio_map
,
656 .num_dapm_routes
= ARRAY_SIZE(tas5720_audio_map
),
658 .use_pmdown_time
= 1,
662 static const struct snd_soc_component_driver soc_component_dev_tas5722
= {
663 .probe
= tas5720_codec_probe
,
664 .remove
= tas5720_codec_remove
,
665 .suspend
= tas5720_suspend
,
666 .resume
= tas5720_resume
,
667 .controls
= tas5722_snd_controls
,
668 .num_controls
= ARRAY_SIZE(tas5722_snd_controls
),
669 .dapm_widgets
= tas5720_dapm_widgets
,
670 .num_dapm_widgets
= ARRAY_SIZE(tas5720_dapm_widgets
),
671 .dapm_routes
= tas5720_audio_map
,
672 .num_dapm_routes
= ARRAY_SIZE(tas5720_audio_map
),
674 .use_pmdown_time
= 1,
678 /* PCM rates supported by the TAS5720 driver */
679 #define TAS5720_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
680 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
682 /* Formats supported by TAS5720 driver */
683 #define TAS5720_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\
684 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
686 static const struct snd_soc_dai_ops tas5720_speaker_dai_ops
= {
687 .hw_params
= tas5720_hw_params
,
688 .set_fmt
= tas5720_set_dai_fmt
,
689 .set_tdm_slot
= tas5720_set_dai_tdm_slot
,
690 .mute_stream
= tas5720_mute
,
691 .no_capture_mute
= 1,
695 * TAS5720 DAI structure
697 * Note that were are advertising .playback.channels_max = 2 despite this being
698 * a mono amplifier. The reason for that is that some serial ports such as TI's
699 * McASP module have a minimum number of channels (2) that they can output.
700 * Advertising more channels than we have will allow us to interface with such
701 * a serial port without really any negative side effects as the TAS5720 will
702 * simply ignore any extra channel(s) asides from the one channel that is
703 * configured to be played back.
705 static struct snd_soc_dai_driver tas5720_dai
[] = {
707 .name
= "tas5720-amplifier",
709 .stream_name
= "Playback",
712 .rates
= TAS5720_RATES
,
713 .formats
= TAS5720_FORMATS
,
715 .ops
= &tas5720_speaker_dai_ops
,
719 static const struct i2c_device_id tas5720_id
[] = {
720 { "tas5720", TAS5720
},
721 { "tas5720a-q1", TAS5720A_Q1
},
722 { "tas5722", TAS5722
},
725 MODULE_DEVICE_TABLE(i2c
, tas5720_id
);
727 static int tas5720_probe(struct i2c_client
*client
)
729 struct device
*dev
= &client
->dev
;
730 struct tas5720_data
*data
;
731 const struct regmap_config
*regmap_config
;
732 const struct i2c_device_id
*id
;
736 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
740 id
= i2c_match_id(tas5720_id
, client
);
741 data
->tas5720_client
= client
;
742 data
->devtype
= id
->driver_data
;
744 switch (id
->driver_data
) {
746 regmap_config
= &tas5720_regmap_config
;
749 regmap_config
= &tas5720a_q1_regmap_config
;
752 regmap_config
= &tas5722_regmap_config
;
755 dev_err(dev
, "unexpected private driver data\n");
758 data
->regmap
= devm_regmap_init_i2c(client
, regmap_config
);
759 if (IS_ERR(data
->regmap
)) {
760 ret
= PTR_ERR(data
->regmap
);
761 dev_err(dev
, "failed to allocate register map: %d\n", ret
);
765 for (i
= 0; i
< ARRAY_SIZE(data
->supplies
); i
++)
766 data
->supplies
[i
].supply
= tas5720_supply_names
[i
];
768 ret
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(data
->supplies
),
771 dev_err(dev
, "failed to request supplies: %d\n", ret
);
775 dev_set_drvdata(dev
, data
);
777 switch (id
->driver_data
) {
779 ret
= devm_snd_soc_register_component(&client
->dev
,
780 &soc_component_dev_tas5720
,
782 ARRAY_SIZE(tas5720_dai
));
785 ret
= devm_snd_soc_register_component(&client
->dev
,
786 &soc_component_dev_tas5720_a_q1
,
788 ARRAY_SIZE(tas5720_dai
));
791 ret
= devm_snd_soc_register_component(&client
->dev
,
792 &soc_component_dev_tas5722
,
794 ARRAY_SIZE(tas5720_dai
));
797 dev_err(dev
, "unexpected private driver data\n");
801 dev_err(dev
, "failed to register component: %d\n", ret
);
808 #if IS_ENABLED(CONFIG_OF)
809 static const struct of_device_id tas5720_of_match
[] = {
810 { .compatible
= "ti,tas5720", },
811 { .compatible
= "ti,tas5720a-q1", },
812 { .compatible
= "ti,tas5722", },
815 MODULE_DEVICE_TABLE(of
, tas5720_of_match
);
818 static struct i2c_driver tas5720_i2c_driver
= {
821 .of_match_table
= of_match_ptr(tas5720_of_match
),
823 .probe
= tas5720_probe
,
824 .id_table
= tas5720_id
,
827 module_i2c_driver(tas5720_i2c_driver
);
829 MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>");
830 MODULE_DESCRIPTION("TAS5720 Audio amplifier driver");
831 MODULE_LICENSE("GPL");