Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Driver for the Texas Instruments TAS2562 CODEC
0004 // Copyright (C) 2019 Texas Instruments Inc.
0005 
0006 
0007 #include <linux/module.h>
0008 #include <linux/errno.h>
0009 #include <linux/device.h>
0010 #include <linux/i2c.h>
0011 #include <linux/pm_runtime.h>
0012 #include <linux/regmap.h>
0013 #include <linux/slab.h>
0014 #include <linux/gpio/consumer.h>
0015 #include <linux/regulator/consumer.h>
0016 #include <linux/delay.h>
0017 
0018 #include <sound/pcm.h>
0019 #include <sound/pcm_params.h>
0020 #include <sound/soc.h>
0021 #include <sound/soc-dapm.h>
0022 #include <sound/tlv.h>
0023 
0024 #include "tas2562.h"
0025 
0026 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
0027              SNDRV_PCM_FORMAT_S32_LE)
0028 
0029 /* DVC equation involves floating point math
0030  * round(10^(volume in dB/20)*2^30)
0031  * so create a lookup table for 2dB step
0032  */
0033 static const unsigned int float_vol_db_lookup[] = {
0034 0x00000d43, 0x000010b2, 0x00001505, 0x00001a67, 0x00002151,
0035 0x000029f1, 0x000034cd, 0x00004279, 0x000053af, 0x0000695b,
0036 0x0000695b, 0x0000a6fa, 0x0000d236, 0x000108a4, 0x00014d2a,
0037 0x0001a36e, 0x00021008, 0x000298c0, 0x000344df, 0x00041d8f,
0038 0x00052e5a, 0x000685c8, 0x00083621, 0x000a566d, 0x000d03a7,
0039 0x0010624d, 0x0014a050, 0x0019f786, 0x0020b0bc, 0x0029279d,
0040 0x0033cf8d, 0x004139d3, 0x00521d50, 0x00676044, 0x0082248a,
0041 0x00a3d70a, 0x00ce4328, 0x0103ab3d, 0x0146e75d, 0x019b8c27,
0042 0x02061b89, 0x028c423f, 0x03352529, 0x0409c2b0, 0x05156d68,
0043 0x080e9f96, 0x0a24b062, 0x0cc509ab, 0x10137987, 0x143d1362,
0044 0x197a967f, 0x2013739e, 0x28619ae9, 0x32d64617, 0x40000000
0045 };
0046 
0047 struct tas2562_data {
0048     struct snd_soc_component *component;
0049     struct gpio_desc *sdz_gpio;
0050     struct regmap *regmap;
0051     struct device *dev;
0052     struct i2c_client *client;
0053     int v_sense_slot;
0054     int i_sense_slot;
0055     int volume_lvl;
0056     int model_id;
0057 };
0058 
0059 enum tas256x_model {
0060     TAS2562,
0061     TAS2563,
0062     TAS2564,
0063     TAS2110,
0064 };
0065 
0066 static int tas2562_set_bias_level(struct snd_soc_component *component,
0067                  enum snd_soc_bias_level level)
0068 {
0069     struct tas2562_data *tas2562 =
0070             snd_soc_component_get_drvdata(component);
0071 
0072     switch (level) {
0073     case SND_SOC_BIAS_ON:
0074         snd_soc_component_update_bits(component,
0075             TAS2562_PWR_CTRL,
0076             TAS2562_MODE_MASK, TAS2562_ACTIVE);
0077         break;
0078     case SND_SOC_BIAS_STANDBY:
0079     case SND_SOC_BIAS_PREPARE:
0080         snd_soc_component_update_bits(component,
0081             TAS2562_PWR_CTRL,
0082             TAS2562_MODE_MASK, TAS2562_MUTE);
0083         break;
0084     case SND_SOC_BIAS_OFF:
0085         snd_soc_component_update_bits(component,
0086             TAS2562_PWR_CTRL,
0087             TAS2562_MODE_MASK, TAS2562_SHUTDOWN);
0088         break;
0089 
0090     default:
0091         dev_err(tas2562->dev,
0092                 "wrong power level setting %d\n", level);
0093         return -EINVAL;
0094     }
0095 
0096     return 0;
0097 }
0098 
0099 static int tas2562_set_samplerate(struct tas2562_data *tas2562, int samplerate)
0100 {
0101     int samp_rate;
0102     int ramp_rate;
0103 
0104     switch (samplerate) {
0105     case 7350:
0106         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0107         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ;
0108         break;
0109     case 8000:
0110         ramp_rate = 0;
0111         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ;
0112         break;
0113     case 14700:
0114         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0115         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ;
0116         break;
0117     case 16000:
0118         ramp_rate = 0;
0119         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ;
0120         break;
0121     case 22050:
0122         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0123         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ;
0124         break;
0125     case 24000:
0126         ramp_rate = 0;
0127         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ;
0128         break;
0129     case 29400:
0130         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0131         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ;
0132         break;
0133     case 32000:
0134         ramp_rate = 0;
0135         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ;
0136         break;
0137     case 44100:
0138         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0139         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ;
0140         break;
0141     case 48000:
0142         ramp_rate = 0;
0143         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ;
0144         break;
0145     case 88200:
0146         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0147         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ;
0148         break;
0149     case 96000:
0150         ramp_rate = 0;
0151         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ;
0152         break;
0153     case 176400:
0154         ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
0155         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ;
0156         break;
0157     case 192000:
0158         ramp_rate = 0;
0159         samp_rate = TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ;
0160         break;
0161     default:
0162         dev_info(tas2562->dev, "%s, unsupported sample rate, %d\n",
0163             __func__, samplerate);
0164         return -EINVAL;
0165     }
0166 
0167     snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG0,
0168         TAS2562_TDM_CFG0_RAMPRATE_MASK, ramp_rate);
0169     snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG0,
0170         TAS2562_TDM_CFG0_SAMPRATE_MASK, samp_rate);
0171 
0172     return 0;
0173 }
0174 
0175 static int tas2562_set_dai_tdm_slot(struct snd_soc_dai *dai,
0176         unsigned int tx_mask, unsigned int rx_mask,
0177         int slots, int slot_width)
0178 {
0179     struct snd_soc_component *component = dai->component;
0180     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0181     int left_slot, right_slot;
0182     int slots_cfg;
0183     int ret;
0184 
0185     if (!tx_mask) {
0186         dev_err(component->dev, "tx masks must not be 0\n");
0187         return -EINVAL;
0188     }
0189 
0190     if (slots == 1) {
0191         if (tx_mask != 1)
0192             return -EINVAL;
0193 
0194         left_slot = 0;
0195         right_slot = 0;
0196     } else {
0197         left_slot = __ffs(tx_mask);
0198         tx_mask &= ~(1 << left_slot);
0199         if (tx_mask == 0) {
0200             right_slot = left_slot;
0201         } else {
0202             right_slot = __ffs(tx_mask);
0203         }
0204     }
0205 
0206     slots_cfg = (right_slot << TAS2562_RIGHT_SLOT_SHIFT) | left_slot;
0207 
0208     ret = snd_soc_component_write(component, TAS2562_TDM_CFG3, slots_cfg);
0209     if (ret < 0)
0210         return ret;
0211 
0212     switch (slot_width) {
0213     case 16:
0214         ret = snd_soc_component_update_bits(component,
0215                             TAS2562_TDM_CFG2,
0216                             TAS2562_TDM_CFG2_RXLEN_MASK,
0217                             TAS2562_TDM_CFG2_RXLEN_16B);
0218         break;
0219     case 24:
0220         ret = snd_soc_component_update_bits(component,
0221                             TAS2562_TDM_CFG2,
0222                             TAS2562_TDM_CFG2_RXLEN_MASK,
0223                             TAS2562_TDM_CFG2_RXLEN_24B);
0224         break;
0225     case 32:
0226         ret = snd_soc_component_update_bits(component,
0227                             TAS2562_TDM_CFG2,
0228                             TAS2562_TDM_CFG2_RXLEN_MASK,
0229                             TAS2562_TDM_CFG2_RXLEN_32B);
0230         break;
0231 
0232     case 0:
0233         /* Do not change slot width */
0234         break;
0235     default:
0236         dev_err(tas2562->dev, "slot width not supported");
0237         ret = -EINVAL;
0238     }
0239 
0240     if (ret < 0)
0241         return ret;
0242 
0243     ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG5,
0244                         TAS2562_TDM_CFG5_VSNS_SLOT_MASK,
0245                         tas2562->v_sense_slot);
0246     if (ret < 0)
0247         return ret;
0248 
0249     ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG6,
0250                         TAS2562_TDM_CFG6_ISNS_SLOT_MASK,
0251                         tas2562->i_sense_slot);
0252     if (ret < 0)
0253         return ret;
0254 
0255     return 0;
0256 }
0257 
0258 static int tas2562_set_bitwidth(struct tas2562_data *tas2562, int bitwidth)
0259 {
0260     int ret;
0261     int val;
0262     int sense_en;
0263 
0264     switch (bitwidth) {
0265     case SNDRV_PCM_FORMAT_S16_LE:
0266         snd_soc_component_update_bits(tas2562->component,
0267                           TAS2562_TDM_CFG2,
0268                           TAS2562_TDM_CFG2_RXWLEN_MASK,
0269                           TAS2562_TDM_CFG2_RXWLEN_16B);
0270         break;
0271     case SNDRV_PCM_FORMAT_S24_LE:
0272         snd_soc_component_update_bits(tas2562->component,
0273                           TAS2562_TDM_CFG2,
0274                           TAS2562_TDM_CFG2_RXWLEN_MASK,
0275                           TAS2562_TDM_CFG2_RXWLEN_24B);
0276         break;
0277     case SNDRV_PCM_FORMAT_S32_LE:
0278         snd_soc_component_update_bits(tas2562->component,
0279                           TAS2562_TDM_CFG2,
0280                           TAS2562_TDM_CFG2_RXWLEN_MASK,
0281                           TAS2562_TDM_CFG2_RXWLEN_32B);
0282         break;
0283 
0284     default:
0285         dev_info(tas2562->dev, "Unsupported bitwidth format\n");
0286         return -EINVAL;
0287     }
0288 
0289     val = snd_soc_component_read(tas2562->component, TAS2562_PWR_CTRL);
0290     if (val < 0)
0291         return val;
0292 
0293     if (val & (1 << TAS2562_VSENSE_POWER_EN))
0294         sense_en = 0;
0295     else
0296         sense_en = TAS2562_TDM_CFG5_VSNS_EN;
0297 
0298     ret = snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG5,
0299         TAS2562_TDM_CFG5_VSNS_EN, sense_en);
0300     if (ret < 0)
0301         return ret;
0302 
0303     if (val & (1 << TAS2562_ISENSE_POWER_EN))
0304         sense_en = 0;
0305     else
0306         sense_en = TAS2562_TDM_CFG6_ISNS_EN;
0307 
0308     ret = snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG6,
0309         TAS2562_TDM_CFG6_ISNS_EN, sense_en);
0310     if (ret < 0)
0311         return ret;
0312 
0313     return 0;
0314 }
0315 
0316 static int tas2562_hw_params(struct snd_pcm_substream *substream,
0317                  struct snd_pcm_hw_params *params,
0318                  struct snd_soc_dai *dai)
0319 {
0320     struct snd_soc_component *component = dai->component;
0321     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0322     int ret;
0323 
0324     ret = tas2562_set_bitwidth(tas2562, params_format(params));
0325     if (ret) {
0326         dev_err(tas2562->dev, "set bitwidth failed, %d\n", ret);
0327         return ret;
0328     }
0329 
0330     ret = tas2562_set_samplerate(tas2562, params_rate(params));
0331     if (ret)
0332         dev_err(tas2562->dev, "set sample rate failed, %d\n", ret);
0333 
0334     return ret;
0335 }
0336 
0337 static int tas2562_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0338 {
0339     struct snd_soc_component *component = dai->component;
0340     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0341     u8 asi_cfg_1 = 0;
0342     u8 tdm_rx_start_slot = 0;
0343     int ret;
0344 
0345     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0346     case SND_SOC_DAIFMT_NB_NF:
0347         asi_cfg_1 = 0;
0348         break;
0349     case SND_SOC_DAIFMT_IB_NF:
0350         asi_cfg_1 |= TAS2562_TDM_CFG1_RX_FALLING;
0351         break;
0352     default:
0353         dev_err(tas2562->dev, "ASI format Inverse is not found\n");
0354         return -EINVAL;
0355     }
0356 
0357     ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG1,
0358                         TAS2562_TDM_CFG1_RX_EDGE_MASK,
0359                         asi_cfg_1);
0360     if (ret < 0) {
0361         dev_err(tas2562->dev, "Failed to set RX edge\n");
0362         return ret;
0363     }
0364     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0365     case SND_SOC_DAIFMT_LEFT_J:
0366     case SND_SOC_DAIFMT_DSP_B:
0367         tdm_rx_start_slot = 0;
0368         break;
0369     case SND_SOC_DAIFMT_I2S:
0370     case SND_SOC_DAIFMT_DSP_A:
0371         tdm_rx_start_slot = 1;
0372         break;
0373     default:
0374         dev_err(tas2562->dev,
0375             "DAI Format is not found, fmt=0x%x\n", fmt);
0376         return -EINVAL;
0377     }
0378 
0379     ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG1,
0380                 TAS2562_RX_OFF_MASK, (tdm_rx_start_slot << 1));
0381     if (ret < 0)
0382         return ret;
0383 
0384     return 0;
0385 }
0386 
0387 static int tas2562_mute(struct snd_soc_dai *dai, int mute, int direction)
0388 {
0389     struct snd_soc_component *component = dai->component;
0390 
0391     return snd_soc_component_update_bits(component, TAS2562_PWR_CTRL,
0392                          TAS2562_MODE_MASK,
0393                          mute ? TAS2562_MUTE : 0);
0394 }
0395 
0396 static int tas2562_codec_probe(struct snd_soc_component *component)
0397 {
0398     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0399     int ret;
0400 
0401     tas2562->component = component;
0402 
0403     if (tas2562->sdz_gpio)
0404         gpiod_set_value_cansleep(tas2562->sdz_gpio, 1);
0405 
0406     ret = snd_soc_component_update_bits(component, TAS2562_PWR_CTRL,
0407                         TAS2562_MODE_MASK, TAS2562_MUTE);
0408     if (ret < 0)
0409         return ret;
0410 
0411     return 0;
0412 }
0413 
0414 #ifdef CONFIG_PM
0415 static int tas2562_suspend(struct snd_soc_component *component)
0416 {
0417     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0418 
0419     regcache_cache_only(tas2562->regmap, true);
0420     regcache_mark_dirty(tas2562->regmap);
0421 
0422     if (tas2562->sdz_gpio)
0423         gpiod_set_value_cansleep(tas2562->sdz_gpio, 0);
0424 
0425     return 0;
0426 }
0427 
0428 static int tas2562_resume(struct snd_soc_component *component)
0429 {
0430     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0431 
0432     if (tas2562->sdz_gpio)
0433         gpiod_set_value_cansleep(tas2562->sdz_gpio, 1);
0434 
0435     regcache_cache_only(tas2562->regmap, false);
0436 
0437     return regcache_sync(tas2562->regmap);
0438 }
0439 #else
0440 #define tas2562_suspend NULL
0441 #define tas2562_resume NULL
0442 #endif
0443 
0444 static const char * const tas2562_ASI1_src[] = {
0445     "I2C offset", "Left", "Right", "LeftRightDiv2",
0446 };
0447 
0448 static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_enum, TAS2562_TDM_CFG2, 4,
0449                 tas2562_ASI1_src);
0450 
0451 static const struct snd_kcontrol_new tas2562_asi1_mux =
0452     SOC_DAPM_ENUM("ASI1 Source", tas2562_ASI1_src_enum);
0453 
0454 static int tas2562_dac_event(struct snd_soc_dapm_widget *w,
0455                  struct snd_kcontrol *kcontrol, int event)
0456 {
0457     struct snd_soc_component *component =
0458                     snd_soc_dapm_to_component(w->dapm);
0459     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0460     int ret;
0461 
0462     switch (event) {
0463     case SND_SOC_DAPM_POST_PMU:
0464         ret = snd_soc_component_update_bits(component,
0465             TAS2562_PWR_CTRL,
0466             TAS2562_MODE_MASK,
0467             TAS2562_MUTE);
0468         if (ret)
0469             goto end;
0470         break;
0471     case SND_SOC_DAPM_PRE_PMD:
0472         ret = snd_soc_component_update_bits(component,
0473             TAS2562_PWR_CTRL,
0474             TAS2562_MODE_MASK,
0475             TAS2562_SHUTDOWN);
0476         if (ret)
0477             goto end;
0478         break;
0479     default:
0480         dev_err(tas2562->dev, "Not supported evevt\n");
0481         return -EINVAL;
0482     }
0483 
0484 end:
0485     if (ret < 0)
0486         return ret;
0487 
0488     return 0;
0489 }
0490 
0491 static int tas2562_volume_control_get(struct snd_kcontrol *kcontrol,
0492                       struct snd_ctl_elem_value *ucontrol)
0493 {
0494     struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0495     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0496 
0497     ucontrol->value.integer.value[0] = tas2562->volume_lvl;
0498     return 0;
0499 }
0500 
0501 static int tas2562_volume_control_put(struct snd_kcontrol *kcontrol,
0502                       struct snd_ctl_elem_value *ucontrol)
0503 {
0504     struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0505     struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
0506     int ret;
0507     u32 reg_val;
0508 
0509     reg_val = float_vol_db_lookup[ucontrol->value.integer.value[0]/2];
0510     ret = snd_soc_component_write(component, TAS2562_DVC_CFG4,
0511                       (reg_val & 0xff));
0512     if (ret)
0513         return ret;
0514     ret = snd_soc_component_write(component, TAS2562_DVC_CFG3,
0515                       ((reg_val >> 8) & 0xff));
0516     if (ret)
0517         return ret;
0518     ret = snd_soc_component_write(component, TAS2562_DVC_CFG2,
0519                       ((reg_val >> 16) & 0xff));
0520     if (ret)
0521         return ret;
0522     ret = snd_soc_component_write(component, TAS2562_DVC_CFG1,
0523                       ((reg_val >> 24) & 0xff));
0524     if (ret)
0525         return ret;
0526 
0527     tas2562->volume_lvl = ucontrol->value.integer.value[0];
0528 
0529     return 0;
0530 }
0531 
0532 /* Digital Volume Control. From 0 dB to -110 dB in 1 dB steps */
0533 static const DECLARE_TLV_DB_SCALE(dvc_tlv, -11000, 100, 0);
0534 
0535 static DECLARE_TLV_DB_SCALE(tas2562_dac_tlv, 850, 50, 0);
0536 
0537 static const struct snd_kcontrol_new isense_switch =
0538     SOC_DAPM_SINGLE("Switch", TAS2562_PWR_CTRL, TAS2562_ISENSE_POWER_EN,
0539             1, 1);
0540 
0541 static const struct snd_kcontrol_new vsense_switch =
0542     SOC_DAPM_SINGLE("Switch", TAS2562_PWR_CTRL, TAS2562_VSENSE_POWER_EN,
0543             1, 1);
0544 
0545 static const struct snd_kcontrol_new tas2562_snd_controls[] = {
0546     SOC_SINGLE_TLV("Amp Gain Volume", TAS2562_PB_CFG1, 1, 0x1c, 0,
0547                tas2562_dac_tlv),
0548     {
0549         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0550         .name = "Digital Volume Control",
0551         .index = 0,
0552         .tlv.p = dvc_tlv,
0553         .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,
0554         .info = snd_soc_info_volsw,
0555         .get = tas2562_volume_control_get,
0556         .put = tas2562_volume_control_put,
0557         .private_value = SOC_SINGLE_VALUE(TAS2562_DVC_CFG1, 0, 110, 0, 0),
0558     },
0559 };
0560 
0561 static const struct snd_soc_dapm_widget tas2110_dapm_widgets[] = {
0562     SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
0563     SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2562_asi1_mux),
0564     SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event,
0565                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
0566     SND_SOC_DAPM_OUTPUT("OUT"),
0567 };
0568 
0569 static const struct snd_soc_dapm_route tas2110_audio_map[] = {
0570     {"ASI1 Sel", "I2C offset", "ASI1"},
0571     {"ASI1 Sel", "Left", "ASI1"},
0572     {"ASI1 Sel", "Right", "ASI1"},
0573     {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
0574     { "DAC", NULL, "ASI1 Sel" },
0575     { "OUT", NULL, "DAC" },
0576 };
0577 
0578 static const struct snd_soc_component_driver soc_component_dev_tas2110 = {
0579     .probe          = tas2562_codec_probe,
0580     .suspend        = tas2562_suspend,
0581     .resume         = tas2562_resume,
0582     .set_bias_level     = tas2562_set_bias_level,
0583     .controls       = tas2562_snd_controls,
0584     .num_controls       = ARRAY_SIZE(tas2562_snd_controls),
0585     .dapm_widgets       = tas2110_dapm_widgets,
0586     .num_dapm_widgets   = ARRAY_SIZE(tas2110_dapm_widgets),
0587     .dapm_routes        = tas2110_audio_map,
0588     .num_dapm_routes    = ARRAY_SIZE(tas2110_audio_map),
0589     .idle_bias_on       = 1,
0590     .use_pmdown_time    = 1,
0591     .endianness     = 1,
0592 };
0593 
0594 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = {
0595     SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
0596     SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2562_asi1_mux),
0597     SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event,
0598                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
0599     SND_SOC_DAPM_SWITCH("ISENSE", TAS2562_PWR_CTRL, 3, 1, &isense_switch),
0600     SND_SOC_DAPM_SWITCH("VSENSE", TAS2562_PWR_CTRL, 2, 1, &vsense_switch),
0601     SND_SOC_DAPM_SIGGEN("VMON"),
0602     SND_SOC_DAPM_SIGGEN("IMON"),
0603     SND_SOC_DAPM_OUTPUT("OUT"),
0604 };
0605 
0606 static const struct snd_soc_dapm_route tas2562_audio_map[] = {
0607     {"ASI1 Sel", "I2C offset", "ASI1"},
0608     {"ASI1 Sel", "Left", "ASI1"},
0609     {"ASI1 Sel", "Right", "ASI1"},
0610     {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
0611     { "DAC", NULL, "ASI1 Sel" },
0612     { "OUT", NULL, "DAC" },
0613     {"ISENSE", "Switch", "IMON"},
0614     {"VSENSE", "Switch", "VMON"},
0615 };
0616 
0617 static const struct snd_soc_component_driver soc_component_dev_tas2562 = {
0618     .probe          = tas2562_codec_probe,
0619     .suspend        = tas2562_suspend,
0620     .resume         = tas2562_resume,
0621     .set_bias_level     = tas2562_set_bias_level,
0622     .controls       = tas2562_snd_controls,
0623     .num_controls       = ARRAY_SIZE(tas2562_snd_controls),
0624     .dapm_widgets       = tas2562_dapm_widgets,
0625     .num_dapm_widgets   = ARRAY_SIZE(tas2562_dapm_widgets),
0626     .dapm_routes        = tas2562_audio_map,
0627     .num_dapm_routes    = ARRAY_SIZE(tas2562_audio_map),
0628     .idle_bias_on       = 1,
0629     .use_pmdown_time    = 1,
0630     .endianness     = 1,
0631 };
0632 
0633 static const struct snd_soc_dai_ops tas2562_speaker_dai_ops = {
0634     .hw_params  = tas2562_hw_params,
0635     .set_fmt    = tas2562_set_dai_fmt,
0636     .set_tdm_slot   = tas2562_set_dai_tdm_slot,
0637     .mute_stream    = tas2562_mute,
0638     .no_capture_mute = 1,
0639 };
0640 
0641 static struct snd_soc_dai_driver tas2562_dai[] = {
0642     {
0643         .name = "tas2562-amplifier",
0644         .id = 0,
0645         .playback = {
0646             .stream_name    = "ASI1 Playback",
0647             .channels_min   = 2,
0648             .channels_max   = 2,
0649             .rates      = SNDRV_PCM_RATE_8000_192000,
0650             .formats    = TAS2562_FORMATS,
0651         },
0652         .capture = {
0653             .stream_name    = "ASI1 Capture",
0654             .channels_min   = 0,
0655             .channels_max   = 2,
0656             .rates      = SNDRV_PCM_RATE_8000_192000,
0657             .formats    = TAS2562_FORMATS,
0658         },
0659         .ops = &tas2562_speaker_dai_ops,
0660     },
0661 };
0662 
0663 static const struct regmap_range_cfg tas2562_ranges[] = {
0664     {
0665         .range_min = 0,
0666         .range_max = 5 * 128,
0667         .selector_reg = TAS2562_PAGE_CTRL,
0668         .selector_mask = 0xff,
0669         .selector_shift = 0,
0670         .window_start = 0,
0671         .window_len = 128,
0672     },
0673 };
0674 
0675 static const struct reg_default tas2562_reg_defaults[] = {
0676     { TAS2562_PAGE_CTRL, 0x00 },
0677     { TAS2562_SW_RESET, 0x00 },
0678     { TAS2562_PWR_CTRL, 0x0e },
0679     { TAS2562_PB_CFG1, 0x20 },
0680     { TAS2562_TDM_CFG0, 0x09 },
0681     { TAS2562_TDM_CFG1, 0x02 },
0682     { TAS2562_DVC_CFG1, 0x40 },
0683     { TAS2562_DVC_CFG2, 0x40 },
0684     { TAS2562_DVC_CFG3, 0x00 },
0685     { TAS2562_DVC_CFG4, 0x00 },
0686 };
0687 
0688 static const struct regmap_config tas2562_regmap_config = {
0689     .reg_bits = 8,
0690     .val_bits = 8,
0691 
0692     .max_register = 5 * 128,
0693     .cache_type = REGCACHE_RBTREE,
0694     .reg_defaults = tas2562_reg_defaults,
0695     .num_reg_defaults = ARRAY_SIZE(tas2562_reg_defaults),
0696     .ranges = tas2562_ranges,
0697     .num_ranges = ARRAY_SIZE(tas2562_ranges),
0698 };
0699 
0700 static int tas2562_parse_dt(struct tas2562_data *tas2562)
0701 {
0702     struct device *dev = tas2562->dev;
0703     int ret = 0;
0704 
0705     tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
0706     if (IS_ERR(tas2562->sdz_gpio)) {
0707         if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
0708             return -EPROBE_DEFER;
0709 
0710         tas2562->sdz_gpio = NULL;
0711     }
0712 
0713     /*
0714      * The shut-down property is deprecated but needs to be checked for
0715      * backwards compatibility.
0716      */
0717     if (tas2562->sdz_gpio == NULL) {
0718         tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
0719                                   GPIOD_OUT_HIGH);
0720         if (IS_ERR(tas2562->sdz_gpio))
0721             if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
0722                 return -EPROBE_DEFER;
0723 
0724         tas2562->sdz_gpio = NULL;
0725     }
0726 
0727     if (tas2562->model_id == TAS2110)
0728         return ret;
0729 
0730     ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
0731             &tas2562->i_sense_slot);
0732     if (ret) {
0733         dev_err(dev, "Property %s is missing setting default slot\n",
0734             "ti,imon-slot-no");
0735         tas2562->i_sense_slot = 0;
0736     }
0737 
0738 
0739     ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
0740             &tas2562->v_sense_slot);
0741     if (ret) {
0742         dev_info(dev, "Property %s is missing setting default slot\n",
0743             "ti,vmon-slot-no");
0744         tas2562->v_sense_slot = 2;
0745     }
0746 
0747     if (tas2562->v_sense_slot < tas2562->i_sense_slot) {
0748         dev_err(dev, "Vsense slot must be greater than Isense slot\n");
0749         return -EINVAL;
0750     }
0751 
0752     return ret;
0753 }
0754 
0755 static const struct i2c_device_id tas2562_id[] = {
0756     { "tas2562", TAS2562 },
0757     { "tas2563", TAS2563 },
0758     { "tas2564", TAS2564 },
0759     { "tas2110", TAS2110 },
0760     { }
0761 };
0762 MODULE_DEVICE_TABLE(i2c, tas2562_id);
0763 
0764 static int tas2562_probe(struct i2c_client *client)
0765 {
0766     struct device *dev = &client->dev;
0767     struct tas2562_data *data;
0768     int ret;
0769     const struct i2c_device_id *id;
0770 
0771     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0772     if (!data)
0773         return -ENOMEM;
0774 
0775     id = i2c_match_id(tas2562_id, client);
0776     data->client = client;
0777     data->dev = &client->dev;
0778     data->model_id = id->driver_data;
0779 
0780     tas2562_parse_dt(data);
0781 
0782     data->regmap = devm_regmap_init_i2c(client, &tas2562_regmap_config);
0783     if (IS_ERR(data->regmap)) {
0784         ret = PTR_ERR(data->regmap);
0785         dev_err(dev, "failed to allocate register map: %d\n", ret);
0786         return ret;
0787     }
0788 
0789     dev_set_drvdata(&client->dev, data);
0790 
0791     if (data->model_id == TAS2110)
0792         return devm_snd_soc_register_component(dev,
0793                                &soc_component_dev_tas2110,
0794                                tas2562_dai,
0795                                ARRAY_SIZE(tas2562_dai));
0796 
0797     return devm_snd_soc_register_component(dev, &soc_component_dev_tas2562,
0798                            tas2562_dai,
0799                            ARRAY_SIZE(tas2562_dai));
0800 
0801 }
0802 
0803 #ifdef CONFIG_OF
0804 static const struct of_device_id tas2562_of_match[] = {
0805     { .compatible = "ti,tas2562", },
0806     { .compatible = "ti,tas2563", },
0807     { .compatible = "ti,tas2564", },
0808     { .compatible = "ti,tas2110", },
0809     { },
0810 };
0811 MODULE_DEVICE_TABLE(of, tas2562_of_match);
0812 #endif
0813 
0814 static struct i2c_driver tas2562_i2c_driver = {
0815     .driver = {
0816         .name = "tas2562",
0817         .of_match_table = of_match_ptr(tas2562_of_match),
0818     },
0819     .probe_new = tas2562_probe,
0820     .id_table = tas2562_id,
0821 };
0822 
0823 module_i2c_driver(tas2562_i2c_driver);
0824 
0825 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
0826 MODULE_DESCRIPTION("TAS2562 Audio amplifier driver");
0827 MODULE_LICENSE("GPL");