1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Driver for the Texas Instruments TAS2562 CODEC 4 // Copyright (C) 2019 Texas Instruments Inc. 5 6 7 #include <linux/module.h> 8 #include <linux/errno.h> 9 #include <linux/device.h> 10 #include <linux/i2c.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/regmap.h> 13 #include <linux/slab.h> 14 #include <linux/gpio/consumer.h> 15 #include <linux/regulator/consumer.h> 16 #include <linux/delay.h> 17 18 #include <sound/pcm.h> 19 #include <sound/pcm_params.h> 20 #include <sound/soc.h> 21 #include <sound/soc-dapm.h> 22 #include <sound/tlv.h> 23 24 #include "tas2562.h" 25 26 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 27 SNDRV_PCM_FORMAT_S32_LE) 28 29 /* DVC equation involves floating point math 30 * round(10^(volume in dB/20)*2^30) 31 * so create a lookup table for 2dB step 32 */ 33 static const unsigned int float_vol_db_lookup[] = { 34 0x00000d43, 0x000010b2, 0x00001505, 0x00001a67, 0x00002151, 35 0x000029f1, 0x000034cd, 0x00004279, 0x000053af, 0x0000695b, 36 0x0000695b, 0x0000a6fa, 0x0000d236, 0x000108a4, 0x00014d2a, 37 0x0001a36e, 0x00021008, 0x000298c0, 0x000344df, 0x00041d8f, 38 0x00052e5a, 0x000685c8, 0x00083621, 0x000a566d, 0x000d03a7, 39 0x0010624d, 0x0014a050, 0x0019f786, 0x0020b0bc, 0x0029279d, 40 0x0033cf8d, 0x004139d3, 0x00521d50, 0x00676044, 0x0082248a, 41 0x00a3d70a, 0x00ce4328, 0x0103ab3d, 0x0146e75d, 0x019b8c27, 42 0x02061b89, 0x028c423f, 0x03352529, 0x0409c2b0, 0x05156d68, 43 0x080e9f96, 0x0a24b062, 0x0cc509ab, 0x10137987, 0x143d1362, 44 0x197a967f, 0x2013739e, 0x28619ae9, 0x32d64617, 0x40000000 45 }; 46 47 struct tas2562_data { 48 struct snd_soc_component *component; 49 struct gpio_desc *sdz_gpio; 50 struct regmap *regmap; 51 struct device *dev; 52 struct i2c_client *client; 53 int v_sense_slot; 54 int i_sense_slot; 55 int volume_lvl; 56 int model_id; 57 bool dac_powered; 58 bool unmuted; 59 }; 60 61 enum tas256x_model { 62 TAS2562, 63 TAS2563, 64 TAS2564, 65 TAS2110, 66 }; 67 68 static int tas2562_set_samplerate(struct tas2562_data *tas2562, int samplerate) 69 { 70 int samp_rate; 71 int ramp_rate; 72 73 switch (samplerate) { 74 case 7350: 75 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 76 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ; 77 break; 78 case 8000: 79 ramp_rate = 0; 80 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ; 81 break; 82 case 14700: 83 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 84 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ; 85 break; 86 case 16000: 87 ramp_rate = 0; 88 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ; 89 break; 90 case 22050: 91 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 92 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ; 93 break; 94 case 24000: 95 ramp_rate = 0; 96 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ; 97 break; 98 case 29400: 99 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 100 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ; 101 break; 102 case 32000: 103 ramp_rate = 0; 104 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ; 105 break; 106 case 44100: 107 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 108 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ; 109 break; 110 case 48000: 111 ramp_rate = 0; 112 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ; 113 break; 114 case 88200: 115 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 116 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ; 117 break; 118 case 96000: 119 ramp_rate = 0; 120 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ; 121 break; 122 case 176400: 123 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1; 124 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ; 125 break; 126 case 192000: 127 ramp_rate = 0; 128 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ; 129 break; 130 default: 131 dev_info(tas2562->dev, "%s, unsupported sample rate, %d\n", 132 __func__, samplerate); 133 return -EINVAL; 134 } 135 136 snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG0, 137 TAS2562_TDM_CFG0_RAMPRATE_MASK, ramp_rate); 138 snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG0, 139 TAS2562_TDM_CFG0_SAMPRATE_MASK, samp_rate); 140 141 return 0; 142 } 143 144 static int tas2562_set_dai_tdm_slot(struct snd_soc_dai *dai, 145 unsigned int tx_mask, unsigned int rx_mask, 146 int slots, int slot_width) 147 { 148 struct snd_soc_component *component = dai->component; 149 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 150 int left_slot, right_slot; 151 int slots_cfg; 152 int ret; 153 154 if (!tx_mask) { 155 dev_err(component->dev, "tx masks must not be 0\n"); 156 return -EINVAL; 157 } 158 159 if (slots == 1) { 160 if (tx_mask != 1) 161 return -EINVAL; 162 163 left_slot = 0; 164 right_slot = 0; 165 } else { 166 left_slot = __ffs(tx_mask); 167 tx_mask &= ~(1 << left_slot); 168 if (tx_mask == 0) { 169 right_slot = left_slot; 170 } else { 171 right_slot = __ffs(tx_mask); 172 } 173 } 174 175 slots_cfg = (right_slot << TAS2562_RIGHT_SLOT_SHIFT) | left_slot; 176 177 ret = snd_soc_component_write(component, TAS2562_TDM_CFG3, slots_cfg); 178 if (ret < 0) 179 return ret; 180 181 switch (slot_width) { 182 case 16: 183 ret = snd_soc_component_update_bits(component, 184 TAS2562_TDM_CFG2, 185 TAS2562_TDM_CFG2_RXLEN_MASK, 186 TAS2562_TDM_CFG2_RXLEN_16B); 187 break; 188 case 24: 189 ret = snd_soc_component_update_bits(component, 190 TAS2562_TDM_CFG2, 191 TAS2562_TDM_CFG2_RXLEN_MASK, 192 TAS2562_TDM_CFG2_RXLEN_24B); 193 break; 194 case 32: 195 ret = snd_soc_component_update_bits(component, 196 TAS2562_TDM_CFG2, 197 TAS2562_TDM_CFG2_RXLEN_MASK, 198 TAS2562_TDM_CFG2_RXLEN_32B); 199 break; 200 201 case 0: 202 /* Do not change slot width */ 203 break; 204 default: 205 dev_err(tas2562->dev, "slot width not supported"); 206 ret = -EINVAL; 207 } 208 209 if (ret < 0) 210 return ret; 211 212 ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG5, 213 TAS2562_TDM_CFG5_VSNS_SLOT_MASK, 214 tas2562->v_sense_slot); 215 if (ret < 0) 216 return ret; 217 218 ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG6, 219 TAS2562_TDM_CFG6_ISNS_SLOT_MASK, 220 tas2562->i_sense_slot); 221 if (ret < 0) 222 return ret; 223 224 return 0; 225 } 226 227 static int tas2562_set_bitwidth(struct tas2562_data *tas2562, int bitwidth) 228 { 229 int ret; 230 int val; 231 int sense_en; 232 233 switch (bitwidth) { 234 case SNDRV_PCM_FORMAT_S16_LE: 235 snd_soc_component_update_bits(tas2562->component, 236 TAS2562_TDM_CFG2, 237 TAS2562_TDM_CFG2_RXWLEN_MASK, 238 TAS2562_TDM_CFG2_RXWLEN_16B); 239 break; 240 case SNDRV_PCM_FORMAT_S24_LE: 241 snd_soc_component_update_bits(tas2562->component, 242 TAS2562_TDM_CFG2, 243 TAS2562_TDM_CFG2_RXWLEN_MASK, 244 TAS2562_TDM_CFG2_RXWLEN_24B); 245 break; 246 case SNDRV_PCM_FORMAT_S32_LE: 247 snd_soc_component_update_bits(tas2562->component, 248 TAS2562_TDM_CFG2, 249 TAS2562_TDM_CFG2_RXWLEN_MASK, 250 TAS2562_TDM_CFG2_RXWLEN_32B); 251 break; 252 253 default: 254 dev_info(tas2562->dev, "Unsupported bitwidth format\n"); 255 return -EINVAL; 256 } 257 258 val = snd_soc_component_read(tas2562->component, TAS2562_PWR_CTRL); 259 if (val < 0) 260 return val; 261 262 if (val & (1 << TAS2562_VSENSE_POWER_EN)) 263 sense_en = 0; 264 else 265 sense_en = TAS2562_TDM_CFG5_VSNS_EN; 266 267 ret = snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG5, 268 TAS2562_TDM_CFG5_VSNS_EN, sense_en); 269 if (ret < 0) 270 return ret; 271 272 if (val & (1 << TAS2562_ISENSE_POWER_EN)) 273 sense_en = 0; 274 else 275 sense_en = TAS2562_TDM_CFG6_ISNS_EN; 276 277 ret = snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG6, 278 TAS2562_TDM_CFG6_ISNS_EN, sense_en); 279 if (ret < 0) 280 return ret; 281 282 return 0; 283 } 284 285 static int tas2562_hw_params(struct snd_pcm_substream *substream, 286 struct snd_pcm_hw_params *params, 287 struct snd_soc_dai *dai) 288 { 289 struct snd_soc_component *component = dai->component; 290 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 291 int ret; 292 293 ret = tas2562_set_bitwidth(tas2562, params_format(params)); 294 if (ret) { 295 dev_err(tas2562->dev, "set bitwidth failed, %d\n", ret); 296 return ret; 297 } 298 299 ret = tas2562_set_samplerate(tas2562, params_rate(params)); 300 if (ret) 301 dev_err(tas2562->dev, "set sample rate failed, %d\n", ret); 302 303 return ret; 304 } 305 306 static int tas2562_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 307 { 308 struct snd_soc_component *component = dai->component; 309 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 310 u8 asi_cfg_1 = 0; 311 u8 tdm_rx_start_slot = 0; 312 int ret; 313 314 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 315 case SND_SOC_DAIFMT_NB_NF: 316 asi_cfg_1 = 0; 317 break; 318 case SND_SOC_DAIFMT_IB_NF: 319 asi_cfg_1 |= TAS2562_TDM_CFG1_RX_FALLING; 320 break; 321 default: 322 dev_err(tas2562->dev, "ASI format Inverse is not found\n"); 323 return -EINVAL; 324 } 325 326 ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG1, 327 TAS2562_TDM_CFG1_RX_EDGE_MASK, 328 asi_cfg_1); 329 if (ret < 0) { 330 dev_err(tas2562->dev, "Failed to set RX edge\n"); 331 return ret; 332 } 333 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 334 case SND_SOC_DAIFMT_LEFT_J: 335 case SND_SOC_DAIFMT_DSP_B: 336 tdm_rx_start_slot = 0; 337 break; 338 case SND_SOC_DAIFMT_I2S: 339 case SND_SOC_DAIFMT_DSP_A: 340 tdm_rx_start_slot = 1; 341 break; 342 default: 343 dev_err(tas2562->dev, 344 "DAI Format is not found, fmt=0x%x\n", fmt); 345 return -EINVAL; 346 } 347 348 ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG1, 349 TAS2562_RX_OFF_MASK, (tdm_rx_start_slot << 1)); 350 if (ret < 0) 351 return ret; 352 353 return 0; 354 } 355 356 static int tas2562_update_pwr_ctrl(struct tas2562_data *tas2562) 357 { 358 struct snd_soc_component *component = tas2562->component; 359 unsigned int val; 360 int ret; 361 362 if (tas2562->dac_powered) 363 val = tas2562->unmuted ? 364 TAS2562_ACTIVE : TAS2562_MUTE; 365 else 366 val = TAS2562_SHUTDOWN; 367 368 ret = snd_soc_component_update_bits(component, TAS2562_PWR_CTRL, 369 TAS2562_MODE_MASK, val); 370 if (ret < 0) 371 return ret; 372 373 return 0; 374 } 375 376 static int tas2562_mute(struct snd_soc_dai *dai, int mute, int direction) 377 { 378 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(dai->component); 379 380 tas2562->unmuted = !mute; 381 return tas2562_update_pwr_ctrl(tas2562); 382 } 383 384 static int tas2562_codec_probe(struct snd_soc_component *component) 385 { 386 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 387 388 tas2562->component = component; 389 390 if (tas2562->sdz_gpio) 391 gpiod_set_value_cansleep(tas2562->sdz_gpio, 1); 392 393 return 0; 394 } 395 396 #ifdef CONFIG_PM 397 static int tas2562_suspend(struct snd_soc_component *component) 398 { 399 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 400 401 regcache_cache_only(tas2562->regmap, true); 402 regcache_mark_dirty(tas2562->regmap); 403 404 if (tas2562->sdz_gpio) 405 gpiod_set_value_cansleep(tas2562->sdz_gpio, 0); 406 407 return 0; 408 } 409 410 static int tas2562_resume(struct snd_soc_component *component) 411 { 412 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 413 414 if (tas2562->sdz_gpio) 415 gpiod_set_value_cansleep(tas2562->sdz_gpio, 1); 416 417 regcache_cache_only(tas2562->regmap, false); 418 419 return regcache_sync(tas2562->regmap); 420 } 421 #else 422 #define tas2562_suspend NULL 423 #define tas2562_resume NULL 424 #endif 425 426 static const char * const tas2562_ASI1_src[] = { 427 "I2C offset", "Left", "Right", "LeftRightDiv2", 428 }; 429 430 static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_enum, TAS2562_TDM_CFG2, 4, 431 tas2562_ASI1_src); 432 433 static const struct snd_kcontrol_new tas2562_asi1_mux = 434 SOC_DAPM_ENUM("ASI1 Source", tas2562_ASI1_src_enum); 435 436 static int tas2562_dac_event(struct snd_soc_dapm_widget *w, 437 struct snd_kcontrol *kcontrol, int event) 438 { 439 struct snd_soc_component *component = 440 snd_soc_dapm_to_component(w->dapm); 441 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 442 int ret = 0; 443 444 switch (event) { 445 case SND_SOC_DAPM_POST_PMU: 446 tas2562->dac_powered = true; 447 ret = tas2562_update_pwr_ctrl(tas2562); 448 break; 449 case SND_SOC_DAPM_PRE_PMD: 450 tas2562->dac_powered = false; 451 ret = tas2562_update_pwr_ctrl(tas2562); 452 break; 453 default: 454 dev_err(tas2562->dev, "Not supported evevt\n"); 455 return -EINVAL; 456 } 457 458 return ret; 459 } 460 461 static int tas2562_volume_control_get(struct snd_kcontrol *kcontrol, 462 struct snd_ctl_elem_value *ucontrol) 463 { 464 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 465 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 466 467 ucontrol->value.integer.value[0] = tas2562->volume_lvl; 468 return 0; 469 } 470 471 static int tas2562_volume_control_put(struct snd_kcontrol *kcontrol, 472 struct snd_ctl_elem_value *ucontrol) 473 { 474 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 475 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 476 int ret; 477 u32 reg_val; 478 479 reg_val = float_vol_db_lookup[ucontrol->value.integer.value[0]/2]; 480 ret = snd_soc_component_write(component, TAS2562_DVC_CFG4, 481 (reg_val & 0xff)); 482 if (ret) 483 return ret; 484 ret = snd_soc_component_write(component, TAS2562_DVC_CFG3, 485 ((reg_val >> 8) & 0xff)); 486 if (ret) 487 return ret; 488 ret = snd_soc_component_write(component, TAS2562_DVC_CFG2, 489 ((reg_val >> 16) & 0xff)); 490 if (ret) 491 return ret; 492 ret = snd_soc_component_write(component, TAS2562_DVC_CFG1, 493 ((reg_val >> 24) & 0xff)); 494 if (ret) 495 return ret; 496 497 tas2562->volume_lvl = ucontrol->value.integer.value[0]; 498 499 return 0; 500 } 501 502 /* Digital Volume Control. From 0 dB to -110 dB in 1 dB steps */ 503 static const DECLARE_TLV_DB_SCALE(dvc_tlv, -11000, 100, 0); 504 505 static DECLARE_TLV_DB_SCALE(tas2562_dac_tlv, 850, 50, 0); 506 507 static const struct snd_kcontrol_new isense_switch = 508 SOC_DAPM_SINGLE("Switch", TAS2562_PWR_CTRL, TAS2562_ISENSE_POWER_EN, 509 1, 1); 510 511 static const struct snd_kcontrol_new vsense_switch = 512 SOC_DAPM_SINGLE("Switch", TAS2562_PWR_CTRL, TAS2562_VSENSE_POWER_EN, 513 1, 1); 514 515 static const struct snd_kcontrol_new tas2562_snd_controls[] = { 516 SOC_SINGLE_TLV("Amp Gain Volume", TAS2562_PB_CFG1, 1, 0x1c, 0, 517 tas2562_dac_tlv), 518 { 519 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 520 .name = "Digital Volume Control", 521 .index = 0, 522 .tlv.p = dvc_tlv, 523 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, 524 .info = snd_soc_info_volsw, 525 .get = tas2562_volume_control_get, 526 .put = tas2562_volume_control_put, 527 .private_value = SOC_SINGLE_VALUE(TAS2562_DVC_CFG1, 0, 110, 0, 0), 528 }, 529 }; 530 531 static const struct snd_soc_dapm_widget tas2110_dapm_widgets[] = { 532 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), 533 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2562_asi1_mux), 534 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event, 535 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 536 SND_SOC_DAPM_OUTPUT("OUT"), 537 }; 538 539 static const struct snd_soc_dapm_route tas2110_audio_map[] = { 540 {"ASI1 Sel", "I2C offset", "ASI1"}, 541 {"ASI1 Sel", "Left", "ASI1"}, 542 {"ASI1 Sel", "Right", "ASI1"}, 543 {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, 544 { "DAC", NULL, "ASI1 Sel" }, 545 { "OUT", NULL, "DAC" }, 546 }; 547 548 static const struct snd_soc_component_driver soc_component_dev_tas2110 = { 549 .probe = tas2562_codec_probe, 550 .suspend = tas2562_suspend, 551 .resume = tas2562_resume, 552 .controls = tas2562_snd_controls, 553 .num_controls = ARRAY_SIZE(tas2562_snd_controls), 554 .dapm_widgets = tas2110_dapm_widgets, 555 .num_dapm_widgets = ARRAY_SIZE(tas2110_dapm_widgets), 556 .dapm_routes = tas2110_audio_map, 557 .num_dapm_routes = ARRAY_SIZE(tas2110_audio_map), 558 .idle_bias_on = 1, 559 .use_pmdown_time = 1, 560 .endianness = 1, 561 }; 562 563 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = { 564 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), 565 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2562_asi1_mux), 566 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event, 567 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 568 SND_SOC_DAPM_SWITCH("ISENSE", TAS2562_PWR_CTRL, 3, 1, &isense_switch), 569 SND_SOC_DAPM_SWITCH("VSENSE", TAS2562_PWR_CTRL, 2, 1, &vsense_switch), 570 SND_SOC_DAPM_SIGGEN("VMON"), 571 SND_SOC_DAPM_SIGGEN("IMON"), 572 SND_SOC_DAPM_OUTPUT("OUT"), 573 }; 574 575 static const struct snd_soc_dapm_route tas2562_audio_map[] = { 576 {"ASI1 Sel", "I2C offset", "ASI1"}, 577 {"ASI1 Sel", "Left", "ASI1"}, 578 {"ASI1 Sel", "Right", "ASI1"}, 579 {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, 580 { "DAC", NULL, "ASI1 Sel" }, 581 { "OUT", NULL, "DAC" }, 582 {"ISENSE", "Switch", "IMON"}, 583 {"VSENSE", "Switch", "VMON"}, 584 }; 585 586 static const struct snd_soc_component_driver soc_component_dev_tas2562 = { 587 .probe = tas2562_codec_probe, 588 .suspend = tas2562_suspend, 589 .resume = tas2562_resume, 590 .controls = tas2562_snd_controls, 591 .num_controls = ARRAY_SIZE(tas2562_snd_controls), 592 .dapm_widgets = tas2562_dapm_widgets, 593 .num_dapm_widgets = ARRAY_SIZE(tas2562_dapm_widgets), 594 .dapm_routes = tas2562_audio_map, 595 .num_dapm_routes = ARRAY_SIZE(tas2562_audio_map), 596 .idle_bias_on = 1, 597 .use_pmdown_time = 1, 598 .endianness = 1, 599 }; 600 601 static const struct snd_soc_dai_ops tas2562_speaker_dai_ops = { 602 .hw_params = tas2562_hw_params, 603 .set_fmt = tas2562_set_dai_fmt, 604 .set_tdm_slot = tas2562_set_dai_tdm_slot, 605 .mute_stream = tas2562_mute, 606 .no_capture_mute = 1, 607 }; 608 609 static struct snd_soc_dai_driver tas2562_dai[] = { 610 { 611 .name = "tas2562-amplifier", 612 .id = 0, 613 .playback = { 614 .stream_name = "ASI1 Playback", 615 .channels_min = 2, 616 .channels_max = 2, 617 .rates = SNDRV_PCM_RATE_8000_192000, 618 .formats = TAS2562_FORMATS, 619 }, 620 .capture = { 621 .stream_name = "ASI1 Capture", 622 .channels_min = 0, 623 .channels_max = 2, 624 .rates = SNDRV_PCM_RATE_8000_192000, 625 .formats = TAS2562_FORMATS, 626 }, 627 .ops = &tas2562_speaker_dai_ops, 628 }, 629 }; 630 631 static const struct regmap_range_cfg tas2562_ranges[] = { 632 { 633 .range_min = 0, 634 .range_max = 5 * 128, 635 .selector_reg = TAS2562_PAGE_CTRL, 636 .selector_mask = 0xff, 637 .selector_shift = 0, 638 .window_start = 0, 639 .window_len = 128, 640 }, 641 }; 642 643 static const struct reg_default tas2562_reg_defaults[] = { 644 { TAS2562_PAGE_CTRL, 0x00 }, 645 { TAS2562_SW_RESET, 0x00 }, 646 { TAS2562_PWR_CTRL, 0x0e }, 647 { TAS2562_PB_CFG1, 0x20 }, 648 { TAS2562_TDM_CFG0, 0x09 }, 649 { TAS2562_TDM_CFG1, 0x02 }, 650 { TAS2562_DVC_CFG1, 0x40 }, 651 { TAS2562_DVC_CFG2, 0x40 }, 652 { TAS2562_DVC_CFG3, 0x00 }, 653 { TAS2562_DVC_CFG4, 0x00 }, 654 }; 655 656 static const struct regmap_config tas2562_regmap_config = { 657 .reg_bits = 8, 658 .val_bits = 8, 659 660 .max_register = 5 * 128, 661 .cache_type = REGCACHE_RBTREE, 662 .reg_defaults = tas2562_reg_defaults, 663 .num_reg_defaults = ARRAY_SIZE(tas2562_reg_defaults), 664 .ranges = tas2562_ranges, 665 .num_ranges = ARRAY_SIZE(tas2562_ranges), 666 }; 667 668 static int tas2562_parse_dt(struct tas2562_data *tas2562) 669 { 670 struct device *dev = tas2562->dev; 671 int ret = 0; 672 673 tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH); 674 if (IS_ERR(tas2562->sdz_gpio)) { 675 if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER) 676 return -EPROBE_DEFER; 677 678 tas2562->sdz_gpio = NULL; 679 } 680 681 /* 682 * The shut-down property is deprecated but needs to be checked for 683 * backwards compatibility. 684 */ 685 if (tas2562->sdz_gpio == NULL) { 686 tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down", 687 GPIOD_OUT_HIGH); 688 if (IS_ERR(tas2562->sdz_gpio)) 689 if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER) 690 return -EPROBE_DEFER; 691 692 tas2562->sdz_gpio = NULL; 693 } 694 695 if (tas2562->model_id == TAS2110) 696 return ret; 697 698 ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", 699 &tas2562->i_sense_slot); 700 if (ret) { 701 dev_err(dev, "Property %s is missing setting default slot\n", 702 "ti,imon-slot-no"); 703 tas2562->i_sense_slot = 0; 704 } 705 706 707 ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", 708 &tas2562->v_sense_slot); 709 if (ret) { 710 dev_info(dev, "Property %s is missing setting default slot\n", 711 "ti,vmon-slot-no"); 712 tas2562->v_sense_slot = 2; 713 } 714 715 if (tas2562->v_sense_slot < tas2562->i_sense_slot) { 716 dev_err(dev, "Vsense slot must be greater than Isense slot\n"); 717 return -EINVAL; 718 } 719 720 return ret; 721 } 722 723 static const struct i2c_device_id tas2562_id[] = { 724 { "tas2562", TAS2562 }, 725 { "tas2563", TAS2563 }, 726 { "tas2564", TAS2564 }, 727 { "tas2110", TAS2110 }, 728 { } 729 }; 730 MODULE_DEVICE_TABLE(i2c, tas2562_id); 731 732 static int tas2562_probe(struct i2c_client *client) 733 { 734 struct device *dev = &client->dev; 735 struct tas2562_data *data; 736 int ret; 737 const struct i2c_device_id *id; 738 739 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 740 if (!data) 741 return -ENOMEM; 742 743 id = i2c_match_id(tas2562_id, client); 744 data->client = client; 745 data->dev = &client->dev; 746 data->model_id = id->driver_data; 747 748 tas2562_parse_dt(data); 749 750 data->regmap = devm_regmap_init_i2c(client, &tas2562_regmap_config); 751 if (IS_ERR(data->regmap)) { 752 ret = PTR_ERR(data->regmap); 753 dev_err(dev, "failed to allocate register map: %d\n", ret); 754 return ret; 755 } 756 757 dev_set_drvdata(&client->dev, data); 758 759 if (data->model_id == TAS2110) 760 return devm_snd_soc_register_component(dev, 761 &soc_component_dev_tas2110, 762 tas2562_dai, 763 ARRAY_SIZE(tas2562_dai)); 764 765 return devm_snd_soc_register_component(dev, &soc_component_dev_tas2562, 766 tas2562_dai, 767 ARRAY_SIZE(tas2562_dai)); 768 769 } 770 771 #ifdef CONFIG_OF 772 static const struct of_device_id tas2562_of_match[] = { 773 { .compatible = "ti,tas2562", }, 774 { .compatible = "ti,tas2563", }, 775 { .compatible = "ti,tas2564", }, 776 { .compatible = "ti,tas2110", }, 777 { }, 778 }; 779 MODULE_DEVICE_TABLE(of, tas2562_of_match); 780 #endif 781 782 static struct i2c_driver tas2562_i2c_driver = { 783 .driver = { 784 .name = "tas2562", 785 .of_match_table = of_match_ptr(tas2562_of_match), 786 }, 787 .probe_new = tas2562_probe, 788 .id_table = tas2562_id, 789 }; 790 791 module_i2c_driver(tas2562_i2c_driver); 792 793 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 794 MODULE_DESCRIPTION("TAS2562 Audio amplifier driver"); 795 MODULE_LICENSE("GPL"); 796