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