tas571x.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * TAS571x amplifier audio driver
  4. *
  5. * Copyright (C) 2015 Google, Inc.
  6. * Copyright (c) 2013 Daniel Mack <zonque@gmail.com>
  7. *
  8. * TAS5721 support:
  9. * Copyright (C) 2016 Petr Kulhavy, Barix AG <petr@barix.com>
  10. *
  11. * TAS5707 support:
  12. * Copyright (C) 2018 Jerome Brunet, Baylibre SAS <jbrunet@baylibre.com>
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/delay.h>
  16. #include <linux/device.h>
  17. #include <linux/gpio/consumer.h>
  18. #include <linux/i2c.h>
  19. #include <linux/init.h>
  20. #include <linux/kernel.h>
  21. #include <linux/module.h>
  22. #include <linux/of_device.h>
  23. #include <linux/regmap.h>
  24. #include <linux/regulator/consumer.h>
  25. #include <linux/stddef.h>
  26. #include <sound/pcm_params.h>
  27. #include <sound/soc.h>
  28. #include <sound/tlv.h>
  29. #include <asm/unaligned.h>
  30. #include "tas571x.h"
  31. #define TAS571X_MAX_SUPPLIES 6
  32. struct tas571x_chip {
  33. const char *const *supply_names;
  34. int num_supply_names;
  35. const struct snd_kcontrol_new *controls;
  36. int num_controls;
  37. const struct regmap_config *regmap_config;
  38. int vol_reg_size;
  39. };
  40. struct tas571x_private {
  41. const struct tas571x_chip *chip;
  42. struct regmap *regmap;
  43. struct regulator_bulk_data supplies[TAS571X_MAX_SUPPLIES];
  44. struct clk *mclk;
  45. unsigned int format;
  46. struct gpio_desc *reset_gpio;
  47. struct gpio_desc *pdn_gpio;
  48. struct snd_soc_component_driver component_driver;
  49. };
  50. static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
  51. {
  52. switch (reg) {
  53. case TAS571X_MVOL_REG:
  54. case TAS571X_CH1_VOL_REG:
  55. case TAS571X_CH2_VOL_REG:
  56. return priv->chip->vol_reg_size;
  57. case TAS571X_INPUT_MUX_REG:
  58. case TAS571X_CH4_SRC_SELECT_REG:
  59. case TAS571X_PWM_MUX_REG:
  60. case TAS5717_CH1_RIGHT_CH_MIX_REG:
  61. case TAS5717_CH1_LEFT_CH_MIX_REG:
  62. case TAS5717_CH2_LEFT_CH_MIX_REG:
  63. case TAS5717_CH2_RIGHT_CH_MIX_REG:
  64. return 4;
  65. default:
  66. return 1;
  67. }
  68. }
  69. static int tas571x_reg_write(void *context, unsigned int reg,
  70. unsigned int value)
  71. {
  72. struct i2c_client *client = context;
  73. struct tas571x_private *priv = i2c_get_clientdata(client);
  74. unsigned int i, size;
  75. uint8_t buf[5];
  76. int ret;
  77. size = tas571x_register_size(priv, reg);
  78. buf[0] = reg;
  79. for (i = size; i >= 1; --i) {
  80. buf[i] = value;
  81. value >>= 8;
  82. }
  83. ret = i2c_master_send(client, buf, size + 1);
  84. if (ret == size + 1)
  85. return 0;
  86. else if (ret < 0)
  87. return ret;
  88. else
  89. return -EIO;
  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. size = tas571x_register_size(priv, reg);
  102. send_buf = reg;
  103. msgs[0].addr = client->addr;
  104. msgs[0].len = sizeof(send_buf);
  105. msgs[0].buf = &send_buf;
  106. msgs[0].flags = 0;
  107. msgs[1].addr = client->addr;
  108. msgs[1].len = size;
  109. msgs[1].buf = recv_buf;
  110. msgs[1].flags = I2C_M_RD;
  111. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  112. if (ret < 0)
  113. return ret;
  114. else if (ret != ARRAY_SIZE(msgs))
  115. return -EIO;
  116. *value = 0;
  117. for (i = 0; i < size; i++) {
  118. *value <<= 8;
  119. *value |= recv_buf[i];
  120. }
  121. return 0;
  122. }
  123. /*
  124. * register write for 8- and 20-byte registers
  125. */
  126. static int tas571x_reg_write_multiword(struct i2c_client *client,
  127. unsigned int reg, const long values[], size_t len)
  128. {
  129. size_t i;
  130. uint8_t *buf, *p;
  131. int ret;
  132. size_t send_size = 1 + len * sizeof(uint32_t);
  133. buf = kzalloc(send_size, GFP_KERNEL | GFP_DMA);
  134. if (!buf)
  135. return -ENOMEM;
  136. buf[0] = reg;
  137. for (i = 0, p = buf + 1; i < len; i++, p += sizeof(uint32_t))
  138. put_unaligned_be32(values[i], p);
  139. ret = i2c_master_send(client, buf, send_size);
  140. kfree(buf);
  141. if (ret == send_size)
  142. return 0;
  143. else if (ret < 0)
  144. return ret;
  145. else
  146. return -EIO;
  147. }
  148. /*
  149. * register read for 8- and 20-byte registers
  150. */
  151. static int tas571x_reg_read_multiword(struct i2c_client *client,
  152. unsigned int reg, long values[], size_t len)
  153. {
  154. unsigned int i;
  155. uint8_t send_buf;
  156. uint8_t *recv_buf, *p;
  157. struct i2c_msg msgs[2];
  158. unsigned int recv_size = len * sizeof(uint32_t);
  159. int ret;
  160. recv_buf = kzalloc(recv_size, GFP_KERNEL | GFP_DMA);
  161. if (!recv_buf)
  162. return -ENOMEM;
  163. send_buf = reg;
  164. msgs[0].addr = client->addr;
  165. msgs[0].len = sizeof(send_buf);
  166. msgs[0].buf = &send_buf;
  167. msgs[0].flags = 0;
  168. msgs[1].addr = client->addr;
  169. msgs[1].len = recv_size;
  170. msgs[1].buf = recv_buf;
  171. msgs[1].flags = I2C_M_RD;
  172. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  173. if (ret < 0)
  174. goto err_ret;
  175. else if (ret != ARRAY_SIZE(msgs)) {
  176. ret = -EIO;
  177. goto err_ret;
  178. }
  179. for (i = 0, p = recv_buf; i < len; i++, p += sizeof(uint32_t))
  180. values[i] = get_unaligned_be32(p);
  181. err_ret:
  182. kfree(recv_buf);
  183. return ret;
  184. }
  185. /*
  186. * Integer array controls for setting biquad, mixer, DRC coefficients.
  187. * According to the datasheet each coefficient is effectively 26bits,
  188. * i.e. stored as 32bits, where bits [31:26] are ignored.
  189. * TI's TAS57xx Graphical Development Environment tool however produces
  190. * coefficients with more than 26 bits. For this reason we allow values
  191. * in the full 32-bits reange.
  192. * The coefficients are ordered as given in the TAS571x data sheet:
  193. * b0, b1, b2, a1, a2
  194. */
  195. static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,
  196. struct snd_ctl_elem_info *uinfo)
  197. {
  198. int numcoef = kcontrol->private_value >> 16;
  199. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  200. uinfo->count = numcoef;
  201. uinfo->value.integer.min = 0;
  202. uinfo->value.integer.max = 0xffffffff;
  203. return 0;
  204. }
  205. static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
  206. struct snd_ctl_elem_value *ucontrol)
  207. {
  208. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  209. struct i2c_client *i2c = to_i2c_client(component->dev);
  210. int numcoef = kcontrol->private_value >> 16;
  211. int index = kcontrol->private_value & 0xffff;
  212. return tas571x_reg_read_multiword(i2c, index,
  213. ucontrol->value.integer.value, numcoef);
  214. }
  215. static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
  216. struct snd_ctl_elem_value *ucontrol)
  217. {
  218. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  219. struct i2c_client *i2c = to_i2c_client(component->dev);
  220. int numcoef = kcontrol->private_value >> 16;
  221. int index = kcontrol->private_value & 0xffff;
  222. return tas571x_reg_write_multiword(i2c, index,
  223. ucontrol->value.integer.value, numcoef);
  224. }
  225. static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
  226. {
  227. struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
  228. priv->format = format;
  229. return 0;
  230. }
  231. static int tas571x_hw_params(struct snd_pcm_substream *substream,
  232. struct snd_pcm_hw_params *params,
  233. struct snd_soc_dai *dai)
  234. {
  235. struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
  236. u32 val;
  237. switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
  238. case SND_SOC_DAIFMT_RIGHT_J:
  239. val = 0x00;
  240. break;
  241. case SND_SOC_DAIFMT_I2S:
  242. val = 0x03;
  243. break;
  244. case SND_SOC_DAIFMT_LEFT_J:
  245. val = 0x06;
  246. break;
  247. default:
  248. return -EINVAL;
  249. }
  250. if (params_width(params) >= 24)
  251. val += 2;
  252. else if (params_width(params) >= 20)
  253. val += 1;
  254. return regmap_update_bits(priv->regmap, TAS571X_SDI_REG,
  255. TAS571X_SDI_FMT_MASK, val);
  256. }
  257. static int tas571x_mute(struct snd_soc_dai *dai, int mute, int direction)
  258. {
  259. struct snd_soc_component *component = dai->component;
  260. u8 sysctl2;
  261. int ret;
  262. sysctl2 = mute ? TAS571X_SYS_CTRL_2_SDN_MASK : 0;
  263. ret = snd_soc_component_update_bits(component,
  264. TAS571X_SYS_CTRL_2_REG,
  265. TAS571X_SYS_CTRL_2_SDN_MASK,
  266. sysctl2);
  267. usleep_range(1000, 2000);
  268. return ret;
  269. }
  270. static int tas571x_set_bias_level(struct snd_soc_component *component,
  271. enum snd_soc_bias_level level)
  272. {
  273. struct tas571x_private *priv = snd_soc_component_get_drvdata(component);
  274. int ret;
  275. switch (level) {
  276. case SND_SOC_BIAS_ON:
  277. break;
  278. case SND_SOC_BIAS_PREPARE:
  279. break;
  280. case SND_SOC_BIAS_STANDBY:
  281. if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
  282. if (!IS_ERR(priv->mclk)) {
  283. ret = clk_prepare_enable(priv->mclk);
  284. if (ret) {
  285. dev_err(component->dev,
  286. "Failed to enable master clock: %d\n",
  287. ret);
  288. return ret;
  289. }
  290. }
  291. }
  292. break;
  293. case SND_SOC_BIAS_OFF:
  294. if (!IS_ERR(priv->mclk))
  295. clk_disable_unprepare(priv->mclk);
  296. break;
  297. }
  298. return 0;
  299. }
  300. static const struct snd_soc_dai_ops tas571x_dai_ops = {
  301. .set_fmt = tas571x_set_dai_fmt,
  302. .hw_params = tas571x_hw_params,
  303. .mute_stream = tas571x_mute,
  304. .no_capture_mute = 1,
  305. };
  306. #define BIQUAD_COEFS(xname, reg) \
  307. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
  308. .info = tas571x_coefficient_info, \
  309. .get = tas571x_coefficient_get,\
  310. .put = tas571x_coefficient_put, \
  311. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  312. .private_value = reg | (5 << 16) }
  313. static const char *const tas5711_supply_names[] = {
  314. "AVDD",
  315. "DVDD",
  316. "PVDD_A",
  317. "PVDD_B",
  318. "PVDD_C",
  319. "PVDD_D",
  320. };
  321. static const DECLARE_TLV_DB_SCALE(tas5711_volume_tlv, -10350, 50, 1);
  322. static const struct snd_kcontrol_new tas5711_controls[] = {
  323. SOC_SINGLE_TLV("Master Volume",
  324. TAS571X_MVOL_REG,
  325. 0, 0xff, 1, tas5711_volume_tlv),
  326. SOC_DOUBLE_R_TLV("Speaker Volume",
  327. TAS571X_CH1_VOL_REG,
  328. TAS571X_CH2_VOL_REG,
  329. 0, 0xff, 1, tas5711_volume_tlv),
  330. SOC_DOUBLE("Speaker Switch",
  331. TAS571X_SOFT_MUTE_REG,
  332. TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
  333. 1, 1),
  334. };
  335. static const struct regmap_range tas571x_readonly_regs_range[] = {
  336. regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_DEV_ID_REG),
  337. };
  338. static const struct regmap_range tas571x_volatile_regs_range[] = {
  339. regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_ERR_STATUS_REG),
  340. regmap_reg_range(TAS571X_OSC_TRIM_REG, TAS571X_OSC_TRIM_REG),
  341. };
  342. static const struct regmap_access_table tas571x_write_regs = {
  343. .no_ranges = tas571x_readonly_regs_range,
  344. .n_no_ranges = ARRAY_SIZE(tas571x_readonly_regs_range),
  345. };
  346. static const struct regmap_access_table tas571x_volatile_regs = {
  347. .yes_ranges = tas571x_volatile_regs_range,
  348. .n_yes_ranges = ARRAY_SIZE(tas571x_volatile_regs_range),
  349. };
  350. static const struct reg_default tas5711_reg_defaults[] = {
  351. { 0x04, 0x05 },
  352. { 0x05, 0x40 },
  353. { 0x06, 0x00 },
  354. { 0x07, 0xff },
  355. { 0x08, 0x30 },
  356. { 0x09, 0x30 },
  357. { 0x1b, 0x82 },
  358. };
  359. static const struct regmap_config tas5711_regmap_config = {
  360. .reg_bits = 8,
  361. .val_bits = 32,
  362. .max_register = 0xff,
  363. .reg_read = tas571x_reg_read,
  364. .reg_write = tas571x_reg_write,
  365. .reg_defaults = tas5711_reg_defaults,
  366. .num_reg_defaults = ARRAY_SIZE(tas5711_reg_defaults),
  367. .cache_type = REGCACHE_RBTREE,
  368. .wr_table = &tas571x_write_regs,
  369. .volatile_table = &tas571x_volatile_regs,
  370. };
  371. static const struct tas571x_chip tas5711_chip = {
  372. .supply_names = tas5711_supply_names,
  373. .num_supply_names = ARRAY_SIZE(tas5711_supply_names),
  374. .controls = tas5711_controls,
  375. .num_controls = ARRAY_SIZE(tas5711_controls),
  376. .regmap_config = &tas5711_regmap_config,
  377. .vol_reg_size = 1,
  378. };
  379. static const struct regmap_range tas5707_volatile_regs_range[] = {
  380. regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_ERR_STATUS_REG),
  381. regmap_reg_range(TAS571X_OSC_TRIM_REG, TAS571X_OSC_TRIM_REG),
  382. regmap_reg_range(TAS5707_CH1_BQ0_REG, TAS5707_CH2_BQ6_REG),
  383. };
  384. static const struct regmap_access_table tas5707_volatile_regs = {
  385. .yes_ranges = tas5707_volatile_regs_range,
  386. .n_yes_ranges = ARRAY_SIZE(tas5707_volatile_regs_range),
  387. };
  388. static const DECLARE_TLV_DB_SCALE(tas5707_volume_tlv, -7900, 50, 1);
  389. static const char * const tas5707_volume_slew_step_txt[] = {
  390. "256", "512", "1024", "2048",
  391. };
  392. static const unsigned int tas5707_volume_slew_step_values[] = {
  393. 3, 0, 1, 2,
  394. };
  395. static SOC_VALUE_ENUM_SINGLE_DECL(tas5707_volume_slew_step_enum,
  396. TAS571X_VOL_CFG_REG, 0, 0x3,
  397. tas5707_volume_slew_step_txt,
  398. tas5707_volume_slew_step_values);
  399. static const struct snd_kcontrol_new tas5707_controls[] = {
  400. SOC_SINGLE_TLV("Master Volume",
  401. TAS571X_MVOL_REG,
  402. 0, 0xff, 1, tas5707_volume_tlv),
  403. SOC_DOUBLE_R_TLV("Speaker Volume",
  404. TAS571X_CH1_VOL_REG,
  405. TAS571X_CH2_VOL_REG,
  406. 0, 0xff, 1, tas5707_volume_tlv),
  407. SOC_DOUBLE("Speaker Switch",
  408. TAS571X_SOFT_MUTE_REG,
  409. TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
  410. 1, 1),
  411. SOC_ENUM("Slew Rate Steps", tas5707_volume_slew_step_enum),
  412. BIQUAD_COEFS("CH1 - Biquad 0", TAS5707_CH1_BQ0_REG),
  413. BIQUAD_COEFS("CH1 - Biquad 1", TAS5707_CH1_BQ1_REG),
  414. BIQUAD_COEFS("CH1 - Biquad 2", TAS5707_CH1_BQ2_REG),
  415. BIQUAD_COEFS("CH1 - Biquad 3", TAS5707_CH1_BQ3_REG),
  416. BIQUAD_COEFS("CH1 - Biquad 4", TAS5707_CH1_BQ4_REG),
  417. BIQUAD_COEFS("CH1 - Biquad 5", TAS5707_CH1_BQ5_REG),
  418. BIQUAD_COEFS("CH1 - Biquad 6", TAS5707_CH1_BQ6_REG),
  419. BIQUAD_COEFS("CH2 - Biquad 0", TAS5707_CH2_BQ0_REG),
  420. BIQUAD_COEFS("CH2 - Biquad 1", TAS5707_CH2_BQ1_REG),
  421. BIQUAD_COEFS("CH2 - Biquad 2", TAS5707_CH2_BQ2_REG),
  422. BIQUAD_COEFS("CH2 - Biquad 3", TAS5707_CH2_BQ3_REG),
  423. BIQUAD_COEFS("CH2 - Biquad 4", TAS5707_CH2_BQ4_REG),
  424. BIQUAD_COEFS("CH2 - Biquad 5", TAS5707_CH2_BQ5_REG),
  425. BIQUAD_COEFS("CH2 - Biquad 6", TAS5707_CH2_BQ6_REG),
  426. };
  427. static const struct reg_default tas5707_reg_defaults[] = {
  428. {TAS571X_CLK_CTRL_REG, 0x6c},
  429. {TAS571X_DEV_ID_REG, 0x70},
  430. {TAS571X_ERR_STATUS_REG, 0x00},
  431. {TAS571X_SYS_CTRL_1_REG, 0xa0},
  432. {TAS571X_SDI_REG, 0x05},
  433. {TAS571X_SYS_CTRL_2_REG, 0x40},
  434. {TAS571X_SOFT_MUTE_REG, 0x00},
  435. {TAS571X_MVOL_REG, 0xff},
  436. {TAS571X_CH1_VOL_REG, 0x30},
  437. {TAS571X_CH2_VOL_REG, 0x30},
  438. {TAS571X_VOL_CFG_REG, 0x91},
  439. {TAS571X_MODULATION_LIMIT_REG, 0x02},
  440. {TAS571X_IC_DELAY_CH1_REG, 0xac},
  441. {TAS571X_IC_DELAY_CH2_REG, 0x54},
  442. {TAS571X_IC_DELAY_CH3_REG, 0xac},
  443. {TAS571X_IC_DELAY_CH4_REG, 0x54},
  444. {TAS571X_START_STOP_PERIOD_REG, 0x0f},
  445. {TAS571X_OSC_TRIM_REG, 0x82},
  446. {TAS571X_BKND_ERR_REG, 0x02},
  447. {TAS571X_INPUT_MUX_REG, 0x17772},
  448. {TAS571X_PWM_MUX_REG, 0x1021345},
  449. };
  450. static const struct regmap_config tas5707_regmap_config = {
  451. .reg_bits = 8,
  452. .val_bits = 32,
  453. .max_register = 0xff,
  454. .reg_read = tas571x_reg_read,
  455. .reg_write = tas571x_reg_write,
  456. .reg_defaults = tas5707_reg_defaults,
  457. .num_reg_defaults = ARRAY_SIZE(tas5707_reg_defaults),
  458. .cache_type = REGCACHE_RBTREE,
  459. .wr_table = &tas571x_write_regs,
  460. .volatile_table = &tas5707_volatile_regs,
  461. };
  462. static const struct tas571x_chip tas5707_chip = {
  463. .supply_names = tas5711_supply_names,
  464. .num_supply_names = ARRAY_SIZE(tas5711_supply_names),
  465. .controls = tas5707_controls,
  466. .num_controls = ARRAY_SIZE(tas5707_controls),
  467. .regmap_config = &tas5707_regmap_config,
  468. .vol_reg_size = 1,
  469. };
  470. static const char *const tas5717_supply_names[] = {
  471. "AVDD",
  472. "DVDD",
  473. "HPVDD",
  474. "PVDD_AB",
  475. "PVDD_CD",
  476. };
  477. static const DECLARE_TLV_DB_SCALE(tas5717_volume_tlv, -10375, 25, 0);
  478. static const struct snd_kcontrol_new tas5717_controls[] = {
  479. /* MVOL LSB is ignored - see comments in tas571x_i2c_probe() */
  480. SOC_SINGLE_TLV("Master Volume",
  481. TAS571X_MVOL_REG, 1, 0x1ff, 1,
  482. tas5717_volume_tlv),
  483. SOC_DOUBLE_R_TLV("Speaker Volume",
  484. TAS571X_CH1_VOL_REG, TAS571X_CH2_VOL_REG,
  485. 1, 0x1ff, 1, tas5717_volume_tlv),
  486. SOC_DOUBLE("Speaker Switch",
  487. TAS571X_SOFT_MUTE_REG,
  488. TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
  489. 1, 1),
  490. SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",
  491. TAS5717_CH1_LEFT_CH_MIX_REG,
  492. TAS5717_CH1_RIGHT_CH_MIX_REG,
  493. 16, 0, 0x80, 0),
  494. SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",
  495. TAS5717_CH2_LEFT_CH_MIX_REG,
  496. TAS5717_CH2_RIGHT_CH_MIX_REG,
  497. 16, 0, 0x80, 0),
  498. /*
  499. * The biquads are named according to the register names.
  500. * Please note that TI's TAS57xx Graphical Development Environment
  501. * tool names them different.
  502. */
  503. BIQUAD_COEFS("CH1 - Biquad 0", TAS5717_CH1_BQ0_REG),
  504. BIQUAD_COEFS("CH1 - Biquad 1", TAS5717_CH1_BQ1_REG),
  505. BIQUAD_COEFS("CH1 - Biquad 2", TAS5717_CH1_BQ2_REG),
  506. BIQUAD_COEFS("CH1 - Biquad 3", TAS5717_CH1_BQ3_REG),
  507. BIQUAD_COEFS("CH1 - Biquad 4", TAS5717_CH1_BQ4_REG),
  508. BIQUAD_COEFS("CH1 - Biquad 5", TAS5717_CH1_BQ5_REG),
  509. BIQUAD_COEFS("CH1 - Biquad 6", TAS5717_CH1_BQ6_REG),
  510. BIQUAD_COEFS("CH1 - Biquad 7", TAS5717_CH1_BQ7_REG),
  511. BIQUAD_COEFS("CH1 - Biquad 8", TAS5717_CH1_BQ8_REG),
  512. BIQUAD_COEFS("CH1 - Biquad 9", TAS5717_CH1_BQ9_REG),
  513. BIQUAD_COEFS("CH1 - Biquad 10", TAS5717_CH1_BQ10_REG),
  514. BIQUAD_COEFS("CH1 - Biquad 11", TAS5717_CH1_BQ11_REG),
  515. BIQUAD_COEFS("CH2 - Biquad 0", TAS5717_CH2_BQ0_REG),
  516. BIQUAD_COEFS("CH2 - Biquad 1", TAS5717_CH2_BQ1_REG),
  517. BIQUAD_COEFS("CH2 - Biquad 2", TAS5717_CH2_BQ2_REG),
  518. BIQUAD_COEFS("CH2 - Biquad 3", TAS5717_CH2_BQ3_REG),
  519. BIQUAD_COEFS("CH2 - Biquad 4", TAS5717_CH2_BQ4_REG),
  520. BIQUAD_COEFS("CH2 - Biquad 5", TAS5717_CH2_BQ5_REG),
  521. BIQUAD_COEFS("CH2 - Biquad 6", TAS5717_CH2_BQ6_REG),
  522. BIQUAD_COEFS("CH2 - Biquad 7", TAS5717_CH2_BQ7_REG),
  523. BIQUAD_COEFS("CH2 - Biquad 8", TAS5717_CH2_BQ8_REG),
  524. BIQUAD_COEFS("CH2 - Biquad 9", TAS5717_CH2_BQ9_REG),
  525. BIQUAD_COEFS("CH2 - Biquad 10", TAS5717_CH2_BQ10_REG),
  526. BIQUAD_COEFS("CH2 - Biquad 11", TAS5717_CH2_BQ11_REG),
  527. BIQUAD_COEFS("CH3 - Biquad 0", TAS5717_CH3_BQ0_REG),
  528. BIQUAD_COEFS("CH3 - Biquad 1", TAS5717_CH3_BQ1_REG),
  529. BIQUAD_COEFS("CH4 - Biquad 0", TAS5717_CH4_BQ0_REG),
  530. BIQUAD_COEFS("CH4 - Biquad 1", TAS5717_CH4_BQ1_REG),
  531. };
  532. static const struct reg_default tas5717_reg_defaults[] = {
  533. { 0x04, 0x05 },
  534. { 0x05, 0x40 },
  535. { 0x06, 0x00 },
  536. { 0x07, 0x03ff },
  537. { 0x08, 0x00c0 },
  538. { 0x09, 0x00c0 },
  539. { 0x1b, 0x82 },
  540. { TAS5717_CH1_RIGHT_CH_MIX_REG, 0x0 },
  541. { TAS5717_CH1_LEFT_CH_MIX_REG, 0x800000},
  542. { TAS5717_CH2_LEFT_CH_MIX_REG, 0x0 },
  543. { TAS5717_CH2_RIGHT_CH_MIX_REG, 0x800000},
  544. };
  545. static const struct regmap_config tas5717_regmap_config = {
  546. .reg_bits = 8,
  547. .val_bits = 32,
  548. .max_register = 0xff,
  549. .reg_read = tas571x_reg_read,
  550. .reg_write = tas571x_reg_write,
  551. .reg_defaults = tas5717_reg_defaults,
  552. .num_reg_defaults = ARRAY_SIZE(tas5717_reg_defaults),
  553. .cache_type = REGCACHE_RBTREE,
  554. .wr_table = &tas571x_write_regs,
  555. .volatile_table = &tas571x_volatile_regs,
  556. };
  557. /* This entry is reused for tas5719 as the software interface is identical. */
  558. static const struct tas571x_chip tas5717_chip = {
  559. .supply_names = tas5717_supply_names,
  560. .num_supply_names = ARRAY_SIZE(tas5717_supply_names),
  561. .controls = tas5717_controls,
  562. .num_controls = ARRAY_SIZE(tas5717_controls),
  563. .regmap_config = &tas5717_regmap_config,
  564. .vol_reg_size = 2,
  565. };
  566. static const char *const tas5721_supply_names[] = {
  567. "AVDD",
  568. "DVDD",
  569. "DRVDD",
  570. "PVDD",
  571. };
  572. static const struct snd_kcontrol_new tas5721_controls[] = {
  573. SOC_SINGLE_TLV("Master Volume",
  574. TAS571X_MVOL_REG,
  575. 0, 0xff, 1, tas5711_volume_tlv),
  576. SOC_DOUBLE_R_TLV("Speaker Volume",
  577. TAS571X_CH1_VOL_REG,
  578. TAS571X_CH2_VOL_REG,
  579. 0, 0xff, 1, tas5711_volume_tlv),
  580. SOC_DOUBLE("Speaker Switch",
  581. TAS571X_SOFT_MUTE_REG,
  582. TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
  583. 1, 1),
  584. };
  585. static const struct reg_default tas5721_reg_defaults[] = {
  586. {TAS571X_CLK_CTRL_REG, 0x6c},
  587. {TAS571X_DEV_ID_REG, 0x00},
  588. {TAS571X_ERR_STATUS_REG, 0x00},
  589. {TAS571X_SYS_CTRL_1_REG, 0xa0},
  590. {TAS571X_SDI_REG, 0x05},
  591. {TAS571X_SYS_CTRL_2_REG, 0x40},
  592. {TAS571X_SOFT_MUTE_REG, 0x00},
  593. {TAS571X_MVOL_REG, 0xff},
  594. {TAS571X_CH1_VOL_REG, 0x30},
  595. {TAS571X_CH2_VOL_REG, 0x30},
  596. {TAS571X_CH3_VOL_REG, 0x30},
  597. {TAS571X_VOL_CFG_REG, 0x91},
  598. {TAS571X_MODULATION_LIMIT_REG, 0x02},
  599. {TAS571X_IC_DELAY_CH1_REG, 0xac},
  600. {TAS571X_IC_DELAY_CH2_REG, 0x54},
  601. {TAS571X_IC_DELAY_CH3_REG, 0xac},
  602. {TAS571X_IC_DELAY_CH4_REG, 0x54},
  603. {TAS571X_PWM_CH_SDN_GROUP_REG, 0x30},
  604. {TAS571X_START_STOP_PERIOD_REG, 0x0f},
  605. {TAS571X_OSC_TRIM_REG, 0x82},
  606. {TAS571X_BKND_ERR_REG, 0x02},
  607. {TAS571X_INPUT_MUX_REG, 0x17772},
  608. {TAS571X_CH4_SRC_SELECT_REG, 0x4303},
  609. {TAS571X_PWM_MUX_REG, 0x1021345},
  610. };
  611. static const struct regmap_config tas5721_regmap_config = {
  612. .reg_bits = 8,
  613. .val_bits = 32,
  614. .max_register = 0xff,
  615. .reg_read = tas571x_reg_read,
  616. .reg_write = tas571x_reg_write,
  617. .reg_defaults = tas5721_reg_defaults,
  618. .num_reg_defaults = ARRAY_SIZE(tas5721_reg_defaults),
  619. .cache_type = REGCACHE_RBTREE,
  620. .wr_table = &tas571x_write_regs,
  621. .volatile_table = &tas571x_volatile_regs,
  622. };
  623. static const struct tas571x_chip tas5721_chip = {
  624. .supply_names = tas5721_supply_names,
  625. .num_supply_names = ARRAY_SIZE(tas5721_supply_names),
  626. .controls = tas5721_controls,
  627. .num_controls = ARRAY_SIZE(tas5721_controls),
  628. .regmap_config = &tas5721_regmap_config,
  629. .vol_reg_size = 1,
  630. };
  631. static const struct snd_soc_dapm_widget tas571x_dapm_widgets[] = {
  632. SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
  633. SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
  634. SND_SOC_DAPM_OUTPUT("OUT_A"),
  635. SND_SOC_DAPM_OUTPUT("OUT_B"),
  636. SND_SOC_DAPM_OUTPUT("OUT_C"),
  637. SND_SOC_DAPM_OUTPUT("OUT_D"),
  638. };
  639. static const struct snd_soc_dapm_route tas571x_dapm_routes[] = {
  640. { "DACL", NULL, "Playback" },
  641. { "DACR", NULL, "Playback" },
  642. { "OUT_A", NULL, "DACL" },
  643. { "OUT_B", NULL, "DACL" },
  644. { "OUT_C", NULL, "DACR" },
  645. { "OUT_D", NULL, "DACR" },
  646. };
  647. static const struct snd_soc_component_driver tas571x_component = {
  648. .set_bias_level = tas571x_set_bias_level,
  649. .dapm_widgets = tas571x_dapm_widgets,
  650. .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets),
  651. .dapm_routes = tas571x_dapm_routes,
  652. .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes),
  653. .use_pmdown_time = 1,
  654. .endianness = 1,
  655. .non_legacy_dai_naming = 1,
  656. };
  657. static struct snd_soc_dai_driver tas571x_dai = {
  658. .name = "tas571x-hifi",
  659. .playback = {
  660. .stream_name = "Playback",
  661. .channels_min = 2,
  662. .channels_max = 2,
  663. .rates = SNDRV_PCM_RATE_8000_48000,
  664. .formats = SNDRV_PCM_FMTBIT_S32_LE |
  665. SNDRV_PCM_FMTBIT_S24_LE |
  666. SNDRV_PCM_FMTBIT_S16_LE,
  667. },
  668. .ops = &tas571x_dai_ops,
  669. };
  670. static const struct of_device_id tas571x_of_match[];
  671. static int tas571x_i2c_probe(struct i2c_client *client,
  672. const struct i2c_device_id *id)
  673. {
  674. struct tas571x_private *priv;
  675. struct device *dev = &client->dev;
  676. const struct of_device_id *of_id;
  677. int i, ret;
  678. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  679. if (!priv)
  680. return -ENOMEM;
  681. i2c_set_clientdata(client, priv);
  682. of_id = of_match_device(tas571x_of_match, dev);
  683. if (of_id)
  684. priv->chip = of_id->data;
  685. else
  686. priv->chip = (void *) id->driver_data;
  687. priv->mclk = devm_clk_get(dev, "mclk");
  688. if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) {
  689. dev_err(dev, "Failed to request mclk: %ld\n",
  690. PTR_ERR(priv->mclk));
  691. return PTR_ERR(priv->mclk);
  692. }
  693. if (WARN_ON(priv->chip->num_supply_names > TAS571X_MAX_SUPPLIES))
  694. return -EINVAL;
  695. for (i = 0; i < priv->chip->num_supply_names; i++)
  696. priv->supplies[i].supply = priv->chip->supply_names[i];
  697. ret = devm_regulator_bulk_get(dev, priv->chip->num_supply_names,
  698. priv->supplies);
  699. if (ret) {
  700. dev_err(dev, "Failed to get supplies: %d\n", ret);
  701. return ret;
  702. }
  703. ret = regulator_bulk_enable(priv->chip->num_supply_names,
  704. priv->supplies);
  705. if (ret) {
  706. dev_err(dev, "Failed to enable supplies: %d\n", ret);
  707. return ret;
  708. }
  709. priv->regmap = devm_regmap_init(dev, NULL, client,
  710. priv->chip->regmap_config);
  711. if (IS_ERR(priv->regmap)) {
  712. ret = PTR_ERR(priv->regmap);
  713. goto disable_regs;
  714. }
  715. priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW);
  716. if (IS_ERR(priv->pdn_gpio)) {
  717. dev_err(dev, "error requesting pdn_gpio: %ld\n",
  718. PTR_ERR(priv->pdn_gpio));
  719. return PTR_ERR(priv->pdn_gpio);
  720. }
  721. priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",
  722. GPIOD_OUT_HIGH);
  723. if (IS_ERR(priv->reset_gpio)) {
  724. dev_err(dev, "error requesting reset_gpio: %ld\n",
  725. PTR_ERR(priv->reset_gpio));
  726. return PTR_ERR(priv->reset_gpio);
  727. } else if (priv->reset_gpio) {
  728. /* pulse the active low reset line for ~100us */
  729. usleep_range(100, 200);
  730. gpiod_set_value(priv->reset_gpio, 0);
  731. usleep_range(13500, 20000);
  732. }
  733. ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);
  734. if (ret)
  735. goto disable_regs;
  736. usleep_range(50000, 60000);
  737. memcpy(&priv->component_driver, &tas571x_component, sizeof(priv->component_driver));
  738. priv->component_driver.controls = priv->chip->controls;
  739. priv->component_driver.num_controls = priv->chip->num_controls;
  740. if (priv->chip->vol_reg_size == 2) {
  741. /*
  742. * The master volume defaults to 0x3ff (mute), but we ignore
  743. * (zero) the LSB because the hardware step size is 0.125 dB
  744. * and TLV_DB_SCALE_ITEM has a resolution of 0.01 dB.
  745. */
  746. ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0);
  747. if (ret)
  748. goto disable_regs;
  749. }
  750. ret = devm_snd_soc_register_component(&client->dev,
  751. &priv->component_driver,
  752. &tas571x_dai, 1);
  753. if (ret)
  754. goto disable_regs;
  755. return ret;
  756. disable_regs:
  757. regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
  758. return ret;
  759. }
  760. static int tas571x_i2c_remove(struct i2c_client *client)
  761. {
  762. struct tas571x_private *priv = i2c_get_clientdata(client);
  763. regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
  764. return 0;
  765. }
  766. static const struct of_device_id tas571x_of_match[] = {
  767. { .compatible = "ti,tas5707", .data = &tas5707_chip, },
  768. { .compatible = "ti,tas5711", .data = &tas5711_chip, },
  769. { .compatible = "ti,tas5717", .data = &tas5717_chip, },
  770. { .compatible = "ti,tas5719", .data = &tas5717_chip, },
  771. { .compatible = "ti,tas5721", .data = &tas5721_chip, },
  772. { }
  773. };
  774. MODULE_DEVICE_TABLE(of, tas571x_of_match);
  775. static const struct i2c_device_id tas571x_i2c_id[] = {
  776. { "tas5707", (kernel_ulong_t) &tas5707_chip },
  777. { "tas5711", (kernel_ulong_t) &tas5711_chip },
  778. { "tas5717", (kernel_ulong_t) &tas5717_chip },
  779. { "tas5719", (kernel_ulong_t) &tas5717_chip },
  780. { "tas5721", (kernel_ulong_t) &tas5721_chip },
  781. { }
  782. };
  783. MODULE_DEVICE_TABLE(i2c, tas571x_i2c_id);
  784. static struct i2c_driver tas571x_i2c_driver = {
  785. .driver = {
  786. .name = "tas571x",
  787. .of_match_table = of_match_ptr(tas571x_of_match),
  788. },
  789. .probe = tas571x_i2c_probe,
  790. .remove = tas571x_i2c_remove,
  791. .id_table = tas571x_i2c_id,
  792. };
  793. module_i2c_driver(tas571x_i2c_driver);
  794. MODULE_DESCRIPTION("ASoC TAS571x driver");
  795. MODULE_AUTHOR("Kevin Cernekee <cernekee@chromium.org>");
  796. MODULE_LICENSE("GPL");