0001
0002
0003
0004
0005
0006
0007
0008
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
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:
0572 case TAS2770_SW_RST:
0573 case TAS2770_BO_PRV_REG0:
0574 case TAS2770_LVE_INT_REG0:
0575 case TAS2770_LVE_INT_REG1:
0576 case TAS2770_LAT_INT_REG0:
0577 case TAS2770_LAT_INT_REG1:
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");