1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Driver for the Texas Instruments TAS2764 CODEC 4 // Copyright (C) 2020 Texas Instruments Inc. 5 6 #include <linux/module.h> 7 #include <linux/moduleparam.h> 8 #include <linux/err.h> 9 #include <linux/init.h> 10 #include <linux/delay.h> 11 #include <linux/pm.h> 12 #include <linux/i2c.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/regulator/consumer.h> 15 #include <linux/regmap.h> 16 #include <linux/of.h> 17 #include <linux/slab.h> 18 #include <sound/soc.h> 19 #include <sound/pcm.h> 20 #include <sound/pcm_params.h> 21 #include <sound/initval.h> 22 #include <sound/tlv.h> 23 24 #include "tas2764.h" 25 26 struct tas2764_priv { 27 struct snd_soc_component *component; 28 struct gpio_desc *reset_gpio; 29 struct gpio_desc *sdz_gpio; 30 struct regmap *regmap; 31 struct device *dev; 32 int irq; 33 34 int v_sense_slot; 35 int i_sense_slot; 36 37 bool dac_powered; 38 bool unmuted; 39 }; 40 41 static const char *tas2764_int_ltch0_msgs[8] = { 42 "fault: over temperature", /* INT_LTCH0 & BIT(0) */ 43 "fault: over current", 44 "fault: bad TDM clock", 45 "limiter active", 46 "fault: PVDD below limiter inflection point", 47 "fault: limiter max attenuation", 48 "fault: BOP infinite hold", 49 "fault: BOP mute", /* INT_LTCH0 & BIT(7) */ 50 }; 51 52 static const unsigned int tas2764_int_readout_regs[6] = { 53 TAS2764_INT_LTCH0, 54 TAS2764_INT_LTCH1, 55 TAS2764_INT_LTCH1_0, 56 TAS2764_INT_LTCH2, 57 TAS2764_INT_LTCH3, 58 TAS2764_INT_LTCH4, 59 }; 60 61 static irqreturn_t tas2764_irq(int irq, void *data) 62 { 63 struct tas2764_priv *tas2764 = data; 64 u8 latched[6] = {0, 0, 0, 0, 0, 0}; 65 int ret = IRQ_NONE; 66 int i; 67 68 for (i = 0; i < ARRAY_SIZE(latched); i++) 69 latched[i] = snd_soc_component_read(tas2764->component, 70 tas2764_int_readout_regs[i]); 71 72 for (i = 0; i < 8; i++) { 73 if (latched[0] & BIT(i)) { 74 dev_crit_ratelimited(tas2764->dev, "%s\n", 75 tas2764_int_ltch0_msgs[i]); 76 ret = IRQ_HANDLED; 77 } 78 } 79 80 if (latched[0]) { 81 dev_err_ratelimited(tas2764->dev, "other context to the fault: %02x,%02x,%02x,%02x,%02x", 82 latched[1], latched[2], latched[3], latched[4], latched[5]); 83 snd_soc_component_update_bits(tas2764->component, 84 TAS2764_INT_CLK_CFG, 85 TAS2764_INT_CLK_CFG_IRQZ_CLR, 86 TAS2764_INT_CLK_CFG_IRQZ_CLR); 87 } 88 89 return ret; 90 } 91 92 static void tas2764_reset(struct tas2764_priv *tas2764) 93 { 94 if (tas2764->reset_gpio) { 95 gpiod_set_value_cansleep(tas2764->reset_gpio, 0); 96 msleep(20); 97 gpiod_set_value_cansleep(tas2764->reset_gpio, 1); 98 usleep_range(1000, 2000); 99 } 100 101 snd_soc_component_write(tas2764->component, TAS2764_SW_RST, 102 TAS2764_RST); 103 usleep_range(1000, 2000); 104 } 105 106 static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764) 107 { 108 struct snd_soc_component *component = tas2764->component; 109 unsigned int val; 110 int ret; 111 112 if (tas2764->dac_powered) 113 val = tas2764->unmuted ? 114 TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE; 115 else 116 val = TAS2764_PWR_CTRL_SHUTDOWN; 117 118 ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, 119 TAS2764_PWR_CTRL_MASK, val); 120 if (ret < 0) 121 return ret; 122 123 return 0; 124 } 125 126 #ifdef CONFIG_PM 127 static int tas2764_codec_suspend(struct snd_soc_component *component) 128 { 129 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 130 int ret; 131 132 ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, 133 TAS2764_PWR_CTRL_MASK, 134 TAS2764_PWR_CTRL_SHUTDOWN); 135 136 if (ret < 0) 137 return ret; 138 139 if (tas2764->sdz_gpio) 140 gpiod_set_value_cansleep(tas2764->sdz_gpio, 0); 141 142 regcache_cache_only(tas2764->regmap, true); 143 regcache_mark_dirty(tas2764->regmap); 144 145 return 0; 146 } 147 148 static int tas2764_codec_resume(struct snd_soc_component *component) 149 { 150 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 151 int ret; 152 153 if (tas2764->sdz_gpio) { 154 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1); 155 usleep_range(1000, 2000); 156 } 157 158 ret = tas2764_update_pwr_ctrl(tas2764); 159 160 if (ret < 0) 161 return ret; 162 163 regcache_cache_only(tas2764->regmap, false); 164 165 return regcache_sync(tas2764->regmap); 166 } 167 #else 168 #define tas2764_codec_suspend NULL 169 #define tas2764_codec_resume NULL 170 #endif 171 172 static const char * const tas2764_ASI1_src[] = { 173 "I2C offset", "Left", "Right", "LeftRightDiv2", 174 }; 175 176 static SOC_ENUM_SINGLE_DECL( 177 tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, TAS2764_TDM_CFG2_SCFG_SHIFT, 178 tas2764_ASI1_src); 179 180 static const struct snd_kcontrol_new tas2764_asi1_mux = 181 SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum); 182 183 static int tas2764_dac_event(struct snd_soc_dapm_widget *w, 184 struct snd_kcontrol *kcontrol, int event) 185 { 186 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 187 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 188 int ret; 189 190 switch (event) { 191 case SND_SOC_DAPM_POST_PMU: 192 tas2764->dac_powered = true; 193 ret = tas2764_update_pwr_ctrl(tas2764); 194 break; 195 case SND_SOC_DAPM_PRE_PMD: 196 tas2764->dac_powered = false; 197 ret = tas2764_update_pwr_ctrl(tas2764); 198 break; 199 default: 200 dev_err(tas2764->dev, "Unsupported event\n"); 201 return -EINVAL; 202 } 203 204 if (ret < 0) 205 return ret; 206 207 return 0; 208 } 209 210 static const struct snd_kcontrol_new isense_switch = 211 SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1); 212 static const struct snd_kcontrol_new vsense_switch = 213 SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 1, 1); 214 215 static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = { 216 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), 217 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2764_asi1_mux), 218 SND_SOC_DAPM_SWITCH("ISENSE", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 219 1, &isense_switch), 220 SND_SOC_DAPM_SWITCH("VSENSE", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 221 1, &vsense_switch), 222 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2764_dac_event, 223 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 224 SND_SOC_DAPM_OUTPUT("OUT"), 225 SND_SOC_DAPM_SIGGEN("VMON"), 226 SND_SOC_DAPM_SIGGEN("IMON") 227 }; 228 229 static const struct snd_soc_dapm_route tas2764_audio_map[] = { 230 {"ASI1 Sel", "I2C offset", "ASI1"}, 231 {"ASI1 Sel", "Left", "ASI1"}, 232 {"ASI1 Sel", "Right", "ASI1"}, 233 {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, 234 {"DAC", NULL, "ASI1 Sel"}, 235 {"OUT", NULL, "DAC"}, 236 {"ISENSE", "Switch", "IMON"}, 237 {"VSENSE", "Switch", "VMON"}, 238 }; 239 240 static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) 241 { 242 struct tas2764_priv *tas2764 = 243 snd_soc_component_get_drvdata(dai->component); 244 245 tas2764->unmuted = !mute; 246 return tas2764_update_pwr_ctrl(tas2764); 247 } 248 249 static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth) 250 { 251 struct snd_soc_component *component = tas2764->component; 252 int sense_en; 253 int val; 254 int ret; 255 256 switch (bitwidth) { 257 case SNDRV_PCM_FORMAT_S16_LE: 258 ret = snd_soc_component_update_bits(component, 259 TAS2764_TDM_CFG2, 260 TAS2764_TDM_CFG2_RXW_MASK, 261 TAS2764_TDM_CFG2_RXW_16BITS); 262 break; 263 case SNDRV_PCM_FORMAT_S24_LE: 264 ret = snd_soc_component_update_bits(component, 265 TAS2764_TDM_CFG2, 266 TAS2764_TDM_CFG2_RXW_MASK, 267 TAS2764_TDM_CFG2_RXW_24BITS); 268 break; 269 case SNDRV_PCM_FORMAT_S32_LE: 270 ret = snd_soc_component_update_bits(component, 271 TAS2764_TDM_CFG2, 272 TAS2764_TDM_CFG2_RXW_MASK, 273 TAS2764_TDM_CFG2_RXW_32BITS); 274 break; 275 276 default: 277 return -EINVAL; 278 } 279 280 if (ret < 0) 281 return ret; 282 283 val = snd_soc_component_read(tas2764->component, TAS2764_PWR_CTRL); 284 if (val < 0) 285 return val; 286 287 if (val & (1 << TAS2764_VSENSE_POWER_EN)) 288 sense_en = 0; 289 else 290 sense_en = TAS2764_TDM_CFG5_VSNS_ENABLE; 291 292 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5, 293 TAS2764_TDM_CFG5_VSNS_ENABLE, 294 sense_en); 295 if (ret < 0) 296 return ret; 297 298 if (val & (1 << TAS2764_ISENSE_POWER_EN)) 299 sense_en = 0; 300 else 301 sense_en = TAS2764_TDM_CFG6_ISNS_ENABLE; 302 303 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6, 304 TAS2764_TDM_CFG6_ISNS_ENABLE, 305 sense_en); 306 if (ret < 0) 307 return ret; 308 309 return 0; 310 } 311 312 static int tas2764_set_samplerate(struct tas2764_priv *tas2764, int samplerate) 313 { 314 struct snd_soc_component *component = tas2764->component; 315 int ramp_rate_val; 316 int ret; 317 318 switch (samplerate) { 319 case 48000: 320 ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ | 321 TAS2764_TDM_CFG0_44_1_48KHZ; 322 break; 323 case 44100: 324 ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ | 325 TAS2764_TDM_CFG0_44_1_48KHZ; 326 break; 327 case 96000: 328 ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ | 329 TAS2764_TDM_CFG0_88_2_96KHZ; 330 break; 331 case 88200: 332 ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ | 333 TAS2764_TDM_CFG0_88_2_96KHZ; 334 break; 335 default: 336 return -EINVAL; 337 } 338 339 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0, 340 TAS2764_TDM_CFG0_SMP_MASK | 341 TAS2764_TDM_CFG0_MASK, 342 ramp_rate_val); 343 if (ret < 0) 344 return ret; 345 346 return 0; 347 } 348 349 static int tas2764_hw_params(struct snd_pcm_substream *substream, 350 struct snd_pcm_hw_params *params, 351 struct snd_soc_dai *dai) 352 { 353 struct snd_soc_component *component = dai->component; 354 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 355 int ret; 356 357 ret = tas2764_set_bitwidth(tas2764, params_format(params)); 358 if (ret < 0) 359 return ret; 360 361 return tas2764_set_samplerate(tas2764, params_rate(params)); 362 } 363 364 static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 365 { 366 struct snd_soc_component *component = dai->component; 367 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 368 u8 tdm_rx_start_slot = 0, asi_cfg_0 = 0, asi_cfg_1 = 0; 369 int ret; 370 371 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 372 case SND_SOC_DAIFMT_NB_IF: 373 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 374 fallthrough; 375 case SND_SOC_DAIFMT_NB_NF: 376 asi_cfg_1 = TAS2764_TDM_CFG1_RX_RISING; 377 break; 378 case SND_SOC_DAIFMT_IB_IF: 379 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 380 fallthrough; 381 case SND_SOC_DAIFMT_IB_NF: 382 asi_cfg_1 = TAS2764_TDM_CFG1_RX_FALLING; 383 break; 384 } 385 386 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1, 387 TAS2764_TDM_CFG1_RX_MASK, 388 asi_cfg_1); 389 if (ret < 0) 390 return ret; 391 392 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 393 case SND_SOC_DAIFMT_I2S: 394 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 395 fallthrough; 396 case SND_SOC_DAIFMT_DSP_A: 397 tdm_rx_start_slot = 1; 398 break; 399 case SND_SOC_DAIFMT_DSP_B: 400 case SND_SOC_DAIFMT_LEFT_J: 401 tdm_rx_start_slot = 0; 402 break; 403 default: 404 dev_err(tas2764->dev, 405 "DAI Format is not found, fmt=0x%x\n", fmt); 406 return -EINVAL; 407 } 408 409 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0, 410 TAS2764_TDM_CFG0_FRAME_START, 411 asi_cfg_0); 412 if (ret < 0) 413 return ret; 414 415 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1, 416 TAS2764_TDM_CFG1_MASK, 417 (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT)); 418 if (ret < 0) 419 return ret; 420 421 return 0; 422 } 423 424 static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai, 425 unsigned int tx_mask, 426 unsigned int rx_mask, 427 int slots, int slot_width) 428 { 429 struct snd_soc_component *component = dai->component; 430 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 431 int left_slot, right_slot; 432 int slots_cfg; 433 int slot_size; 434 int ret; 435 436 if (tx_mask == 0 || rx_mask != 0) 437 return -EINVAL; 438 439 left_slot = __ffs(tx_mask); 440 tx_mask &= ~(1 << left_slot); 441 if (tx_mask == 0) { 442 right_slot = left_slot; 443 } else { 444 right_slot = __ffs(tx_mask); 445 tx_mask &= ~(1 << right_slot); 446 } 447 448 if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) 449 return -EINVAL; 450 451 slots_cfg = (right_slot << TAS2764_TDM_CFG3_RXS_SHIFT) | left_slot; 452 453 ret = snd_soc_component_write(component, TAS2764_TDM_CFG3, slots_cfg); 454 if (ret) 455 return ret; 456 457 switch (slot_width) { 458 case 16: 459 slot_size = TAS2764_TDM_CFG2_RXS_16BITS; 460 break; 461 case 24: 462 slot_size = TAS2764_TDM_CFG2_RXS_24BITS; 463 break; 464 case 32: 465 slot_size = TAS2764_TDM_CFG2_RXS_32BITS; 466 break; 467 default: 468 return -EINVAL; 469 } 470 471 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG2, 472 TAS2764_TDM_CFG2_RXS_MASK, 473 slot_size); 474 if (ret < 0) 475 return ret; 476 477 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG5, 478 TAS2764_TDM_CFG5_50_MASK, 479 tas2764->v_sense_slot); 480 if (ret < 0) 481 return ret; 482 483 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG6, 484 TAS2764_TDM_CFG6_50_MASK, 485 tas2764->i_sense_slot); 486 if (ret < 0) 487 return ret; 488 489 return 0; 490 } 491 492 static const struct snd_soc_dai_ops tas2764_dai_ops = { 493 .mute_stream = tas2764_mute, 494 .hw_params = tas2764_hw_params, 495 .set_fmt = tas2764_set_fmt, 496 .set_tdm_slot = tas2764_set_dai_tdm_slot, 497 .no_capture_mute = 1, 498 }; 499 500 #define TAS2764_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 501 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 502 503 #define TAS2764_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 504 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) 505 506 static struct snd_soc_dai_driver tas2764_dai_driver[] = { 507 { 508 .name = "tas2764 ASI1", 509 .id = 0, 510 .playback = { 511 .stream_name = "ASI1 Playback", 512 .channels_min = 1, 513 .channels_max = 2, 514 .rates = TAS2764_RATES, 515 .formats = TAS2764_FORMATS, 516 }, 517 .capture = { 518 .stream_name = "ASI1 Capture", 519 .channels_min = 0, 520 .channels_max = 2, 521 .rates = TAS2764_RATES, 522 .formats = TAS2764_FORMATS, 523 }, 524 .ops = &tas2764_dai_ops, 525 .symmetric_rate = 1, 526 }, 527 }; 528 529 static int tas2764_codec_probe(struct snd_soc_component *component) 530 { 531 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 532 int ret; 533 534 tas2764->component = component; 535 536 if (tas2764->sdz_gpio) { 537 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1); 538 usleep_range(1000, 2000); 539 } 540 541 tas2764_reset(tas2764); 542 543 if (tas2764->irq) { 544 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff); 545 if (ret < 0) 546 return ret; 547 548 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK1, 0xff); 549 if (ret < 0) 550 return ret; 551 552 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK2, 0xff); 553 if (ret < 0) 554 return ret; 555 556 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK3, 0xff); 557 if (ret < 0) 558 return ret; 559 560 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK4, 0xff); 561 if (ret < 0) 562 return ret; 563 564 ret = devm_request_threaded_irq(tas2764->dev, tas2764->irq, NULL, tas2764_irq, 565 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW, 566 "tas2764", tas2764); 567 if (ret) 568 dev_warn(tas2764->dev, "failed to request IRQ: %d\n", ret); 569 } 570 571 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5, 572 TAS2764_TDM_CFG5_VSNS_ENABLE, 0); 573 if (ret < 0) 574 return ret; 575 576 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6, 577 TAS2764_TDM_CFG6_ISNS_ENABLE, 0); 578 if (ret < 0) 579 return ret; 580 581 return 0; 582 } 583 584 static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0); 585 static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1); 586 587 static const char * const tas2764_hpf_texts[] = { 588 "Disabled", "2 Hz", "50 Hz", "100 Hz", "200 Hz", 589 "400 Hz", "800 Hz" 590 }; 591 592 static SOC_ENUM_SINGLE_DECL( 593 tas2764_hpf_enum, TAS2764_DC_BLK0, 594 TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts); 595 596 static const struct snd_kcontrol_new tas2764_snd_controls[] = { 597 SOC_SINGLE_TLV("Speaker Volume", TAS2764_DVC, 0, 598 TAS2764_DVC_MAX, 1, tas2764_playback_volume), 599 SOC_SINGLE_TLV("Amp Gain Volume", TAS2764_CHNL_0, 1, 0x14, 0, 600 tas2764_digital_tlv), 601 SOC_ENUM("HPF Corner Frequency", tas2764_hpf_enum), 602 }; 603 604 static const struct snd_soc_component_driver soc_component_driver_tas2764 = { 605 .probe = tas2764_codec_probe, 606 .suspend = tas2764_codec_suspend, 607 .resume = tas2764_codec_resume, 608 .controls = tas2764_snd_controls, 609 .num_controls = ARRAY_SIZE(tas2764_snd_controls), 610 .dapm_widgets = tas2764_dapm_widgets, 611 .num_dapm_widgets = ARRAY_SIZE(tas2764_dapm_widgets), 612 .dapm_routes = tas2764_audio_map, 613 .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map), 614 .idle_bias_on = 1, 615 .endianness = 1, 616 }; 617 618 static const struct reg_default tas2764_reg_defaults[] = { 619 { TAS2764_PAGE, 0x00 }, 620 { TAS2764_SW_RST, 0x00 }, 621 { TAS2764_PWR_CTRL, 0x1a }, 622 { TAS2764_DVC, 0x00 }, 623 { TAS2764_CHNL_0, 0x28 }, 624 { TAS2764_TDM_CFG0, 0x09 }, 625 { TAS2764_TDM_CFG1, 0x02 }, 626 { TAS2764_TDM_CFG2, 0x0a }, 627 { TAS2764_TDM_CFG3, 0x10 }, 628 { TAS2764_TDM_CFG5, 0x42 }, 629 }; 630 631 static const struct regmap_range_cfg tas2764_regmap_ranges[] = { 632 { 633 .range_min = 0, 634 .range_max = 1 * 128, 635 .selector_reg = TAS2764_PAGE, 636 .selector_mask = 0xff, 637 .selector_shift = 0, 638 .window_start = 0, 639 .window_len = 128, 640 }, 641 }; 642 643 static bool tas2764_volatile_register(struct device *dev, unsigned int reg) 644 { 645 switch (reg) { 646 case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4: 647 case TAS2764_INT_CLK_CFG: 648 return true; 649 default: 650 return false; 651 } 652 } 653 654 static const struct regmap_config tas2764_i2c_regmap = { 655 .reg_bits = 8, 656 .val_bits = 8, 657 .volatile_reg = tas2764_volatile_register, 658 .reg_defaults = tas2764_reg_defaults, 659 .num_reg_defaults = ARRAY_SIZE(tas2764_reg_defaults), 660 .cache_type = REGCACHE_RBTREE, 661 .ranges = tas2764_regmap_ranges, 662 .num_ranges = ARRAY_SIZE(tas2764_regmap_ranges), 663 .max_register = 1 * 128, 664 }; 665 666 static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764) 667 { 668 int ret = 0; 669 670 tas2764->reset_gpio = devm_gpiod_get_optional(tas2764->dev, "reset", 671 GPIOD_OUT_HIGH); 672 if (IS_ERR(tas2764->reset_gpio)) { 673 if (PTR_ERR(tas2764->reset_gpio) == -EPROBE_DEFER) { 674 tas2764->reset_gpio = NULL; 675 return -EPROBE_DEFER; 676 } 677 } 678 679 tas2764->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH); 680 if (IS_ERR(tas2764->sdz_gpio)) { 681 if (PTR_ERR(tas2764->sdz_gpio) == -EPROBE_DEFER) 682 return -EPROBE_DEFER; 683 684 tas2764->sdz_gpio = NULL; 685 } 686 687 ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", 688 &tas2764->i_sense_slot); 689 if (ret) 690 tas2764->i_sense_slot = 0; 691 692 ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", 693 &tas2764->v_sense_slot); 694 if (ret) 695 tas2764->v_sense_slot = 2; 696 697 return 0; 698 } 699 700 static int tas2764_i2c_probe(struct i2c_client *client) 701 { 702 struct tas2764_priv *tas2764; 703 int result; 704 705 tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv), 706 GFP_KERNEL); 707 if (!tas2764) 708 return -ENOMEM; 709 710 tas2764->dev = &client->dev; 711 tas2764->irq = client->irq; 712 i2c_set_clientdata(client, tas2764); 713 dev_set_drvdata(&client->dev, tas2764); 714 715 tas2764->regmap = devm_regmap_init_i2c(client, &tas2764_i2c_regmap); 716 if (IS_ERR(tas2764->regmap)) { 717 result = PTR_ERR(tas2764->regmap); 718 dev_err(&client->dev, "Failed to allocate register map: %d\n", 719 result); 720 return result; 721 } 722 723 if (client->dev.of_node) { 724 result = tas2764_parse_dt(&client->dev, tas2764); 725 if (result) { 726 dev_err(tas2764->dev, "%s: Failed to parse devicetree\n", 727 __func__); 728 return result; 729 } 730 } 731 732 return devm_snd_soc_register_component(tas2764->dev, 733 &soc_component_driver_tas2764, 734 tas2764_dai_driver, 735 ARRAY_SIZE(tas2764_dai_driver)); 736 } 737 738 static const struct i2c_device_id tas2764_i2c_id[] = { 739 { "tas2764"}, 740 { } 741 }; 742 MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id); 743 744 #if defined(CONFIG_OF) 745 static const struct of_device_id tas2764_of_match[] = { 746 { .compatible = "ti,tas2764" }, 747 {}, 748 }; 749 MODULE_DEVICE_TABLE(of, tas2764_of_match); 750 #endif 751 752 static struct i2c_driver tas2764_i2c_driver = { 753 .driver = { 754 .name = "tas2764", 755 .of_match_table = of_match_ptr(tas2764_of_match), 756 }, 757 .probe = tas2764_i2c_probe, 758 .id_table = tas2764_i2c_id, 759 }; 760 module_i2c_driver(tas2764_i2c_driver); 761 762 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 763 MODULE_DESCRIPTION("TAS2764 I2C Smart Amplifier driver"); 764 MODULE_LICENSE("GPL v2"); 765