Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * tas2552.c - ALSA SoC Texas Instruments TAS2552 Mono Audio Amplifier
0004  *
0005  * Copyright (C) 2014 Texas Instruments Incorporated -  https://www.ti.com
0006  *
0007  * Author: Dan Murphy <dmurphy@ti.com>
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",     /* vbat voltage */
0060     "iovdd",    /* I/O Voltage */
0061     "avdd",     /* Analog DAC Voltage */
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 /* Input mux controls */
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     /* MUX Controls */
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         /* By pass the PLL configuration */
0180         snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_2,
0181                     TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
0182     } else {
0183         /* Fill in the PLL control registers for J & D
0184          * pll_clk = (.5 * pll_clkin * J.D) / 2^p
0185          * Need to fill in J and D here based on incoming freq
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         /* Will clear the PLL_BYPASS bit */
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     /* Restore PLL status */
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     /* TDM slot selection only valid in DSP_A/_B mode */
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     /* Configure data delay */
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             /* out of range PLL_CLKIN, fall back to use BCLK */
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; /* bit 4:5 in the register */
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; /* bit 0:1 in the register */
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     /* TDM based on DSP mode requires slots to be adjacent */
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     /* DOUT in high-impedance on inactive bit clocks */
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 /* Formats supported by TAS2552 driver. */
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 /* TAS2552 dai structure. */
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  * DAC digital volumes. From -7 to 24 dB in 1 dB steps
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");