2 * tas2552.c - ALSA SoC Texas Instruments TAS2552 Mono Audio Amplifier
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
6 * Author: Dan Murphy <dmurphy@ti.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
18 #include <linux/module.h>
19 #include <linux/errno.h>
20 #include <linux/device.h>
21 #include <linux/i2c.h>
22 #include <linux/gpio.h>
23 #include <linux/of_gpio.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/regmap.h>
26 #include <linux/slab.h>
28 #include <linux/gpio/consumer.h>
29 #include <linux/regulator/consumer.h>
31 #include <sound/pcm.h>
32 #include <sound/pcm_params.h>
33 #include <sound/soc.h>
34 #include <sound/soc-dapm.h>
35 #include <sound/tlv.h>
36 #include <sound/tas2552-plat.h>
37 #include <dt-bindings/sound/tas2552.h>
41 static struct reg_default tas2552_reg_defs
[] = {
42 {TAS2552_CFG_1
, 0x22},
43 {TAS2552_CFG_3
, 0x80},
45 {TAS2552_OUTPUT_DATA
, 0xc0},
46 {TAS2552_PDM_CFG
, 0x01},
47 {TAS2552_PGA_GAIN
, 0x00},
48 {TAS2552_BOOST_PT_CTRL
, 0x0f},
49 {TAS2552_RESERVED_0D
, 0xbe},
50 {TAS2552_LIMIT_RATE_HYS
, 0x08},
51 {TAS2552_CFG_2
, 0xef},
52 {TAS2552_SER_CTRL_1
, 0x00},
53 {TAS2552_SER_CTRL_2
, 0x00},
54 {TAS2552_PLL_CTRL_1
, 0x10},
55 {TAS2552_PLL_CTRL_2
, 0x00},
56 {TAS2552_PLL_CTRL_3
, 0x00},
58 {TAS2552_BTS_CTRL
, 0x80},
59 {TAS2552_LIMIT_RELEASE
, 0x04},
60 {TAS2552_LIMIT_INT_COUNT
, 0x00},
61 {TAS2552_EDGE_RATE_CTRL
, 0x40},
62 {TAS2552_VBAT_DATA
, 0x00},
65 #define TAS2552_NUM_SUPPLIES 3
66 static const char *tas2552_supply_names
[TAS2552_NUM_SUPPLIES
] = {
67 "vbat", /* vbat voltage */
68 "iovdd", /* I/O Voltage */
69 "avdd", /* Analog DAC Voltage */
73 struct snd_soc_codec
*codec
;
74 struct regmap
*regmap
;
75 struct i2c_client
*tas2552_client
;
76 struct regulator_bulk_data supplies
[TAS2552_NUM_SUPPLIES
];
77 struct gpio_desc
*enable_gpio
;
78 unsigned char regs
[TAS2552_VBAT_DATA
];
79 unsigned int pll_clkin
;
83 unsigned int tdm_delay
;
86 static int tas2552_post_event(struct snd_soc_dapm_widget
*w
,
87 struct snd_kcontrol
*kcontrol
, int event
)
89 struct snd_soc_codec
*codec
= snd_soc_dapm_to_codec(w
->dapm
);
92 case SND_SOC_DAPM_POST_PMU
:
93 snd_soc_write(codec
, TAS2552_RESERVED_0D
, 0xc0);
94 snd_soc_update_bits(codec
, TAS2552_LIMIT_RATE_HYS
, (1 << 5),
96 snd_soc_update_bits(codec
, TAS2552_CFG_2
, 1, 0);
97 snd_soc_update_bits(codec
, TAS2552_CFG_1
, TAS2552_SWS
, 0);
99 case SND_SOC_DAPM_POST_PMD
:
100 snd_soc_update_bits(codec
, TAS2552_CFG_1
, TAS2552_SWS
,
102 snd_soc_update_bits(codec
, TAS2552_CFG_2
, 1, 1);
103 snd_soc_update_bits(codec
, TAS2552_LIMIT_RATE_HYS
, (1 << 5), 0);
104 snd_soc_write(codec
, TAS2552_RESERVED_0D
, 0xbe);
110 /* Input mux controls */
111 static const char * const tas2552_input_texts
[] = {
112 "Digital", "Analog" };
113 static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum
, TAS2552_CFG_3
, 7,
114 tas2552_input_texts
);
116 static const struct snd_kcontrol_new tas2552_input_mux_control
=
117 SOC_DAPM_ENUM("Route", tas2552_input_mux_enum
);
119 static const struct snd_soc_dapm_widget tas2552_dapm_widgets
[] =
121 SND_SOC_DAPM_INPUT("IN"),
124 SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM
, 0, 0,
125 &tas2552_input_mux_control
),
127 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM
, 0, 0),
128 SND_SOC_DAPM_DAC("DAC", NULL
, SND_SOC_NOPM
, 0, 0),
129 SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2
, 7, 0, NULL
, 0),
130 SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2
, 3, 0, NULL
, 0),
131 SND_SOC_DAPM_POST("Post Event", tas2552_post_event
),
133 SND_SOC_DAPM_OUTPUT("OUT")
136 static const struct snd_soc_dapm_route tas2552_audio_map
[] = {
137 {"DAC", NULL
, "DAC IN"},
138 {"Input selection", "Digital", "DAC"},
139 {"Input selection", "Analog", "IN"},
140 {"ClassD", NULL
, "Input selection"},
141 {"OUT", NULL
, "ClassD"},
142 {"ClassD", NULL
, "PLL"},
146 static void tas2552_sw_shutdown(struct tas2552_data
*tas_data
, int sw_shutdown
)
150 if (!tas_data
->codec
)
154 cfg1_reg
= TAS2552_SWS
;
156 snd_soc_update_bits(tas_data
->codec
, TAS2552_CFG_1
, TAS2552_SWS
,
161 static int tas2552_hw_params(struct snd_pcm_substream
*substream
,
162 struct snd_pcm_hw_params
*params
,
163 struct snd_soc_dai
*dai
)
165 struct snd_soc_codec
*codec
= dai
->codec
;
166 struct tas2552_data
*tas2552
= dev_get_drvdata(codec
->dev
);
167 int sample_rate
, pll_clk
;
171 u8 ser_ctrl1_reg
, wclk_rate
;
173 switch (params_width(params
)) {
175 ser_ctrl1_reg
= TAS2552_WORDLENGTH_16BIT
;
176 cpf
= 32 + tas2552
->tdm_delay
;
179 ser_ctrl1_reg
= TAS2552_WORDLENGTH_20BIT
;
180 cpf
= 64 + tas2552
->tdm_delay
;
183 ser_ctrl1_reg
= TAS2552_WORDLENGTH_24BIT
;
184 cpf
= 64 + tas2552
->tdm_delay
;
187 ser_ctrl1_reg
= TAS2552_WORDLENGTH_32BIT
;
188 cpf
= 64 + tas2552
->tdm_delay
;
191 dev_err(codec
->dev
, "Not supported sample size: %d\n",
192 params_width(params
));
197 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_32
;
199 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_64
;
201 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_128
;
203 ser_ctrl1_reg
|= TAS2552_CLKSPERFRAME_256
;
205 snd_soc_update_bits(codec
, TAS2552_SER_CTRL_1
,
206 TAS2552_WORDLENGTH_MASK
| TAS2552_CLKSPERFRAME_MASK
,
209 switch (params_rate(params
)) {
211 wclk_rate
= TAS2552_WCLK_FREQ_8KHZ
;
215 wclk_rate
= TAS2552_WCLK_FREQ_11_12KHZ
;
218 wclk_rate
= TAS2552_WCLK_FREQ_16KHZ
;
222 wclk_rate
= TAS2552_WCLK_FREQ_22_24KHZ
;
225 wclk_rate
= TAS2552_WCLK_FREQ_32KHZ
;
229 wclk_rate
= TAS2552_WCLK_FREQ_44_48KHZ
;
233 wclk_rate
= TAS2552_WCLK_FREQ_88_96KHZ
;
237 wclk_rate
= TAS2552_WCLK_FREQ_176_192KHZ
;
240 dev_err(codec
->dev
, "Not supported sample rate: %d\n",
241 params_rate(params
));
245 snd_soc_update_bits(codec
, TAS2552_CFG_3
, TAS2552_WCLK_FREQ_MASK
,
248 if (!tas2552
->pll_clkin
)
251 snd_soc_update_bits(codec
, TAS2552_CFG_2
, TAS2552_PLL_ENABLE
, 0);
253 if (tas2552
->pll_clkin
== TAS2552_245MHZ_CLK
||
254 tas2552
->pll_clkin
== TAS2552_225MHZ_CLK
) {
255 /* By pass the PLL configuration */
256 snd_soc_update_bits(codec
, TAS2552_PLL_CTRL_2
,
257 TAS2552_PLL_BYPASS_MASK
,
260 /* Fill in the PLL control registers for J & D
261 * PLL_CLK = (.5 * freq * J.D) / 2^p
262 * Need to fill in J and D here based on incoming freq
264 p
= snd_soc_read(codec
, TAS2552_PLL_CTRL_1
);
266 sample_rate
= params_rate(params
);
268 if (sample_rate
== 48000)
269 pll_clk
= TAS2552_245MHZ_CLK
;
270 else if (sample_rate
== 44100)
271 pll_clk
= TAS2552_225MHZ_CLK
;
273 dev_vdbg(codec
->dev
, "Substream sample rate is not found %i\n",
274 params_rate(params
));
278 j
= (pll_clk
* 2 * (1 << p
)) / tas2552
->pll_clkin
;
279 d
= (pll_clk
* 2 * (1 << p
)) % tas2552
->pll_clkin
;
281 snd_soc_update_bits(codec
, TAS2552_PLL_CTRL_1
,
282 TAS2552_PLL_J_MASK
, j
);
283 snd_soc_write(codec
, TAS2552_PLL_CTRL_2
,
284 (d
>> 7) & TAS2552_PLL_D_UPPER_MASK
);
285 snd_soc_write(codec
, TAS2552_PLL_CTRL_3
,
286 d
& TAS2552_PLL_D_LOWER_MASK
);
293 #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
295 TAS2552_DATAFORMAT_MASK)
296 static int tas2552_prepare(struct snd_pcm_substream
*substream
,
297 struct snd_soc_dai
*dai
)
299 struct snd_soc_codec
*codec
= dai
->codec
;
300 struct tas2552_data
*tas2552
= snd_soc_codec_get_drvdata(codec
);
303 /* TDM slot selection only valid in DSP_A/_B mode */
304 if (tas2552
->dai_fmt
== SND_SOC_DAIFMT_DSP_A
)
305 delay
+= (tas2552
->tdm_delay
+ 1);
306 else if (tas2552
->dai_fmt
== SND_SOC_DAIFMT_DSP_B
)
307 delay
+= tas2552
->tdm_delay
;
309 /* Configure data delay */
310 snd_soc_write(codec
, TAS2552_SER_CTRL_2
, delay
);
315 static int tas2552_set_dai_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
317 struct snd_soc_codec
*codec
= dai
->codec
;
318 struct tas2552_data
*tas2552
= dev_get_drvdata(codec
->dev
);
321 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
322 case SND_SOC_DAIFMT_CBS_CFS
:
323 serial_format
= 0x00;
325 case SND_SOC_DAIFMT_CBS_CFM
:
326 serial_format
= TAS2552_WCLKDIR
;
328 case SND_SOC_DAIFMT_CBM_CFS
:
329 serial_format
= TAS2552_BCLKDIR
;
331 case SND_SOC_DAIFMT_CBM_CFM
:
332 serial_format
= (TAS2552_BCLKDIR
| TAS2552_WCLKDIR
);
335 dev_vdbg(codec
->dev
, "DAI Format master is not found\n");
339 switch (fmt
& (SND_SOC_DAIFMT_FORMAT_MASK
|
340 SND_SOC_DAIFMT_INV_MASK
)) {
341 case (SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
):
343 case (SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_IB_NF
):
344 case (SND_SOC_DAIFMT_DSP_B
| SND_SOC_DAIFMT_IB_NF
):
345 serial_format
|= TAS2552_DATAFORMAT_DSP
;
347 case (SND_SOC_DAIFMT_RIGHT_J
| SND_SOC_DAIFMT_NB_NF
):
348 serial_format
|= TAS2552_DATAFORMAT_RIGHT_J
;
350 case (SND_SOC_DAIFMT_LEFT_J
| SND_SOC_DAIFMT_NB_NF
):
351 serial_format
|= TAS2552_DATAFORMAT_LEFT_J
;
354 dev_vdbg(codec
->dev
, "DAI Format is not found\n");
357 tas2552
->dai_fmt
= fmt
& SND_SOC_DAIFMT_FORMAT_MASK
;
359 snd_soc_update_bits(codec
, TAS2552_SER_CTRL_1
, TAS2552_DAI_FMT_MASK
,
364 static int tas2552_set_dai_sysclk(struct snd_soc_dai
*dai
, int clk_id
,
365 unsigned int freq
, int dir
)
367 struct snd_soc_codec
*codec
= dai
->codec
;
368 struct tas2552_data
*tas2552
= dev_get_drvdata(codec
->dev
);
372 case TAS2552_PLL_CLKIN_MCLK
:
373 case TAS2552_PLL_CLKIN_BCLK
:
374 case TAS2552_PLL_CLKIN_IVCLKIN
:
375 case TAS2552_PLL_CLKIN_1_8_FIXED
:
376 mask
= TAS2552_PLL_SRC_MASK
;
377 val
= (clk_id
<< 3) & mask
; /* bit 4:5 in the register */
379 tas2552
->pll_clkin
= freq
;
381 case TAS2552_PDM_CLK_PLL
:
382 case TAS2552_PDM_CLK_IVCLKIN
:
383 case TAS2552_PDM_CLK_BCLK
:
384 case TAS2552_PDM_CLK_MCLK
:
385 mask
= TAS2552_PDM_CLK_SEL_MASK
;
386 val
= (clk_id
>> 1) & mask
; /* bit 0:1 in the register */
387 reg
= TAS2552_PDM_CFG
;
388 tas2552
->pdm_clk
= freq
;
391 dev_err(codec
->dev
, "Invalid clk id: %d\n", clk_id
);
395 snd_soc_update_bits(codec
, reg
, mask
, val
);
400 static int tas2552_set_dai_tdm_slot(struct snd_soc_dai
*dai
,
401 unsigned int tx_mask
, unsigned int rx_mask
,
402 int slots
, int slot_width
)
404 struct snd_soc_codec
*codec
= dai
->codec
;
405 struct tas2552_data
*tas2552
= snd_soc_codec_get_drvdata(codec
);
408 if (unlikely(!tx_mask
)) {
409 dev_err(codec
->dev
, "tx masks need to be non 0\n");
413 /* TDM based on DSP mode requires slots to be adjacent */
414 lsb
= __ffs(tx_mask
);
415 if ((lsb
+ 1) != __fls(tx_mask
)) {
416 dev_err(codec
->dev
, "Invalid mask, slots must be adjacent\n");
420 tas2552
->tdm_delay
= lsb
* slot_width
;
422 /* DOUT in high-impedance on inactive bit clocks */
423 snd_soc_update_bits(codec
, TAS2552_DOUT
,
424 TAS2552_SDOUT_TRISTATE
, TAS2552_SDOUT_TRISTATE
);
429 static int tas2552_mute(struct snd_soc_dai
*dai
, int mute
)
432 struct snd_soc_codec
*codec
= dai
->codec
;
435 cfg1_reg
|= TAS2552_MUTE
;
437 snd_soc_update_bits(codec
, TAS2552_CFG_1
, TAS2552_MUTE
, cfg1_reg
);
443 static int tas2552_runtime_suspend(struct device
*dev
)
445 struct tas2552_data
*tas2552
= dev_get_drvdata(dev
);
447 tas2552_sw_shutdown(tas2552
, 1);
449 regcache_cache_only(tas2552
->regmap
, true);
450 regcache_mark_dirty(tas2552
->regmap
);
452 if (tas2552
->enable_gpio
)
453 gpiod_set_value(tas2552
->enable_gpio
, 0);
458 static int tas2552_runtime_resume(struct device
*dev
)
460 struct tas2552_data
*tas2552
= dev_get_drvdata(dev
);
462 if (tas2552
->enable_gpio
)
463 gpiod_set_value(tas2552
->enable_gpio
, 1);
465 tas2552_sw_shutdown(tas2552
, 0);
467 regcache_cache_only(tas2552
->regmap
, false);
468 regcache_sync(tas2552
->regmap
);
474 static const struct dev_pm_ops tas2552_pm
= {
475 SET_RUNTIME_PM_OPS(tas2552_runtime_suspend
, tas2552_runtime_resume
,
479 static struct snd_soc_dai_ops tas2552_speaker_dai_ops
= {
480 .hw_params
= tas2552_hw_params
,
481 .prepare
= tas2552_prepare
,
482 .set_sysclk
= tas2552_set_dai_sysclk
,
483 .set_fmt
= tas2552_set_dai_fmt
,
484 .set_tdm_slot
= tas2552_set_dai_tdm_slot
,
485 .digital_mute
= tas2552_mute
,
488 /* Formats supported by TAS2552 driver. */
489 #define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
490 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
492 /* TAS2552 dai structure. */
493 static struct snd_soc_dai_driver tas2552_dai
[] = {
495 .name
= "tas2552-amplifier",
497 .stream_name
= "Playback",
500 .rates
= SNDRV_PCM_RATE_8000_192000
,
501 .formats
= TAS2552_FORMATS
,
503 .ops
= &tas2552_speaker_dai_ops
,
508 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
510 static DECLARE_TLV_DB_SCALE(dac_tlv
, -7, 100, 0);
512 static const struct snd_kcontrol_new tas2552_snd_controls
[] = {
513 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
514 TAS2552_PGA_GAIN
, 0, 0x1f, 0, dac_tlv
),
517 static int tas2552_codec_probe(struct snd_soc_codec
*codec
)
519 struct tas2552_data
*tas2552
= snd_soc_codec_get_drvdata(codec
);
522 tas2552
->codec
= codec
;
524 ret
= regulator_bulk_enable(ARRAY_SIZE(tas2552
->supplies
),
528 dev_err(codec
->dev
, "Failed to enable supplies: %d\n",
533 if (tas2552
->enable_gpio
)
534 gpiod_set_value(tas2552
->enable_gpio
, 1);
536 ret
= pm_runtime_get_sync(codec
->dev
);
538 dev_err(codec
->dev
, "Enabling device failed: %d\n",
543 snd_soc_update_bits(codec
, TAS2552_CFG_1
, TAS2552_MUTE
, TAS2552_MUTE
);
544 snd_soc_write(codec
, TAS2552_CFG_3
, TAS2552_I2S_OUT_SEL
|
545 TAS2552_DIN_SRC_SEL_AVG_L_R
);
546 snd_soc_write(codec
, TAS2552_DOUT
, TAS2552_PDM_DATA_I
);
547 snd_soc_write(codec
, TAS2552_OUTPUT_DATA
, TAS2552_PDM_DATA_V_I
| 0x8);
548 snd_soc_write(codec
, TAS2552_BOOST_PT_CTRL
, TAS2552_APT_DELAY_200
|
549 TAS2552_APT_THRESH_2_1_7
);
551 snd_soc_write(codec
, TAS2552_CFG_2
, TAS2552_BOOST_EN
|
552 TAS2552_APT_EN
| TAS2552_LIM_EN
);
557 if (tas2552
->enable_gpio
)
558 gpiod_set_value(tas2552
->enable_gpio
, 0);
560 regulator_bulk_disable(ARRAY_SIZE(tas2552
->supplies
),
565 static int tas2552_codec_remove(struct snd_soc_codec
*codec
)
567 struct tas2552_data
*tas2552
= snd_soc_codec_get_drvdata(codec
);
569 pm_runtime_put(codec
->dev
);
571 if (tas2552
->enable_gpio
)
572 gpiod_set_value(tas2552
->enable_gpio
, 0);
578 static int tas2552_suspend(struct snd_soc_codec
*codec
)
580 struct tas2552_data
*tas2552
= snd_soc_codec_get_drvdata(codec
);
583 ret
= regulator_bulk_disable(ARRAY_SIZE(tas2552
->supplies
),
587 dev_err(codec
->dev
, "Failed to disable supplies: %d\n",
592 static int tas2552_resume(struct snd_soc_codec
*codec
)
594 struct tas2552_data
*tas2552
= snd_soc_codec_get_drvdata(codec
);
597 ret
= regulator_bulk_enable(ARRAY_SIZE(tas2552
->supplies
),
601 dev_err(codec
->dev
, "Failed to enable supplies: %d\n",
608 #define tas2552_suspend NULL
609 #define tas2552_resume NULL
612 static struct snd_soc_codec_driver soc_codec_dev_tas2552
= {
613 .probe
= tas2552_codec_probe
,
614 .remove
= tas2552_codec_remove
,
615 .suspend
= tas2552_suspend
,
616 .resume
= tas2552_resume
,
617 .ignore_pmdown_time
= true,
619 .controls
= tas2552_snd_controls
,
620 .num_controls
= ARRAY_SIZE(tas2552_snd_controls
),
621 .dapm_widgets
= tas2552_dapm_widgets
,
622 .num_dapm_widgets
= ARRAY_SIZE(tas2552_dapm_widgets
),
623 .dapm_routes
= tas2552_audio_map
,
624 .num_dapm_routes
= ARRAY_SIZE(tas2552_audio_map
),
627 static const struct regmap_config tas2552_regmap_config
= {
631 .max_register
= TAS2552_MAX_REG
,
632 .reg_defaults
= tas2552_reg_defs
,
633 .num_reg_defaults
= ARRAY_SIZE(tas2552_reg_defs
),
634 .cache_type
= REGCACHE_RBTREE
,
637 static int tas2552_probe(struct i2c_client
*client
,
638 const struct i2c_device_id
*id
)
641 struct tas2552_data
*data
;
646 data
= devm_kzalloc(&client
->dev
, sizeof(*data
), GFP_KERNEL
);
650 data
->enable_gpio
= devm_gpiod_get(dev
, "enable", GPIOD_OUT_LOW
);
651 if (IS_ERR(data
->enable_gpio
)) {
652 if (PTR_ERR(data
->enable_gpio
) == -EPROBE_DEFER
)
653 return -EPROBE_DEFER
;
655 data
->enable_gpio
= NULL
;;
658 data
->tas2552_client
= client
;
659 data
->regmap
= devm_regmap_init_i2c(client
, &tas2552_regmap_config
);
660 if (IS_ERR(data
->regmap
)) {
661 ret
= PTR_ERR(data
->regmap
);
662 dev_err(&client
->dev
, "Failed to allocate register map: %d\n",
667 for (i
= 0; i
< ARRAY_SIZE(data
->supplies
); i
++)
668 data
->supplies
[i
].supply
= tas2552_supply_names
[i
];
670 ret
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(data
->supplies
),
673 dev_err(dev
, "Failed to request supplies: %d\n", ret
);
677 pm_runtime_set_active(&client
->dev
);
678 pm_runtime_set_autosuspend_delay(&client
->dev
, 1000);
679 pm_runtime_use_autosuspend(&client
->dev
);
680 pm_runtime_enable(&client
->dev
);
681 pm_runtime_mark_last_busy(&client
->dev
);
682 pm_runtime_put_sync_autosuspend(&client
->dev
);
684 dev_set_drvdata(&client
->dev
, data
);
686 ret
= snd_soc_register_codec(&client
->dev
,
687 &soc_codec_dev_tas2552
,
688 tas2552_dai
, ARRAY_SIZE(tas2552_dai
));
690 dev_err(&client
->dev
, "Failed to register codec: %d\n", ret
);
695 static int tas2552_i2c_remove(struct i2c_client
*client
)
697 snd_soc_unregister_codec(&client
->dev
);
701 static const struct i2c_device_id tas2552_id
[] = {
705 MODULE_DEVICE_TABLE(i2c
, tas2552_id
);
707 #if IS_ENABLED(CONFIG_OF)
708 static const struct of_device_id tas2552_of_match
[] = {
709 { .compatible
= "ti,tas2552", },
712 MODULE_DEVICE_TABLE(of
, tas2552_of_match
);
715 static struct i2c_driver tas2552_i2c_driver
= {
718 .owner
= THIS_MODULE
,
719 .of_match_table
= of_match_ptr(tas2552_of_match
),
722 .probe
= tas2552_probe
,
723 .remove
= tas2552_i2c_remove
,
724 .id_table
= tas2552_id
,
727 module_i2c_driver(tas2552_i2c_driver
);
729 MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>");
730 MODULE_DESCRIPTION("TAS2552 Audio amplifier driver");
731 MODULE_LICENSE("GPL");