1 /* 2 * tas2552.c - ALSA SoC Texas Instruments TAS2552 Mono Audio Amplifier 3 * 4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com 5 * 6 * Author: Dan Murphy <dmurphy@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/gpio.h> 23 #include <linux/of_gpio.h> 24 #include <linux/pm_runtime.h> 25 #include <linux/regmap.h> 26 #include <linux/slab.h> 27 28 #include <linux/gpio/consumer.h> 29 #include <linux/regulator/consumer.h> 30 31 #include <sound/pcm.h> 32 #include <sound/pcm_params.h> 33 #include <sound/soc.h> 34 #include <sound/soc-dapm.h> 35 #include <sound/tlv.h> 36 #include <sound/tas2552-plat.h> 37 38 #include "tas2552.h" 39 40 static struct reg_default tas2552_reg_defs[] = { 41 {TAS2552_CFG_1, 0x22}, 42 {TAS2552_CFG_3, 0x80}, 43 {TAS2552_DOUT, 0x00}, 44 {TAS2552_OUTPUT_DATA, 0xc0}, 45 {TAS2552_PDM_CFG, 0x01}, 46 {TAS2552_PGA_GAIN, 0x00}, 47 {TAS2552_BOOST_PT_CTRL, 0x0f}, 48 {TAS2552_RESERVED_0D, 0x00}, 49 {TAS2552_LIMIT_RATE_HYS, 0x08}, 50 {TAS2552_CFG_2, 0xef}, 51 {TAS2552_SER_CTRL_1, 0x00}, 52 {TAS2552_SER_CTRL_2, 0x00}, 53 {TAS2552_PLL_CTRL_1, 0x10}, 54 {TAS2552_PLL_CTRL_2, 0x00}, 55 {TAS2552_PLL_CTRL_3, 0x00}, 56 {TAS2552_BTIP, 0x8f}, 57 {TAS2552_BTS_CTRL, 0x80}, 58 {TAS2552_LIMIT_RELEASE, 0x04}, 59 {TAS2552_LIMIT_INT_COUNT, 0x00}, 60 {TAS2552_EDGE_RATE_CTRL, 0x40}, 61 {TAS2552_VBAT_DATA, 0x00}, 62 }; 63 64 #define TAS2552_NUM_SUPPLIES 3 65 static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = { 66 "vbat", /* vbat voltage */ 67 "iovdd", /* I/O Voltage */ 68 "avdd", /* Analog DAC Voltage */ 69 }; 70 71 struct tas2552_data { 72 struct snd_soc_codec *codec; 73 struct regmap *regmap; 74 struct i2c_client *tas2552_client; 75 struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES]; 76 struct gpio_desc *enable_gpio; 77 unsigned char regs[TAS2552_VBAT_DATA]; 78 unsigned int mclk; 79 }; 80 81 /* Input mux controls */ 82 static const char *tas2552_input_texts[] = { 83 "Digital", "Analog" 84 }; 85 86 static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7, 87 tas2552_input_texts); 88 89 static const struct snd_kcontrol_new tas2552_input_mux_control[] = { 90 SOC_DAPM_ENUM("Input selection", tas2552_input_mux_enum) 91 }; 92 93 static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] = 94 { 95 SND_SOC_DAPM_INPUT("IN"), 96 97 /* MUX Controls */ 98 SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0, 99 tas2552_input_mux_control), 100 101 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), 102 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), 103 SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0), 104 SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0), 105 106 SND_SOC_DAPM_OUTPUT("OUT") 107 }; 108 109 static const struct snd_soc_dapm_route tas2552_audio_map[] = { 110 {"DAC", NULL, "DAC IN"}, 111 {"Input selection", "Digital", "DAC"}, 112 {"Input selection", "Analog", "IN"}, 113 {"ClassD", NULL, "Input selection"}, 114 {"OUT", NULL, "ClassD"}, 115 {"ClassD", NULL, "PLL"}, 116 }; 117 118 #ifdef CONFIG_PM_RUNTIME 119 static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) 120 { 121 u8 cfg1_reg; 122 123 if (sw_shutdown) 124 cfg1_reg = 0; 125 else 126 cfg1_reg = TAS2552_SWS_MASK; 127 128 snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, 129 TAS2552_SWS_MASK, cfg1_reg); 130 } 131 #endif 132 133 static int tas2552_hw_params(struct snd_pcm_substream *substream, 134 struct snd_pcm_hw_params *params, 135 struct snd_soc_dai *dai) 136 { 137 struct snd_soc_codec *codec = dai->codec; 138 struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev); 139 int sample_rate, pll_clk; 140 int d; 141 u8 p, j; 142 143 if (!tas2552->mclk) 144 return -EINVAL; 145 146 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0); 147 148 if (tas2552->mclk == TAS2552_245MHZ_CLK || 149 tas2552->mclk == TAS2552_225MHZ_CLK) { 150 /* By pass the PLL configuration */ 151 snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2, 152 TAS2552_PLL_BYPASS_MASK, 153 TAS2552_PLL_BYPASS); 154 } else { 155 /* Fill in the PLL control registers for J & D 156 * PLL_CLK = (.5 * freq * J.D) / 2^p 157 * Need to fill in J and D here based on incoming freq 158 */ 159 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1); 160 p = (p >> 7); 161 sample_rate = params_rate(params); 162 163 if (sample_rate == 48000) 164 pll_clk = TAS2552_245MHZ_CLK; 165 else if (sample_rate == 44100) 166 pll_clk = TAS2552_225MHZ_CLK; 167 else { 168 dev_vdbg(codec->dev, "Substream sample rate is not found %i\n", 169 params_rate(params)); 170 return -EINVAL; 171 } 172 173 j = (pll_clk * 2 * (1 << p)) / tas2552->mclk; 174 d = (pll_clk * 2 * (1 << p)) % tas2552->mclk; 175 176 snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1, 177 TAS2552_PLL_J_MASK, j); 178 snd_soc_write(codec, TAS2552_PLL_CTRL_2, 179 (d >> 7) & TAS2552_PLL_D_UPPER_MASK); 180 snd_soc_write(codec, TAS2552_PLL_CTRL_3, 181 d & TAS2552_PLL_D_LOWER_MASK); 182 183 } 184 185 return 0; 186 } 187 188 static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 189 { 190 struct snd_soc_codec *codec = dai->codec; 191 u8 serial_format; 192 u8 serial_control_mask; 193 194 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 195 case SND_SOC_DAIFMT_CBS_CFS: 196 serial_format = 0x00; 197 break; 198 case SND_SOC_DAIFMT_CBS_CFM: 199 serial_format = TAS2552_WORD_CLK_MASK; 200 break; 201 case SND_SOC_DAIFMT_CBM_CFS: 202 serial_format = TAS2552_BIT_CLK_MASK; 203 break; 204 case SND_SOC_DAIFMT_CBM_CFM: 205 serial_format = (TAS2552_BIT_CLK_MASK | TAS2552_WORD_CLK_MASK); 206 break; 207 default: 208 dev_vdbg(codec->dev, "DAI Format master is not found\n"); 209 return -EINVAL; 210 } 211 212 serial_control_mask = TAS2552_BIT_CLK_MASK | TAS2552_WORD_CLK_MASK; 213 214 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 215 case SND_SOC_DAIFMT_I2S: 216 serial_format &= TAS2552_DAIFMT_I2S_MASK; 217 break; 218 case SND_SOC_DAIFMT_DSP_A: 219 serial_format |= TAS2552_DAIFMT_DSP; 220 break; 221 case SND_SOC_DAIFMT_RIGHT_J: 222 serial_format |= TAS2552_DAIFMT_RIGHT_J; 223 break; 224 case SND_SOC_DAIFMT_LEFT_J: 225 serial_format |= TAS2552_DAIFMT_LEFT_J; 226 break; 227 default: 228 dev_vdbg(codec->dev, "DAI Format is not found\n"); 229 return -EINVAL; 230 } 231 232 if (fmt & SND_SOC_DAIFMT_FORMAT_MASK) 233 serial_control_mask |= TAS2552_DATA_FORMAT_MASK; 234 235 snd_soc_update_bits(codec, TAS2552_SER_CTRL_1, serial_control_mask, 236 serial_format); 237 238 return 0; 239 } 240 241 static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 242 unsigned int freq, int dir) 243 { 244 struct snd_soc_codec *codec = dai->codec; 245 struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev); 246 247 tas2552->mclk = freq; 248 249 return 0; 250 } 251 252 static int tas2552_mute(struct snd_soc_dai *dai, int mute) 253 { 254 u8 cfg1_reg; 255 struct snd_soc_codec *codec = dai->codec; 256 257 if (mute) 258 cfg1_reg = TAS2552_MUTE_MASK; 259 else 260 cfg1_reg = ~TAS2552_MUTE_MASK; 261 262 snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE_MASK, cfg1_reg); 263 264 return 0; 265 } 266 267 #ifdef CONFIG_PM_RUNTIME 268 static int tas2552_runtime_suspend(struct device *dev) 269 { 270 struct tas2552_data *tas2552 = dev_get_drvdata(dev); 271 272 tas2552_sw_shutdown(tas2552, 0); 273 274 regcache_cache_only(tas2552->regmap, true); 275 regcache_mark_dirty(tas2552->regmap); 276 277 if (tas2552->enable_gpio) 278 gpiod_set_value(tas2552->enable_gpio, 0); 279 280 return 0; 281 } 282 283 static int tas2552_runtime_resume(struct device *dev) 284 { 285 struct tas2552_data *tas2552 = dev_get_drvdata(dev); 286 287 if (tas2552->enable_gpio) 288 gpiod_set_value(tas2552->enable_gpio, 1); 289 290 tas2552_sw_shutdown(tas2552, 1); 291 292 regcache_cache_only(tas2552->regmap, false); 293 regcache_sync(tas2552->regmap); 294 295 return 0; 296 } 297 #endif 298 299 static const struct dev_pm_ops tas2552_pm = { 300 SET_RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume, 301 NULL) 302 }; 303 304 static struct snd_soc_dai_ops tas2552_speaker_dai_ops = { 305 .hw_params = tas2552_hw_params, 306 .set_sysclk = tas2552_set_dai_sysclk, 307 .set_fmt = tas2552_set_dai_fmt, 308 .digital_mute = tas2552_mute, 309 }; 310 311 /* Formats supported by TAS2552 driver. */ 312 #define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 313 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 314 315 /* TAS2552 dai structure. */ 316 static struct snd_soc_dai_driver tas2552_dai[] = { 317 { 318 .name = "tas2552-amplifier", 319 .playback = { 320 .stream_name = "Playback", 321 .channels_min = 2, 322 .channels_max = 2, 323 .rates = SNDRV_PCM_RATE_8000_192000, 324 .formats = TAS2552_FORMATS, 325 }, 326 .ops = &tas2552_speaker_dai_ops, 327 }, 328 }; 329 330 /* 331 * DAC digital volumes. From -7 to 24 dB in 1 dB steps 332 */ 333 static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 24); 334 335 static const struct snd_kcontrol_new tas2552_snd_controls[] = { 336 SOC_SINGLE_TLV("Speaker Driver Playback Volume", 337 TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv), 338 SOC_DAPM_SINGLE("Playback AMP", SND_SOC_NOPM, 0, 1, 0), 339 }; 340 341 static const struct reg_default tas2552_init_regs[] = { 342 { TAS2552_RESERVED_0D, 0xc0 }, 343 }; 344 345 static int tas2552_codec_probe(struct snd_soc_codec *codec) 346 { 347 struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); 348 struct snd_soc_dapm_context *dapm = &codec->dapm; 349 int ret; 350 351 tas2552->codec = codec; 352 353 ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies), 354 tas2552->supplies); 355 356 if (ret != 0) { 357 dev_err(codec->dev, "Failed to enable supplies: %d\n", 358 ret); 359 return ret; 360 } 361 362 if (tas2552->enable_gpio) 363 gpiod_set_value(tas2552->enable_gpio, 1); 364 365 ret = pm_runtime_get_sync(codec->dev); 366 if (ret < 0) { 367 dev_err(codec->dev, "Enabling device failed: %d\n", 368 ret); 369 goto probe_fail; 370 } 371 372 snd_soc_write(codec, TAS2552_CFG_1, TAS2552_MUTE_MASK | 373 TAS2552_PLL_SRC_BCLK); 374 snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL | 375 TAS2552_DIN_SRC_SEL_AVG_L_R | TAS2552_88_96KHZ); 376 snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I); 377 snd_soc_write(codec, TAS2552_OUTPUT_DATA, TAS2552_PDM_DATA_V_I | 0x8); 378 snd_soc_write(codec, TAS2552_PDM_CFG, TAS2552_PDM_BCLK_SEL); 379 snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 | 380 TAS2552_APT_THRESH_2_1_7); 381 382 ret = regmap_register_patch(tas2552->regmap, tas2552_init_regs, 383 ARRAY_SIZE(tas2552_init_regs)); 384 if (ret != 0) { 385 dev_err(codec->dev, "Failed to write init registers: %d\n", 386 ret); 387 goto patch_fail; 388 } 389 390 snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | 391 TAS2552_APT_EN | TAS2552_LIM_EN); 392 393 snd_soc_dapm_new_controls(dapm, tas2552_dapm_widgets, 394 ARRAY_SIZE(tas2552_dapm_widgets)); 395 snd_soc_dapm_add_routes(dapm, tas2552_audio_map, 396 ARRAY_SIZE(tas2552_audio_map)); 397 398 return 0; 399 400 patch_fail: 401 pm_runtime_put(codec->dev); 402 probe_fail: 403 if (tas2552->enable_gpio) 404 gpiod_set_value(tas2552->enable_gpio, 0); 405 406 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies), 407 tas2552->supplies); 408 return -EIO; 409 } 410 411 static int tas2552_codec_remove(struct snd_soc_codec *codec) 412 { 413 struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); 414 415 pm_runtime_put(codec->dev); 416 417 if (tas2552->enable_gpio) 418 gpiod_set_value(tas2552->enable_gpio, 0); 419 420 return 0; 421 }; 422 423 #ifdef CONFIG_PM 424 static int tas2552_suspend(struct snd_soc_codec *codec) 425 { 426 struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); 427 int ret; 428 429 ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies), 430 tas2552->supplies); 431 432 if (ret != 0) 433 dev_err(codec->dev, "Failed to disable supplies: %d\n", 434 ret); 435 return 0; 436 } 437 438 static int tas2552_resume(struct snd_soc_codec *codec) 439 { 440 struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); 441 int ret; 442 443 ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies), 444 tas2552->supplies); 445 446 if (ret != 0) { 447 dev_err(codec->dev, "Failed to enable supplies: %d\n", 448 ret); 449 } 450 451 return 0; 452 } 453 #else 454 #define tas2552_suspend NULL 455 #define tas2552_resume NULL 456 #endif 457 458 static struct snd_soc_codec_driver soc_codec_dev_tas2552 = { 459 .probe = tas2552_codec_probe, 460 .remove = tas2552_codec_remove, 461 .suspend = tas2552_suspend, 462 .resume = tas2552_resume, 463 .controls = tas2552_snd_controls, 464 .num_controls = ARRAY_SIZE(tas2552_snd_controls), 465 }; 466 467 static const struct regmap_config tas2552_regmap_config = { 468 .reg_bits = 8, 469 .val_bits = 8, 470 471 .max_register = TAS2552_MAX_REG, 472 .reg_defaults = tas2552_reg_defs, 473 .num_reg_defaults = ARRAY_SIZE(tas2552_reg_defs), 474 .cache_type = REGCACHE_RBTREE, 475 }; 476 477 static int tas2552_probe(struct i2c_client *client, 478 const struct i2c_device_id *id) 479 { 480 struct device *dev; 481 struct tas2552_data *data; 482 int ret; 483 int i; 484 485 dev = &client->dev; 486 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 487 if (data == NULL) 488 return -ENOMEM; 489 490 data->enable_gpio = devm_gpiod_get(dev, "enable"); 491 if (IS_ERR(data->enable_gpio)) { 492 ret = PTR_ERR(data->enable_gpio); 493 if (ret != -ENOENT && ret != -ENOSYS) 494 return ret; 495 496 data->enable_gpio = NULL; 497 } else { 498 gpiod_direction_output(data->enable_gpio, 0); 499 } 500 501 data->tas2552_client = client; 502 data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config); 503 if (IS_ERR(data->regmap)) { 504 ret = PTR_ERR(data->regmap); 505 dev_err(&client->dev, "Failed to allocate register map: %d\n", 506 ret); 507 return ret; 508 } 509 510 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 511 data->supplies[i].supply = tas2552_supply_names[i]; 512 513 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), 514 data->supplies); 515 if (ret != 0) { 516 dev_err(dev, "Failed to request supplies: %d\n", ret); 517 return ret; 518 } 519 520 pm_runtime_set_active(&client->dev); 521 pm_runtime_set_autosuspend_delay(&client->dev, 1000); 522 pm_runtime_use_autosuspend(&client->dev); 523 pm_runtime_enable(&client->dev); 524 pm_runtime_mark_last_busy(&client->dev); 525 pm_runtime_put_sync_autosuspend(&client->dev); 526 527 dev_set_drvdata(&client->dev, data); 528 529 ret = snd_soc_register_codec(&client->dev, 530 &soc_codec_dev_tas2552, 531 tas2552_dai, ARRAY_SIZE(tas2552_dai)); 532 if (ret < 0) 533 dev_err(&client->dev, "Failed to register codec: %d\n", ret); 534 535 return ret; 536 } 537 538 static int tas2552_i2c_remove(struct i2c_client *client) 539 { 540 snd_soc_unregister_codec(&client->dev); 541 return 0; 542 } 543 544 static const struct i2c_device_id tas2552_id[] = { 545 { "tas2552", 0 }, 546 { } 547 }; 548 MODULE_DEVICE_TABLE(i2c, tas2552_id); 549 550 #if IS_ENABLED(CONFIG_OF) 551 static const struct of_device_id tas2552_of_match[] = { 552 { .compatible = "ti,tas2552", }, 553 {}, 554 }; 555 MODULE_DEVICE_TABLE(of, tas2552_of_match); 556 #endif 557 558 static struct i2c_driver tas2552_i2c_driver = { 559 .driver = { 560 .name = "tas2552", 561 .owner = THIS_MODULE, 562 .of_match_table = of_match_ptr(tas2552_of_match), 563 .pm = &tas2552_pm, 564 }, 565 .probe = tas2552_probe, 566 .remove = tas2552_i2c_remove, 567 .id_table = tas2552_id, 568 }; 569 570 module_i2c_driver(tas2552_i2c_driver); 571 572 MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>"); 573 MODULE_DESCRIPTION("TAS2552 Audio amplifier driver"); 574 MODULE_LICENSE("GPL"); 575