1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * tas5720.c - ALSA SoC Texas Instruments TAS5720 Mono Audio Amplifier 4 * 5 * Copyright (C)2015-2016 Texas Instruments Incorporated - https://www.ti.com 6 * 7 * Author: Andreas Dannenberg <dannenberg@ti.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/errno.h> 12 #include <linux/device.h> 13 #include <linux/i2c.h> 14 #include <linux/pm_runtime.h> 15 #include <linux/regmap.h> 16 #include <linux/slab.h> 17 #include <linux/regulator/consumer.h> 18 #include <linux/delay.h> 19 20 #include <sound/pcm.h> 21 #include <sound/pcm_params.h> 22 #include <sound/soc.h> 23 #include <sound/soc-dapm.h> 24 #include <sound/tlv.h> 25 26 #include "tas5720.h" 27 28 /* Define how often to check (and clear) the fault status register (in ms) */ 29 #define TAS5720_FAULT_CHECK_INTERVAL 200 30 31 enum tas572x_type { 32 TAS5720, 33 TAS5722, 34 }; 35 36 static const char * const tas5720_supply_names[] = { 37 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */ 38 "pvdd", /* Class-D amp and analog power supply (connected). */ 39 }; 40 41 #define TAS5720_NUM_SUPPLIES ARRAY_SIZE(tas5720_supply_names) 42 43 struct tas5720_data { 44 struct snd_soc_component *component; 45 struct regmap *regmap; 46 struct i2c_client *tas5720_client; 47 enum tas572x_type devtype; 48 struct regulator_bulk_data supplies[TAS5720_NUM_SUPPLIES]; 49 struct delayed_work fault_check_work; 50 unsigned int last_fault; 51 }; 52 53 static int tas5720_hw_params(struct snd_pcm_substream *substream, 54 struct snd_pcm_hw_params *params, 55 struct snd_soc_dai *dai) 56 { 57 struct snd_soc_component *component = dai->component; 58 unsigned int rate = params_rate(params); 59 bool ssz_ds; 60 int ret; 61 62 switch (rate) { 63 case 44100: 64 case 48000: 65 ssz_ds = false; 66 break; 67 case 88200: 68 case 96000: 69 ssz_ds = true; 70 break; 71 default: 72 dev_err(component->dev, "unsupported sample rate: %u\n", rate); 73 return -EINVAL; 74 } 75 76 ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG, 77 TAS5720_SSZ_DS, ssz_ds); 78 if (ret < 0) { 79 dev_err(component->dev, "error setting sample rate: %d\n", ret); 80 return ret; 81 } 82 83 return 0; 84 } 85 86 static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 87 { 88 struct snd_soc_component *component = dai->component; 89 u8 serial_format; 90 int ret; 91 92 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { 93 dev_vdbg(component->dev, "DAI Format master is not found\n"); 94 return -EINVAL; 95 } 96 97 switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | 98 SND_SOC_DAIFMT_INV_MASK)) { 99 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF): 100 /* 1st data bit occur one BCLK cycle after the frame sync */ 101 serial_format = TAS5720_SAIF_I2S; 102 break; 103 case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF): 104 /* 105 * Note that although the TAS5720 does not have a dedicated DSP 106 * mode it doesn't care about the LRCLK duty cycle during TDM 107 * operation. Therefore we can use the device's I2S mode with 108 * its delaying of the 1st data bit to receive DSP_A formatted 109 * data. See device datasheet for additional details. 110 */ 111 serial_format = TAS5720_SAIF_I2S; 112 break; 113 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF): 114 /* 115 * Similar to DSP_A, we can use the fact that the TAS5720 does 116 * not care about the LRCLK duty cycle during TDM to receive 117 * DSP_B formatted data in LEFTJ mode (no delaying of the 1st 118 * data bit). 119 */ 120 serial_format = TAS5720_SAIF_LEFTJ; 121 break; 122 case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF): 123 /* No delay after the frame sync */ 124 serial_format = TAS5720_SAIF_LEFTJ; 125 break; 126 default: 127 dev_vdbg(component->dev, "DAI Format is not found\n"); 128 return -EINVAL; 129 } 130 131 ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG, 132 TAS5720_SAIF_FORMAT_MASK, 133 serial_format); 134 if (ret < 0) { 135 dev_err(component->dev, "error setting SAIF format: %d\n", ret); 136 return ret; 137 } 138 139 return 0; 140 } 141 142 static int tas5720_set_dai_tdm_slot(struct snd_soc_dai *dai, 143 unsigned int tx_mask, unsigned int rx_mask, 144 int slots, int slot_width) 145 { 146 struct snd_soc_component *component = dai->component; 147 struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component); 148 unsigned int first_slot; 149 int ret; 150 151 if (!tx_mask) { 152 dev_err(component->dev, "tx masks must not be 0\n"); 153 return -EINVAL; 154 } 155 156 /* 157 * Determine the first slot that is being requested. We will only 158 * use the first slot that is found since the TAS5720 is a mono 159 * amplifier. 160 */ 161 first_slot = __ffs(tx_mask); 162 163 if (first_slot > 7) { 164 dev_err(component->dev, "slot selection out of bounds (%u)\n", 165 first_slot); 166 return -EINVAL; 167 } 168 169 /* Enable manual TDM slot selection (instead of I2C ID based) */ 170 ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG, 171 TAS5720_TDM_CFG_SRC, TAS5720_TDM_CFG_SRC); 172 if (ret < 0) 173 goto error_snd_soc_component_update_bits; 174 175 /* Configure the TDM slot to process audio from */ 176 ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG, 177 TAS5720_TDM_SLOT_SEL_MASK, first_slot); 178 if (ret < 0) 179 goto error_snd_soc_component_update_bits; 180 181 /* Configure TDM slot width. This is only applicable to TAS5722. */ 182 switch (tas5720->devtype) { 183 case TAS5722: 184 ret = snd_soc_component_update_bits(component, TAS5722_DIGITAL_CTRL2_REG, 185 TAS5722_TDM_SLOT_16B, 186 slot_width == 16 ? 187 TAS5722_TDM_SLOT_16B : 0); 188 if (ret < 0) 189 goto error_snd_soc_component_update_bits; 190 break; 191 default: 192 break; 193 } 194 195 return 0; 196 197 error_snd_soc_component_update_bits: 198 dev_err(component->dev, "error configuring TDM mode: %d\n", ret); 199 return ret; 200 } 201 202 static int tas5720_mute(struct snd_soc_dai *dai, int mute, int direction) 203 { 204 struct snd_soc_component *component = dai->component; 205 int ret; 206 207 ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG, 208 TAS5720_MUTE, mute ? TAS5720_MUTE : 0); 209 if (ret < 0) { 210 dev_err(component->dev, "error (un-)muting device: %d\n", ret); 211 return ret; 212 } 213 214 return 0; 215 } 216 217 static void tas5720_fault_check_work(struct work_struct *work) 218 { 219 struct tas5720_data *tas5720 = container_of(work, struct tas5720_data, 220 fault_check_work.work); 221 struct device *dev = tas5720->component->dev; 222 unsigned int curr_fault; 223 int ret; 224 225 ret = regmap_read(tas5720->regmap, TAS5720_FAULT_REG, &curr_fault); 226 if (ret < 0) { 227 dev_err(dev, "failed to read FAULT register: %d\n", ret); 228 goto out; 229 } 230 231 /* Check/handle all errors except SAIF clock errors */ 232 curr_fault &= TAS5720_OCE | TAS5720_DCE | TAS5720_OTE; 233 234 /* 235 * Only flag errors once for a given occurrence. This is needed as 236 * the TAS5720 will take time clearing the fault condition internally 237 * during which we don't want to bombard the system with the same 238 * error message over and over. 239 */ 240 if ((curr_fault & TAS5720_OCE) && !(tas5720->last_fault & TAS5720_OCE)) 241 dev_crit(dev, "experienced an over current hardware fault\n"); 242 243 if ((curr_fault & TAS5720_DCE) && !(tas5720->last_fault & TAS5720_DCE)) 244 dev_crit(dev, "experienced a DC detection fault\n"); 245 246 if ((curr_fault & TAS5720_OTE) && !(tas5720->last_fault & TAS5720_OTE)) 247 dev_crit(dev, "experienced an over temperature fault\n"); 248 249 /* Store current fault value so we can detect any changes next time */ 250 tas5720->last_fault = curr_fault; 251 252 if (!curr_fault) 253 goto out; 254 255 /* 256 * Periodically toggle SDZ (shutdown bit) H->L->H to clear any latching 257 * faults as long as a fault condition persists. Always going through 258 * the full sequence no matter the first return value to minimizes 259 * chances for the device to end up in shutdown mode. 260 */ 261 ret = regmap_write_bits(tas5720->regmap, TAS5720_POWER_CTRL_REG, 262 TAS5720_SDZ, 0); 263 if (ret < 0) 264 dev_err(dev, "failed to write POWER_CTRL register: %d\n", ret); 265 266 ret = regmap_write_bits(tas5720->regmap, TAS5720_POWER_CTRL_REG, 267 TAS5720_SDZ, TAS5720_SDZ); 268 if (ret < 0) 269 dev_err(dev, "failed to write POWER_CTRL register: %d\n", ret); 270 271 out: 272 /* Schedule the next fault check at the specified interval */ 273 schedule_delayed_work(&tas5720->fault_check_work, 274 msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL)); 275 } 276 277 static int tas5720_codec_probe(struct snd_soc_component *component) 278 { 279 struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component); 280 unsigned int device_id, expected_device_id; 281 int ret; 282 283 tas5720->component = component; 284 285 ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies), 286 tas5720->supplies); 287 if (ret != 0) { 288 dev_err(component->dev, "failed to enable supplies: %d\n", ret); 289 return ret; 290 } 291 292 /* 293 * Take a liberal approach to checking the device ID to allow the 294 * driver to be used even if the device ID does not match, however 295 * issue a warning if there is a mismatch. 296 */ 297 ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id); 298 if (ret < 0) { 299 dev_err(component->dev, "failed to read device ID register: %d\n", 300 ret); 301 goto probe_fail; 302 } 303 304 switch (tas5720->devtype) { 305 case TAS5720: 306 expected_device_id = TAS5720_DEVICE_ID; 307 break; 308 case TAS5722: 309 expected_device_id = TAS5722_DEVICE_ID; 310 break; 311 default: 312 dev_err(component->dev, "unexpected private driver data\n"); 313 return -EINVAL; 314 } 315 316 if (device_id != expected_device_id) 317 dev_warn(component->dev, "wrong device ID. expected: %u read: %u\n", 318 expected_device_id, device_id); 319 320 /* Set device to mute */ 321 ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG, 322 TAS5720_MUTE, TAS5720_MUTE); 323 if (ret < 0) 324 goto error_snd_soc_component_update_bits; 325 326 /* 327 * Enter shutdown mode - our default when not playing audio - to 328 * minimize current consumption. On the TAS5720 there is no real down 329 * side doing so as all device registers are preserved and the wakeup 330 * of the codec is rather quick which we do using a dapm widget. 331 */ 332 ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG, 333 TAS5720_SDZ, 0); 334 if (ret < 0) 335 goto error_snd_soc_component_update_bits; 336 337 INIT_DELAYED_WORK(&tas5720->fault_check_work, tas5720_fault_check_work); 338 339 return 0; 340 341 error_snd_soc_component_update_bits: 342 dev_err(component->dev, "error configuring device registers: %d\n", ret); 343 344 probe_fail: 345 regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies), 346 tas5720->supplies); 347 return ret; 348 } 349 350 static void tas5720_codec_remove(struct snd_soc_component *component) 351 { 352 struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component); 353 int ret; 354 355 cancel_delayed_work_sync(&tas5720->fault_check_work); 356 357 ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies), 358 tas5720->supplies); 359 if (ret < 0) 360 dev_err(component->dev, "failed to disable supplies: %d\n", ret); 361 }; 362 363 static int tas5720_dac_event(struct snd_soc_dapm_widget *w, 364 struct snd_kcontrol *kcontrol, int event) 365 { 366 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 367 struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component); 368 int ret; 369 370 if (event & SND_SOC_DAPM_POST_PMU) { 371 /* Take TAS5720 out of shutdown mode */ 372 ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG, 373 TAS5720_SDZ, TAS5720_SDZ); 374 if (ret < 0) { 375 dev_err(component->dev, "error waking component: %d\n", ret); 376 return ret; 377 } 378 379 /* 380 * Observe codec shutdown-to-active time. The datasheet only 381 * lists a nominal value however just use-it as-is without 382 * additional padding to minimize the delay introduced in 383 * starting to play audio (actually there is other setup done 384 * by the ASoC framework that will provide additional delays, 385 * so we should always be safe). 386 */ 387 msleep(25); 388 389 /* Turn on TAS5720 periodic fault checking/handling */ 390 tas5720->last_fault = 0; 391 schedule_delayed_work(&tas5720->fault_check_work, 392 msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL)); 393 } else if (event & SND_SOC_DAPM_PRE_PMD) { 394 /* Disable TAS5720 periodic fault checking/handling */ 395 cancel_delayed_work_sync(&tas5720->fault_check_work); 396 397 /* Place TAS5720 in shutdown mode to minimize current draw */ 398 ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG, 399 TAS5720_SDZ, 0); 400 if (ret < 0) { 401 dev_err(component->dev, "error shutting down component: %d\n", 402 ret); 403 return ret; 404 } 405 } 406 407 return 0; 408 } 409 410 #ifdef CONFIG_PM 411 static int tas5720_suspend(struct snd_soc_component *component) 412 { 413 struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component); 414 int ret; 415 416 regcache_cache_only(tas5720->regmap, true); 417 regcache_mark_dirty(tas5720->regmap); 418 419 ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies), 420 tas5720->supplies); 421 if (ret < 0) 422 dev_err(component->dev, "failed to disable supplies: %d\n", ret); 423 424 return ret; 425 } 426 427 static int tas5720_resume(struct snd_soc_component *component) 428 { 429 struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component); 430 int ret; 431 432 ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies), 433 tas5720->supplies); 434 if (ret < 0) { 435 dev_err(component->dev, "failed to enable supplies: %d\n", ret); 436 return ret; 437 } 438 439 regcache_cache_only(tas5720->regmap, false); 440 441 ret = regcache_sync(tas5720->regmap); 442 if (ret < 0) { 443 dev_err(component->dev, "failed to sync regcache: %d\n", ret); 444 return ret; 445 } 446 447 return 0; 448 } 449 #else 450 #define tas5720_suspend NULL 451 #define tas5720_resume NULL 452 #endif 453 454 static bool tas5720_is_volatile_reg(struct device *dev, unsigned int reg) 455 { 456 switch (reg) { 457 case TAS5720_DEVICE_ID_REG: 458 case TAS5720_FAULT_REG: 459 return true; 460 default: 461 return false; 462 } 463 } 464 465 static const struct regmap_config tas5720_regmap_config = { 466 .reg_bits = 8, 467 .val_bits = 8, 468 469 .max_register = TAS5720_MAX_REG, 470 .cache_type = REGCACHE_RBTREE, 471 .volatile_reg = tas5720_is_volatile_reg, 472 }; 473 474 static const struct regmap_config tas5722_regmap_config = { 475 .reg_bits = 8, 476 .val_bits = 8, 477 478 .max_register = TAS5722_MAX_REG, 479 .cache_type = REGCACHE_RBTREE, 480 .volatile_reg = tas5720_is_volatile_reg, 481 }; 482 483 /* 484 * DAC analog gain. There are four discrete values to select from, ranging 485 * from 19.2 dB to 26.3dB. 486 */ 487 static const DECLARE_TLV_DB_RANGE(dac_analog_tlv, 488 0x0, 0x0, TLV_DB_SCALE_ITEM(1920, 0, 0), 489 0x1, 0x1, TLV_DB_SCALE_ITEM(2070, 0, 0), 490 0x2, 0x2, TLV_DB_SCALE_ITEM(2350, 0, 0), 491 0x3, 0x3, TLV_DB_SCALE_ITEM(2630, 0, 0), 492 ); 493 494 /* 495 * DAC digital volumes. From -103.5 to 24 dB in 0.5 dB or 0.25 dB steps 496 * depending on the device. Note that setting the gain below -100 dB 497 * (register value <0x7) is effectively a MUTE as per device datasheet. 498 * 499 * Note that for the TAS5722 the digital volume controls are actually split 500 * over two registers, so we need custom getters/setters for access. 501 */ 502 static DECLARE_TLV_DB_SCALE(tas5720_dac_tlv, -10350, 50, 0); 503 static DECLARE_TLV_DB_SCALE(tas5722_dac_tlv, -10350, 25, 0); 504 505 static int tas5722_volume_get(struct snd_kcontrol *kcontrol, 506 struct snd_ctl_elem_value *ucontrol) 507 { 508 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 509 unsigned int val; 510 511 val = snd_soc_component_read(component, TAS5720_VOLUME_CTRL_REG); 512 ucontrol->value.integer.value[0] = val << 1; 513 514 val = snd_soc_component_read(component, TAS5722_DIGITAL_CTRL2_REG); 515 ucontrol->value.integer.value[0] |= val & TAS5722_VOL_CONTROL_LSB; 516 517 return 0; 518 } 519 520 static int tas5722_volume_set(struct snd_kcontrol *kcontrol, 521 struct snd_ctl_elem_value *ucontrol) 522 { 523 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 524 unsigned int sel = ucontrol->value.integer.value[0]; 525 526 snd_soc_component_write(component, TAS5720_VOLUME_CTRL_REG, sel >> 1); 527 snd_soc_component_update_bits(component, TAS5722_DIGITAL_CTRL2_REG, 528 TAS5722_VOL_CONTROL_LSB, sel); 529 530 return 0; 531 } 532 533 static const struct snd_kcontrol_new tas5720_snd_controls[] = { 534 SOC_SINGLE_TLV("Speaker Driver Playback Volume", 535 TAS5720_VOLUME_CTRL_REG, 0, 0xff, 0, tas5720_dac_tlv), 536 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG, 537 TAS5720_ANALOG_GAIN_SHIFT, 3, 0, dac_analog_tlv), 538 }; 539 540 static const struct snd_kcontrol_new tas5722_snd_controls[] = { 541 SOC_SINGLE_EXT_TLV("Speaker Driver Playback Volume", 542 0, 0, 511, 0, 543 tas5722_volume_get, tas5722_volume_set, 544 tas5722_dac_tlv), 545 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG, 546 TAS5720_ANALOG_GAIN_SHIFT, 3, 0, dac_analog_tlv), 547 }; 548 549 static const struct snd_soc_dapm_widget tas5720_dapm_widgets[] = { 550 SND_SOC_DAPM_AIF_IN("DAC IN", "Playback", 0, SND_SOC_NOPM, 0, 0), 551 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas5720_dac_event, 552 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 553 SND_SOC_DAPM_OUTPUT("OUT") 554 }; 555 556 static const struct snd_soc_dapm_route tas5720_audio_map[] = { 557 { "DAC", NULL, "DAC IN" }, 558 { "OUT", NULL, "DAC" }, 559 }; 560 561 static const struct snd_soc_component_driver soc_component_dev_tas5720 = { 562 .probe = tas5720_codec_probe, 563 .remove = tas5720_codec_remove, 564 .suspend = tas5720_suspend, 565 .resume = tas5720_resume, 566 .controls = tas5720_snd_controls, 567 .num_controls = ARRAY_SIZE(tas5720_snd_controls), 568 .dapm_widgets = tas5720_dapm_widgets, 569 .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), 570 .dapm_routes = tas5720_audio_map, 571 .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), 572 .idle_bias_on = 1, 573 .use_pmdown_time = 1, 574 .endianness = 1, 575 .non_legacy_dai_naming = 1, 576 }; 577 578 static const struct snd_soc_component_driver soc_component_dev_tas5722 = { 579 .probe = tas5720_codec_probe, 580 .remove = tas5720_codec_remove, 581 .suspend = tas5720_suspend, 582 .resume = tas5720_resume, 583 .controls = tas5722_snd_controls, 584 .num_controls = ARRAY_SIZE(tas5722_snd_controls), 585 .dapm_widgets = tas5720_dapm_widgets, 586 .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), 587 .dapm_routes = tas5720_audio_map, 588 .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), 589 .idle_bias_on = 1, 590 .use_pmdown_time = 1, 591 .endianness = 1, 592 .non_legacy_dai_naming = 1, 593 }; 594 595 /* PCM rates supported by the TAS5720 driver */ 596 #define TAS5720_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 597 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 598 599 /* Formats supported by TAS5720 driver */ 600 #define TAS5720_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\ 601 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) 602 603 static const struct snd_soc_dai_ops tas5720_speaker_dai_ops = { 604 .hw_params = tas5720_hw_params, 605 .set_fmt = tas5720_set_dai_fmt, 606 .set_tdm_slot = tas5720_set_dai_tdm_slot, 607 .mute_stream = tas5720_mute, 608 .no_capture_mute = 1, 609 }; 610 611 /* 612 * TAS5720 DAI structure 613 * 614 * Note that were are advertising .playback.channels_max = 2 despite this being 615 * a mono amplifier. The reason for that is that some serial ports such as TI's 616 * McASP module have a minimum number of channels (2) that they can output. 617 * Advertising more channels than we have will allow us to interface with such 618 * a serial port without really any negative side effects as the TAS5720 will 619 * simply ignore any extra channel(s) asides from the one channel that is 620 * configured to be played back. 621 */ 622 static struct snd_soc_dai_driver tas5720_dai[] = { 623 { 624 .name = "tas5720-amplifier", 625 .playback = { 626 .stream_name = "Playback", 627 .channels_min = 1, 628 .channels_max = 2, 629 .rates = TAS5720_RATES, 630 .formats = TAS5720_FORMATS, 631 }, 632 .ops = &tas5720_speaker_dai_ops, 633 }, 634 }; 635 636 static const struct i2c_device_id tas5720_id[] = { 637 { "tas5720", TAS5720 }, 638 { "tas5722", TAS5722 }, 639 { } 640 }; 641 MODULE_DEVICE_TABLE(i2c, tas5720_id); 642 643 static int tas5720_probe(struct i2c_client *client) 644 { 645 struct device *dev = &client->dev; 646 struct tas5720_data *data; 647 const struct regmap_config *regmap_config; 648 const struct i2c_device_id *id; 649 int ret; 650 int i; 651 652 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 653 if (!data) 654 return -ENOMEM; 655 656 id = i2c_match_id(tas5720_id, client); 657 data->tas5720_client = client; 658 data->devtype = id->driver_data; 659 660 switch (id->driver_data) { 661 case TAS5720: 662 regmap_config = &tas5720_regmap_config; 663 break; 664 case TAS5722: 665 regmap_config = &tas5722_regmap_config; 666 break; 667 default: 668 dev_err(dev, "unexpected private driver data\n"); 669 return -EINVAL; 670 } 671 data->regmap = devm_regmap_init_i2c(client, regmap_config); 672 if (IS_ERR(data->regmap)) { 673 ret = PTR_ERR(data->regmap); 674 dev_err(dev, "failed to allocate register map: %d\n", ret); 675 return ret; 676 } 677 678 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 679 data->supplies[i].supply = tas5720_supply_names[i]; 680 681 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), 682 data->supplies); 683 if (ret != 0) { 684 dev_err(dev, "failed to request supplies: %d\n", ret); 685 return ret; 686 } 687 688 dev_set_drvdata(dev, data); 689 690 switch (id->driver_data) { 691 case TAS5720: 692 ret = devm_snd_soc_register_component(&client->dev, 693 &soc_component_dev_tas5720, 694 tas5720_dai, 695 ARRAY_SIZE(tas5720_dai)); 696 break; 697 case TAS5722: 698 ret = devm_snd_soc_register_component(&client->dev, 699 &soc_component_dev_tas5722, 700 tas5720_dai, 701 ARRAY_SIZE(tas5720_dai)); 702 break; 703 default: 704 dev_err(dev, "unexpected private driver data\n"); 705 return -EINVAL; 706 } 707 if (ret < 0) { 708 dev_err(dev, "failed to register component: %d\n", ret); 709 return ret; 710 } 711 712 return 0; 713 } 714 715 #if IS_ENABLED(CONFIG_OF) 716 static const struct of_device_id tas5720_of_match[] = { 717 { .compatible = "ti,tas5720", }, 718 { .compatible = "ti,tas5722", }, 719 { }, 720 }; 721 MODULE_DEVICE_TABLE(of, tas5720_of_match); 722 #endif 723 724 static struct i2c_driver tas5720_i2c_driver = { 725 .driver = { 726 .name = "tas5720", 727 .of_match_table = of_match_ptr(tas5720_of_match), 728 }, 729 .probe_new = tas5720_probe, 730 .id_table = tas5720_id, 731 }; 732 733 module_i2c_driver(tas5720_i2c_driver); 734 735 MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>"); 736 MODULE_DESCRIPTION("TAS5720 Audio amplifier driver"); 737 MODULE_LICENSE("GPL"); 738