1 /* 2 * TAS571x amplifier audio driver 3 * 4 * Copyright (C) 2015 Google, Inc. 5 * Copyright (c) 2013 Daniel Mack <zonque@gmail.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13 #include <linux/clk.h> 14 #include <linux/delay.h> 15 #include <linux/device.h> 16 #include <linux/gpio/consumer.h> 17 #include <linux/i2c.h> 18 #include <linux/init.h> 19 #include <linux/kernel.h> 20 #include <linux/module.h> 21 #include <linux/of_device.h> 22 #include <linux/regmap.h> 23 #include <linux/regulator/consumer.h> 24 #include <linux/stddef.h> 25 #include <sound/pcm_params.h> 26 #include <sound/soc.h> 27 #include <sound/tlv.h> 28 29 #include "tas571x.h" 30 31 #define TAS571X_MAX_SUPPLIES 6 32 33 struct tas571x_chip { 34 const char *const *supply_names; 35 int num_supply_names; 36 const struct snd_kcontrol_new *controls; 37 int num_controls; 38 const struct regmap_config *regmap_config; 39 int vol_reg_size; 40 }; 41 42 struct tas571x_private { 43 const struct tas571x_chip *chip; 44 struct regmap *regmap; 45 struct regulator_bulk_data supplies[TAS571X_MAX_SUPPLIES]; 46 struct clk *mclk; 47 unsigned int format; 48 struct gpio_desc *reset_gpio; 49 struct gpio_desc *pdn_gpio; 50 struct snd_soc_codec_driver codec_driver; 51 }; 52 53 static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg) 54 { 55 switch (reg) { 56 case TAS571X_MVOL_REG: 57 case TAS571X_CH1_VOL_REG: 58 case TAS571X_CH2_VOL_REG: 59 return priv->chip->vol_reg_size; 60 default: 61 return 1; 62 } 63 } 64 65 static int tas571x_reg_write(void *context, unsigned int reg, 66 unsigned int value) 67 { 68 struct i2c_client *client = context; 69 struct tas571x_private *priv = i2c_get_clientdata(client); 70 unsigned int i, size; 71 uint8_t buf[5]; 72 int ret; 73 74 size = tas571x_register_size(priv, reg); 75 buf[0] = reg; 76 77 for (i = size; i >= 1; --i) { 78 buf[i] = value; 79 value >>= 8; 80 } 81 82 ret = i2c_master_send(client, buf, size + 1); 83 if (ret == size + 1) 84 return 0; 85 else if (ret < 0) 86 return ret; 87 else 88 return -EIO; 89 } 90 91 static int tas571x_reg_read(void *context, unsigned int reg, 92 unsigned int *value) 93 { 94 struct i2c_client *client = context; 95 struct tas571x_private *priv = i2c_get_clientdata(client); 96 uint8_t send_buf, recv_buf[4]; 97 struct i2c_msg msgs[2]; 98 unsigned int size; 99 unsigned int i; 100 int ret; 101 102 size = tas571x_register_size(priv, reg); 103 send_buf = reg; 104 105 msgs[0].addr = client->addr; 106 msgs[0].len = sizeof(send_buf); 107 msgs[0].buf = &send_buf; 108 msgs[0].flags = 0; 109 110 msgs[1].addr = client->addr; 111 msgs[1].len = size; 112 msgs[1].buf = recv_buf; 113 msgs[1].flags = I2C_M_RD; 114 115 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 116 if (ret < 0) 117 return ret; 118 else if (ret != ARRAY_SIZE(msgs)) 119 return -EIO; 120 121 *value = 0; 122 123 for (i = 0; i < size; i++) { 124 *value <<= 8; 125 *value |= recv_buf[i]; 126 } 127 128 return 0; 129 } 130 131 static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format) 132 { 133 struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec); 134 135 priv->format = format; 136 137 return 0; 138 } 139 140 static int tas571x_hw_params(struct snd_pcm_substream *substream, 141 struct snd_pcm_hw_params *params, 142 struct snd_soc_dai *dai) 143 { 144 struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec); 145 u32 val; 146 147 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { 148 case SND_SOC_DAIFMT_RIGHT_J: 149 val = 0x00; 150 break; 151 case SND_SOC_DAIFMT_I2S: 152 val = 0x03; 153 break; 154 case SND_SOC_DAIFMT_LEFT_J: 155 val = 0x06; 156 break; 157 default: 158 return -EINVAL; 159 } 160 161 if (params_width(params) >= 24) 162 val += 2; 163 else if (params_width(params) >= 20) 164 val += 1; 165 166 return regmap_update_bits(priv->regmap, TAS571X_SDI_REG, 167 TAS571X_SDI_FMT_MASK, val); 168 } 169 170 static int tas571x_set_bias_level(struct snd_soc_codec *codec, 171 enum snd_soc_bias_level level) 172 { 173 struct tas571x_private *priv = snd_soc_codec_get_drvdata(codec); 174 int ret; 175 176 switch (level) { 177 case SND_SOC_BIAS_ON: 178 break; 179 case SND_SOC_BIAS_PREPARE: 180 break; 181 case SND_SOC_BIAS_STANDBY: 182 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 183 if (!IS_ERR(priv->mclk)) { 184 ret = clk_prepare_enable(priv->mclk); 185 if (ret) { 186 dev_err(codec->dev, 187 "Failed to enable master clock: %d\n", 188 ret); 189 return ret; 190 } 191 } 192 193 gpiod_set_value(priv->pdn_gpio, 0); 194 usleep_range(5000, 6000); 195 196 regcache_cache_only(priv->regmap, false); 197 ret = regcache_sync(priv->regmap); 198 if (ret) 199 return ret; 200 } 201 break; 202 case SND_SOC_BIAS_OFF: 203 regcache_cache_only(priv->regmap, true); 204 gpiod_set_value(priv->pdn_gpio, 1); 205 206 if (!IS_ERR(priv->mclk)) 207 clk_disable_unprepare(priv->mclk); 208 break; 209 } 210 211 return 0; 212 } 213 214 static const struct snd_soc_dai_ops tas571x_dai_ops = { 215 .set_fmt = tas571x_set_dai_fmt, 216 .hw_params = tas571x_hw_params, 217 }; 218 219 static const char *const tas5711_supply_names[] = { 220 "AVDD", 221 "DVDD", 222 "PVDD_A", 223 "PVDD_B", 224 "PVDD_C", 225 "PVDD_D", 226 }; 227 228 static const DECLARE_TLV_DB_SCALE(tas5711_volume_tlv, -10350, 50, 1); 229 230 static const struct snd_kcontrol_new tas5711_controls[] = { 231 SOC_SINGLE_TLV("Master Volume", 232 TAS571X_MVOL_REG, 233 0, 0xff, 1, tas5711_volume_tlv), 234 SOC_DOUBLE_R_TLV("Speaker Volume", 235 TAS571X_CH1_VOL_REG, 236 TAS571X_CH2_VOL_REG, 237 0, 0xff, 1, tas5711_volume_tlv), 238 SOC_DOUBLE("Speaker Switch", 239 TAS571X_SOFT_MUTE_REG, 240 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, 241 1, 1), 242 }; 243 244 static const struct reg_default tas5711_reg_defaults[] = { 245 { 0x04, 0x05 }, 246 { 0x05, 0x40 }, 247 { 0x06, 0x00 }, 248 { 0x07, 0xff }, 249 { 0x08, 0x30 }, 250 { 0x09, 0x30 }, 251 { 0x1b, 0x82 }, 252 }; 253 254 static const struct regmap_config tas5711_regmap_config = { 255 .reg_bits = 8, 256 .val_bits = 32, 257 .max_register = 0xff, 258 .reg_read = tas571x_reg_read, 259 .reg_write = tas571x_reg_write, 260 .reg_defaults = tas5711_reg_defaults, 261 .num_reg_defaults = ARRAY_SIZE(tas5711_reg_defaults), 262 .cache_type = REGCACHE_RBTREE, 263 }; 264 265 static const struct tas571x_chip tas5711_chip = { 266 .supply_names = tas5711_supply_names, 267 .num_supply_names = ARRAY_SIZE(tas5711_supply_names), 268 .controls = tas5711_controls, 269 .num_controls = ARRAY_SIZE(tas5711_controls), 270 .regmap_config = &tas5711_regmap_config, 271 .vol_reg_size = 1, 272 }; 273 274 static const char *const tas5717_supply_names[] = { 275 "AVDD", 276 "DVDD", 277 "HPVDD", 278 "PVDD_AB", 279 "PVDD_CD", 280 }; 281 282 static const DECLARE_TLV_DB_SCALE(tas5717_volume_tlv, -10375, 25, 0); 283 284 static const struct snd_kcontrol_new tas5717_controls[] = { 285 /* MVOL LSB is ignored - see comments in tas571x_i2c_probe() */ 286 SOC_SINGLE_TLV("Master Volume", 287 TAS571X_MVOL_REG, 1, 0x1ff, 1, 288 tas5717_volume_tlv), 289 SOC_DOUBLE_R_TLV("Speaker Volume", 290 TAS571X_CH1_VOL_REG, TAS571X_CH2_VOL_REG, 291 1, 0x1ff, 1, tas5717_volume_tlv), 292 SOC_DOUBLE("Speaker Switch", 293 TAS571X_SOFT_MUTE_REG, 294 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, 295 1, 1), 296 }; 297 298 static const struct reg_default tas5717_reg_defaults[] = { 299 { 0x04, 0x05 }, 300 { 0x05, 0x40 }, 301 { 0x06, 0x00 }, 302 { 0x07, 0x03ff }, 303 { 0x08, 0x00c0 }, 304 { 0x09, 0x00c0 }, 305 { 0x1b, 0x82 }, 306 }; 307 308 static const struct regmap_config tas5717_regmap_config = { 309 .reg_bits = 8, 310 .val_bits = 32, 311 .max_register = 0xff, 312 .reg_read = tas571x_reg_read, 313 .reg_write = tas571x_reg_write, 314 .reg_defaults = tas5717_reg_defaults, 315 .num_reg_defaults = ARRAY_SIZE(tas5717_reg_defaults), 316 .cache_type = REGCACHE_RBTREE, 317 }; 318 319 /* This entry is reused for tas5719 as the software interface is identical. */ 320 static const struct tas571x_chip tas5717_chip = { 321 .supply_names = tas5717_supply_names, 322 .num_supply_names = ARRAY_SIZE(tas5717_supply_names), 323 .controls = tas5717_controls, 324 .num_controls = ARRAY_SIZE(tas5717_controls), 325 .regmap_config = &tas5717_regmap_config, 326 .vol_reg_size = 2, 327 }; 328 329 static const struct snd_soc_dapm_widget tas571x_dapm_widgets[] = { 330 SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0), 331 SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0), 332 333 SND_SOC_DAPM_OUTPUT("OUT_A"), 334 SND_SOC_DAPM_OUTPUT("OUT_B"), 335 SND_SOC_DAPM_OUTPUT("OUT_C"), 336 SND_SOC_DAPM_OUTPUT("OUT_D"), 337 }; 338 339 static const struct snd_soc_dapm_route tas571x_dapm_routes[] = { 340 { "DACL", NULL, "Playback" }, 341 { "DACR", NULL, "Playback" }, 342 343 { "OUT_A", NULL, "DACL" }, 344 { "OUT_B", NULL, "DACL" }, 345 { "OUT_C", NULL, "DACR" }, 346 { "OUT_D", NULL, "DACR" }, 347 }; 348 349 static const struct snd_soc_codec_driver tas571x_codec = { 350 .set_bias_level = tas571x_set_bias_level, 351 .idle_bias_off = true, 352 353 .dapm_widgets = tas571x_dapm_widgets, 354 .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets), 355 .dapm_routes = tas571x_dapm_routes, 356 .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), 357 }; 358 359 static struct snd_soc_dai_driver tas571x_dai = { 360 .name = "tas571x-hifi", 361 .playback = { 362 .stream_name = "Playback", 363 .channels_min = 2, 364 .channels_max = 2, 365 .rates = SNDRV_PCM_RATE_8000_48000, 366 .formats = SNDRV_PCM_FMTBIT_S32_LE | 367 SNDRV_PCM_FMTBIT_S24_LE | 368 SNDRV_PCM_FMTBIT_S16_LE, 369 }, 370 .ops = &tas571x_dai_ops, 371 }; 372 373 static const struct of_device_id tas571x_of_match[]; 374 375 static int tas571x_i2c_probe(struct i2c_client *client, 376 const struct i2c_device_id *id) 377 { 378 struct tas571x_private *priv; 379 struct device *dev = &client->dev; 380 const struct of_device_id *of_id; 381 int i, ret; 382 383 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 384 if (!priv) 385 return -ENOMEM; 386 i2c_set_clientdata(client, priv); 387 388 of_id = of_match_device(tas571x_of_match, dev); 389 if (!of_id) { 390 dev_err(dev, "Unknown device type\n"); 391 return -EINVAL; 392 } 393 priv->chip = of_id->data; 394 395 priv->mclk = devm_clk_get(dev, "mclk"); 396 if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) { 397 dev_err(dev, "Failed to request mclk: %ld\n", 398 PTR_ERR(priv->mclk)); 399 return PTR_ERR(priv->mclk); 400 } 401 402 BUG_ON(priv->chip->num_supply_names > TAS571X_MAX_SUPPLIES); 403 for (i = 0; i < priv->chip->num_supply_names; i++) 404 priv->supplies[i].supply = priv->chip->supply_names[i]; 405 406 ret = devm_regulator_bulk_get(dev, priv->chip->num_supply_names, 407 priv->supplies); 408 if (ret) { 409 dev_err(dev, "Failed to get supplies: %d\n", ret); 410 return ret; 411 } 412 ret = regulator_bulk_enable(priv->chip->num_supply_names, 413 priv->supplies); 414 if (ret) { 415 dev_err(dev, "Failed to enable supplies: %d\n", ret); 416 return ret; 417 } 418 419 priv->regmap = devm_regmap_init(dev, NULL, client, 420 priv->chip->regmap_config); 421 if (IS_ERR(priv->regmap)) 422 return PTR_ERR(priv->regmap); 423 424 priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW); 425 if (IS_ERR(priv->pdn_gpio)) { 426 dev_err(dev, "error requesting pdn_gpio: %ld\n", 427 PTR_ERR(priv->pdn_gpio)); 428 return PTR_ERR(priv->pdn_gpio); 429 } 430 431 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", 432 GPIOD_OUT_HIGH); 433 if (IS_ERR(priv->reset_gpio)) { 434 dev_err(dev, "error requesting reset_gpio: %ld\n", 435 PTR_ERR(priv->reset_gpio)); 436 return PTR_ERR(priv->reset_gpio); 437 } else if (priv->reset_gpio) { 438 /* pulse the active low reset line for ~100us */ 439 usleep_range(100, 200); 440 gpiod_set_value(priv->reset_gpio, 0); 441 usleep_range(12000, 20000); 442 } 443 444 ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0); 445 if (ret) 446 return ret; 447 448 ret = regmap_update_bits(priv->regmap, TAS571X_SYS_CTRL_2_REG, 449 TAS571X_SYS_CTRL_2_SDN_MASK, 0); 450 if (ret) 451 return ret; 452 453 memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); 454 priv->codec_driver.controls = priv->chip->controls; 455 priv->codec_driver.num_controls = priv->chip->num_controls; 456 457 if (priv->chip->vol_reg_size == 2) { 458 /* 459 * The master volume defaults to 0x3ff (mute), but we ignore 460 * (zero) the LSB because the hardware step size is 0.125 dB 461 * and TLV_DB_SCALE_ITEM has a resolution of 0.01 dB. 462 */ 463 ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0); 464 if (ret) 465 return ret; 466 } 467 468 regcache_cache_only(priv->regmap, true); 469 gpiod_set_value(priv->pdn_gpio, 1); 470 471 return snd_soc_register_codec(&client->dev, &priv->codec_driver, 472 &tas571x_dai, 1); 473 } 474 475 static int tas571x_i2c_remove(struct i2c_client *client) 476 { 477 struct tas571x_private *priv = i2c_get_clientdata(client); 478 479 snd_soc_unregister_codec(&client->dev); 480 regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies); 481 482 return 0; 483 } 484 485 static const struct of_device_id tas571x_of_match[] = { 486 { .compatible = "ti,tas5711", .data = &tas5711_chip, }, 487 { .compatible = "ti,tas5717", .data = &tas5717_chip, }, 488 { .compatible = "ti,tas5719", .data = &tas5717_chip, }, 489 { } 490 }; 491 MODULE_DEVICE_TABLE(of, tas571x_of_match); 492 493 static const struct i2c_device_id tas571x_i2c_id[] = { 494 { "tas5711", 0 }, 495 { "tas5717", 0 }, 496 { "tas5719", 0 }, 497 { } 498 }; 499 MODULE_DEVICE_TABLE(i2c, tas571x_i2c_id); 500 501 static struct i2c_driver tas571x_i2c_driver = { 502 .driver = { 503 .name = "tas571x", 504 .of_match_table = of_match_ptr(tas571x_of_match), 505 }, 506 .probe = tas571x_i2c_probe, 507 .remove = tas571x_i2c_remove, 508 .id_table = tas571x_i2c_id, 509 }; 510 module_i2c_driver(tas571x_i2c_driver); 511 512 MODULE_DESCRIPTION("ASoC TAS571x driver"); 513 MODULE_AUTHOR("Kevin Cernekee <cernekee@chromium.org>"); 514 MODULE_LICENSE("GPL"); 515