1 // SPDX-License-Identifier: GPL-2.0-only
3 * tas2552.c - ALSA SoC Texas Instruments TAS2552 Mono Audio Amplifier
5 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
7 * Author: Dan Murphy <dmurphy@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/gpio.h>
15 #include <linux/of_gpio.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/slab.h>
20 #include <linux/gpio/consumer.h>
21 #include <linux/regulator/consumer.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
26 #include <sound/soc-dapm.h>
27 #include <sound/tlv.h>
28 #include <sound/tas2552-plat.h>
29 #include <dt-bindings/sound/tas2552.h>
33 static const struct reg_default tas2552_reg_defs
[] = {
34 {TAS2552_CFG_1
, 0x22},
35 {TAS2552_CFG_3
, 0x80},
37 {TAS2552_OUTPUT_DATA
, 0xc0},
38 {TAS2552_PDM_CFG
, 0x01},
39 {TAS2552_PGA_GAIN
, 0x00},
40 {TAS2552_BOOST_APT_CTRL
, 0x0f},
41 {TAS2552_RESERVED_0D
, 0xbe},
42 {TAS2552_LIMIT_RATE_HYS
, 0x08},
43 {TAS2552_CFG_2
, 0xef},
44 {TAS2552_SER_CTRL_1
, 0x00},
45 {TAS2552_SER_CTRL_2
, 0x00},
46 {TAS2552_PLL_CTRL_1
, 0x10},
47 {TAS2552_PLL_CTRL_2
, 0x00},
48 {TAS2552_PLL_CTRL_3
, 0x00},
50 {TAS2552_BTS_CTRL
, 0x80},
51 {TAS2552_LIMIT_RELEASE
, 0x04},
52 {TAS2552_LIMIT_INT_COUNT
, 0x00},
53 {TAS2552_EDGE_RATE_CTRL
, 0x40},
54 {TAS2552_VBAT_DATA
, 0x00},
57 #define TAS2552_NUM_SUPPLIES 3
58 static const char *tas2552_supply_names
[TAS2552_NUM_SUPPLIES
] = {
59 "vbat", /* vbat voltage */
60 "iovdd", /* I/O Voltage */
61 "avdd", /* Analog DAC Voltage */
65 struct snd_soc_component
*component
;
66 struct regmap
*regmap
;
67 struct i2c_client
*tas2552_client
;
68 struct regulator_bulk_data supplies
[TAS2552_NUM_SUPPLIES
];
69 struct gpio_desc
*enable_gpio
;
70 unsigned char regs
[TAS2552_VBAT_DATA
];
71 unsigned int pll_clkin
;
77 unsigned int tdm_delay
;
80 static int tas2552_post_event(struct snd_soc_dapm_widget
*w
,
81 struct snd_kcontrol
*kcontrol
, int event
)
83 struct snd_soc_component
*component
= snd_soc_dapm_to_component(w
->dapm
);
86 case SND_SOC_DAPM_POST_PMU
:
87 snd_soc_component_write(component
, TAS2552_RESERVED_0D
, 0xc0);
88 snd_soc_component_update_bits(component
, TAS2552_LIMIT_RATE_HYS
, (1 << 5),
90 snd_soc_component_update_bits(component
, TAS2552_CFG_2
, 1, 0);
91 snd_soc_component_update_bits(component
, TAS2552_CFG_1
, TAS2552_SWS
, 0);
93 case SND_SOC_DAPM_POST_PMD
:
94 snd_soc_component_update_bits(component
, TAS2552_CFG_1
, TAS2552_SWS
,
96 snd_soc_component_update_bits(component
, TAS2552_CFG_2
, 1, 1);
97 snd_soc_component_update_bits(component
, TAS2552_LIMIT_RATE_HYS
, (1 << 5), 0);
98 snd_soc_component_write(component
, TAS2552_RESERVED_0D
, 0xbe);
104 /* Input mux controls */
105 static const char * const tas2552_input_texts
[] = {
106 "Digital", "Analog" };
107 static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum
, TAS2552_CFG_3
, 7,
108 tas2552_input_texts
);
110 static const struct snd_kcontrol_new tas2552_input_mux_control
=
111 SOC_DAPM_ENUM("Route", tas2552_input_mux_enum
);
113 static const struct snd_soc_dapm_widget tas2552_dapm_widgets
[] =
115 SND_SOC_DAPM_INPUT("IN"),
118 SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM
, 0, 0,
119 &tas2552_input_mux_control
),
121 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM
, 0, 0),
122 SND_SOC_DAPM_DAC("DAC", NULL
, SND_SOC_NOPM
, 0, 0),
123 SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2
, 7, 0, NULL
, 0),
124 SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2
, 3, 0, NULL
, 0),
125 SND_SOC_DAPM_POST("Post Event", tas2552_post_event
),
127 SND_SOC_DAPM_OUTPUT("OUT")
130 static const struct snd_soc_dapm_route tas2552_audio_map
[] = {
131 {"DAC", NULL
, "DAC IN"},
132 {"Input selection", "Digital", "DAC"},
133 {"Input selection", "Analog", "IN"},
134 {"ClassD", NULL
, "Input selection"},
135 {"OUT", NULL
, "ClassD"},
136 {"ClassD", NULL
, "PLL"},
140 static void tas2552_sw_shutdown(struct tas2552_data
*tas2552
, int sw_shutdown
)
144 if (!tas2552
->component
)
148 cfg1_reg
= TAS2552_SWS
;
150 snd_soc_component_update_bits(tas2552
->component
, TAS2552_CFG_1
, TAS2552_SWS
,
155 static int tas2552_setup_pll(struct snd_soc_component
*component
,
156 struct snd_pcm_hw_params
*params
)
158 struct tas2552_data
*tas2552
= dev_get_drvdata(component
->dev
);
159 bool bypass_pll
= false;
160 unsigned int pll_clk
= params_rate(params
) * 512;
161 unsigned int pll_clkin
= tas2552
->pll_clkin
;
165 if (tas2552
->pll_clk_id
!= TAS2552_PLL_CLKIN_BCLK
)
168 pll_clkin
= snd_soc_params_to_bclk(params
);
169 pll_clkin
+= tas2552
->tdm_delay
;
172 pll_enable
= snd_soc_component_read32(component
, TAS2552_CFG_2
) & TAS2552_PLL_ENABLE
;
173 snd_soc_component_update_bits(component
, TAS2552_CFG_2
, TAS2552_PLL_ENABLE
, 0);
175 if (pll_clkin
== pll_clk
)
179 /* By pass the PLL configuration */
180 snd_soc_component_update_bits(component
, TAS2552_PLL_CTRL_2
,
181 TAS2552_PLL_BYPASS
, TAS2552_PLL_BYPASS
);
183 /* Fill in the PLL control registers for J & D
184 * pll_clk = (.5 * pll_clkin * J.D) / 2^p
185 * Need to fill in J and D here based on incoming freq
187 unsigned int d
, q
, t
;
189 u8 pll_sel
= (tas2552
->pll_clk_id
<< 3) & TAS2552_PLL_SRC_MASK
;
190 u8 p
= snd_soc_component_read32(component
, TAS2552_PLL_CTRL_1
);
195 t
= (pll_clk
* 2) << p
;
198 t
= pll_clkin
/ 10000;
200 d
= q
+ ((9999 - pll_clkin
% 10000) * (d
/ t
- q
)) / 10000;
202 if (d
&& (pll_clkin
< 512000 || pll_clkin
> 9200000)) {
203 if (tas2552
->pll_clk_id
== TAS2552_PLL_CLKIN_BCLK
) {
205 pll_sel
= (TAS2552_PLL_CLKIN_1_8_FIXED
<< 3) &
206 TAS2552_PLL_SRC_MASK
;
208 pll_clkin
= snd_soc_params_to_bclk(params
);
209 pll_clkin
+= tas2552
->tdm_delay
;
210 pll_sel
= (TAS2552_PLL_CLKIN_BCLK
<< 3) &
211 TAS2552_PLL_SRC_MASK
;
216 snd_soc_component_update_bits(component
, TAS2552_CFG_1
, TAS2552_PLL_SRC_MASK
,
219 snd_soc_component_update_bits(component
, TAS2552_PLL_CTRL_1
,
220 TAS2552_PLL_J_MASK
, j
);
221 /* Will clear the PLL_BYPASS bit */
222 snd_soc_component_write(component
, TAS2552_PLL_CTRL_2
,
223 TAS2552_PLL_D_UPPER(d
));
224 snd_soc_component_write(component
, TAS2552_PLL_CTRL_3
,
225 TAS2552_PLL_D_LOWER(d
));
228 /* Restore PLL status */
229 snd_soc_component_update_bits(component
, TAS2552_CFG_2
, TAS2552_PLL_ENABLE
,
235 static int tas2552_hw_params(struct snd_pcm_substream
*substream
,
236 struct snd_pcm_hw_params
*params
,
237 struct snd_soc_dai
*dai
)
239 struct snd_soc_component
*component
= dai
->component
;
240 struct tas2552_data
*tas2552
= dev_get_drvdata(component
->dev
);
242 u8 ser_ctrl1_reg
, wclk_rate
;
244 switch (params_width(params
)) {
246 ser_ctrl1_reg
= TAS2552_WORDLENGTH_16BIT
;
247 cpf
= 32 + tas2552
->tdm_delay
;
250 ser_ctrl1_reg
= TAS2552_WORDLENGTH_20BIT
;
251 cpf
= 64 + tas2552
->tdm_delay
;
254 ser_ctrl1_reg
= TAS2552_WORDLENGTH_24BIT
;
255 cpf
= 64 + tas2552
->tdm_delay
;
258 ser_ctrl1_reg
= TAS2552_WORDLENGTH_32BIT
;
259 cpf
= 64 + tas2552
->tdm_delay
;
262 dev_err(component
->dev
, "Not supported sample size: %d\n",
263 params_width(params
));
268 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_32
;
270 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_64
;
272 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_128
;
274 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_256
;
276 snd_soc_component_update_bits(component
, TAS2552_SER_CTRL_1
,
277 TAS2552_WORDLENGTH_MASK
| TAS2552_CLKSPERFRAME_MASK
,
280 switch (params_rate(params
)) {
282 wclk_rate
= TAS2552_WCLK_FREQ_8KHZ
;
286 wclk_rate
= TAS2552_WCLK_FREQ_11_12KHZ
;
289 wclk_rate
= TAS2552_WCLK_FREQ_16KHZ
;
293 wclk_rate
= TAS2552_WCLK_FREQ_22_24KHZ
;
296 wclk_rate
= TAS2552_WCLK_FREQ_32KHZ
;
300 wclk_rate
= TAS2552_WCLK_FREQ_44_48KHZ
;
304 wclk_rate
= TAS2552_WCLK_FREQ_88_96KHZ
;
308 wclk_rate
= TAS2552_WCLK_FREQ_176_192KHZ
;
311 dev_err(component
->dev
, "Not supported sample rate: %d\n",
312 params_rate(params
));
316 snd_soc_component_update_bits(component
, TAS2552_CFG_3
, TAS2552_WCLK_FREQ_MASK
,
319 return tas2552_setup_pll(component
, params
);
322 #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
324 TAS2552_DATAFORMAT_MASK)
325 static int tas2552_prepare(struct snd_pcm_substream
*substream
,
326 struct snd_soc_dai
*dai
)
328 struct snd_soc_component
*component
= dai
->component
;
329 struct tas2552_data
*tas2552
= snd_soc_component_get_drvdata(component
);
332 /* TDM slot selection only valid in DSP_A/_B mode */
333 if (tas2552
->dai_fmt
== SND_SOC_DAIFMT_DSP_A
)
334 delay
+= (tas2552
->tdm_delay
+ 1);
335 else if (tas2552
->dai_fmt
== SND_SOC_DAIFMT_DSP_B
)
336 delay
+= tas2552
->tdm_delay
;
338 /* Configure data delay */
339 snd_soc_component_write(component
, TAS2552_SER_CTRL_2
, delay
);
344 static int tas2552_set_dai_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
346 struct snd_soc_component
*component
= dai
->component
;
347 struct tas2552_data
*tas2552
= dev_get_drvdata(component
->dev
);
350 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
351 case SND_SOC_DAIFMT_CBS_CFS
:
352 serial_format
= 0x00;
354 case SND_SOC_DAIFMT_CBS_CFM
:
355 serial_format
= TAS2552_WCLKDIR
;
357 case SND_SOC_DAIFMT_CBM_CFS
:
358 serial_format
= TAS2552_BCLKDIR
;
360 case SND_SOC_DAIFMT_CBM_CFM
:
361 serial_format
= (TAS2552_BCLKDIR
| TAS2552_WCLKDIR
);
364 dev_vdbg(component
->dev
, "DAI Format master is not found\n");
368 switch (fmt
& (SND_SOC_DAIFMT_FORMAT_MASK
|
369 SND_SOC_DAIFMT_INV_MASK
)) {
370 case (SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
):
372 case (SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_IB_NF
):
373 case (SND_SOC_DAIFMT_DSP_B
| SND_SOC_DAIFMT_IB_NF
):
374 serial_format
|= TAS2552_DATAFORMAT_DSP
;
376 case (SND_SOC_DAIFMT_RIGHT_J
| SND_SOC_DAIFMT_NB_NF
):
377 serial_format
|= TAS2552_DATAFORMAT_RIGHT_J
;
379 case (SND_SOC_DAIFMT_LEFT_J
| SND_SOC_DAIFMT_NB_NF
):
380 serial_format
|= TAS2552_DATAFORMAT_LEFT_J
;
383 dev_vdbg(component
->dev
, "DAI Format is not found\n");
386 tas2552
->dai_fmt
= fmt
& SND_SOC_DAIFMT_FORMAT_MASK
;
388 snd_soc_component_update_bits(component
, TAS2552_SER_CTRL_1
, TAS2552_DAI_FMT_MASK
,
393 static int tas2552_set_dai_sysclk(struct snd_soc_dai
*dai
, int clk_id
,
394 unsigned int freq
, int dir
)
396 struct snd_soc_component
*component
= dai
->component
;
397 struct tas2552_data
*tas2552
= dev_get_drvdata(component
->dev
);
401 case TAS2552_PLL_CLKIN_MCLK
:
402 case TAS2552_PLL_CLKIN_IVCLKIN
:
403 if (freq
< 512000 || freq
> 24576000) {
404 /* out of range PLL_CLKIN, fall back to use BCLK */
405 dev_warn(component
->dev
, "Out of range PLL_CLKIN: %u\n",
407 clk_id
= TAS2552_PLL_CLKIN_BCLK
;
411 case TAS2552_PLL_CLKIN_BCLK
:
412 case TAS2552_PLL_CLKIN_1_8_FIXED
:
413 mask
= TAS2552_PLL_SRC_MASK
;
414 val
= (clk_id
<< 3) & mask
; /* bit 4:5 in the register */
416 tas2552
->pll_clk_id
= clk_id
;
417 tas2552
->pll_clkin
= freq
;
419 case TAS2552_PDM_CLK_PLL
:
420 case TAS2552_PDM_CLK_IVCLKIN
:
421 case TAS2552_PDM_CLK_BCLK
:
422 case TAS2552_PDM_CLK_MCLK
:
423 mask
= TAS2552_PDM_CLK_SEL_MASK
;
424 val
= (clk_id
>> 1) & mask
; /* bit 0:1 in the register */
425 reg
= TAS2552_PDM_CFG
;
426 tas2552
->pdm_clk_id
= clk_id
;
427 tas2552
->pdm_clk
= freq
;
430 dev_err(component
->dev
, "Invalid clk id: %d\n", clk_id
);
434 snd_soc_component_update_bits(component
, reg
, mask
, val
);
439 static int tas2552_set_dai_tdm_slot(struct snd_soc_dai
*dai
,
440 unsigned int tx_mask
, unsigned int rx_mask
,
441 int slots
, int slot_width
)
443 struct snd_soc_component
*component
= dai
->component
;
444 struct tas2552_data
*tas2552
= snd_soc_component_get_drvdata(component
);
447 if (unlikely(!tx_mask
)) {
448 dev_err(component
->dev
, "tx masks need to be non 0\n");
452 /* TDM based on DSP mode requires slots to be adjacent */
453 lsb
= __ffs(tx_mask
);
454 if ((lsb
+ 1) != __fls(tx_mask
)) {
455 dev_err(component
->dev
, "Invalid mask, slots must be adjacent\n");
459 tas2552
->tdm_delay
= lsb
* slot_width
;
461 /* DOUT in high-impedance on inactive bit clocks */
462 snd_soc_component_update_bits(component
, TAS2552_DOUT
,
463 TAS2552_SDOUT_TRISTATE
, TAS2552_SDOUT_TRISTATE
);
468 static int tas2552_mute(struct snd_soc_dai
*dai
, int mute
)
471 struct snd_soc_component
*component
= dai
->component
;
474 cfg1_reg
|= TAS2552_MUTE
;
476 snd_soc_component_update_bits(component
, TAS2552_CFG_1
, TAS2552_MUTE
, cfg1_reg
);
482 static int tas2552_runtime_suspend(struct device
*dev
)
484 struct tas2552_data
*tas2552
= dev_get_drvdata(dev
);
486 tas2552_sw_shutdown(tas2552
, 1);
488 regcache_cache_only(tas2552
->regmap
, true);
489 regcache_mark_dirty(tas2552
->regmap
);
491 gpiod_set_value(tas2552
->enable_gpio
, 0);
496 static int tas2552_runtime_resume(struct device
*dev
)
498 struct tas2552_data
*tas2552
= dev_get_drvdata(dev
);
500 gpiod_set_value(tas2552
->enable_gpio
, 1);
502 tas2552_sw_shutdown(tas2552
, 0);
504 regcache_cache_only(tas2552
->regmap
, false);
505 regcache_sync(tas2552
->regmap
);
511 static const struct dev_pm_ops tas2552_pm
= {
512 SET_RUNTIME_PM_OPS(tas2552_runtime_suspend
, tas2552_runtime_resume
,
516 static const struct snd_soc_dai_ops tas2552_speaker_dai_ops
= {
517 .hw_params
= tas2552_hw_params
,
518 .prepare
= tas2552_prepare
,
519 .set_sysclk
= tas2552_set_dai_sysclk
,
520 .set_fmt
= tas2552_set_dai_fmt
,
521 .set_tdm_slot
= tas2552_set_dai_tdm_slot
,
522 .digital_mute
= tas2552_mute
,
525 /* Formats supported by TAS2552 driver. */
526 #define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
527 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
529 /* TAS2552 dai structure. */
530 static struct snd_soc_dai_driver tas2552_dai
[] = {
532 .name
= "tas2552-amplifier",
534 .stream_name
= "Playback",
537 .rates
= SNDRV_PCM_RATE_8000_192000
,
538 .formats
= TAS2552_FORMATS
,
540 .ops
= &tas2552_speaker_dai_ops
,
545 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
547 static DECLARE_TLV_DB_SCALE(dac_tlv
, -700, 100, 0);
549 static const char * const tas2552_din_source_select
[] = {
553 "Left + Right average",
555 static SOC_ENUM_SINGLE_DECL(tas2552_din_source_enum
,
557 tas2552_din_source_select
);
559 static const struct snd_kcontrol_new tas2552_snd_controls
[] = {
560 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
561 TAS2552_PGA_GAIN
, 0, 0x1f, 0, dac_tlv
),
562 SOC_ENUM("DIN source", tas2552_din_source_enum
),
565 static int tas2552_component_probe(struct snd_soc_component
*component
)
567 struct tas2552_data
*tas2552
= snd_soc_component_get_drvdata(component
);
570 tas2552
->component
= component
;
572 ret
= regulator_bulk_enable(ARRAY_SIZE(tas2552
->supplies
),
576 dev_err(component
->dev
, "Failed to enable supplies: %d\n",
581 gpiod_set_value(tas2552
->enable_gpio
, 1);
583 ret
= pm_runtime_get_sync(component
->dev
);
585 dev_err(component
->dev
, "Enabling device failed: %d\n",
590 snd_soc_component_update_bits(component
, TAS2552_CFG_1
, TAS2552_MUTE
, TAS2552_MUTE
);
591 snd_soc_component_write(component
, TAS2552_CFG_3
, TAS2552_I2S_OUT_SEL
|
592 TAS2552_DIN_SRC_SEL_AVG_L_R
);
593 snd_soc_component_write(component
, TAS2552_OUTPUT_DATA
,
594 TAS2552_PDM_DATA_SEL_V_I
|
595 TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA
));
596 snd_soc_component_write(component
, TAS2552_BOOST_APT_CTRL
, TAS2552_APT_DELAY_200
|
597 TAS2552_APT_THRESH_20_17
);
599 snd_soc_component_write(component
, TAS2552_CFG_2
, TAS2552_BOOST_EN
| TAS2552_APT_EN
|
605 gpiod_set_value(tas2552
->enable_gpio
, 0);
607 regulator_bulk_disable(ARRAY_SIZE(tas2552
->supplies
),
612 static void tas2552_component_remove(struct snd_soc_component
*component
)
614 struct tas2552_data
*tas2552
= snd_soc_component_get_drvdata(component
);
616 pm_runtime_put(component
->dev
);
618 gpiod_set_value(tas2552
->enable_gpio
, 0);
622 static int tas2552_suspend(struct snd_soc_component
*component
)
624 struct tas2552_data
*tas2552
= snd_soc_component_get_drvdata(component
);
627 ret
= regulator_bulk_disable(ARRAY_SIZE(tas2552
->supplies
),
631 dev_err(component
->dev
, "Failed to disable supplies: %d\n",
636 static int tas2552_resume(struct snd_soc_component
*component
)
638 struct tas2552_data
*tas2552
= snd_soc_component_get_drvdata(component
);
641 ret
= regulator_bulk_enable(ARRAY_SIZE(tas2552
->supplies
),
645 dev_err(component
->dev
, "Failed to enable supplies: %d\n",
652 #define tas2552_suspend NULL
653 #define tas2552_resume NULL
656 static const struct snd_soc_component_driver soc_component_dev_tas2552
= {
657 .probe
= tas2552_component_probe
,
658 .remove
= tas2552_component_remove
,
659 .suspend
= tas2552_suspend
,
660 .resume
= tas2552_resume
,
661 .controls
= tas2552_snd_controls
,
662 .num_controls
= ARRAY_SIZE(tas2552_snd_controls
),
663 .dapm_widgets
= tas2552_dapm_widgets
,
664 .num_dapm_widgets
= ARRAY_SIZE(tas2552_dapm_widgets
),
665 .dapm_routes
= tas2552_audio_map
,
666 .num_dapm_routes
= ARRAY_SIZE(tas2552_audio_map
),
669 .non_legacy_dai_naming
= 1,
672 static const struct regmap_config tas2552_regmap_config
= {
676 .max_register
= TAS2552_MAX_REG
,
677 .reg_defaults
= tas2552_reg_defs
,
678 .num_reg_defaults
= ARRAY_SIZE(tas2552_reg_defs
),
679 .cache_type
= REGCACHE_RBTREE
,
682 static int tas2552_probe(struct i2c_client
*client
,
683 const struct i2c_device_id
*id
)
686 struct tas2552_data
*data
;
691 data
= devm_kzalloc(&client
->dev
, sizeof(*data
), GFP_KERNEL
);
695 data
->enable_gpio
= devm_gpiod_get_optional(dev
, "enable",
697 if (IS_ERR(data
->enable_gpio
))
698 return PTR_ERR(data
->enable_gpio
);
700 data
->tas2552_client
= client
;
701 data
->regmap
= devm_regmap_init_i2c(client
, &tas2552_regmap_config
);
702 if (IS_ERR(data
->regmap
)) {
703 ret
= PTR_ERR(data
->regmap
);
704 dev_err(&client
->dev
, "Failed to allocate register map: %d\n",
709 for (i
= 0; i
< ARRAY_SIZE(data
->supplies
); i
++)
710 data
->supplies
[i
].supply
= tas2552_supply_names
[i
];
712 ret
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(data
->supplies
),
715 dev_err(dev
, "Failed to request supplies: %d\n", ret
);
719 pm_runtime_set_active(&client
->dev
);
720 pm_runtime_set_autosuspend_delay(&client
->dev
, 1000);
721 pm_runtime_use_autosuspend(&client
->dev
);
722 pm_runtime_enable(&client
->dev
);
723 pm_runtime_mark_last_busy(&client
->dev
);
724 pm_runtime_put_sync_autosuspend(&client
->dev
);
726 dev_set_drvdata(&client
->dev
, data
);
728 ret
= devm_snd_soc_register_component(&client
->dev
,
729 &soc_component_dev_tas2552
,
730 tas2552_dai
, ARRAY_SIZE(tas2552_dai
));
732 dev_err(&client
->dev
, "Failed to register component: %d\n", ret
);
737 static int tas2552_i2c_remove(struct i2c_client
*client
)
739 pm_runtime_disable(&client
->dev
);
743 static const struct i2c_device_id tas2552_id
[] = {
747 MODULE_DEVICE_TABLE(i2c
, tas2552_id
);
749 #if IS_ENABLED(CONFIG_OF)
750 static const struct of_device_id tas2552_of_match
[] = {
751 { .compatible
= "ti,tas2552", },
754 MODULE_DEVICE_TABLE(of
, tas2552_of_match
);
757 static struct i2c_driver tas2552_i2c_driver
= {
760 .of_match_table
= of_match_ptr(tas2552_of_match
),
763 .probe
= tas2552_probe
,
764 .remove
= tas2552_i2c_remove
,
765 .id_table
= tas2552_id
,
768 module_i2c_driver(tas2552_i2c_driver
);
770 MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>");
771 MODULE_DESCRIPTION("TAS2552 Audio amplifier driver");
772 MODULE_LICENSE("GPL");