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