Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Driver for the Texas Instruments TAS2780 Mono
0003 //      Audio amplifier
0004 // Copyright (C) 2022 Texas Instruments Inc.
0005 
0006 #include <linux/module.h>
0007 #include <linux/err.h>
0008 #include <linux/pm.h>
0009 #include <linux/i2c.h>
0010 #include <linux/gpio.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/regmap.h>
0013 #include <linux/of.h>
0014 #include <linux/of_gpio.h>
0015 #include <sound/soc.h>
0016 #include <sound/pcm.h>
0017 #include <sound/pcm_params.h>
0018 #include <sound/tlv.h>
0019 
0020 #include "tas2780.h"
0021 
0022 struct tas2780_priv {
0023     struct snd_soc_component *component;
0024     struct gpio_desc *reset_gpio;
0025     struct regmap *regmap;
0026     struct device *dev;
0027     int v_sense_slot;
0028     int i_sense_slot;
0029 };
0030 
0031 static void tas2780_reset(struct tas2780_priv *tas2780)
0032 {
0033     int ret = 0;
0034 
0035     if (tas2780->reset_gpio) {
0036         gpiod_set_value_cansleep(tas2780->reset_gpio, 0);
0037         usleep_range(2000, 2050);
0038         gpiod_set_value_cansleep(tas2780->reset_gpio, 1);
0039         usleep_range(2000, 2050);
0040     }
0041 
0042     snd_soc_component_write(tas2780->component, TAS2780_SW_RST,
0043                 TAS2780_RST);
0044     if (ret)
0045         dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n",
0046             __func__, ret);
0047 }
0048 
0049 #ifdef CONFIG_PM
0050 static int tas2780_codec_suspend(struct snd_soc_component *component)
0051 {
0052     struct tas2780_priv *tas2780 =
0053         snd_soc_component_get_drvdata(component);
0054     int ret = 0;
0055 
0056     ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL,
0057         TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_SHUTDOWN);
0058     if (ret < 0) {
0059         dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n",
0060             __func__, ret);
0061         goto err;
0062     }
0063     ret = 0;
0064     regcache_cache_only(tas2780->regmap, true);
0065     regcache_mark_dirty(tas2780->regmap);
0066 err:
0067     return ret;
0068 }
0069 
0070 static int tas2780_codec_resume(struct snd_soc_component *component)
0071 {
0072     struct tas2780_priv *tas2780 =
0073         snd_soc_component_get_drvdata(component);
0074     int ret = 0;
0075 
0076     ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL,
0077         TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_ACTIVE);
0078 
0079     if (ret < 0) {
0080         dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n",
0081             __func__, ret);
0082         goto err;
0083     }
0084     ret = 0;
0085     regcache_cache_only(tas2780->regmap, false);
0086     ret = regcache_sync(tas2780->regmap);
0087 err:
0088     return ret;
0089 }
0090 #endif
0091 
0092 static const char * const tas2780_ASI1_src[] = {
0093     "I2C offset", "Left", "Right", "LeftRightDiv2",
0094 };
0095 
0096 static SOC_ENUM_SINGLE_DECL(
0097     tas2780_ASI1_src_enum, TAS2780_TDM_CFG2, 4, tas2780_ASI1_src);
0098 
0099 static const struct snd_kcontrol_new tas2780_asi1_mux =
0100     SOC_DAPM_ENUM("ASI1 Source", tas2780_ASI1_src_enum);
0101 
0102 static const struct snd_kcontrol_new isense_switch =
0103     SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL,
0104             TAS2780_ISENSE_POWER_EN, 1, 1);
0105 static const struct snd_kcontrol_new vsense_switch =
0106     SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL,
0107             TAS2780_VSENSE_POWER_EN, 1, 1);
0108 
0109 static const struct snd_soc_dapm_widget tas2780_dapm_widgets[] = {
0110     SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
0111     SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2780_asi1_mux),
0112     SND_SOC_DAPM_SWITCH("ISENSE", TAS2780_PWR_CTRL,
0113         TAS2780_ISENSE_POWER_EN, 1, &isense_switch),
0114     SND_SOC_DAPM_SWITCH("VSENSE", TAS2780_PWR_CTRL,
0115         TAS2780_VSENSE_POWER_EN, 1, &vsense_switch),
0116     SND_SOC_DAPM_OUTPUT("OUT"),
0117     SND_SOC_DAPM_SIGGEN("VMON"),
0118     SND_SOC_DAPM_SIGGEN("IMON")
0119 };
0120 
0121 static const struct snd_soc_dapm_route tas2780_audio_map[] = {
0122     {"ASI1 Sel", "I2C offset", "ASI1"},
0123     {"ASI1 Sel", "Left", "ASI1"},
0124     {"ASI1 Sel", "Right", "ASI1"},
0125     {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
0126     {"OUT", NULL, "ASI1 Sel"},
0127     {"ISENSE", "Switch", "IMON"},
0128     {"VSENSE", "Switch", "VMON"},
0129 };
0130 
0131 static int tas2780_mute(struct snd_soc_dai *dai, int mute, int direction)
0132 {
0133     struct snd_soc_component *component = dai->component;
0134     struct tas2780_priv *tas2780 =
0135         snd_soc_component_get_drvdata(component);
0136     int ret = 0;
0137 
0138     ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL,
0139         TAS2780_PWR_CTRL_MASK,
0140         mute ? TAS2780_PWR_CTRL_MUTE : 0);
0141     if (ret < 0) {
0142         dev_err(tas2780->dev, "%s: Failed to set powercontrol\n",
0143             __func__);
0144         goto err;
0145     }
0146     ret = 0;
0147 err:
0148     return ret;
0149 }
0150 
0151 static int tas2780_set_bitwidth(struct tas2780_priv *tas2780, int bitwidth)
0152 {
0153     struct snd_soc_component *component = tas2780->component;
0154     int sense_en;
0155     int val;
0156     int ret;
0157     int slot_size;
0158 
0159     switch (bitwidth) {
0160     case SNDRV_PCM_FORMAT_S16_LE:
0161         ret = snd_soc_component_update_bits(component,
0162             TAS2780_TDM_CFG2,
0163             TAS2780_TDM_CFG2_RXW_MASK,
0164             TAS2780_TDM_CFG2_RXW_16BITS);
0165         slot_size = TAS2780_TDM_CFG2_RXS_16BITS;
0166         break;
0167     case SNDRV_PCM_FORMAT_S24_LE:
0168         ret = snd_soc_component_update_bits(component,
0169             TAS2780_TDM_CFG2,
0170             TAS2780_TDM_CFG2_RXW_MASK,
0171             TAS2780_TDM_CFG2_RXW_24BITS);
0172         slot_size = TAS2780_TDM_CFG2_RXS_24BITS;
0173         break;
0174     case SNDRV_PCM_FORMAT_S32_LE:
0175         ret = snd_soc_component_update_bits(component,
0176             TAS2780_TDM_CFG2,
0177             TAS2780_TDM_CFG2_RXW_MASK,
0178             TAS2780_TDM_CFG2_RXW_32BITS);
0179         slot_size = TAS2780_TDM_CFG2_RXS_32BITS;
0180         break;
0181 
0182     default:
0183         ret = -EINVAL;
0184     }
0185 
0186     if (ret < 0) {
0187         dev_err(tas2780->dev, "%s:errCode:0x%x set bitwidth error\n",
0188             __func__, ret);
0189         goto err;
0190     }
0191 
0192     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2,
0193         TAS2780_TDM_CFG2_RXS_MASK, slot_size);
0194     if (ret < 0) {
0195         dev_err(tas2780->dev,
0196             "%s:errCode:0x%x set RX slot size error\n",
0197             __func__, ret);
0198         goto err;
0199     }
0200 
0201     val = snd_soc_component_read(tas2780->component, TAS2780_PWR_CTRL);
0202     if (val < 0) {
0203         dev_err(tas2780->dev, "%s:errCode:0x%x read PWR_CTRL error\n",
0204             __func__, val);
0205         ret = val;
0206         goto err;
0207     }
0208 
0209     if (val & (1 << TAS2780_VSENSE_POWER_EN))
0210         sense_en = 0;
0211     else
0212         sense_en = TAS2780_TDM_CFG5_VSNS_ENABLE;
0213 
0214     ret = snd_soc_component_update_bits(tas2780->component,
0215         TAS2780_TDM_CFG5, TAS2780_TDM_CFG5_VSNS_ENABLE, sense_en);
0216     if (ret < 0) {
0217         dev_err(tas2780->dev, "%s:errCode:0x%x enable vSNS error\n",
0218             __func__, ret);
0219         goto err;
0220     }
0221 
0222     if (val & (1 << TAS2780_ISENSE_POWER_EN))
0223         sense_en = 0;
0224     else
0225         sense_en = TAS2780_TDM_CFG6_ISNS_ENABLE;
0226 
0227     ret = snd_soc_component_update_bits(tas2780->component,
0228         TAS2780_TDM_CFG6, TAS2780_TDM_CFG6_ISNS_ENABLE, sense_en);
0229     if (ret < 0) {
0230         dev_err(tas2780->dev, "%s:errCode:0x%x enable iSNS error\n",
0231             __func__, ret);
0232         goto err;
0233     }
0234     ret = 0;
0235 err:
0236     return ret;
0237 }
0238 
0239 static int tas2780_set_samplerate(
0240     struct tas2780_priv *tas2780, int samplerate)
0241 {
0242     struct snd_soc_component *component = tas2780->component;
0243     int ramp_rate_val;
0244     int ret;
0245 
0246     switch (samplerate) {
0247     case 48000:
0248         ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ |
0249                 TAS2780_TDM_CFG0_44_1_48KHZ;
0250         break;
0251     case 44100:
0252         ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ |
0253                 TAS2780_TDM_CFG0_44_1_48KHZ;
0254         break;
0255     case 96000:
0256         ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ |
0257                 TAS2780_TDM_CFG0_88_2_96KHZ;
0258         break;
0259     case 88200:
0260         ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ |
0261                 TAS2780_TDM_CFG0_88_2_96KHZ;
0262         break;
0263     default:
0264         return -EINVAL;
0265     }
0266     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG0,
0267         TAS2780_TDM_CFG0_SMP_MASK | TAS2780_TDM_CFG0_MASK,
0268         ramp_rate_val);
0269     if (ret < 0) {
0270         dev_err(tas2780->dev,
0271             "%s:errCode:0x%x Failed to set ramp_rate_val\n",
0272             __func__, ret);
0273         goto err;
0274     }
0275     ret = 0;
0276 err:
0277     return ret;
0278 }
0279 
0280 static int tas2780_hw_params(struct snd_pcm_substream *substream,
0281     struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
0282 {
0283     struct snd_soc_component *component = dai->component;
0284     struct tas2780_priv *tas2780 =
0285         snd_soc_component_get_drvdata(component);
0286     int ret;
0287 
0288     ret = tas2780_set_bitwidth(tas2780, params_format(params));
0289     if (ret < 0)
0290         return ret;
0291 
0292     return tas2780_set_samplerate(tas2780, params_rate(params));
0293 }
0294 
0295 static int tas2780_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0296 {
0297     struct snd_soc_component *component = dai->component;
0298     struct tas2780_priv *tas2780 =
0299         snd_soc_component_get_drvdata(component);
0300     u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
0301     int iface;
0302     int ret = 0;
0303 
0304     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0305     case SND_SOC_DAIFMT_NB_NF:
0306         asi_cfg_1 = TAS2780_TDM_CFG1_RX_RISING;
0307         break;
0308     case SND_SOC_DAIFMT_IB_NF:
0309         asi_cfg_1 = TAS2780_TDM_CFG1_RX_FALLING;
0310         break;
0311     default:
0312         dev_err(tas2780->dev, "ASI format Inverse is not found\n");
0313         return -EINVAL;
0314     }
0315 
0316     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1,
0317         TAS2780_TDM_CFG1_RX_MASK, asi_cfg_1);
0318     if (ret < 0) {
0319         dev_err(tas2780->dev,
0320             "%s:errCode:0x%x Failed to set asi_cfg_1\n",
0321             __func__, ret);
0322         goto err;
0323     }
0324 
0325     if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
0326         || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK)
0327         == SND_SOC_DAIFMT_DSP_A)){
0328         iface = TAS2780_TDM_CFG2_SCFG_I2S;
0329         tdm_rx_start_slot = 1;
0330     } else {
0331         if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK)
0332             == SND_SOC_DAIFMT_DSP_B)
0333             || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK)
0334             == SND_SOC_DAIFMT_LEFT_J)) {
0335             iface = TAS2780_TDM_CFG2_SCFG_LEFT_J;
0336             tdm_rx_start_slot = 0;
0337         } else {
0338             dev_err(tas2780->dev,
0339                 "%s:DAI Format is not found, fmt=0x%x\n",
0340                 __func__, fmt);
0341             ret = -EINVAL;
0342             goto err;
0343         }
0344     }
0345     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1,
0346         TAS2780_TDM_CFG1_MASK,
0347         (tdm_rx_start_slot << TAS2780_TDM_CFG1_51_SHIFT));
0348     if (ret < 0) {
0349         dev_err(tas2780->dev,
0350             "%s:errCode:0x%x Failed to set tdm_rx_start_slot\n",
0351             __func__, ret);
0352         goto err;
0353     }
0354 
0355     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2,
0356         TAS2780_TDM_CFG2_SCFG_MASK, iface);
0357     if (ret < 0) {
0358         dev_err(tas2780->dev, "%s:errCode:0x%x Failed to set iface\n",
0359             __func__, ret);
0360         goto err;
0361     }
0362     ret = 0;
0363 err:
0364     return ret;
0365 }
0366 
0367 static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai,
0368                 unsigned int tx_mask,
0369                 unsigned int rx_mask,
0370                 int slots, int slot_width)
0371 {
0372     struct snd_soc_component *component = dai->component;
0373     struct tas2780_priv *tas2780 =
0374         snd_soc_component_get_drvdata(component);
0375     int left_slot, right_slot;
0376     int slots_cfg;
0377     int slot_size;
0378     int ret = 0;
0379 
0380     if (tx_mask == 0 || rx_mask != 0)
0381         return -EINVAL;
0382 
0383     if (slots == 1) {
0384         if (tx_mask != 1)
0385             return -EINVAL;
0386         left_slot = 0;
0387         right_slot = 0;
0388     } else {
0389         left_slot = __ffs(tx_mask);
0390         tx_mask &= ~(1 << left_slot);
0391         if (tx_mask == 0) {
0392             right_slot = left_slot;
0393         } else {
0394             right_slot = __ffs(tx_mask);
0395             tx_mask &= ~(1 << right_slot);
0396         }
0397     }
0398 
0399     if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
0400         return -EINVAL;
0401 
0402     slots_cfg = (right_slot << TAS2780_TDM_CFG3_RXS_SHIFT) | left_slot;
0403     ret = snd_soc_component_write(component, TAS2780_TDM_CFG3, slots_cfg);
0404     if (ret) {
0405         dev_err(tas2780->dev,
0406             "%s:errCode:0x%x Failed to set slots_cfg\n",
0407             __func__, ret);
0408         goto err;
0409     }
0410 
0411     switch (slot_width) {
0412     case 16:
0413         slot_size = TAS2780_TDM_CFG2_RXS_16BITS;
0414         break;
0415     case 24:
0416         slot_size = TAS2780_TDM_CFG2_RXS_24BITS;
0417         break;
0418     case 32:
0419         slot_size = TAS2780_TDM_CFG2_RXS_32BITS;
0420         break;
0421     default:
0422         ret = -EINVAL;
0423         goto err;
0424     }
0425 
0426     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2,
0427         TAS2780_TDM_CFG2_RXS_MASK, slot_size);
0428     if (ret < 0) {
0429         dev_err(tas2780->dev,
0430             "%s:errCode:0x%x Failed to set slot_size\n",
0431             __func__, ret);
0432         goto err;
0433     }
0434 
0435     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG5,
0436         TAS2780_TDM_CFG5_50_MASK, tas2780->v_sense_slot);
0437     if (ret < 0) {
0438         dev_err(tas2780->dev,
0439             "%s:errCode:0x%x Failed to set v_sense_slot\n",
0440             __func__, ret);
0441         goto err;
0442     }
0443 
0444     ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG6,
0445         TAS2780_TDM_CFG6_50_MASK, tas2780->i_sense_slot);
0446     if (ret < 0) {
0447         dev_err(tas2780->dev,
0448             "%s:errCode:0x%x Failed to set i_sense_slot\n",
0449             __func__, ret);
0450         goto err;
0451     }
0452     ret = 0;
0453 err:
0454     return ret;
0455 }
0456 
0457 static const struct snd_soc_dai_ops tas2780_dai_ops = {
0458     .mute_stream = tas2780_mute,
0459     .hw_params  = tas2780_hw_params,
0460     .set_fmt    = tas2780_set_fmt,
0461     .set_tdm_slot = tas2780_set_dai_tdm_slot,
0462     .no_capture_mute = 1,
0463 };
0464 
0465 #define TAS2780_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0466              SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0467 
0468 #define TAS2780_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
0469                SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200)
0470 
0471 static struct snd_soc_dai_driver tas2780_dai_driver[] = {
0472     {
0473         .name = "tas2780 ASI1",
0474         .id = 0,
0475         .playback = {
0476             .stream_name    = "ASI1 Playback",
0477             .channels_min   = 2,
0478             .channels_max   = 2,
0479             .rates      = TAS2780_RATES,
0480             .formats    = TAS2780_FORMATS,
0481         },
0482         .capture = {
0483             .stream_name    = "ASI1 Capture",
0484             .channels_min   = 1,
0485             .channels_max   = 2,
0486             .rates = TAS2780_RATES,
0487             .formats = TAS2780_FORMATS,
0488         },
0489         .ops = &tas2780_dai_ops,
0490         .symmetric_rate = 1,
0491     },
0492 };
0493 
0494 static int tas2780_codec_probe(struct snd_soc_component *component)
0495 {
0496     struct tas2780_priv *tas2780 =
0497         snd_soc_component_get_drvdata(component);
0498     int ret = 0;
0499 
0500     tas2780->component = component;
0501 
0502     tas2780_reset(tas2780);
0503     ret = snd_soc_component_update_bits(component,
0504             TAS2780_IC_CFG, TAS2780_IC_CFG_MASK,
0505             TAS2780_IC_CFG_ENABLE);
0506     if (ret < 0)
0507         dev_err(tas2780->dev, "%s:errCode:0x%0x\n",
0508             __func__, ret);
0509 
0510     return ret;
0511 }
0512 
0513 static DECLARE_TLV_DB_SCALE(tas2780_digital_tlv, 1100, 50, 0);
0514 static DECLARE_TLV_DB_SCALE(tas2780_playback_volume, -10000, 50, 0);
0515 
0516 static const struct snd_kcontrol_new tas2780_snd_controls[] = {
0517     SOC_SINGLE_TLV("Speaker Volume", TAS2780_DVC, 0,
0518                TAS2780_DVC_MAX, 1, tas2780_playback_volume),
0519     SOC_SINGLE_TLV("Amp Gain Volume", TAS2780_CHNL_0, 0, 0x14, 0,
0520                tas2780_digital_tlv),
0521 };
0522 
0523 static const struct snd_soc_component_driver soc_component_driver_tas2780 = {
0524     .probe          = tas2780_codec_probe,
0525 #ifdef CONFIG_PM
0526     .suspend        = tas2780_codec_suspend,
0527     .resume         = tas2780_codec_resume,
0528 #endif
0529     .controls       = tas2780_snd_controls,
0530     .num_controls       = ARRAY_SIZE(tas2780_snd_controls),
0531     .dapm_widgets       = tas2780_dapm_widgets,
0532     .num_dapm_widgets   = ARRAY_SIZE(tas2780_dapm_widgets),
0533     .dapm_routes        = tas2780_audio_map,
0534     .num_dapm_routes    = ARRAY_SIZE(tas2780_audio_map),
0535     .idle_bias_on       = 1,
0536     .endianness     = 1,
0537 };
0538 
0539 static const struct reg_default tas2780_reg_defaults[] = {
0540     { TAS2780_PAGE, 0x00 },
0541     { TAS2780_SW_RST, 0x00 },
0542     { TAS2780_PWR_CTRL, 0x1a },
0543     { TAS2780_DVC, 0x00 },
0544     { TAS2780_CHNL_0, 0x00 },
0545     { TAS2780_TDM_CFG0, 0x09 },
0546     { TAS2780_TDM_CFG1, 0x02 },
0547     { TAS2780_TDM_CFG2, 0x0a },
0548     { TAS2780_TDM_CFG3, 0x10 },
0549     { TAS2780_TDM_CFG5, 0x42 },
0550 };
0551 
0552 static const struct regmap_range_cfg tas2780_regmap_ranges[] = {
0553     {
0554         .range_min = 0,
0555         .range_max = 1 * 128,
0556         .selector_reg = TAS2780_PAGE,
0557         .selector_mask = 0xff,
0558         .selector_shift = 0,
0559         .window_start = 0,
0560         .window_len = 128,
0561     },
0562 };
0563 
0564 static const struct regmap_config tas2780_i2c_regmap = {
0565     .reg_bits = 8,
0566     .val_bits = 8,
0567     .reg_defaults = tas2780_reg_defaults,
0568     .num_reg_defaults = ARRAY_SIZE(tas2780_reg_defaults),
0569     .cache_type = REGCACHE_RBTREE,
0570     .ranges = tas2780_regmap_ranges,
0571     .num_ranges = ARRAY_SIZE(tas2780_regmap_ranges),
0572     .max_register = 1 * 128,
0573 };
0574 
0575 static int tas2780_parse_dt(struct device *dev, struct tas2780_priv *tas2780)
0576 {
0577     int ret = 0;
0578 
0579     tas2780->reset_gpio = devm_gpiod_get_optional(tas2780->dev, "reset",
0580         GPIOD_OUT_HIGH);
0581     if (IS_ERR(tas2780->reset_gpio)) {
0582         if (PTR_ERR(tas2780->reset_gpio) == -EPROBE_DEFER) {
0583             tas2780->reset_gpio = NULL;
0584             return -EPROBE_DEFER;
0585         }
0586     }
0587 
0588     ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
0589         &tas2780->i_sense_slot);
0590     if (ret)
0591         tas2780->i_sense_slot = 0;
0592 
0593     ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
0594         &tas2780->v_sense_slot);
0595     if (ret)
0596         tas2780->v_sense_slot = 2;
0597 
0598     return 0;
0599 }
0600 
0601 static int tas2780_i2c_probe(struct i2c_client *client,
0602             const struct i2c_device_id *id)
0603 {
0604     struct tas2780_priv *tas2780;
0605     int result;
0606 
0607     tas2780 = devm_kzalloc(&client->dev, sizeof(struct tas2780_priv),
0608         GFP_KERNEL);
0609     if (!tas2780)
0610         return -ENOMEM;
0611     tas2780->dev = &client->dev;
0612     i2c_set_clientdata(client, tas2780);
0613     dev_set_drvdata(&client->dev, tas2780);
0614 
0615     tas2780->regmap = devm_regmap_init_i2c(client, &tas2780_i2c_regmap);
0616     if (IS_ERR(tas2780->regmap)) {
0617         result = PTR_ERR(tas2780->regmap);
0618         dev_err(&client->dev, "Failed to allocate register map: %d\n",
0619             result);
0620         return result;
0621     }
0622 
0623     if (client->dev.of_node) {
0624         result = tas2780_parse_dt(&client->dev, tas2780);
0625         if (result) {
0626             dev_err(tas2780->dev,
0627                 "%s: Failed to parse devicetree\n", __func__);
0628             return result;
0629         }
0630     }
0631 
0632     return devm_snd_soc_register_component(tas2780->dev,
0633         &soc_component_driver_tas2780, tas2780_dai_driver,
0634         ARRAY_SIZE(tas2780_dai_driver));
0635 }
0636 
0637 static const struct i2c_device_id tas2780_i2c_id[] = {
0638     { "tas2780", 0},
0639     { }
0640 };
0641 MODULE_DEVICE_TABLE(i2c, tas2780_i2c_id);
0642 
0643 #if defined(CONFIG_OF)
0644 static const struct of_device_id tas2780_of_match[] = {
0645     { .compatible = "ti,tas2780" },
0646     {},
0647 };
0648 MODULE_DEVICE_TABLE(of, tas2780_of_match);
0649 #endif
0650 
0651 static struct i2c_driver tas2780_i2c_driver = {
0652     .driver = {
0653         .name   = "tas2780",
0654         .of_match_table = of_match_ptr(tas2780_of_match),
0655     },
0656     .probe  = tas2780_i2c_probe,
0657     .id_table   = tas2780_i2c_id,
0658 };
0659 module_i2c_driver(tas2780_i2c_driver);
0660 
0661 MODULE_AUTHOR("Raphael Xu <raphael-xu@ti.com>");
0662 MODULE_DESCRIPTION("TAS2780 I2C Smart Amplifier driver");
0663 MODULE_LICENSE("GPL");