tas2552.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  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. #include <linux/module.h>
  18. #include <linux/errno.h>
  19. #include <linux/device.h>
  20. #include <linux/i2c.h>
  21. #include <linux/gpio.h>
  22. #include <linux/of_gpio.h>
  23. #include <linux/pm_runtime.h>
  24. #include <linux/regmap.h>
  25. #include <linux/slab.h>
  26. #include <linux/gpio/consumer.h>
  27. #include <linux/regulator/consumer.h>
  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. #include <sound/tas2552-plat.h>
  34. #include <dt-bindings/sound/tas2552.h>
  35. #include "tas2552.h"
  36. static const struct reg_default tas2552_reg_defs[] = {
  37. {TAS2552_CFG_1, 0x22},
  38. {TAS2552_CFG_3, 0x80},
  39. {TAS2552_DOUT, 0x00},
  40. {TAS2552_OUTPUT_DATA, 0xc0},
  41. {TAS2552_PDM_CFG, 0x01},
  42. {TAS2552_PGA_GAIN, 0x00},
  43. {TAS2552_BOOST_APT_CTRL, 0x0f},
  44. {TAS2552_RESERVED_0D, 0xbe},
  45. {TAS2552_LIMIT_RATE_HYS, 0x08},
  46. {TAS2552_CFG_2, 0xef},
  47. {TAS2552_SER_CTRL_1, 0x00},
  48. {TAS2552_SER_CTRL_2, 0x00},
  49. {TAS2552_PLL_CTRL_1, 0x10},
  50. {TAS2552_PLL_CTRL_2, 0x00},
  51. {TAS2552_PLL_CTRL_3, 0x00},
  52. {TAS2552_BTIP, 0x8f},
  53. {TAS2552_BTS_CTRL, 0x80},
  54. {TAS2552_LIMIT_RELEASE, 0x04},
  55. {TAS2552_LIMIT_INT_COUNT, 0x00},
  56. {TAS2552_EDGE_RATE_CTRL, 0x40},
  57. {TAS2552_VBAT_DATA, 0x00},
  58. };
  59. #define TAS2552_NUM_SUPPLIES 3
  60. static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = {
  61. "vbat", /* vbat voltage */
  62. "iovdd", /* I/O Voltage */
  63. "avdd", /* Analog DAC Voltage */
  64. };
  65. struct tas2552_data {
  66. struct snd_soc_codec *codec;
  67. struct regmap *regmap;
  68. struct i2c_client *tas2552_client;
  69. struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
  70. struct gpio_desc *enable_gpio;
  71. unsigned char regs[TAS2552_VBAT_DATA];
  72. unsigned int pll_clkin;
  73. int pll_clk_id;
  74. unsigned int pdm_clk;
  75. int pdm_clk_id;
  76. unsigned int dai_fmt;
  77. unsigned int tdm_delay;
  78. };
  79. static int tas2552_post_event(struct snd_soc_dapm_widget *w,
  80. struct snd_kcontrol *kcontrol, int event)
  81. {
  82. struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
  83. switch (event) {
  84. case SND_SOC_DAPM_POST_PMU:
  85. snd_soc_write(codec, TAS2552_RESERVED_0D, 0xc0);
  86. snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5),
  87. (1 << 5));
  88. snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 0);
  89. snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS, 0);
  90. break;
  91. case SND_SOC_DAPM_POST_PMD:
  92. snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS,
  93. TAS2552_SWS);
  94. snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 1);
  95. snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
  96. snd_soc_write(codec, TAS2552_RESERVED_0D, 0xbe);
  97. break;
  98. }
  99. return 0;
  100. }
  101. /* Input mux controls */
  102. static const char * const tas2552_input_texts[] = {
  103. "Digital", "Analog" };
  104. static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
  105. tas2552_input_texts);
  106. static const struct snd_kcontrol_new tas2552_input_mux_control =
  107. SOC_DAPM_ENUM("Route", tas2552_input_mux_enum);
  108. static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
  109. {
  110. SND_SOC_DAPM_INPUT("IN"),
  111. /* MUX Controls */
  112. SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
  113. &tas2552_input_mux_control),
  114. SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
  115. SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
  116. SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
  117. SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
  118. SND_SOC_DAPM_POST("Post Event", tas2552_post_event),
  119. SND_SOC_DAPM_OUTPUT("OUT")
  120. };
  121. static const struct snd_soc_dapm_route tas2552_audio_map[] = {
  122. {"DAC", NULL, "DAC IN"},
  123. {"Input selection", "Digital", "DAC"},
  124. {"Input selection", "Analog", "IN"},
  125. {"ClassD", NULL, "Input selection"},
  126. {"OUT", NULL, "ClassD"},
  127. {"ClassD", NULL, "PLL"},
  128. };
  129. #ifdef CONFIG_PM
  130. static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
  131. {
  132. u8 cfg1_reg = 0;
  133. if (!tas2552->codec)
  134. return;
  135. if (sw_shutdown)
  136. cfg1_reg = TAS2552_SWS;
  137. snd_soc_update_bits(tas2552->codec, TAS2552_CFG_1, TAS2552_SWS,
  138. cfg1_reg);
  139. }
  140. #endif
  141. static int tas2552_setup_pll(struct snd_soc_codec *codec,
  142. struct snd_pcm_hw_params *params)
  143. {
  144. struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
  145. bool bypass_pll = false;
  146. unsigned int pll_clk = params_rate(params) * 512;
  147. unsigned int pll_clkin = tas2552->pll_clkin;
  148. u8 pll_enable;
  149. if (!pll_clkin) {
  150. if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK)
  151. return -EINVAL;
  152. pll_clkin = snd_soc_params_to_bclk(params);
  153. pll_clkin += tas2552->tdm_delay;
  154. }
  155. pll_enable = snd_soc_read(codec, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
  156. snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
  157. if (pll_clkin == pll_clk)
  158. bypass_pll = true;
  159. if (bypass_pll) {
  160. /* By pass the PLL configuration */
  161. snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
  162. TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
  163. } else {
  164. /* Fill in the PLL control registers for J & D
  165. * pll_clk = (.5 * pll_clkin * J.D) / 2^p
  166. * Need to fill in J and D here based on incoming freq
  167. */
  168. unsigned int d;
  169. u8 j;
  170. u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
  171. u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
  172. p = (p >> 7);
  173. recalc:
  174. j = (pll_clk * 2 * (1 << p)) / pll_clkin;
  175. d = (pll_clk * 2 * (1 << p)) % pll_clkin;
  176. d /= (pll_clkin / 10000);
  177. if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) {
  178. if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) {
  179. pll_clkin = 1800000;
  180. pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) &
  181. TAS2552_PLL_SRC_MASK;
  182. } else {
  183. pll_clkin = snd_soc_params_to_bclk(params);
  184. pll_clkin += tas2552->tdm_delay;
  185. pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) &
  186. TAS2552_PLL_SRC_MASK;
  187. }
  188. goto recalc;
  189. }
  190. snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
  191. pll_sel);
  192. snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
  193. TAS2552_PLL_J_MASK, j);
  194. /* Will clear the PLL_BYPASS bit */
  195. snd_soc_write(codec, TAS2552_PLL_CTRL_2,
  196. TAS2552_PLL_D_UPPER(d));
  197. snd_soc_write(codec, TAS2552_PLL_CTRL_3,
  198. TAS2552_PLL_D_LOWER(d));
  199. }
  200. /* Restore PLL status */
  201. snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
  202. pll_enable);
  203. return 0;
  204. }
  205. static int tas2552_hw_params(struct snd_pcm_substream *substream,
  206. struct snd_pcm_hw_params *params,
  207. struct snd_soc_dai *dai)
  208. {
  209. struct snd_soc_codec *codec = dai->codec;
  210. struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
  211. int cpf;
  212. u8 ser_ctrl1_reg, wclk_rate;
  213. switch (params_width(params)) {
  214. case 16:
  215. ser_ctrl1_reg = TAS2552_WORDLENGTH_16BIT;
  216. cpf = 32 + tas2552->tdm_delay;
  217. break;
  218. case 20:
  219. ser_ctrl1_reg = TAS2552_WORDLENGTH_20BIT;
  220. cpf = 64 + tas2552->tdm_delay;
  221. break;
  222. case 24:
  223. ser_ctrl1_reg = TAS2552_WORDLENGTH_24BIT;
  224. cpf = 64 + tas2552->tdm_delay;
  225. break;
  226. case 32:
  227. ser_ctrl1_reg = TAS2552_WORDLENGTH_32BIT;
  228. cpf = 64 + tas2552->tdm_delay;
  229. break;
  230. default:
  231. dev_err(codec->dev, "Not supported sample size: %d\n",
  232. params_width(params));
  233. return -EINVAL;
  234. }
  235. if (cpf <= 32)
  236. ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_32;
  237. else if (cpf <= 64)
  238. ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_64;
  239. else if (cpf <= 128)
  240. ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_128;
  241. else
  242. ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;
  243. snd_soc_update_bits(codec, TAS2552_SER_CTRL_1,
  244. TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
  245. ser_ctrl1_reg);
  246. switch (params_rate(params)) {
  247. case 8000:
  248. wclk_rate = TAS2552_WCLK_FREQ_8KHZ;
  249. break;
  250. case 11025:
  251. case 12000:
  252. wclk_rate = TAS2552_WCLK_FREQ_11_12KHZ;
  253. break;
  254. case 16000:
  255. wclk_rate = TAS2552_WCLK_FREQ_16KHZ;
  256. break;
  257. case 22050:
  258. case 24000:
  259. wclk_rate = TAS2552_WCLK_FREQ_22_24KHZ;
  260. break;
  261. case 32000:
  262. wclk_rate = TAS2552_WCLK_FREQ_32KHZ;
  263. break;
  264. case 44100:
  265. case 48000:
  266. wclk_rate = TAS2552_WCLK_FREQ_44_48KHZ;
  267. break;
  268. case 88200:
  269. case 96000:
  270. wclk_rate = TAS2552_WCLK_FREQ_88_96KHZ;
  271. break;
  272. case 176400:
  273. case 192000:
  274. wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
  275. break;
  276. default:
  277. dev_err(codec->dev, "Not supported sample rate: %d\n",
  278. params_rate(params));
  279. return -EINVAL;
  280. }
  281. snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
  282. wclk_rate);
  283. return tas2552_setup_pll(codec, params);
  284. }
  285. #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
  286. TAS2552_WCLKDIR | \
  287. TAS2552_DATAFORMAT_MASK)
  288. static int tas2552_prepare(struct snd_pcm_substream *substream,
  289. struct snd_soc_dai *dai)
  290. {
  291. struct snd_soc_codec *codec = dai->codec;
  292. struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
  293. int delay = 0;
  294. /* TDM slot selection only valid in DSP_A/_B mode */
  295. if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_A)
  296. delay += (tas2552->tdm_delay + 1);
  297. else if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_B)
  298. delay += tas2552->tdm_delay;
  299. /* Configure data delay */
  300. snd_soc_write(codec, TAS2552_SER_CTRL_2, delay);
  301. return 0;
  302. }
  303. static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  304. {
  305. struct snd_soc_codec *codec = dai->codec;
  306. struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
  307. u8 serial_format;
  308. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  309. case SND_SOC_DAIFMT_CBS_CFS:
  310. serial_format = 0x00;
  311. break;
  312. case SND_SOC_DAIFMT_CBS_CFM:
  313. serial_format = TAS2552_WCLKDIR;
  314. break;
  315. case SND_SOC_DAIFMT_CBM_CFS:
  316. serial_format = TAS2552_BCLKDIR;
  317. break;
  318. case SND_SOC_DAIFMT_CBM_CFM:
  319. serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR);
  320. break;
  321. default:
  322. dev_vdbg(codec->dev, "DAI Format master is not found\n");
  323. return -EINVAL;
  324. }
  325. switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
  326. SND_SOC_DAIFMT_INV_MASK)) {
  327. case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
  328. break;
  329. case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
  330. case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
  331. serial_format |= TAS2552_DATAFORMAT_DSP;
  332. break;
  333. case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
  334. serial_format |= TAS2552_DATAFORMAT_RIGHT_J;
  335. break;
  336. case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
  337. serial_format |= TAS2552_DATAFORMAT_LEFT_J;
  338. break;
  339. default:
  340. dev_vdbg(codec->dev, "DAI Format is not found\n");
  341. return -EINVAL;
  342. }
  343. tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
  344. snd_soc_update_bits(codec, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
  345. serial_format);
  346. return 0;
  347. }
  348. static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
  349. unsigned int freq, int dir)
  350. {
  351. struct snd_soc_codec *codec = dai->codec;
  352. struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
  353. u8 reg, mask, val;
  354. switch (clk_id) {
  355. case TAS2552_PLL_CLKIN_MCLK:
  356. case TAS2552_PLL_CLKIN_IVCLKIN:
  357. if (freq < 512000 || freq > 24576000) {
  358. /* out of range PLL_CLKIN, fall back to use BCLK */
  359. dev_warn(codec->dev, "Out of range PLL_CLKIN: %u\n",
  360. freq);
  361. clk_id = TAS2552_PLL_CLKIN_BCLK;
  362. freq = 0;
  363. }
  364. /* fall through */
  365. case TAS2552_PLL_CLKIN_BCLK:
  366. case TAS2552_PLL_CLKIN_1_8_FIXED:
  367. mask = TAS2552_PLL_SRC_MASK;
  368. val = (clk_id << 3) & mask; /* bit 4:5 in the register */
  369. reg = TAS2552_CFG_1;
  370. tas2552->pll_clk_id = clk_id;
  371. tas2552->pll_clkin = freq;
  372. break;
  373. case TAS2552_PDM_CLK_PLL:
  374. case TAS2552_PDM_CLK_IVCLKIN:
  375. case TAS2552_PDM_CLK_BCLK:
  376. case TAS2552_PDM_CLK_MCLK:
  377. mask = TAS2552_PDM_CLK_SEL_MASK;
  378. val = (clk_id >> 1) & mask; /* bit 0:1 in the register */
  379. reg = TAS2552_PDM_CFG;
  380. tas2552->pdm_clk_id = clk_id;
  381. tas2552->pdm_clk = freq;
  382. break;
  383. default:
  384. dev_err(codec->dev, "Invalid clk id: %d\n", clk_id);
  385. return -EINVAL;
  386. }
  387. snd_soc_update_bits(codec, reg, mask, val);
  388. return 0;
  389. }
  390. static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
  391. unsigned int tx_mask, unsigned int rx_mask,
  392. int slots, int slot_width)
  393. {
  394. struct snd_soc_codec *codec = dai->codec;
  395. struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
  396. unsigned int lsb;
  397. if (unlikely(!tx_mask)) {
  398. dev_err(codec->dev, "tx masks need to be non 0\n");
  399. return -EINVAL;
  400. }
  401. /* TDM based on DSP mode requires slots to be adjacent */
  402. lsb = __ffs(tx_mask);
  403. if ((lsb + 1) != __fls(tx_mask)) {
  404. dev_err(codec->dev, "Invalid mask, slots must be adjacent\n");
  405. return -EINVAL;
  406. }
  407. tas2552->tdm_delay = lsb * slot_width;
  408. /* DOUT in high-impedance on inactive bit clocks */
  409. snd_soc_update_bits(codec, TAS2552_DOUT,
  410. TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);
  411. return 0;
  412. }
  413. static int tas2552_mute(struct snd_soc_dai *dai, int mute)
  414. {
  415. u8 cfg1_reg = 0;
  416. struct snd_soc_codec *codec = dai->codec;
  417. if (mute)
  418. cfg1_reg |= TAS2552_MUTE;
  419. snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
  420. return 0;
  421. }
  422. #ifdef CONFIG_PM
  423. static int tas2552_runtime_suspend(struct device *dev)
  424. {
  425. struct tas2552_data *tas2552 = dev_get_drvdata(dev);
  426. tas2552_sw_shutdown(tas2552, 1);
  427. regcache_cache_only(tas2552->regmap, true);
  428. regcache_mark_dirty(tas2552->regmap);
  429. gpiod_set_value(tas2552->enable_gpio, 0);
  430. return 0;
  431. }
  432. static int tas2552_runtime_resume(struct device *dev)
  433. {
  434. struct tas2552_data *tas2552 = dev_get_drvdata(dev);
  435. gpiod_set_value(tas2552->enable_gpio, 1);
  436. tas2552_sw_shutdown(tas2552, 0);
  437. regcache_cache_only(tas2552->regmap, false);
  438. regcache_sync(tas2552->regmap);
  439. return 0;
  440. }
  441. #endif
  442. static const struct dev_pm_ops tas2552_pm = {
  443. SET_RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume,
  444. NULL)
  445. };
  446. static const struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
  447. .hw_params = tas2552_hw_params,
  448. .prepare = tas2552_prepare,
  449. .set_sysclk = tas2552_set_dai_sysclk,
  450. .set_fmt = tas2552_set_dai_fmt,
  451. .set_tdm_slot = tas2552_set_dai_tdm_slot,
  452. .digital_mute = tas2552_mute,
  453. };
  454. /* Formats supported by TAS2552 driver. */
  455. #define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  456. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  457. /* TAS2552 dai structure. */
  458. static struct snd_soc_dai_driver tas2552_dai[] = {
  459. {
  460. .name = "tas2552-amplifier",
  461. .playback = {
  462. .stream_name = "Playback",
  463. .channels_min = 2,
  464. .channels_max = 2,
  465. .rates = SNDRV_PCM_RATE_8000_192000,
  466. .formats = TAS2552_FORMATS,
  467. },
  468. .ops = &tas2552_speaker_dai_ops,
  469. },
  470. };
  471. /*
  472. * DAC digital volumes. From -7 to 24 dB in 1 dB steps
  473. */
  474. static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);
  475. static const char * const tas2552_din_source_select[] = {
  476. "Muted",
  477. "Left",
  478. "Right",
  479. "Left + Right average",
  480. };
  481. static SOC_ENUM_SINGLE_DECL(tas2552_din_source_enum,
  482. TAS2552_CFG_3, 3,
  483. tas2552_din_source_select);
  484. static const struct snd_kcontrol_new tas2552_snd_controls[] = {
  485. SOC_SINGLE_TLV("Speaker Driver Playback Volume",
  486. TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv),
  487. SOC_ENUM("DIN source", tas2552_din_source_enum),
  488. };
  489. static int tas2552_codec_probe(struct snd_soc_codec *codec)
  490. {
  491. struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
  492. int ret;
  493. tas2552->codec = codec;
  494. ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
  495. tas2552->supplies);
  496. if (ret != 0) {
  497. dev_err(codec->dev, "Failed to enable supplies: %d\n",
  498. ret);
  499. return ret;
  500. }
  501. gpiod_set_value(tas2552->enable_gpio, 1);
  502. ret = pm_runtime_get_sync(codec->dev);
  503. if (ret < 0) {
  504. dev_err(codec->dev, "Enabling device failed: %d\n",
  505. ret);
  506. goto probe_fail;
  507. }
  508. snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
  509. snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
  510. TAS2552_DIN_SRC_SEL_AVG_L_R);
  511. snd_soc_write(codec, TAS2552_OUTPUT_DATA,
  512. TAS2552_PDM_DATA_SEL_V_I |
  513. TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
  514. snd_soc_write(codec, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
  515. TAS2552_APT_THRESH_20_17);
  516. snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
  517. TAS2552_LIM_EN);
  518. return 0;
  519. probe_fail:
  520. gpiod_set_value(tas2552->enable_gpio, 0);
  521. regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
  522. tas2552->supplies);
  523. return -EIO;
  524. }
  525. static int tas2552_codec_remove(struct snd_soc_codec *codec)
  526. {
  527. struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
  528. pm_runtime_put(codec->dev);
  529. gpiod_set_value(tas2552->enable_gpio, 0);
  530. return 0;
  531. };
  532. #ifdef CONFIG_PM
  533. static int tas2552_suspend(struct snd_soc_codec *codec)
  534. {
  535. struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
  536. int ret;
  537. ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
  538. tas2552->supplies);
  539. if (ret != 0)
  540. dev_err(codec->dev, "Failed to disable supplies: %d\n",
  541. ret);
  542. return 0;
  543. }
  544. static int tas2552_resume(struct snd_soc_codec *codec)
  545. {
  546. struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
  547. int ret;
  548. ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
  549. tas2552->supplies);
  550. if (ret != 0) {
  551. dev_err(codec->dev, "Failed to enable supplies: %d\n",
  552. ret);
  553. }
  554. return 0;
  555. }
  556. #else
  557. #define tas2552_suspend NULL
  558. #define tas2552_resume NULL
  559. #endif
  560. static struct snd_soc_codec_driver soc_codec_dev_tas2552 = {
  561. .probe = tas2552_codec_probe,
  562. .remove = tas2552_codec_remove,
  563. .suspend = tas2552_suspend,
  564. .resume = tas2552_resume,
  565. .ignore_pmdown_time = true,
  566. .component_driver = {
  567. .controls = tas2552_snd_controls,
  568. .num_controls = ARRAY_SIZE(tas2552_snd_controls),
  569. .dapm_widgets = tas2552_dapm_widgets,
  570. .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets),
  571. .dapm_routes = tas2552_audio_map,
  572. .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map),
  573. },
  574. };
  575. static const struct regmap_config tas2552_regmap_config = {
  576. .reg_bits = 8,
  577. .val_bits = 8,
  578. .max_register = TAS2552_MAX_REG,
  579. .reg_defaults = tas2552_reg_defs,
  580. .num_reg_defaults = ARRAY_SIZE(tas2552_reg_defs),
  581. .cache_type = REGCACHE_RBTREE,
  582. };
  583. static int tas2552_probe(struct i2c_client *client,
  584. const struct i2c_device_id *id)
  585. {
  586. struct device *dev;
  587. struct tas2552_data *data;
  588. int ret;
  589. int i;
  590. dev = &client->dev;
  591. data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
  592. if (data == NULL)
  593. return -ENOMEM;
  594. data->enable_gpio = devm_gpiod_get_optional(dev, "enable",
  595. GPIOD_OUT_LOW);
  596. if (IS_ERR(data->enable_gpio))
  597. return PTR_ERR(data->enable_gpio);
  598. data->tas2552_client = client;
  599. data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
  600. if (IS_ERR(data->regmap)) {
  601. ret = PTR_ERR(data->regmap);
  602. dev_err(&client->dev, "Failed to allocate register map: %d\n",
  603. ret);
  604. return ret;
  605. }
  606. for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
  607. data->supplies[i].supply = tas2552_supply_names[i];
  608. ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
  609. data->supplies);
  610. if (ret != 0) {
  611. dev_err(dev, "Failed to request supplies: %d\n", ret);
  612. return ret;
  613. }
  614. pm_runtime_set_active(&client->dev);
  615. pm_runtime_set_autosuspend_delay(&client->dev, 1000);
  616. pm_runtime_use_autosuspend(&client->dev);
  617. pm_runtime_enable(&client->dev);
  618. pm_runtime_mark_last_busy(&client->dev);
  619. pm_runtime_put_sync_autosuspend(&client->dev);
  620. dev_set_drvdata(&client->dev, data);
  621. ret = snd_soc_register_codec(&client->dev,
  622. &soc_codec_dev_tas2552,
  623. tas2552_dai, ARRAY_SIZE(tas2552_dai));
  624. if (ret < 0)
  625. dev_err(&client->dev, "Failed to register codec: %d\n", ret);
  626. return ret;
  627. }
  628. static int tas2552_i2c_remove(struct i2c_client *client)
  629. {
  630. snd_soc_unregister_codec(&client->dev);
  631. pm_runtime_disable(&client->dev);
  632. return 0;
  633. }
  634. static const struct i2c_device_id tas2552_id[] = {
  635. { "tas2552", 0 },
  636. { }
  637. };
  638. MODULE_DEVICE_TABLE(i2c, tas2552_id);
  639. #if IS_ENABLED(CONFIG_OF)
  640. static const struct of_device_id tas2552_of_match[] = {
  641. { .compatible = "ti,tas2552", },
  642. {},
  643. };
  644. MODULE_DEVICE_TABLE(of, tas2552_of_match);
  645. #endif
  646. static struct i2c_driver tas2552_i2c_driver = {
  647. .driver = {
  648. .name = "tas2552",
  649. .of_match_table = of_match_ptr(tas2552_of_match),
  650. .pm = &tas2552_pm,
  651. },
  652. .probe = tas2552_probe,
  653. .remove = tas2552_i2c_remove,
  654. .id_table = tas2552_id,
  655. };
  656. module_i2c_driver(tas2552_i2c_driver);
  657. MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>");
  658. MODULE_DESCRIPTION("TAS2552 Audio amplifier driver");
  659. MODULE_LICENSE("GPL");