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, asi_cfg_4 = 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 asi_cfg_4 = TAS2764_TDM_CFG4_TX_FALLING; 378 break; 379 case SND_SOC_DAIFMT_IB_IF: 380 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 381 fallthrough; 382 case SND_SOC_DAIFMT_IB_NF: 383 asi_cfg_1 = TAS2764_TDM_CFG1_RX_FALLING; 384 asi_cfg_4 = TAS2764_TDM_CFG4_TX_RISING; 385 break; 386 } 387 388 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1, 389 TAS2764_TDM_CFG1_RX_MASK, 390 asi_cfg_1); 391 if (ret < 0) 392 return ret; 393 394 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG4, 395 TAS2764_TDM_CFG4_TX_MASK, 396 asi_cfg_4); 397 if (ret < 0) 398 return ret; 399 400 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 401 case SND_SOC_DAIFMT_I2S: 402 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 403 fallthrough; 404 case SND_SOC_DAIFMT_DSP_A: 405 tdm_rx_start_slot = 1; 406 break; 407 case SND_SOC_DAIFMT_DSP_B: 408 case SND_SOC_DAIFMT_LEFT_J: 409 tdm_rx_start_slot = 0; 410 break; 411 default: 412 dev_err(tas2764->dev, 413 "DAI Format is not found, fmt=0x%x\n", fmt); 414 return -EINVAL; 415 } 416 417 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0, 418 TAS2764_TDM_CFG0_FRAME_START, 419 asi_cfg_0); 420 if (ret < 0) 421 return ret; 422 423 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1, 424 TAS2764_TDM_CFG1_MASK, 425 (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT)); 426 if (ret < 0) 427 return ret; 428 429 return 0; 430 } 431 432 static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai, 433 unsigned int tx_mask, 434 unsigned int rx_mask, 435 int slots, int slot_width) 436 { 437 struct snd_soc_component *component = dai->component; 438 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 439 int left_slot, right_slot; 440 int slots_cfg; 441 int slot_size; 442 int ret; 443 444 if (tx_mask == 0 || rx_mask != 0) 445 return -EINVAL; 446 447 left_slot = __ffs(tx_mask); 448 tx_mask &= ~(1 << left_slot); 449 if (tx_mask == 0) { 450 right_slot = left_slot; 451 } else { 452 right_slot = __ffs(tx_mask); 453 tx_mask &= ~(1 << right_slot); 454 } 455 456 if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) 457 return -EINVAL; 458 459 slots_cfg = (right_slot << TAS2764_TDM_CFG3_RXS_SHIFT) | left_slot; 460 461 ret = snd_soc_component_write(component, TAS2764_TDM_CFG3, slots_cfg); 462 if (ret) 463 return ret; 464 465 switch (slot_width) { 466 case 16: 467 slot_size = TAS2764_TDM_CFG2_RXS_16BITS; 468 break; 469 case 24: 470 slot_size = TAS2764_TDM_CFG2_RXS_24BITS; 471 break; 472 case 32: 473 slot_size = TAS2764_TDM_CFG2_RXS_32BITS; 474 break; 475 default: 476 return -EINVAL; 477 } 478 479 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG2, 480 TAS2764_TDM_CFG2_RXS_MASK, 481 slot_size); 482 if (ret < 0) 483 return ret; 484 485 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG5, 486 TAS2764_TDM_CFG5_50_MASK, 487 tas2764->v_sense_slot); 488 if (ret < 0) 489 return ret; 490 491 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG6, 492 TAS2764_TDM_CFG6_50_MASK, 493 tas2764->i_sense_slot); 494 if (ret < 0) 495 return ret; 496 497 return 0; 498 } 499 500 static const struct snd_soc_dai_ops tas2764_dai_ops = { 501 .mute_stream = tas2764_mute, 502 .hw_params = tas2764_hw_params, 503 .set_fmt = tas2764_set_fmt, 504 .set_tdm_slot = tas2764_set_dai_tdm_slot, 505 .no_capture_mute = 1, 506 }; 507 508 #define TAS2764_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 509 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 510 511 #define TAS2764_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 512 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) 513 514 static struct snd_soc_dai_driver tas2764_dai_driver[] = { 515 { 516 .name = "tas2764 ASI1", 517 .id = 0, 518 .playback = { 519 .stream_name = "ASI1 Playback", 520 .channels_min = 1, 521 .channels_max = 2, 522 .rates = TAS2764_RATES, 523 .formats = TAS2764_FORMATS, 524 }, 525 .capture = { 526 .stream_name = "ASI1 Capture", 527 .channels_min = 0, 528 .channels_max = 2, 529 .rates = TAS2764_RATES, 530 .formats = TAS2764_FORMATS, 531 }, 532 .ops = &tas2764_dai_ops, 533 .symmetric_rate = 1, 534 }, 535 }; 536 537 static int tas2764_codec_probe(struct snd_soc_component *component) 538 { 539 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 540 int ret; 541 542 tas2764->component = component; 543 544 if (tas2764->sdz_gpio) { 545 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1); 546 usleep_range(1000, 2000); 547 } 548 549 tas2764_reset(tas2764); 550 551 if (tas2764->irq) { 552 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff); 553 if (ret < 0) 554 return ret; 555 556 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK1, 0xff); 557 if (ret < 0) 558 return ret; 559 560 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK2, 0xff); 561 if (ret < 0) 562 return ret; 563 564 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK3, 0xff); 565 if (ret < 0) 566 return ret; 567 568 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK4, 0xff); 569 if (ret < 0) 570 return ret; 571 572 ret = devm_request_threaded_irq(tas2764->dev, tas2764->irq, NULL, tas2764_irq, 573 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW, 574 "tas2764", tas2764); 575 if (ret) 576 dev_warn(tas2764->dev, "failed to request IRQ: %d\n", ret); 577 } 578 579 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5, 580 TAS2764_TDM_CFG5_VSNS_ENABLE, 0); 581 if (ret < 0) 582 return ret; 583 584 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6, 585 TAS2764_TDM_CFG6_ISNS_ENABLE, 0); 586 if (ret < 0) 587 return ret; 588 589 return 0; 590 } 591 592 static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0); 593 static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1); 594 595 static const char * const tas2764_hpf_texts[] = { 596 "Disabled", "2 Hz", "50 Hz", "100 Hz", "200 Hz", 597 "400 Hz", "800 Hz" 598 }; 599 600 static SOC_ENUM_SINGLE_DECL( 601 tas2764_hpf_enum, TAS2764_DC_BLK0, 602 TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts); 603 604 static const struct snd_kcontrol_new tas2764_snd_controls[] = { 605 SOC_SINGLE_TLV("Speaker Volume", TAS2764_DVC, 0, 606 TAS2764_DVC_MAX, 1, tas2764_playback_volume), 607 SOC_SINGLE_TLV("Amp Gain Volume", TAS2764_CHNL_0, 1, 0x14, 0, 608 tas2764_digital_tlv), 609 SOC_ENUM("HPF Corner Frequency", tas2764_hpf_enum), 610 }; 611 612 static const struct snd_soc_component_driver soc_component_driver_tas2764 = { 613 .probe = tas2764_codec_probe, 614 .suspend = tas2764_codec_suspend, 615 .resume = tas2764_codec_resume, 616 .controls = tas2764_snd_controls, 617 .num_controls = ARRAY_SIZE(tas2764_snd_controls), 618 .dapm_widgets = tas2764_dapm_widgets, 619 .num_dapm_widgets = ARRAY_SIZE(tas2764_dapm_widgets), 620 .dapm_routes = tas2764_audio_map, 621 .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map), 622 .idle_bias_on = 1, 623 .endianness = 1, 624 }; 625 626 static const struct reg_default tas2764_reg_defaults[] = { 627 { TAS2764_PAGE, 0x00 }, 628 { TAS2764_SW_RST, 0x00 }, 629 { TAS2764_PWR_CTRL, 0x1a }, 630 { TAS2764_DVC, 0x00 }, 631 { TAS2764_CHNL_0, 0x28 }, 632 { TAS2764_TDM_CFG0, 0x09 }, 633 { TAS2764_TDM_CFG1, 0x02 }, 634 { TAS2764_TDM_CFG2, 0x0a }, 635 { TAS2764_TDM_CFG3, 0x10 }, 636 { TAS2764_TDM_CFG5, 0x42 }, 637 }; 638 639 static const struct regmap_range_cfg tas2764_regmap_ranges[] = { 640 { 641 .range_min = 0, 642 .range_max = 1 * 128, 643 .selector_reg = TAS2764_PAGE, 644 .selector_mask = 0xff, 645 .selector_shift = 0, 646 .window_start = 0, 647 .window_len = 128, 648 }, 649 }; 650 651 static bool tas2764_volatile_register(struct device *dev, unsigned int reg) 652 { 653 switch (reg) { 654 case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4: 655 case TAS2764_INT_CLK_CFG: 656 return true; 657 default: 658 return false; 659 } 660 } 661 662 static const struct regmap_config tas2764_i2c_regmap = { 663 .reg_bits = 8, 664 .val_bits = 8, 665 .volatile_reg = tas2764_volatile_register, 666 .reg_defaults = tas2764_reg_defaults, 667 .num_reg_defaults = ARRAY_SIZE(tas2764_reg_defaults), 668 .cache_type = REGCACHE_RBTREE, 669 .ranges = tas2764_regmap_ranges, 670 .num_ranges = ARRAY_SIZE(tas2764_regmap_ranges), 671 .max_register = 1 * 128, 672 }; 673 674 static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764) 675 { 676 int ret = 0; 677 678 tas2764->reset_gpio = devm_gpiod_get_optional(tas2764->dev, "reset", 679 GPIOD_OUT_HIGH); 680 if (IS_ERR(tas2764->reset_gpio)) { 681 if (PTR_ERR(tas2764->reset_gpio) == -EPROBE_DEFER) { 682 tas2764->reset_gpio = NULL; 683 return -EPROBE_DEFER; 684 } 685 } 686 687 tas2764->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH); 688 if (IS_ERR(tas2764->sdz_gpio)) { 689 if (PTR_ERR(tas2764->sdz_gpio) == -EPROBE_DEFER) 690 return -EPROBE_DEFER; 691 692 tas2764->sdz_gpio = NULL; 693 } 694 695 ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", 696 &tas2764->i_sense_slot); 697 if (ret) 698 tas2764->i_sense_slot = 0; 699 700 ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", 701 &tas2764->v_sense_slot); 702 if (ret) 703 tas2764->v_sense_slot = 2; 704 705 return 0; 706 } 707 708 static int tas2764_i2c_probe(struct i2c_client *client) 709 { 710 struct tas2764_priv *tas2764; 711 int result; 712 713 tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv), 714 GFP_KERNEL); 715 if (!tas2764) 716 return -ENOMEM; 717 718 tas2764->dev = &client->dev; 719 tas2764->irq = client->irq; 720 i2c_set_clientdata(client, tas2764); 721 dev_set_drvdata(&client->dev, tas2764); 722 723 tas2764->regmap = devm_regmap_init_i2c(client, &tas2764_i2c_regmap); 724 if (IS_ERR(tas2764->regmap)) { 725 result = PTR_ERR(tas2764->regmap); 726 dev_err(&client->dev, "Failed to allocate register map: %d\n", 727 result); 728 return result; 729 } 730 731 if (client->dev.of_node) { 732 result = tas2764_parse_dt(&client->dev, tas2764); 733 if (result) { 734 dev_err(tas2764->dev, "%s: Failed to parse devicetree\n", 735 __func__); 736 return result; 737 } 738 } 739 740 return devm_snd_soc_register_component(tas2764->dev, 741 &soc_component_driver_tas2764, 742 tas2764_dai_driver, 743 ARRAY_SIZE(tas2764_dai_driver)); 744 } 745 746 static const struct i2c_device_id tas2764_i2c_id[] = { 747 { "tas2764"}, 748 { } 749 }; 750 MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id); 751 752 #if defined(CONFIG_OF) 753 static const struct of_device_id tas2764_of_match[] = { 754 { .compatible = "ti,tas2764" }, 755 {}, 756 }; 757 MODULE_DEVICE_TABLE(of, tas2764_of_match); 758 #endif 759 760 static struct i2c_driver tas2764_i2c_driver = { 761 .driver = { 762 .name = "tas2764", 763 .of_match_table = of_match_ptr(tas2764_of_match), 764 }, 765 .probe = tas2764_i2c_probe, 766 .id_table = tas2764_i2c_id, 767 }; 768 module_i2c_driver(tas2764_i2c_driver); 769 770 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 771 MODULE_DESCRIPTION("TAS2764 I2C Smart Amplifier driver"); 772 MODULE_LICENSE("GPL v2"); 773