Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // ALSA SoC Texas Instruments TAS2770 20-W Digital Input Mono Class-D
0004 // Audio Amplifier with Speaker I/V Sense
0005 //
0006 // Copyright (C) 2016-2017 Texas Instruments Incorporated - https://www.ti.com/
0007 //  Author: Tracy Yi <tracy-yi@ti.com>
0008 //  Frank Shi <shifu0704@thundersoft.com>
0009 
0010 #include <linux/module.h>
0011 #include <linux/moduleparam.h>
0012 #include <linux/err.h>
0013 #include <linux/init.h>
0014 #include <linux/delay.h>
0015 #include <linux/pm.h>
0016 #include <linux/i2c.h>
0017 #include <linux/gpio.h>
0018 #include <linux/gpio/consumer.h>
0019 #include <linux/regulator/consumer.h>
0020 #include <linux/firmware.h>
0021 #include <linux/regmap.h>
0022 #include <linux/of.h>
0023 #include <linux/of_gpio.h>
0024 #include <linux/slab.h>
0025 #include <sound/soc.h>
0026 #include <sound/pcm.h>
0027 #include <sound/pcm_params.h>
0028 #include <sound/initval.h>
0029 #include <sound/tlv.h>
0030 
0031 #include "tas2770.h"
0032 
0033 #define TAS2770_MDELAY 0xFFFFFFFE
0034 
0035 static void tas2770_reset(struct tas2770_priv *tas2770)
0036 {
0037     if (tas2770->reset_gpio) {
0038         gpiod_set_value_cansleep(tas2770->reset_gpio, 0);
0039         msleep(20);
0040         gpiod_set_value_cansleep(tas2770->reset_gpio, 1);
0041         usleep_range(1000, 2000);
0042     }
0043 
0044     snd_soc_component_write(tas2770->component, TAS2770_SW_RST,
0045         TAS2770_RST);
0046     usleep_range(1000, 2000);
0047 }
0048 
0049 static int tas2770_update_pwr_ctrl(struct tas2770_priv *tas2770)
0050 {
0051     struct snd_soc_component *component = tas2770->component;
0052     unsigned int val;
0053     int ret;
0054 
0055     if (tas2770->dac_powered)
0056         val = tas2770->unmuted ?
0057             TAS2770_PWR_CTRL_ACTIVE : TAS2770_PWR_CTRL_MUTE;
0058     else
0059         val = TAS2770_PWR_CTRL_SHUTDOWN;
0060 
0061     ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
0062                         TAS2770_PWR_CTRL_MASK, val);
0063     if (ret < 0)
0064         return ret;
0065 
0066     return 0;
0067 }
0068 
0069 #ifdef CONFIG_PM
0070 static int tas2770_codec_suspend(struct snd_soc_component *component)
0071 {
0072     struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
0073     int ret = 0;
0074 
0075     regcache_cache_only(tas2770->regmap, true);
0076     regcache_mark_dirty(tas2770->regmap);
0077 
0078     if (tas2770->sdz_gpio) {
0079         gpiod_set_value_cansleep(tas2770->sdz_gpio, 0);
0080     } else {
0081         ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
0082                             TAS2770_PWR_CTRL_MASK,
0083                             TAS2770_PWR_CTRL_SHUTDOWN);
0084         if (ret < 0) {
0085             regcache_cache_only(tas2770->regmap, false);
0086             regcache_sync(tas2770->regmap);
0087             return ret;
0088         }
0089 
0090         ret = 0;
0091     }
0092 
0093     return ret;
0094 }
0095 
0096 static int tas2770_codec_resume(struct snd_soc_component *component)
0097 {
0098     struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
0099     int ret;
0100 
0101     if (tas2770->sdz_gpio) {
0102         gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
0103         usleep_range(1000, 2000);
0104     } else {
0105         ret = tas2770_update_pwr_ctrl(tas2770);
0106         if (ret < 0)
0107             return ret;
0108     }
0109 
0110     regcache_cache_only(tas2770->regmap, false);
0111 
0112     return regcache_sync(tas2770->regmap);
0113 }
0114 #else
0115 #define tas2770_codec_suspend NULL
0116 #define tas2770_codec_resume NULL
0117 #endif
0118 
0119 static const char * const tas2770_ASI1_src[] = {
0120     "I2C offset", "Left", "Right", "LeftRightDiv2",
0121 };
0122 
0123 static SOC_ENUM_SINGLE_DECL(
0124     tas2770_ASI1_src_enum, TAS2770_TDM_CFG_REG2,
0125     4, tas2770_ASI1_src);
0126 
0127 static const struct snd_kcontrol_new tas2770_asi1_mux =
0128     SOC_DAPM_ENUM("ASI1 Source", tas2770_ASI1_src_enum);
0129 
0130 static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
0131                  struct snd_kcontrol *kcontrol, int event)
0132 {
0133     struct snd_soc_component *component =
0134             snd_soc_dapm_to_component(w->dapm);
0135     struct tas2770_priv *tas2770 =
0136             snd_soc_component_get_drvdata(component);
0137     int ret;
0138 
0139     switch (event) {
0140     case SND_SOC_DAPM_POST_PMU:
0141         tas2770->dac_powered = 1;
0142         ret = tas2770_update_pwr_ctrl(tas2770);
0143         break;
0144     case SND_SOC_DAPM_PRE_PMD:
0145         tas2770->dac_powered = 0;
0146         ret = tas2770_update_pwr_ctrl(tas2770);
0147         break;
0148     default:
0149         dev_err(tas2770->dev, "Not supported evevt\n");
0150         return -EINVAL;
0151     }
0152 
0153     return ret;
0154 }
0155 
0156 static const struct snd_kcontrol_new isense_switch =
0157     SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 3, 1, 1);
0158 static const struct snd_kcontrol_new vsense_switch =
0159     SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 2, 1, 1);
0160 
0161 static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = {
0162     SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
0163     SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2770_asi1_mux),
0164     SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch),
0165     SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch),
0166     SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2770_dac_event,
0167                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
0168     SND_SOC_DAPM_OUTPUT("OUT"),
0169     SND_SOC_DAPM_SIGGEN("VMON"),
0170     SND_SOC_DAPM_SIGGEN("IMON")
0171 };
0172 
0173 static const struct snd_soc_dapm_route tas2770_audio_map[] = {
0174     {"ASI1 Sel", "I2C offset", "ASI1"},
0175     {"ASI1 Sel", "Left", "ASI1"},
0176     {"ASI1 Sel", "Right", "ASI1"},
0177     {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
0178     {"DAC", NULL, "ASI1 Sel"},
0179     {"OUT", NULL, "DAC"},
0180     {"ISENSE", "Switch", "IMON"},
0181     {"VSENSE", "Switch", "VMON"},
0182 };
0183 
0184 static int tas2770_mute(struct snd_soc_dai *dai, int mute, int direction)
0185 {
0186     struct snd_soc_component *component = dai->component;
0187     struct tas2770_priv *tas2770 =
0188             snd_soc_component_get_drvdata(component);
0189 
0190     tas2770->unmuted = !mute;
0191     return tas2770_update_pwr_ctrl(tas2770);
0192 }
0193 
0194 static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
0195 {
0196     int ret;
0197     struct snd_soc_component *component = tas2770->component;
0198 
0199     switch (bitwidth) {
0200     case SNDRV_PCM_FORMAT_S16_LE:
0201         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
0202                             TAS2770_TDM_CFG_REG2_RXW_MASK,
0203                             TAS2770_TDM_CFG_REG2_RXW_16BITS);
0204         tas2770->v_sense_slot = tas2770->i_sense_slot + 2;
0205         break;
0206     case SNDRV_PCM_FORMAT_S24_LE:
0207         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
0208                             TAS2770_TDM_CFG_REG2_RXW_MASK,
0209                             TAS2770_TDM_CFG_REG2_RXW_24BITS);
0210         tas2770->v_sense_slot = tas2770->i_sense_slot + 4;
0211         break;
0212     case SNDRV_PCM_FORMAT_S32_LE:
0213         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
0214                             TAS2770_TDM_CFG_REG2_RXW_MASK,
0215                             TAS2770_TDM_CFG_REG2_RXW_32BITS);
0216         tas2770->v_sense_slot = tas2770->i_sense_slot + 4;
0217         break;
0218 
0219     default:
0220         return -EINVAL;
0221     }
0222 
0223     if (ret < 0)
0224         return ret;
0225 
0226     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG5,
0227                         TAS2770_TDM_CFG_REG5_VSNS_MASK |
0228                         TAS2770_TDM_CFG_REG5_50_MASK,
0229                         TAS2770_TDM_CFG_REG5_VSNS_ENABLE |
0230         tas2770->v_sense_slot);
0231     if (ret < 0)
0232         return ret;
0233 
0234     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG6,
0235                         TAS2770_TDM_CFG_REG6_ISNS_MASK |
0236                         TAS2770_TDM_CFG_REG6_50_MASK,
0237                         TAS2770_TDM_CFG_REG6_ISNS_ENABLE |
0238                         tas2770->i_sense_slot);
0239     if (ret < 0)
0240         return ret;
0241 
0242     return 0;
0243 }
0244 
0245 static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
0246 {
0247     struct snd_soc_component *component = tas2770->component;
0248     int ramp_rate_val;
0249     int ret;
0250 
0251     switch (samplerate) {
0252     case 48000:
0253         ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_48KHZ |
0254                 TAS2770_TDM_CFG_REG0_31_44_1_48KHZ;
0255         break;
0256     case 44100:
0257         ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_44_1KHZ |
0258                 TAS2770_TDM_CFG_REG0_31_44_1_48KHZ;
0259         break;
0260     case 96000:
0261         ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_48KHZ |
0262                 TAS2770_TDM_CFG_REG0_31_88_2_96KHZ;
0263         break;
0264     case 88200:
0265         ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_44_1KHZ |
0266                 TAS2770_TDM_CFG_REG0_31_88_2_96KHZ;
0267         break;
0268     case 192000:
0269         ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_48KHZ |
0270                 TAS2770_TDM_CFG_REG0_31_176_4_192KHZ;
0271         break;
0272     case 176400:
0273         ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_44_1KHZ |
0274                 TAS2770_TDM_CFG_REG0_31_176_4_192KHZ;
0275         break;
0276     default:
0277         return -EINVAL;
0278     }
0279 
0280     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
0281                         TAS2770_TDM_CFG_REG0_SMP_MASK |
0282                         TAS2770_TDM_CFG_REG0_31_MASK,
0283                         ramp_rate_val);
0284     if (ret < 0)
0285         return ret;
0286 
0287     return 0;
0288 }
0289 
0290 static int tas2770_hw_params(struct snd_pcm_substream *substream,
0291                  struct snd_pcm_hw_params *params,
0292                  struct snd_soc_dai *dai)
0293 {
0294     struct snd_soc_component *component = dai->component;
0295     struct tas2770_priv *tas2770 =
0296             snd_soc_component_get_drvdata(component);
0297     int ret;
0298 
0299     ret = tas2770_set_bitwidth(tas2770, params_format(params));
0300     if (ret)
0301         return ret;
0302 
0303     return tas2770_set_samplerate(tas2770, params_rate(params));
0304 }
0305 
0306 static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0307 {
0308     struct snd_soc_component *component = dai->component;
0309     struct tas2770_priv *tas2770 =
0310             snd_soc_component_get_drvdata(component);
0311     u8 tdm_rx_start_slot = 0, invert_fpol = 0, fpol_preinv = 0, asi_cfg_1 = 0;
0312     int ret;
0313 
0314     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0315     case SND_SOC_DAIFMT_CBC_CFC:
0316         break;
0317     default:
0318         dev_err(tas2770->dev, "ASI invalid DAI clocking\n");
0319         return -EINVAL;
0320     }
0321 
0322     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0323     case SND_SOC_DAIFMT_NB_IF:
0324         invert_fpol = 1;
0325         fallthrough;
0326     case SND_SOC_DAIFMT_NB_NF:
0327         asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_RSING;
0328         break;
0329     case SND_SOC_DAIFMT_IB_IF:
0330         invert_fpol = 1;
0331         fallthrough;
0332     case SND_SOC_DAIFMT_IB_NF:
0333         asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_FALING;
0334         break;
0335     default:
0336         dev_err(tas2770->dev, "ASI format Inverse is not found\n");
0337         return -EINVAL;
0338     }
0339 
0340     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG1,
0341                         TAS2770_TDM_CFG_REG1_RX_MASK,
0342                         asi_cfg_1);
0343     if (ret < 0)
0344         return ret;
0345 
0346     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0347     case SND_SOC_DAIFMT_I2S:
0348         tdm_rx_start_slot = 1;
0349         fpol_preinv = 0;
0350         break;
0351     case SND_SOC_DAIFMT_DSP_A:
0352         tdm_rx_start_slot = 0;
0353         fpol_preinv = 1;
0354         break;
0355     case SND_SOC_DAIFMT_DSP_B:
0356         tdm_rx_start_slot = 1;
0357         fpol_preinv = 1;
0358         break;
0359     case SND_SOC_DAIFMT_LEFT_J:
0360         tdm_rx_start_slot = 0;
0361         fpol_preinv = 1;
0362         break;
0363     default:
0364         dev_err(tas2770->dev,
0365             "DAI Format is not found, fmt=0x%x\n", fmt);
0366         return -EINVAL;
0367     }
0368 
0369     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG1,
0370                         TAS2770_TDM_CFG_REG1_MASK,
0371                         (tdm_rx_start_slot << TAS2770_TDM_CFG_REG1_51_SHIFT));
0372     if (ret < 0)
0373         return ret;
0374 
0375     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
0376                         TAS2770_TDM_CFG_REG0_FPOL_MASK,
0377                         (fpol_preinv ^ invert_fpol)
0378                          ? TAS2770_TDM_CFG_REG0_FPOL_RSING
0379                          : TAS2770_TDM_CFG_REG0_FPOL_FALING);
0380     if (ret < 0)
0381         return ret;
0382 
0383     return 0;
0384 }
0385 
0386 static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai,
0387                 unsigned int tx_mask,
0388                 unsigned int rx_mask,
0389                 int slots, int slot_width)
0390 {
0391     struct snd_soc_component *component = dai->component;
0392     int left_slot, right_slot;
0393     int ret;
0394 
0395     if (tx_mask == 0 || rx_mask != 0)
0396         return -EINVAL;
0397 
0398     if (slots == 1) {
0399         if (tx_mask != 1)
0400             return -EINVAL;
0401 
0402         left_slot = 0;
0403         right_slot = 0;
0404     } else {
0405         left_slot = __ffs(tx_mask);
0406         tx_mask &= ~(1 << left_slot);
0407         if (tx_mask == 0) {
0408             right_slot = left_slot;
0409         } else {
0410             right_slot = __ffs(tx_mask);
0411             tx_mask &= ~(1 << right_slot);
0412         }
0413     }
0414 
0415     if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
0416         return -EINVAL;
0417 
0418     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG3,
0419                         TAS2770_TDM_CFG_REG3_30_MASK,
0420                         (left_slot << TAS2770_TDM_CFG_REG3_30_SHIFT));
0421     if (ret < 0)
0422         return ret;
0423     ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG3,
0424                         TAS2770_TDM_CFG_REG3_RXS_MASK,
0425                         (right_slot << TAS2770_TDM_CFG_REG3_RXS_SHIFT));
0426     if (ret < 0)
0427         return ret;
0428 
0429     switch (slot_width) {
0430     case 16:
0431         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
0432                             TAS2770_TDM_CFG_REG2_RXS_MASK,
0433                             TAS2770_TDM_CFG_REG2_RXS_16BITS);
0434         break;
0435     case 24:
0436         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
0437                             TAS2770_TDM_CFG_REG2_RXS_MASK,
0438                             TAS2770_TDM_CFG_REG2_RXS_24BITS);
0439         break;
0440     case 32:
0441         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
0442                             TAS2770_TDM_CFG_REG2_RXS_MASK,
0443                             TAS2770_TDM_CFG_REG2_RXS_32BITS);
0444         break;
0445     case 0:
0446         /* Do not change slot width */
0447         ret = 0;
0448         break;
0449     default:
0450         ret = -EINVAL;
0451     }
0452 
0453     if (ret < 0)
0454         return ret;
0455 
0456     return 0;
0457 }
0458 
0459 static const struct snd_soc_dai_ops tas2770_dai_ops = {
0460     .mute_stream = tas2770_mute,
0461     .hw_params  = tas2770_hw_params,
0462     .set_fmt    = tas2770_set_fmt,
0463     .set_tdm_slot = tas2770_set_dai_tdm_slot,
0464     .no_capture_mute = 1,
0465 };
0466 
0467 #define TAS2770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0468         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0469 
0470 #define TAS2770_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
0471                        SNDRV_PCM_RATE_96000 |\
0472                         SNDRV_PCM_RATE_192000\
0473                       )
0474 
0475 static struct snd_soc_dai_driver tas2770_dai_driver[] = {
0476     {
0477         .name = "tas2770 ASI1",
0478         .id = 0,
0479         .playback = {
0480             .stream_name    = "ASI1 Playback",
0481             .channels_min   = 1,
0482             .channels_max   = 2,
0483             .rates      = TAS2770_RATES,
0484             .formats    = TAS2770_FORMATS,
0485         },
0486         .capture = {
0487             .stream_name    = "ASI1 Capture",
0488             .channels_min   = 0,
0489             .channels_max   = 2,
0490             .rates          = TAS2770_RATES,
0491             .formats    = TAS2770_FORMATS,
0492         },
0493         .ops = &tas2770_dai_ops,
0494         .symmetric_rate = 1,
0495     },
0496 };
0497 
0498 static const struct regmap_config tas2770_i2c_regmap;
0499 
0500 static int tas2770_codec_probe(struct snd_soc_component *component)
0501 {
0502     struct tas2770_priv *tas2770 =
0503             snd_soc_component_get_drvdata(component);
0504 
0505     tas2770->component = component;
0506 
0507     if (tas2770->sdz_gpio) {
0508         gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
0509         usleep_range(1000, 2000);
0510     }
0511 
0512     tas2770_reset(tas2770);
0513     regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap);
0514 
0515     return 0;
0516 }
0517 
0518 static DECLARE_TLV_DB_SCALE(tas2770_digital_tlv, 1100, 50, 0);
0519 static DECLARE_TLV_DB_SCALE(tas2770_playback_volume, -12750, 50, 0);
0520 
0521 static const struct snd_kcontrol_new tas2770_snd_controls[] = {
0522     SOC_SINGLE_TLV("Speaker Playback Volume", TAS2770_PLAY_CFG_REG2,
0523                0, TAS2770_PLAY_CFG_REG2_VMAX, 1, tas2770_playback_volume),
0524     SOC_SINGLE_TLV("Amp Gain Volume", TAS2770_PLAY_CFG_REG0, 0, 0x14, 0,
0525                tas2770_digital_tlv),
0526 };
0527 
0528 static const struct snd_soc_component_driver soc_component_driver_tas2770 = {
0529     .probe          = tas2770_codec_probe,
0530     .suspend        = tas2770_codec_suspend,
0531     .resume         = tas2770_codec_resume,
0532     .controls       = tas2770_snd_controls,
0533     .num_controls       = ARRAY_SIZE(tas2770_snd_controls),
0534     .dapm_widgets       = tas2770_dapm_widgets,
0535     .num_dapm_widgets   = ARRAY_SIZE(tas2770_dapm_widgets),
0536     .dapm_routes        = tas2770_audio_map,
0537     .num_dapm_routes    = ARRAY_SIZE(tas2770_audio_map),
0538     .idle_bias_on       = 1,
0539     .endianness     = 1,
0540 };
0541 
0542 static int tas2770_register_codec(struct tas2770_priv *tas2770)
0543 {
0544     return devm_snd_soc_register_component(tas2770->dev,
0545         &soc_component_driver_tas2770,
0546         tas2770_dai_driver, ARRAY_SIZE(tas2770_dai_driver));
0547 }
0548 
0549 static const struct reg_default tas2770_reg_defaults[] = {
0550     { TAS2770_PAGE, 0x00 },
0551     { TAS2770_SW_RST, 0x00 },
0552     { TAS2770_PWR_CTRL, 0x0e },
0553     { TAS2770_PLAY_CFG_REG0, 0x10 },
0554     { TAS2770_PLAY_CFG_REG1, 0x01 },
0555     { TAS2770_PLAY_CFG_REG2, 0x00 },
0556     { TAS2770_MSC_CFG_REG0, 0x07 },
0557     { TAS2770_TDM_CFG_REG1, 0x02 },
0558     { TAS2770_TDM_CFG_REG2, 0x0a },
0559     { TAS2770_TDM_CFG_REG3, 0x10 },
0560     { TAS2770_INT_MASK_REG0, 0xfc },
0561     { TAS2770_INT_MASK_REG1, 0xb1 },
0562     { TAS2770_INT_CFG, 0x05 },
0563     { TAS2770_MISC_IRQ, 0x81 },
0564     { TAS2770_CLK_CGF, 0x0c },
0565 
0566 };
0567 
0568 static bool tas2770_volatile(struct device *dev, unsigned int reg)
0569 {
0570     switch (reg) {
0571     case TAS2770_PAGE: /* regmap implementation requires this */
0572     case TAS2770_SW_RST: /* always clears after write */
0573     case TAS2770_BO_PRV_REG0:/* has a self clearing bit */
0574     case TAS2770_LVE_INT_REG0:
0575     case TAS2770_LVE_INT_REG1:
0576     case TAS2770_LAT_INT_REG0:/* Sticky interrupt flags */
0577     case TAS2770_LAT_INT_REG1:/* Sticky interrupt flags */
0578     case TAS2770_VBAT_MSB:
0579     case TAS2770_VBAT_LSB:
0580     case TAS2770_TEMP_MSB:
0581     case TAS2770_TEMP_LSB:
0582         return true;
0583     }
0584 
0585     return false;
0586 }
0587 
0588 static bool tas2770_writeable(struct device *dev, unsigned int reg)
0589 {
0590     switch (reg) {
0591     case TAS2770_LVE_INT_REG0:
0592     case TAS2770_LVE_INT_REG1:
0593     case TAS2770_LAT_INT_REG0:
0594     case TAS2770_LAT_INT_REG1:
0595     case TAS2770_VBAT_MSB:
0596     case TAS2770_VBAT_LSB:
0597     case TAS2770_TEMP_MSB:
0598     case TAS2770_TEMP_LSB:
0599     case TAS2770_TDM_CLK_DETC:
0600     case TAS2770_REV_AND_GPID:
0601         return false;
0602     }
0603 
0604     return true;
0605 }
0606 
0607 static const struct regmap_range_cfg tas2770_regmap_ranges[] = {
0608     {
0609         .range_min = 0,
0610         .range_max = 1 * 128,
0611         .selector_reg = TAS2770_PAGE,
0612         .selector_mask = 0xff,
0613         .selector_shift = 0,
0614         .window_start = 0,
0615         .window_len = 128,
0616     },
0617 };
0618 
0619 static const struct regmap_config tas2770_i2c_regmap = {
0620     .reg_bits = 8,
0621     .val_bits = 8,
0622     .writeable_reg = tas2770_writeable,
0623     .volatile_reg = tas2770_volatile,
0624     .reg_defaults = tas2770_reg_defaults,
0625     .num_reg_defaults = ARRAY_SIZE(tas2770_reg_defaults),
0626     .cache_type = REGCACHE_RBTREE,
0627     .ranges = tas2770_regmap_ranges,
0628     .num_ranges = ARRAY_SIZE(tas2770_regmap_ranges),
0629     .max_register = 1 * 128,
0630 };
0631 
0632 static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
0633 {
0634     int rc = 0;
0635 
0636     rc = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
0637                       &tas2770->i_sense_slot);
0638     if (rc) {
0639         dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
0640              "ti,imon-slot-no");
0641 
0642         tas2770->i_sense_slot = 0;
0643     }
0644 
0645     rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
0646                       &tas2770->v_sense_slot);
0647     if (rc) {
0648         dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
0649              "ti,vmon-slot-no");
0650 
0651         tas2770->v_sense_slot = 2;
0652     }
0653 
0654     tas2770->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
0655     if (IS_ERR(tas2770->sdz_gpio)) {
0656         if (PTR_ERR(tas2770->sdz_gpio) == -EPROBE_DEFER)
0657             return -EPROBE_DEFER;
0658 
0659         tas2770->sdz_gpio = NULL;
0660     }
0661 
0662     return 0;
0663 }
0664 
0665 static int tas2770_i2c_probe(struct i2c_client *client)
0666 {
0667     struct tas2770_priv *tas2770;
0668     int result;
0669 
0670     tas2770 = devm_kzalloc(&client->dev, sizeof(struct tas2770_priv),
0671                    GFP_KERNEL);
0672     if (!tas2770)
0673         return -ENOMEM;
0674 
0675     tas2770->dev = &client->dev;
0676     i2c_set_clientdata(client, tas2770);
0677     dev_set_drvdata(&client->dev, tas2770);
0678 
0679     tas2770->regmap = devm_regmap_init_i2c(client, &tas2770_i2c_regmap);
0680     if (IS_ERR(tas2770->regmap)) {
0681         result = PTR_ERR(tas2770->regmap);
0682         dev_err(&client->dev, "Failed to allocate register map: %d\n",
0683             result);
0684         return result;
0685     }
0686 
0687     if (client->dev.of_node) {
0688         result = tas2770_parse_dt(&client->dev, tas2770);
0689         if (result) {
0690             dev_err(tas2770->dev, "%s: Failed to parse devicetree\n",
0691                 __func__);
0692             return result;
0693         }
0694     }
0695 
0696     tas2770->reset_gpio = devm_gpiod_get_optional(tas2770->dev, "reset",
0697                               GPIOD_OUT_HIGH);
0698     if (IS_ERR(tas2770->reset_gpio)) {
0699         if (PTR_ERR(tas2770->reset_gpio) == -EPROBE_DEFER) {
0700             tas2770->reset_gpio = NULL;
0701             return -EPROBE_DEFER;
0702         }
0703     }
0704 
0705     result = tas2770_register_codec(tas2770);
0706     if (result)
0707         dev_err(tas2770->dev, "Register codec failed.\n");
0708 
0709     return result;
0710 }
0711 
0712 static const struct i2c_device_id tas2770_i2c_id[] = {
0713     { "tas2770", 0},
0714     { }
0715 };
0716 MODULE_DEVICE_TABLE(i2c, tas2770_i2c_id);
0717 
0718 #if defined(CONFIG_OF)
0719 static const struct of_device_id tas2770_of_match[] = {
0720     { .compatible = "ti,tas2770" },
0721     {},
0722 };
0723 MODULE_DEVICE_TABLE(of, tas2770_of_match);
0724 #endif
0725 
0726 static struct i2c_driver tas2770_i2c_driver = {
0727     .driver = {
0728         .name   = "tas2770",
0729         .of_match_table = of_match_ptr(tas2770_of_match),
0730     },
0731     .probe_new  = tas2770_i2c_probe,
0732     .id_table   = tas2770_i2c_id,
0733 };
0734 module_i2c_driver(tas2770_i2c_driver);
0735 
0736 MODULE_AUTHOR("Shi Fu <shifu0704@thundersoft.com>");
0737 MODULE_DESCRIPTION("TAS2770 I2C Smart Amplifier driver");
0738 MODULE_LICENSE("GPL v2");