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