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 usleep_range(6000, 7000); 146 147 return 0; 148 } 149 150 static int tas2764_codec_resume(struct snd_soc_component *component) 151 { 152 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 153 int ret; 154 155 if (tas2764->sdz_gpio) { 156 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1); 157 usleep_range(1000, 2000); 158 } 159 160 ret = tas2764_update_pwr_ctrl(tas2764); 161 162 if (ret < 0) 163 return ret; 164 165 regcache_cache_only(tas2764->regmap, false); 166 167 return regcache_sync(tas2764->regmap); 168 } 169 #else 170 #define tas2764_codec_suspend NULL 171 #define tas2764_codec_resume NULL 172 #endif 173 174 static const char * const tas2764_ASI1_src[] = { 175 "I2C offset", "Left", "Right", "LeftRightDiv2", 176 }; 177 178 static SOC_ENUM_SINGLE_DECL( 179 tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, TAS2764_TDM_CFG2_SCFG_SHIFT, 180 tas2764_ASI1_src); 181 182 static const struct snd_kcontrol_new tas2764_asi1_mux = 183 SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum); 184 185 static const struct snd_kcontrol_new isense_switch = 186 SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1); 187 static const struct snd_kcontrol_new vsense_switch = 188 SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 1, 1); 189 190 static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = { 191 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), 192 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2764_asi1_mux), 193 SND_SOC_DAPM_SWITCH("ISENSE", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 194 1, &isense_switch), 195 SND_SOC_DAPM_SWITCH("VSENSE", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 196 1, &vsense_switch), 197 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), 198 SND_SOC_DAPM_OUTPUT("OUT"), 199 SND_SOC_DAPM_SIGGEN("VMON"), 200 SND_SOC_DAPM_SIGGEN("IMON") 201 }; 202 203 static const struct snd_soc_dapm_route tas2764_audio_map[] = { 204 {"ASI1 Sel", "I2C offset", "ASI1"}, 205 {"ASI1 Sel", "Left", "ASI1"}, 206 {"ASI1 Sel", "Right", "ASI1"}, 207 {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, 208 {"DAC", NULL, "ASI1 Sel"}, 209 {"OUT", NULL, "DAC"}, 210 {"ISENSE", "Switch", "IMON"}, 211 {"VSENSE", "Switch", "VMON"}, 212 }; 213 214 static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) 215 { 216 struct tas2764_priv *tas2764 = 217 snd_soc_component_get_drvdata(dai->component); 218 int ret; 219 220 if (!mute) { 221 tas2764->dac_powered = true; 222 ret = tas2764_update_pwr_ctrl(tas2764); 223 if (ret) 224 return ret; 225 } 226 227 tas2764->unmuted = !mute; 228 ret = tas2764_update_pwr_ctrl(tas2764); 229 if (ret) 230 return ret; 231 232 if (mute) { 233 /* Wait for ramp-down */ 234 usleep_range(6000, 7000); 235 236 tas2764->dac_powered = false; 237 ret = tas2764_update_pwr_ctrl(tas2764); 238 if (ret) 239 return ret; 240 241 /* Wait a bit after shutdown */ 242 usleep_range(2000, 3000); 243 } 244 245 return 0; 246 } 247 248 static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth) 249 { 250 struct snd_soc_component *component = tas2764->component; 251 int sense_en; 252 int val; 253 int ret; 254 255 switch (bitwidth) { 256 case SNDRV_PCM_FORMAT_S16_LE: 257 ret = snd_soc_component_update_bits(component, 258 TAS2764_TDM_CFG2, 259 TAS2764_TDM_CFG2_RXW_MASK, 260 TAS2764_TDM_CFG2_RXW_16BITS); 261 break; 262 case SNDRV_PCM_FORMAT_S24_LE: 263 ret = snd_soc_component_update_bits(component, 264 TAS2764_TDM_CFG2, 265 TAS2764_TDM_CFG2_RXW_MASK, 266 TAS2764_TDM_CFG2_RXW_24BITS); 267 break; 268 case SNDRV_PCM_FORMAT_S32_LE: 269 ret = snd_soc_component_update_bits(component, 270 TAS2764_TDM_CFG2, 271 TAS2764_TDM_CFG2_RXW_MASK, 272 TAS2764_TDM_CFG2_RXW_32BITS); 273 break; 274 275 default: 276 return -EINVAL; 277 } 278 279 if (ret < 0) 280 return ret; 281 282 val = snd_soc_component_read(tas2764->component, TAS2764_PWR_CTRL); 283 if (val < 0) 284 return val; 285 286 if (val & (1 << TAS2764_VSENSE_POWER_EN)) 287 sense_en = 0; 288 else 289 sense_en = TAS2764_TDM_CFG5_VSNS_ENABLE; 290 291 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5, 292 TAS2764_TDM_CFG5_VSNS_ENABLE, 293 sense_en); 294 if (ret < 0) 295 return ret; 296 297 if (val & (1 << TAS2764_ISENSE_POWER_EN)) 298 sense_en = 0; 299 else 300 sense_en = TAS2764_TDM_CFG6_ISNS_ENABLE; 301 302 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6, 303 TAS2764_TDM_CFG6_ISNS_ENABLE, 304 sense_en); 305 if (ret < 0) 306 return ret; 307 308 return 0; 309 } 310 311 static int tas2764_set_samplerate(struct tas2764_priv *tas2764, int samplerate) 312 { 313 struct snd_soc_component *component = tas2764->component; 314 int ramp_rate_val; 315 int ret; 316 317 switch (samplerate) { 318 case 48000: 319 ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ | 320 TAS2764_TDM_CFG0_44_1_48KHZ; 321 break; 322 case 44100: 323 ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ | 324 TAS2764_TDM_CFG0_44_1_48KHZ; 325 break; 326 case 96000: 327 ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ | 328 TAS2764_TDM_CFG0_88_2_96KHZ; 329 break; 330 case 88200: 331 ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ | 332 TAS2764_TDM_CFG0_88_2_96KHZ; 333 break; 334 default: 335 return -EINVAL; 336 } 337 338 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0, 339 TAS2764_TDM_CFG0_SMP_MASK | 340 TAS2764_TDM_CFG0_MASK, 341 ramp_rate_val); 342 if (ret < 0) 343 return ret; 344 345 return 0; 346 } 347 348 static int tas2764_hw_params(struct snd_pcm_substream *substream, 349 struct snd_pcm_hw_params *params, 350 struct snd_soc_dai *dai) 351 { 352 struct snd_soc_component *component = dai->component; 353 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 354 int ret; 355 356 ret = tas2764_set_bitwidth(tas2764, params_format(params)); 357 if (ret < 0) 358 return ret; 359 360 return tas2764_set_samplerate(tas2764, params_rate(params)); 361 } 362 363 static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 364 { 365 struct snd_soc_component *component = dai->component; 366 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 367 u8 tdm_rx_start_slot = 0, asi_cfg_0 = 0, asi_cfg_1 = 0; 368 int ret; 369 370 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 371 case SND_SOC_DAIFMT_NB_IF: 372 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 373 fallthrough; 374 case SND_SOC_DAIFMT_NB_NF: 375 asi_cfg_1 = TAS2764_TDM_CFG1_RX_RISING; 376 break; 377 case SND_SOC_DAIFMT_IB_IF: 378 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 379 fallthrough; 380 case SND_SOC_DAIFMT_IB_NF: 381 asi_cfg_1 = TAS2764_TDM_CFG1_RX_FALLING; 382 break; 383 } 384 385 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1, 386 TAS2764_TDM_CFG1_RX_MASK, 387 asi_cfg_1); 388 if (ret < 0) 389 return ret; 390 391 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 392 case SND_SOC_DAIFMT_I2S: 393 asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START; 394 fallthrough; 395 case SND_SOC_DAIFMT_DSP_A: 396 tdm_rx_start_slot = 1; 397 break; 398 case SND_SOC_DAIFMT_DSP_B: 399 case SND_SOC_DAIFMT_LEFT_J: 400 tdm_rx_start_slot = 0; 401 break; 402 default: 403 dev_err(tas2764->dev, 404 "DAI Format is not found, fmt=0x%x\n", fmt); 405 return -EINVAL; 406 } 407 408 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0, 409 TAS2764_TDM_CFG0_FRAME_START, 410 asi_cfg_0); 411 if (ret < 0) 412 return ret; 413 414 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1, 415 TAS2764_TDM_CFG1_MASK, 416 (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT)); 417 if (ret < 0) 418 return ret; 419 420 return 0; 421 } 422 423 static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai, 424 unsigned int tx_mask, 425 unsigned int rx_mask, 426 int slots, int slot_width) 427 { 428 struct snd_soc_component *component = dai->component; 429 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 430 int left_slot, right_slot; 431 int slots_cfg; 432 int slot_size; 433 int ret; 434 435 if (tx_mask == 0 || rx_mask != 0) 436 return -EINVAL; 437 438 left_slot = __ffs(tx_mask); 439 tx_mask &= ~(1 << left_slot); 440 if (tx_mask == 0) { 441 right_slot = left_slot; 442 } else { 443 right_slot = __ffs(tx_mask); 444 tx_mask &= ~(1 << right_slot); 445 } 446 447 if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) 448 return -EINVAL; 449 450 slots_cfg = (right_slot << TAS2764_TDM_CFG3_RXS_SHIFT) | left_slot; 451 452 ret = snd_soc_component_write(component, TAS2764_TDM_CFG3, slots_cfg); 453 if (ret) 454 return ret; 455 456 switch (slot_width) { 457 case 16: 458 slot_size = TAS2764_TDM_CFG2_RXS_16BITS; 459 break; 460 case 24: 461 slot_size = TAS2764_TDM_CFG2_RXS_24BITS; 462 break; 463 case 32: 464 slot_size = TAS2764_TDM_CFG2_RXS_32BITS; 465 break; 466 default: 467 return -EINVAL; 468 } 469 470 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG2, 471 TAS2764_TDM_CFG2_RXS_MASK, 472 slot_size); 473 if (ret < 0) 474 return ret; 475 476 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG5, 477 TAS2764_TDM_CFG5_50_MASK, 478 tas2764->v_sense_slot); 479 if (ret < 0) 480 return ret; 481 482 ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG6, 483 TAS2764_TDM_CFG6_50_MASK, 484 tas2764->i_sense_slot); 485 if (ret < 0) 486 return ret; 487 488 return 0; 489 } 490 491 static const struct snd_soc_dai_ops tas2764_dai_ops = { 492 .mute_stream = tas2764_mute, 493 .hw_params = tas2764_hw_params, 494 .set_fmt = tas2764_set_fmt, 495 .set_tdm_slot = tas2764_set_dai_tdm_slot, 496 .no_capture_mute = 1, 497 }; 498 499 #define TAS2764_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 500 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 501 502 #define TAS2764_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 503 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) 504 505 static struct snd_soc_dai_driver tas2764_dai_driver[] = { 506 { 507 .name = "tas2764 ASI1", 508 .id = 0, 509 .playback = { 510 .stream_name = "ASI1 Playback", 511 .channels_min = 1, 512 .channels_max = 2, 513 .rates = TAS2764_RATES, 514 .formats = TAS2764_FORMATS, 515 }, 516 .capture = { 517 .stream_name = "ASI1 Capture", 518 .channels_min = 0, 519 .channels_max = 2, 520 .rates = TAS2764_RATES, 521 .formats = TAS2764_FORMATS, 522 }, 523 .ops = &tas2764_dai_ops, 524 .symmetric_rate = 1, 525 }, 526 }; 527 528 static int tas2764_codec_probe(struct snd_soc_component *component) 529 { 530 struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); 531 int ret; 532 533 tas2764->component = component; 534 535 if (tas2764->sdz_gpio) { 536 gpiod_set_value_cansleep(tas2764->sdz_gpio, 1); 537 usleep_range(1000, 2000); 538 } 539 540 tas2764_reset(tas2764); 541 542 if (tas2764->irq) { 543 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff); 544 if (ret < 0) 545 return ret; 546 547 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK1, 0xff); 548 if (ret < 0) 549 return ret; 550 551 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK2, 0xff); 552 if (ret < 0) 553 return ret; 554 555 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK3, 0xff); 556 if (ret < 0) 557 return ret; 558 559 ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK4, 0xff); 560 if (ret < 0) 561 return ret; 562 563 ret = devm_request_threaded_irq(tas2764->dev, tas2764->irq, NULL, tas2764_irq, 564 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW, 565 "tas2764", tas2764); 566 if (ret) 567 dev_warn(tas2764->dev, "failed to request IRQ: %d\n", ret); 568 } 569 570 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5, 571 TAS2764_TDM_CFG5_VSNS_ENABLE, 0); 572 if (ret < 0) 573 return ret; 574 575 ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6, 576 TAS2764_TDM_CFG6_ISNS_ENABLE, 0); 577 if (ret < 0) 578 return ret; 579 580 return 0; 581 } 582 583 static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0); 584 static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1); 585 586 static const char * const tas2764_hpf_texts[] = { 587 "Disabled", "2 Hz", "50 Hz", "100 Hz", "200 Hz", 588 "400 Hz", "800 Hz" 589 }; 590 591 static SOC_ENUM_SINGLE_DECL( 592 tas2764_hpf_enum, TAS2764_DC_BLK0, 593 TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts); 594 595 static const struct snd_kcontrol_new tas2764_snd_controls[] = { 596 SOC_SINGLE_TLV("Speaker Volume", TAS2764_DVC, 0, 597 TAS2764_DVC_MAX, 1, tas2764_playback_volume), 598 SOC_SINGLE_TLV("Amp Gain Volume", TAS2764_CHNL_0, 1, 0x14, 0, 599 tas2764_digital_tlv), 600 SOC_ENUM("HPF Corner Frequency", tas2764_hpf_enum), 601 }; 602 603 static const struct snd_soc_component_driver soc_component_driver_tas2764 = { 604 .probe = tas2764_codec_probe, 605 .suspend = tas2764_codec_suspend, 606 .resume = tas2764_codec_resume, 607 .controls = tas2764_snd_controls, 608 .num_controls = ARRAY_SIZE(tas2764_snd_controls), 609 .dapm_widgets = tas2764_dapm_widgets, 610 .num_dapm_widgets = ARRAY_SIZE(tas2764_dapm_widgets), 611 .dapm_routes = tas2764_audio_map, 612 .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map), 613 .idle_bias_on = 1, 614 .endianness = 1, 615 }; 616 617 static const struct reg_default tas2764_reg_defaults[] = { 618 { TAS2764_PAGE, 0x00 }, 619 { TAS2764_SW_RST, 0x00 }, 620 { TAS2764_PWR_CTRL, 0x1a }, 621 { TAS2764_DVC, 0x00 }, 622 { TAS2764_CHNL_0, 0x28 }, 623 { TAS2764_TDM_CFG0, 0x09 }, 624 { TAS2764_TDM_CFG1, 0x02 }, 625 { TAS2764_TDM_CFG2, 0x0a }, 626 { TAS2764_TDM_CFG3, 0x10 }, 627 { TAS2764_TDM_CFG5, 0x42 }, 628 { TAS2764_INT_CLK_CFG, 0x19 }, 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_SW_RST: 647 case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4: 648 case TAS2764_INT_CLK_CFG: 649 return true; 650 default: 651 return false; 652 } 653 } 654 655 static const struct regmap_config tas2764_i2c_regmap = { 656 .reg_bits = 8, 657 .val_bits = 8, 658 .volatile_reg = tas2764_volatile_register, 659 .reg_defaults = tas2764_reg_defaults, 660 .num_reg_defaults = ARRAY_SIZE(tas2764_reg_defaults), 661 .cache_type = REGCACHE_RBTREE, 662 .ranges = tas2764_regmap_ranges, 663 .num_ranges = ARRAY_SIZE(tas2764_regmap_ranges), 664 .max_register = 1 * 128, 665 }; 666 667 static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764) 668 { 669 int ret = 0; 670 671 tas2764->reset_gpio = devm_gpiod_get_optional(tas2764->dev, "reset", 672 GPIOD_OUT_HIGH); 673 if (IS_ERR(tas2764->reset_gpio)) { 674 if (PTR_ERR(tas2764->reset_gpio) == -EPROBE_DEFER) { 675 tas2764->reset_gpio = NULL; 676 return -EPROBE_DEFER; 677 } 678 } 679 680 tas2764->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH); 681 if (IS_ERR(tas2764->sdz_gpio)) { 682 if (PTR_ERR(tas2764->sdz_gpio) == -EPROBE_DEFER) 683 return -EPROBE_DEFER; 684 685 tas2764->sdz_gpio = NULL; 686 } 687 688 ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", 689 &tas2764->i_sense_slot); 690 if (ret) 691 tas2764->i_sense_slot = 0; 692 693 ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", 694 &tas2764->v_sense_slot); 695 if (ret) 696 tas2764->v_sense_slot = 2; 697 698 return 0; 699 } 700 701 static int tas2764_i2c_probe(struct i2c_client *client) 702 { 703 struct tas2764_priv *tas2764; 704 int result; 705 706 tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv), 707 GFP_KERNEL); 708 if (!tas2764) 709 return -ENOMEM; 710 711 tas2764->dev = &client->dev; 712 tas2764->irq = client->irq; 713 i2c_set_clientdata(client, tas2764); 714 dev_set_drvdata(&client->dev, tas2764); 715 716 tas2764->regmap = devm_regmap_init_i2c(client, &tas2764_i2c_regmap); 717 if (IS_ERR(tas2764->regmap)) { 718 result = PTR_ERR(tas2764->regmap); 719 dev_err(&client->dev, "Failed to allocate register map: %d\n", 720 result); 721 return result; 722 } 723 724 if (client->dev.of_node) { 725 result = tas2764_parse_dt(&client->dev, tas2764); 726 if (result) { 727 dev_err(tas2764->dev, "%s: Failed to parse devicetree\n", 728 __func__); 729 return result; 730 } 731 } 732 733 return devm_snd_soc_register_component(tas2764->dev, 734 &soc_component_driver_tas2764, 735 tas2764_dai_driver, 736 ARRAY_SIZE(tas2764_dai_driver)); 737 } 738 739 static const struct i2c_device_id tas2764_i2c_id[] = { 740 { "tas2764"}, 741 { } 742 }; 743 MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id); 744 745 #if defined(CONFIG_OF) 746 static const struct of_device_id tas2764_of_match[] = { 747 { .compatible = "ti,tas2764" }, 748 {}, 749 }; 750 MODULE_DEVICE_TABLE(of, tas2764_of_match); 751 #endif 752 753 static struct i2c_driver tas2764_i2c_driver = { 754 .driver = { 755 .name = "tas2764", 756 .of_match_table = of_match_ptr(tas2764_of_match), 757 }, 758 .probe = tas2764_i2c_probe, 759 .id_table = tas2764_i2c_id, 760 }; 761 module_i2c_driver(tas2764_i2c_driver); 762 763 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 764 MODULE_DESCRIPTION("TAS2764 I2C Smart Amplifier driver"); 765 MODULE_LICENSE("GPL v2"); 766