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