0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/errno.h>
0012 #include <linux/device.h>
0013 #include <linux/i2c.h>
0014 #include <linux/gpio.h>
0015 #include <linux/of_gpio.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/regmap.h>
0018 #include <linux/slab.h>
0019
0020 #include <linux/gpio/consumer.h>
0021 #include <linux/regulator/consumer.h>
0022
0023 #include <sound/pcm.h>
0024 #include <sound/pcm_params.h>
0025 #include <sound/soc.h>
0026 #include <sound/soc-dapm.h>
0027 #include <sound/tlv.h>
0028 #include <sound/tas2552-plat.h>
0029 #include <dt-bindings/sound/tas2552.h>
0030
0031 #include "tas2552.h"
0032
0033 static const struct reg_default tas2552_reg_defs[] = {
0034 {TAS2552_CFG_1, 0x22},
0035 {TAS2552_CFG_3, 0x80},
0036 {TAS2552_DOUT, 0x00},
0037 {TAS2552_OUTPUT_DATA, 0xc0},
0038 {TAS2552_PDM_CFG, 0x01},
0039 {TAS2552_PGA_GAIN, 0x00},
0040 {TAS2552_BOOST_APT_CTRL, 0x0f},
0041 {TAS2552_RESERVED_0D, 0xbe},
0042 {TAS2552_LIMIT_RATE_HYS, 0x08},
0043 {TAS2552_CFG_2, 0xef},
0044 {TAS2552_SER_CTRL_1, 0x00},
0045 {TAS2552_SER_CTRL_2, 0x00},
0046 {TAS2552_PLL_CTRL_1, 0x10},
0047 {TAS2552_PLL_CTRL_2, 0x00},
0048 {TAS2552_PLL_CTRL_3, 0x00},
0049 {TAS2552_BTIP, 0x8f},
0050 {TAS2552_BTS_CTRL, 0x80},
0051 {TAS2552_LIMIT_RELEASE, 0x04},
0052 {TAS2552_LIMIT_INT_COUNT, 0x00},
0053 {TAS2552_EDGE_RATE_CTRL, 0x40},
0054 {TAS2552_VBAT_DATA, 0x00},
0055 };
0056
0057 #define TAS2552_NUM_SUPPLIES 3
0058 static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = {
0059 "vbat",
0060 "iovdd",
0061 "avdd",
0062 };
0063
0064 struct tas2552_data {
0065 struct snd_soc_component *component;
0066 struct regmap *regmap;
0067 struct i2c_client *tas2552_client;
0068 struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
0069 struct gpio_desc *enable_gpio;
0070 unsigned char regs[TAS2552_VBAT_DATA];
0071 unsigned int pll_clkin;
0072 int pll_clk_id;
0073 unsigned int pdm_clk;
0074 int pdm_clk_id;
0075
0076 unsigned int dai_fmt;
0077 unsigned int tdm_delay;
0078 };
0079
0080 static int tas2552_post_event(struct snd_soc_dapm_widget *w,
0081 struct snd_kcontrol *kcontrol, int event)
0082 {
0083 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0084
0085 switch (event) {
0086 case SND_SOC_DAPM_POST_PMU:
0087 snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xc0);
0088 snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5),
0089 (1 << 5));
0090 snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 0);
0091 snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS, 0);
0092 break;
0093 case SND_SOC_DAPM_POST_PMD:
0094 snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS,
0095 TAS2552_SWS);
0096 snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 1);
0097 snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
0098 snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xbe);
0099 break;
0100 }
0101 return 0;
0102 }
0103
0104
0105 static const char * const tas2552_input_texts[] = {
0106 "Digital", "Analog" };
0107 static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
0108 tas2552_input_texts);
0109
0110 static const struct snd_kcontrol_new tas2552_input_mux_control =
0111 SOC_DAPM_ENUM("Route", tas2552_input_mux_enum);
0112
0113 static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
0114 {
0115 SND_SOC_DAPM_INPUT("IN"),
0116
0117
0118 SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
0119 &tas2552_input_mux_control),
0120
0121 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
0122 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
0123 SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
0124 SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
0125 SND_SOC_DAPM_POST("Post Event", tas2552_post_event),
0126
0127 SND_SOC_DAPM_OUTPUT("OUT")
0128 };
0129
0130 static const struct snd_soc_dapm_route tas2552_audio_map[] = {
0131 {"DAC", NULL, "DAC IN"},
0132 {"Input selection", "Digital", "DAC"},
0133 {"Input selection", "Analog", "IN"},
0134 {"ClassD", NULL, "Input selection"},
0135 {"OUT", NULL, "ClassD"},
0136 {"ClassD", NULL, "PLL"},
0137 };
0138
0139 #ifdef CONFIG_PM
0140 static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
0141 {
0142 u8 cfg1_reg = 0;
0143
0144 if (!tas2552->component)
0145 return;
0146
0147 if (sw_shutdown)
0148 cfg1_reg = TAS2552_SWS;
0149
0150 snd_soc_component_update_bits(tas2552->component, TAS2552_CFG_1, TAS2552_SWS,
0151 cfg1_reg);
0152 }
0153 #endif
0154
0155 static int tas2552_setup_pll(struct snd_soc_component *component,
0156 struct snd_pcm_hw_params *params)
0157 {
0158 struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
0159 bool bypass_pll = false;
0160 unsigned int pll_clk = params_rate(params) * 512;
0161 unsigned int pll_clkin = tas2552->pll_clkin;
0162 u8 pll_enable;
0163
0164 if (!pll_clkin) {
0165 if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK)
0166 return -EINVAL;
0167
0168 pll_clkin = snd_soc_params_to_bclk(params);
0169 pll_clkin += tas2552->tdm_delay;
0170 }
0171
0172 pll_enable = snd_soc_component_read(component, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
0173 snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
0174
0175 if (pll_clkin == pll_clk)
0176 bypass_pll = true;
0177
0178 if (bypass_pll) {
0179
0180 snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_2,
0181 TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
0182 } else {
0183
0184
0185
0186
0187 unsigned int d, q, t;
0188 u8 j;
0189 u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
0190 u8 p = snd_soc_component_read(component, TAS2552_PLL_CTRL_1);
0191
0192 p = (p >> 7);
0193
0194 recalc:
0195 t = (pll_clk * 2) << p;
0196 j = t / pll_clkin;
0197 d = t % pll_clkin;
0198 t = pll_clkin / 10000;
0199 q = d / (t + 1);
0200 d = q + ((9999 - pll_clkin % 10000) * (d / t - q)) / 10000;
0201
0202 if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) {
0203 if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) {
0204 pll_clkin = 1800000;
0205 pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) &
0206 TAS2552_PLL_SRC_MASK;
0207 } else {
0208 pll_clkin = snd_soc_params_to_bclk(params);
0209 pll_clkin += tas2552->tdm_delay;
0210 pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) &
0211 TAS2552_PLL_SRC_MASK;
0212 }
0213 goto recalc;
0214 }
0215
0216 snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
0217 pll_sel);
0218
0219 snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_1,
0220 TAS2552_PLL_J_MASK, j);
0221
0222 snd_soc_component_write(component, TAS2552_PLL_CTRL_2,
0223 TAS2552_PLL_D_UPPER(d));
0224 snd_soc_component_write(component, TAS2552_PLL_CTRL_3,
0225 TAS2552_PLL_D_LOWER(d));
0226 }
0227
0228
0229 snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
0230 pll_enable);
0231
0232 return 0;
0233 }
0234
0235 static int tas2552_hw_params(struct snd_pcm_substream *substream,
0236 struct snd_pcm_hw_params *params,
0237 struct snd_soc_dai *dai)
0238 {
0239 struct snd_soc_component *component = dai->component;
0240 struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
0241 int cpf;
0242 u8 ser_ctrl1_reg, wclk_rate;
0243
0244 switch (params_width(params)) {
0245 case 16:
0246 ser_ctrl1_reg = TAS2552_WORDLENGTH_16BIT;
0247 cpf = 32 + tas2552->tdm_delay;
0248 break;
0249 case 20:
0250 ser_ctrl1_reg = TAS2552_WORDLENGTH_20BIT;
0251 cpf = 64 + tas2552->tdm_delay;
0252 break;
0253 case 24:
0254 ser_ctrl1_reg = TAS2552_WORDLENGTH_24BIT;
0255 cpf = 64 + tas2552->tdm_delay;
0256 break;
0257 case 32:
0258 ser_ctrl1_reg = TAS2552_WORDLENGTH_32BIT;
0259 cpf = 64 + tas2552->tdm_delay;
0260 break;
0261 default:
0262 dev_err(component->dev, "Not supported sample size: %d\n",
0263 params_width(params));
0264 return -EINVAL;
0265 }
0266
0267 if (cpf <= 32)
0268 ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_32;
0269 else if (cpf <= 64)
0270 ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_64;
0271 else if (cpf <= 128)
0272 ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_128;
0273 else
0274 ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;
0275
0276 snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1,
0277 TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
0278 ser_ctrl1_reg);
0279
0280 switch (params_rate(params)) {
0281 case 8000:
0282 wclk_rate = TAS2552_WCLK_FREQ_8KHZ;
0283 break;
0284 case 11025:
0285 case 12000:
0286 wclk_rate = TAS2552_WCLK_FREQ_11_12KHZ;
0287 break;
0288 case 16000:
0289 wclk_rate = TAS2552_WCLK_FREQ_16KHZ;
0290 break;
0291 case 22050:
0292 case 24000:
0293 wclk_rate = TAS2552_WCLK_FREQ_22_24KHZ;
0294 break;
0295 case 32000:
0296 wclk_rate = TAS2552_WCLK_FREQ_32KHZ;
0297 break;
0298 case 44100:
0299 case 48000:
0300 wclk_rate = TAS2552_WCLK_FREQ_44_48KHZ;
0301 break;
0302 case 88200:
0303 case 96000:
0304 wclk_rate = TAS2552_WCLK_FREQ_88_96KHZ;
0305 break;
0306 case 176400:
0307 case 192000:
0308 wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
0309 break;
0310 default:
0311 dev_err(component->dev, "Not supported sample rate: %d\n",
0312 params_rate(params));
0313 return -EINVAL;
0314 }
0315
0316 snd_soc_component_update_bits(component, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
0317 wclk_rate);
0318
0319 return tas2552_setup_pll(component, params);
0320 }
0321
0322 #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
0323 TAS2552_WCLKDIR | \
0324 TAS2552_DATAFORMAT_MASK)
0325 static int tas2552_prepare(struct snd_pcm_substream *substream,
0326 struct snd_soc_dai *dai)
0327 {
0328 struct snd_soc_component *component = dai->component;
0329 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
0330 int delay = 0;
0331
0332
0333 if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_A)
0334 delay += (tas2552->tdm_delay + 1);
0335 else if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_B)
0336 delay += tas2552->tdm_delay;
0337
0338
0339 snd_soc_component_write(component, TAS2552_SER_CTRL_2, delay);
0340
0341 return 0;
0342 }
0343
0344 static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0345 {
0346 struct snd_soc_component *component = dai->component;
0347 struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
0348 u8 serial_format;
0349
0350 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0351 case SND_SOC_DAIFMT_CBC_CFC:
0352 serial_format = 0x00;
0353 break;
0354 case SND_SOC_DAIFMT_CBC_CFP:
0355 serial_format = TAS2552_WCLKDIR;
0356 break;
0357 case SND_SOC_DAIFMT_CBP_CFC:
0358 serial_format = TAS2552_BCLKDIR;
0359 break;
0360 case SND_SOC_DAIFMT_CBP_CFP:
0361 serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR);
0362 break;
0363 default:
0364 dev_vdbg(component->dev, "DAI Format master is not found\n");
0365 return -EINVAL;
0366 }
0367
0368 switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
0369 SND_SOC_DAIFMT_INV_MASK)) {
0370 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
0371 break;
0372 case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
0373 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
0374 serial_format |= TAS2552_DATAFORMAT_DSP;
0375 break;
0376 case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
0377 serial_format |= TAS2552_DATAFORMAT_RIGHT_J;
0378 break;
0379 case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
0380 serial_format |= TAS2552_DATAFORMAT_LEFT_J;
0381 break;
0382 default:
0383 dev_vdbg(component->dev, "DAI Format is not found\n");
0384 return -EINVAL;
0385 }
0386 tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
0387
0388 snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
0389 serial_format);
0390 return 0;
0391 }
0392
0393 static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
0394 unsigned int freq, int dir)
0395 {
0396 struct snd_soc_component *component = dai->component;
0397 struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
0398 u8 reg, mask, val;
0399
0400 switch (clk_id) {
0401 case TAS2552_PLL_CLKIN_MCLK:
0402 case TAS2552_PLL_CLKIN_IVCLKIN:
0403 if (freq < 512000 || freq > 24576000) {
0404
0405 dev_warn(component->dev, "Out of range PLL_CLKIN: %u\n",
0406 freq);
0407 clk_id = TAS2552_PLL_CLKIN_BCLK;
0408 freq = 0;
0409 }
0410 fallthrough;
0411 case TAS2552_PLL_CLKIN_BCLK:
0412 case TAS2552_PLL_CLKIN_1_8_FIXED:
0413 mask = TAS2552_PLL_SRC_MASK;
0414 val = (clk_id << 3) & mask;
0415 reg = TAS2552_CFG_1;
0416 tas2552->pll_clk_id = clk_id;
0417 tas2552->pll_clkin = freq;
0418 break;
0419 case TAS2552_PDM_CLK_PLL:
0420 case TAS2552_PDM_CLK_IVCLKIN:
0421 case TAS2552_PDM_CLK_BCLK:
0422 case TAS2552_PDM_CLK_MCLK:
0423 mask = TAS2552_PDM_CLK_SEL_MASK;
0424 val = (clk_id >> 1) & mask;
0425 reg = TAS2552_PDM_CFG;
0426 tas2552->pdm_clk_id = clk_id;
0427 tas2552->pdm_clk = freq;
0428 break;
0429 default:
0430 dev_err(component->dev, "Invalid clk id: %d\n", clk_id);
0431 return -EINVAL;
0432 }
0433
0434 snd_soc_component_update_bits(component, reg, mask, val);
0435
0436 return 0;
0437 }
0438
0439 static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
0440 unsigned int tx_mask, unsigned int rx_mask,
0441 int slots, int slot_width)
0442 {
0443 struct snd_soc_component *component = dai->component;
0444 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
0445 unsigned int lsb;
0446
0447 if (unlikely(!tx_mask)) {
0448 dev_err(component->dev, "tx masks need to be non 0\n");
0449 return -EINVAL;
0450 }
0451
0452
0453 lsb = __ffs(tx_mask);
0454 if ((lsb + 1) != __fls(tx_mask)) {
0455 dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
0456 return -EINVAL;
0457 }
0458
0459 tas2552->tdm_delay = lsb * slot_width;
0460
0461
0462 snd_soc_component_update_bits(component, TAS2552_DOUT,
0463 TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);
0464
0465 return 0;
0466 }
0467
0468 static int tas2552_mute(struct snd_soc_dai *dai, int mute, int direction)
0469 {
0470 u8 cfg1_reg = 0;
0471 struct snd_soc_component *component = dai->component;
0472
0473 if (mute)
0474 cfg1_reg |= TAS2552_MUTE;
0475
0476 snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
0477
0478 return 0;
0479 }
0480
0481 #ifdef CONFIG_PM
0482 static int tas2552_runtime_suspend(struct device *dev)
0483 {
0484 struct tas2552_data *tas2552 = dev_get_drvdata(dev);
0485
0486 tas2552_sw_shutdown(tas2552, 1);
0487
0488 regcache_cache_only(tas2552->regmap, true);
0489 regcache_mark_dirty(tas2552->regmap);
0490
0491 gpiod_set_value(tas2552->enable_gpio, 0);
0492
0493 return 0;
0494 }
0495
0496 static int tas2552_runtime_resume(struct device *dev)
0497 {
0498 struct tas2552_data *tas2552 = dev_get_drvdata(dev);
0499
0500 gpiod_set_value(tas2552->enable_gpio, 1);
0501
0502 tas2552_sw_shutdown(tas2552, 0);
0503
0504 regcache_cache_only(tas2552->regmap, false);
0505 regcache_sync(tas2552->regmap);
0506
0507 return 0;
0508 }
0509 #endif
0510
0511 static const struct dev_pm_ops tas2552_pm = {
0512 SET_RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume,
0513 NULL)
0514 };
0515
0516 static const struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
0517 .hw_params = tas2552_hw_params,
0518 .prepare = tas2552_prepare,
0519 .set_sysclk = tas2552_set_dai_sysclk,
0520 .set_fmt = tas2552_set_dai_fmt,
0521 .set_tdm_slot = tas2552_set_dai_tdm_slot,
0522 .mute_stream = tas2552_mute,
0523 .no_capture_mute = 1,
0524 };
0525
0526
0527 #define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0528 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0529
0530
0531 static struct snd_soc_dai_driver tas2552_dai[] = {
0532 {
0533 .name = "tas2552-amplifier",
0534 .playback = {
0535 .stream_name = "Playback",
0536 .channels_min = 2,
0537 .channels_max = 2,
0538 .rates = SNDRV_PCM_RATE_8000_192000,
0539 .formats = TAS2552_FORMATS,
0540 },
0541 .ops = &tas2552_speaker_dai_ops,
0542 },
0543 };
0544
0545
0546
0547
0548 static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);
0549
0550 static const char * const tas2552_din_source_select[] = {
0551 "Muted",
0552 "Left",
0553 "Right",
0554 "Left + Right average",
0555 };
0556 static SOC_ENUM_SINGLE_DECL(tas2552_din_source_enum,
0557 TAS2552_CFG_3, 3,
0558 tas2552_din_source_select);
0559
0560 static const struct snd_kcontrol_new tas2552_snd_controls[] = {
0561 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
0562 TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv),
0563 SOC_ENUM("DIN source", tas2552_din_source_enum),
0564 };
0565
0566 static int tas2552_component_probe(struct snd_soc_component *component)
0567 {
0568 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
0569 int ret;
0570
0571 tas2552->component = component;
0572
0573 ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
0574 tas2552->supplies);
0575
0576 if (ret != 0) {
0577 dev_err(component->dev, "Failed to enable supplies: %d\n",
0578 ret);
0579 return ret;
0580 }
0581
0582 gpiod_set_value(tas2552->enable_gpio, 1);
0583
0584 ret = pm_runtime_resume_and_get(component->dev);
0585 if (ret < 0) {
0586 dev_err(component->dev, "Enabling device failed: %d\n",
0587 ret);
0588 goto probe_fail;
0589 }
0590
0591 snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
0592 snd_soc_component_write(component, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
0593 TAS2552_DIN_SRC_SEL_AVG_L_R);
0594 snd_soc_component_write(component, TAS2552_OUTPUT_DATA,
0595 TAS2552_PDM_DATA_SEL_V_I |
0596 TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
0597 snd_soc_component_write(component, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
0598 TAS2552_APT_THRESH_20_17);
0599
0600 snd_soc_component_write(component, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
0601 TAS2552_LIM_EN);
0602
0603 return 0;
0604
0605 probe_fail:
0606 pm_runtime_put_noidle(component->dev);
0607 gpiod_set_value(tas2552->enable_gpio, 0);
0608
0609 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
0610 tas2552->supplies);
0611 return ret;
0612 }
0613
0614 static void tas2552_component_remove(struct snd_soc_component *component)
0615 {
0616 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
0617
0618 pm_runtime_put(component->dev);
0619
0620 gpiod_set_value(tas2552->enable_gpio, 0);
0621 };
0622
0623 #ifdef CONFIG_PM
0624 static int tas2552_suspend(struct snd_soc_component *component)
0625 {
0626 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
0627 int ret;
0628
0629 ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
0630 tas2552->supplies);
0631
0632 if (ret != 0)
0633 dev_err(component->dev, "Failed to disable supplies: %d\n",
0634 ret);
0635 return ret;
0636 }
0637
0638 static int tas2552_resume(struct snd_soc_component *component)
0639 {
0640 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
0641 int ret;
0642
0643 ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
0644 tas2552->supplies);
0645
0646 if (ret != 0) {
0647 dev_err(component->dev, "Failed to enable supplies: %d\n",
0648 ret);
0649 }
0650
0651 return ret;
0652 }
0653 #else
0654 #define tas2552_suspend NULL
0655 #define tas2552_resume NULL
0656 #endif
0657
0658 static const struct snd_soc_component_driver soc_component_dev_tas2552 = {
0659 .probe = tas2552_component_probe,
0660 .remove = tas2552_component_remove,
0661 .suspend = tas2552_suspend,
0662 .resume = tas2552_resume,
0663 .controls = tas2552_snd_controls,
0664 .num_controls = ARRAY_SIZE(tas2552_snd_controls),
0665 .dapm_widgets = tas2552_dapm_widgets,
0666 .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets),
0667 .dapm_routes = tas2552_audio_map,
0668 .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map),
0669 .idle_bias_on = 1,
0670 .endianness = 1,
0671 };
0672
0673 static const struct regmap_config tas2552_regmap_config = {
0674 .reg_bits = 8,
0675 .val_bits = 8,
0676
0677 .max_register = TAS2552_MAX_REG,
0678 .reg_defaults = tas2552_reg_defs,
0679 .num_reg_defaults = ARRAY_SIZE(tas2552_reg_defs),
0680 .cache_type = REGCACHE_RBTREE,
0681 };
0682
0683 static int tas2552_probe(struct i2c_client *client)
0684 {
0685 struct device *dev;
0686 struct tas2552_data *data;
0687 int ret;
0688 int i;
0689
0690 dev = &client->dev;
0691 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
0692 if (data == NULL)
0693 return -ENOMEM;
0694
0695 data->enable_gpio = devm_gpiod_get_optional(dev, "enable",
0696 GPIOD_OUT_LOW);
0697 if (IS_ERR(data->enable_gpio))
0698 return PTR_ERR(data->enable_gpio);
0699
0700 data->tas2552_client = client;
0701 data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
0702 if (IS_ERR(data->regmap)) {
0703 ret = PTR_ERR(data->regmap);
0704 dev_err(&client->dev, "Failed to allocate register map: %d\n",
0705 ret);
0706 return ret;
0707 }
0708
0709 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
0710 data->supplies[i].supply = tas2552_supply_names[i];
0711
0712 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
0713 data->supplies);
0714 if (ret != 0) {
0715 dev_err(dev, "Failed to request supplies: %d\n", ret);
0716 return ret;
0717 }
0718
0719 pm_runtime_set_active(&client->dev);
0720 pm_runtime_set_autosuspend_delay(&client->dev, 1000);
0721 pm_runtime_use_autosuspend(&client->dev);
0722 pm_runtime_enable(&client->dev);
0723 pm_runtime_mark_last_busy(&client->dev);
0724 pm_runtime_put_sync_autosuspend(&client->dev);
0725
0726 dev_set_drvdata(&client->dev, data);
0727
0728 ret = devm_snd_soc_register_component(&client->dev,
0729 &soc_component_dev_tas2552,
0730 tas2552_dai, ARRAY_SIZE(tas2552_dai));
0731 if (ret < 0) {
0732 dev_err(&client->dev, "Failed to register component: %d\n", ret);
0733 pm_runtime_get_noresume(&client->dev);
0734 }
0735
0736 return ret;
0737 }
0738
0739 static int tas2552_i2c_remove(struct i2c_client *client)
0740 {
0741 pm_runtime_disable(&client->dev);
0742 return 0;
0743 }
0744
0745 static const struct i2c_device_id tas2552_id[] = {
0746 { "tas2552", 0 },
0747 { }
0748 };
0749 MODULE_DEVICE_TABLE(i2c, tas2552_id);
0750
0751 #if IS_ENABLED(CONFIG_OF)
0752 static const struct of_device_id tas2552_of_match[] = {
0753 { .compatible = "ti,tas2552", },
0754 {},
0755 };
0756 MODULE_DEVICE_TABLE(of, tas2552_of_match);
0757 #endif
0758
0759 static struct i2c_driver tas2552_i2c_driver = {
0760 .driver = {
0761 .name = "tas2552",
0762 .of_match_table = of_match_ptr(tas2552_of_match),
0763 .pm = &tas2552_pm,
0764 },
0765 .probe_new = tas2552_probe,
0766 .remove = tas2552_i2c_remove,
0767 .id_table = tas2552_id,
0768 };
0769
0770 module_i2c_driver(tas2552_i2c_driver);
0771
0772 MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>");
0773 MODULE_DESCRIPTION("TAS2552 Audio amplifier driver");
0774 MODULE_LICENSE("GPL");