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