0001
0002
0003
0004
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
0030
0031
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
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
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
0715
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");