tas2764.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Driver for the Texas Instruments TAS2764 CODEC
  4. // Copyright (C) 2020 Texas Instruments Inc.
  5. #include <linux/module.h>
  6. #include <linux/moduleparam.h>
  7. #include <linux/err.h>
  8. #include <linux/init.h>
  9. #include <linux/delay.h>
  10. #include <linux/pm.h>
  11. #include <linux/i2c.h>
  12. #include <linux/gpio.h>
  13. #include <linux/gpio/consumer.h>
  14. #include <linux/regulator/consumer.h>
  15. #include <linux/regmap.h>
  16. #include <linux/of.h>
  17. #include <linux/of_gpio.h>
  18. #include <linux/slab.h>
  19. #include <sound/soc.h>
  20. #include <sound/pcm.h>
  21. #include <sound/pcm_params.h>
  22. #include <sound/initval.h>
  23. #include <sound/tlv.h>
  24. #include "tas2764.h"
  25. struct tas2764_priv {
  26. struct snd_soc_component *component;
  27. struct gpio_desc *reset_gpio;
  28. struct gpio_desc *sdz_gpio;
  29. struct regmap *regmap;
  30. struct device *dev;
  31. int irq;
  32. int v_sense_slot;
  33. int i_sense_slot;
  34. bool dac_powered;
  35. bool unmuted;
  36. };
  37. static const char *tas2764_int_ltch0_msgs[8] = {
  38. "fault: over temperature", /* INT_LTCH0 & BIT(0) */
  39. "fault: over current",
  40. "fault: bad TDM clock",
  41. "limiter active",
  42. "fault: PVDD below limiter inflection point",
  43. "fault: limiter max attenuation",
  44. "fault: BOP infinite hold",
  45. "fault: BOP mute", /* INT_LTCH0 & BIT(7) */
  46. };
  47. static const unsigned int tas2764_int_readout_regs[6] = {
  48. TAS2764_INT_LTCH0,
  49. TAS2764_INT_LTCH1,
  50. TAS2764_INT_LTCH1_0,
  51. TAS2764_INT_LTCH2,
  52. TAS2764_INT_LTCH3,
  53. TAS2764_INT_LTCH4,
  54. };
  55. static irqreturn_t tas2764_irq(int irq, void *data)
  56. {
  57. struct tas2764_priv *tas2764 = data;
  58. u8 latched[6] = {0, 0, 0, 0, 0, 0};
  59. int ret = IRQ_NONE;
  60. int i;
  61. for (i = 0; i < ARRAY_SIZE(latched); i++)
  62. latched[i] = snd_soc_component_read(tas2764->component,
  63. tas2764_int_readout_regs[i]);
  64. for (i = 0; i < 8; i++) {
  65. if (latched[0] & BIT(i)) {
  66. dev_crit_ratelimited(tas2764->dev, "%s\n",
  67. tas2764_int_ltch0_msgs[i]);
  68. ret = IRQ_HANDLED;
  69. }
  70. }
  71. if (latched[0]) {
  72. dev_err_ratelimited(tas2764->dev, "other context to the fault: %02x,%02x,%02x,%02x,%02x",
  73. latched[1], latched[2], latched[3], latched[4], latched[5]);
  74. snd_soc_component_update_bits(tas2764->component,
  75. TAS2764_INT_CLK_CFG,
  76. TAS2764_INT_CLK_CFG_IRQZ_CLR,
  77. TAS2764_INT_CLK_CFG_IRQZ_CLR);
  78. }
  79. return ret;
  80. }
  81. static void tas2764_reset(struct tas2764_priv *tas2764)
  82. {
  83. if (tas2764->reset_gpio) {
  84. gpiod_set_value_cansleep(tas2764->reset_gpio, 0);
  85. msleep(20);
  86. gpiod_set_value_cansleep(tas2764->reset_gpio, 1);
  87. usleep_range(1000, 2000);
  88. }
  89. snd_soc_component_write(tas2764->component, TAS2764_SW_RST,
  90. TAS2764_RST);
  91. usleep_range(1000, 2000);
  92. }
  93. static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764)
  94. {
  95. struct snd_soc_component *component = tas2764->component;
  96. unsigned int val;
  97. int ret;
  98. if (tas2764->dac_powered)
  99. val = tas2764->unmuted ?
  100. TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE;
  101. else
  102. val = TAS2764_PWR_CTRL_SHUTDOWN;
  103. ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
  104. TAS2764_PWR_CTRL_MASK, val);
  105. if (ret < 0)
  106. return ret;
  107. return 0;
  108. }
  109. #ifdef CONFIG_PM
  110. static int tas2764_codec_suspend(struct snd_soc_component *component)
  111. {
  112. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  113. int ret;
  114. ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
  115. TAS2764_PWR_CTRL_MASK,
  116. TAS2764_PWR_CTRL_SHUTDOWN);
  117. if (ret < 0)
  118. return ret;
  119. if (tas2764->sdz_gpio)
  120. gpiod_set_value_cansleep(tas2764->sdz_gpio, 0);
  121. regcache_cache_only(tas2764->regmap, true);
  122. regcache_mark_dirty(tas2764->regmap);
  123. return 0;
  124. }
  125. static int tas2764_codec_resume(struct snd_soc_component *component)
  126. {
  127. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  128. int ret;
  129. if (tas2764->sdz_gpio) {
  130. gpiod_set_value_cansleep(tas2764->sdz_gpio, 1);
  131. usleep_range(1000, 2000);
  132. }
  133. ret = tas2764_update_pwr_ctrl(tas2764);
  134. if (ret < 0)
  135. return ret;
  136. regcache_cache_only(tas2764->regmap, false);
  137. return regcache_sync(tas2764->regmap);
  138. }
  139. #else
  140. #define tas2764_codec_suspend NULL
  141. #define tas2764_codec_resume NULL
  142. #endif
  143. static const char * const tas2764_ASI1_src[] = {
  144. "I2C offset", "Left", "Right", "LeftRightDiv2",
  145. };
  146. static SOC_ENUM_SINGLE_DECL(
  147. tas2764_ASI1_src_enum, TAS2764_TDM_CFG2, TAS2764_TDM_CFG2_SCFG_SHIFT,
  148. tas2764_ASI1_src);
  149. static const struct snd_kcontrol_new tas2764_asi1_mux =
  150. SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum);
  151. static int tas2764_dac_event(struct snd_soc_dapm_widget *w,
  152. struct snd_kcontrol *kcontrol, int event)
  153. {
  154. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  155. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  156. int ret;
  157. switch (event) {
  158. case SND_SOC_DAPM_POST_PMU:
  159. tas2764->dac_powered = true;
  160. ret = tas2764_update_pwr_ctrl(tas2764);
  161. break;
  162. case SND_SOC_DAPM_PRE_PMD:
  163. tas2764->dac_powered = false;
  164. ret = tas2764_update_pwr_ctrl(tas2764);
  165. break;
  166. default:
  167. dev_err(tas2764->dev, "Unsupported event\n");
  168. return -EINVAL;
  169. }
  170. if (ret < 0)
  171. return ret;
  172. return 0;
  173. }
  174. static const struct snd_kcontrol_new isense_switch =
  175. SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1);
  176. static const struct snd_kcontrol_new vsense_switch =
  177. SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 1, 1);
  178. static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = {
  179. SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
  180. SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2764_asi1_mux),
  181. SND_SOC_DAPM_SWITCH("ISENSE", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN,
  182. 1, &isense_switch),
  183. SND_SOC_DAPM_SWITCH("VSENSE", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN,
  184. 1, &vsense_switch),
  185. SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2764_dac_event,
  186. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
  187. SND_SOC_DAPM_OUTPUT("OUT"),
  188. SND_SOC_DAPM_SIGGEN("VMON"),
  189. SND_SOC_DAPM_SIGGEN("IMON")
  190. };
  191. static const struct snd_soc_dapm_route tas2764_audio_map[] = {
  192. {"ASI1 Sel", "I2C offset", "ASI1"},
  193. {"ASI1 Sel", "Left", "ASI1"},
  194. {"ASI1 Sel", "Right", "ASI1"},
  195. {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
  196. {"DAC", NULL, "ASI1 Sel"},
  197. {"OUT", NULL, "DAC"},
  198. {"ISENSE", "Switch", "IMON"},
  199. {"VSENSE", "Switch", "VMON"},
  200. };
  201. static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction)
  202. {
  203. struct tas2764_priv *tas2764 =
  204. snd_soc_component_get_drvdata(dai->component);
  205. tas2764->unmuted = !mute;
  206. return tas2764_update_pwr_ctrl(tas2764);
  207. }
  208. static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth)
  209. {
  210. struct snd_soc_component *component = tas2764->component;
  211. int sense_en;
  212. int val;
  213. int ret;
  214. switch (bitwidth) {
  215. case SNDRV_PCM_FORMAT_S16_LE:
  216. ret = snd_soc_component_update_bits(component,
  217. TAS2764_TDM_CFG2,
  218. TAS2764_TDM_CFG2_RXW_MASK,
  219. TAS2764_TDM_CFG2_RXW_16BITS);
  220. break;
  221. case SNDRV_PCM_FORMAT_S24_LE:
  222. ret = snd_soc_component_update_bits(component,
  223. TAS2764_TDM_CFG2,
  224. TAS2764_TDM_CFG2_RXW_MASK,
  225. TAS2764_TDM_CFG2_RXW_24BITS);
  226. break;
  227. case SNDRV_PCM_FORMAT_S32_LE:
  228. ret = snd_soc_component_update_bits(component,
  229. TAS2764_TDM_CFG2,
  230. TAS2764_TDM_CFG2_RXW_MASK,
  231. TAS2764_TDM_CFG2_RXW_32BITS);
  232. break;
  233. default:
  234. return -EINVAL;
  235. }
  236. if (ret < 0)
  237. return ret;
  238. val = snd_soc_component_read(tas2764->component, TAS2764_PWR_CTRL);
  239. if (val < 0)
  240. return val;
  241. if (val & (1 << TAS2764_VSENSE_POWER_EN))
  242. sense_en = 0;
  243. else
  244. sense_en = TAS2764_TDM_CFG5_VSNS_ENABLE;
  245. ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5,
  246. TAS2764_TDM_CFG5_VSNS_ENABLE,
  247. sense_en);
  248. if (ret < 0)
  249. return ret;
  250. if (val & (1 << TAS2764_ISENSE_POWER_EN))
  251. sense_en = 0;
  252. else
  253. sense_en = TAS2764_TDM_CFG6_ISNS_ENABLE;
  254. ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6,
  255. TAS2764_TDM_CFG6_ISNS_ENABLE,
  256. sense_en);
  257. if (ret < 0)
  258. return ret;
  259. return 0;
  260. }
  261. static int tas2764_set_samplerate(struct tas2764_priv *tas2764, int samplerate)
  262. {
  263. struct snd_soc_component *component = tas2764->component;
  264. int ramp_rate_val;
  265. int ret;
  266. switch (samplerate) {
  267. case 48000:
  268. ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ |
  269. TAS2764_TDM_CFG0_44_1_48KHZ;
  270. break;
  271. case 44100:
  272. ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ |
  273. TAS2764_TDM_CFG0_44_1_48KHZ;
  274. break;
  275. case 96000:
  276. ramp_rate_val = TAS2764_TDM_CFG0_SMP_48KHZ |
  277. TAS2764_TDM_CFG0_88_2_96KHZ;
  278. break;
  279. case 88200:
  280. ramp_rate_val = TAS2764_TDM_CFG0_SMP_44_1KHZ |
  281. TAS2764_TDM_CFG0_88_2_96KHZ;
  282. break;
  283. default:
  284. return -EINVAL;
  285. }
  286. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0,
  287. TAS2764_TDM_CFG0_SMP_MASK |
  288. TAS2764_TDM_CFG0_MASK,
  289. ramp_rate_val);
  290. if (ret < 0)
  291. return ret;
  292. return 0;
  293. }
  294. static int tas2764_hw_params(struct snd_pcm_substream *substream,
  295. struct snd_pcm_hw_params *params,
  296. struct snd_soc_dai *dai)
  297. {
  298. struct snd_soc_component *component = dai->component;
  299. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  300. int ret;
  301. ret = tas2764_set_bitwidth(tas2764, params_format(params));
  302. if (ret < 0)
  303. return ret;
  304. return tas2764_set_samplerate(tas2764, params_rate(params));
  305. }
  306. static int tas2764_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  307. {
  308. struct snd_soc_component *component = dai->component;
  309. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  310. u8 tdm_rx_start_slot = 0, asi_cfg_0 = 0, asi_cfg_1 = 0;
  311. int ret;
  312. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  313. case SND_SOC_DAIFMT_NB_IF:
  314. asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
  315. fallthrough;
  316. case SND_SOC_DAIFMT_NB_NF:
  317. asi_cfg_1 = TAS2764_TDM_CFG1_RX_RISING;
  318. break;
  319. case SND_SOC_DAIFMT_IB_IF:
  320. asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
  321. fallthrough;
  322. case SND_SOC_DAIFMT_IB_NF:
  323. asi_cfg_1 = TAS2764_TDM_CFG1_RX_FALLING;
  324. break;
  325. }
  326. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
  327. TAS2764_TDM_CFG1_RX_MASK,
  328. asi_cfg_1);
  329. if (ret < 0)
  330. return ret;
  331. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  332. case SND_SOC_DAIFMT_I2S:
  333. asi_cfg_0 ^= TAS2764_TDM_CFG0_FRAME_START;
  334. fallthrough;
  335. case SND_SOC_DAIFMT_DSP_A:
  336. tdm_rx_start_slot = 1;
  337. break;
  338. case SND_SOC_DAIFMT_DSP_B:
  339. case SND_SOC_DAIFMT_LEFT_J:
  340. tdm_rx_start_slot = 0;
  341. break;
  342. default:
  343. dev_err(tas2764->dev,
  344. "DAI Format is not found, fmt=0x%x\n", fmt);
  345. return -EINVAL;
  346. }
  347. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG0,
  348. TAS2764_TDM_CFG0_FRAME_START,
  349. asi_cfg_0);
  350. if (ret < 0)
  351. return ret;
  352. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG1,
  353. TAS2764_TDM_CFG1_MASK,
  354. (tdm_rx_start_slot << TAS2764_TDM_CFG1_51_SHIFT));
  355. if (ret < 0)
  356. return ret;
  357. return 0;
  358. }
  359. static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai,
  360. unsigned int tx_mask,
  361. unsigned int rx_mask,
  362. int slots, int slot_width)
  363. {
  364. struct snd_soc_component *component = dai->component;
  365. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  366. int left_slot, right_slot;
  367. int slots_cfg;
  368. int slot_size;
  369. int ret;
  370. if (tx_mask == 0 || rx_mask != 0)
  371. return -EINVAL;
  372. left_slot = __ffs(tx_mask);
  373. tx_mask &= ~(1 << left_slot);
  374. if (tx_mask == 0) {
  375. right_slot = left_slot;
  376. } else {
  377. right_slot = __ffs(tx_mask);
  378. tx_mask &= ~(1 << right_slot);
  379. }
  380. if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
  381. return -EINVAL;
  382. slots_cfg = (right_slot << TAS2764_TDM_CFG3_RXS_SHIFT) | left_slot;
  383. ret = snd_soc_component_write(component, TAS2764_TDM_CFG3, slots_cfg);
  384. if (ret)
  385. return ret;
  386. switch (slot_width) {
  387. case 16:
  388. slot_size = TAS2764_TDM_CFG2_RXS_16BITS;
  389. break;
  390. case 24:
  391. slot_size = TAS2764_TDM_CFG2_RXS_24BITS;
  392. break;
  393. case 32:
  394. slot_size = TAS2764_TDM_CFG2_RXS_32BITS;
  395. break;
  396. default:
  397. return -EINVAL;
  398. }
  399. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG2,
  400. TAS2764_TDM_CFG2_RXS_MASK,
  401. slot_size);
  402. if (ret < 0)
  403. return ret;
  404. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG5,
  405. TAS2764_TDM_CFG5_50_MASK,
  406. tas2764->v_sense_slot);
  407. if (ret < 0)
  408. return ret;
  409. ret = snd_soc_component_update_bits(component, TAS2764_TDM_CFG6,
  410. TAS2764_TDM_CFG6_50_MASK,
  411. tas2764->i_sense_slot);
  412. if (ret < 0)
  413. return ret;
  414. return 0;
  415. }
  416. static const struct snd_soc_dai_ops tas2764_dai_ops = {
  417. .mute_stream = tas2764_mute,
  418. .hw_params = tas2764_hw_params,
  419. .set_fmt = tas2764_set_fmt,
  420. .set_tdm_slot = tas2764_set_dai_tdm_slot,
  421. .no_capture_mute = 1,
  422. };
  423. #define TAS2764_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  424. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  425. #define TAS2764_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
  426. SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200)
  427. static struct snd_soc_dai_driver tas2764_dai_driver[] = {
  428. {
  429. .name = "tas2764 ASI1",
  430. .id = 0,
  431. .playback = {
  432. .stream_name = "ASI1 Playback",
  433. .channels_min = 1,
  434. .channels_max = 2,
  435. .rates = TAS2764_RATES,
  436. .formats = TAS2764_FORMATS,
  437. },
  438. .capture = {
  439. .stream_name = "ASI1 Capture",
  440. .channels_min = 0,
  441. .channels_max = 2,
  442. .rates = TAS2764_RATES,
  443. .formats = TAS2764_FORMATS,
  444. },
  445. .ops = &tas2764_dai_ops,
  446. .symmetric_rate = 1,
  447. },
  448. };
  449. static int tas2764_codec_probe(struct snd_soc_component *component)
  450. {
  451. struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
  452. int ret;
  453. tas2764->component = component;
  454. if (tas2764->sdz_gpio) {
  455. gpiod_set_value_cansleep(tas2764->sdz_gpio, 1);
  456. usleep_range(1000, 2000);
  457. }
  458. tas2764_reset(tas2764);
  459. if (tas2764->irq) {
  460. ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff);
  461. if (ret < 0)
  462. return ret;
  463. ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK1, 0xff);
  464. if (ret < 0)
  465. return ret;
  466. ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK2, 0xff);
  467. if (ret < 0)
  468. return ret;
  469. ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK3, 0xff);
  470. if (ret < 0)
  471. return ret;
  472. ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK4, 0xff);
  473. if (ret < 0)
  474. return ret;
  475. ret = devm_request_threaded_irq(tas2764->dev, tas2764->irq, NULL, tas2764_irq,
  476. IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
  477. "tas2764", tas2764);
  478. if (ret)
  479. dev_warn(tas2764->dev, "failed to request IRQ: %d\n", ret);
  480. }
  481. ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG5,
  482. TAS2764_TDM_CFG5_VSNS_ENABLE, 0);
  483. if (ret < 0)
  484. return ret;
  485. ret = snd_soc_component_update_bits(tas2764->component, TAS2764_TDM_CFG6,
  486. TAS2764_TDM_CFG6_ISNS_ENABLE, 0);
  487. if (ret < 0)
  488. return ret;
  489. return 0;
  490. }
  491. static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0);
  492. static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1);
  493. static const char * const tas2764_hpf_texts[] = {
  494. "Disabled", "2 Hz", "50 Hz", "100 Hz", "200 Hz",
  495. "400 Hz", "800 Hz"
  496. };
  497. static SOC_ENUM_SINGLE_DECL(
  498. tas2764_hpf_enum, TAS2764_DC_BLK0,
  499. TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts);
  500. static const struct snd_kcontrol_new tas2764_snd_controls[] = {
  501. SOC_SINGLE_TLV("Speaker Volume", TAS2764_DVC, 0,
  502. TAS2764_DVC_MAX, 1, tas2764_playback_volume),
  503. SOC_SINGLE_TLV("Amp Gain Volume", TAS2764_CHNL_0, 1, 0x14, 0,
  504. tas2764_digital_tlv),
  505. SOC_ENUM("HPF Corner Frequency", tas2764_hpf_enum),
  506. };
  507. static const struct snd_soc_component_driver soc_component_driver_tas2764 = {
  508. .probe = tas2764_codec_probe,
  509. .suspend = tas2764_codec_suspend,
  510. .resume = tas2764_codec_resume,
  511. .controls = tas2764_snd_controls,
  512. .num_controls = ARRAY_SIZE(tas2764_snd_controls),
  513. .dapm_widgets = tas2764_dapm_widgets,
  514. .num_dapm_widgets = ARRAY_SIZE(tas2764_dapm_widgets),
  515. .dapm_routes = tas2764_audio_map,
  516. .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map),
  517. .idle_bias_on = 1,
  518. .endianness = 1,
  519. };
  520. static const struct reg_default tas2764_reg_defaults[] = {
  521. { TAS2764_PAGE, 0x00 },
  522. { TAS2764_SW_RST, 0x00 },
  523. { TAS2764_PWR_CTRL, 0x1a },
  524. { TAS2764_DVC, 0x00 },
  525. { TAS2764_CHNL_0, 0x28 },
  526. { TAS2764_TDM_CFG0, 0x09 },
  527. { TAS2764_TDM_CFG1, 0x02 },
  528. { TAS2764_TDM_CFG2, 0x0a },
  529. { TAS2764_TDM_CFG3, 0x10 },
  530. { TAS2764_TDM_CFG5, 0x42 },
  531. };
  532. static const struct regmap_range_cfg tas2764_regmap_ranges[] = {
  533. {
  534. .range_min = 0,
  535. .range_max = 1 * 128,
  536. .selector_reg = TAS2764_PAGE,
  537. .selector_mask = 0xff,
  538. .selector_shift = 0,
  539. .window_start = 0,
  540. .window_len = 128,
  541. },
  542. };
  543. static bool tas2764_volatile_register(struct device *dev, unsigned int reg)
  544. {
  545. switch (reg) {
  546. case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4:
  547. case TAS2764_INT_CLK_CFG:
  548. return true;
  549. default:
  550. return false;
  551. }
  552. }
  553. static const struct regmap_config tas2764_i2c_regmap = {
  554. .reg_bits = 8,
  555. .val_bits = 8,
  556. .volatile_reg = tas2764_volatile_register,
  557. .reg_defaults = tas2764_reg_defaults,
  558. .num_reg_defaults = ARRAY_SIZE(tas2764_reg_defaults),
  559. .cache_type = REGCACHE_RBTREE,
  560. .ranges = tas2764_regmap_ranges,
  561. .num_ranges = ARRAY_SIZE(tas2764_regmap_ranges),
  562. .max_register = 1 * 128,
  563. };
  564. static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764)
  565. {
  566. int ret = 0;
  567. tas2764->reset_gpio = devm_gpiod_get_optional(tas2764->dev, "reset",
  568. GPIOD_OUT_HIGH);
  569. if (IS_ERR(tas2764->reset_gpio)) {
  570. if (PTR_ERR(tas2764->reset_gpio) == -EPROBE_DEFER) {
  571. tas2764->reset_gpio = NULL;
  572. return -EPROBE_DEFER;
  573. }
  574. }
  575. tas2764->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
  576. if (IS_ERR(tas2764->sdz_gpio)) {
  577. if (PTR_ERR(tas2764->sdz_gpio) == -EPROBE_DEFER)
  578. return -EPROBE_DEFER;
  579. tas2764->sdz_gpio = NULL;
  580. }
  581. ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
  582. &tas2764->i_sense_slot);
  583. if (ret)
  584. tas2764->i_sense_slot = 0;
  585. ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
  586. &tas2764->v_sense_slot);
  587. if (ret)
  588. tas2764->v_sense_slot = 2;
  589. return 0;
  590. }
  591. static int tas2764_i2c_probe(struct i2c_client *client)
  592. {
  593. struct tas2764_priv *tas2764;
  594. int result;
  595. tas2764 = devm_kzalloc(&client->dev, sizeof(struct tas2764_priv),
  596. GFP_KERNEL);
  597. if (!tas2764)
  598. return -ENOMEM;
  599. tas2764->dev = &client->dev;
  600. tas2764->irq = client->irq;
  601. i2c_set_clientdata(client, tas2764);
  602. dev_set_drvdata(&client->dev, tas2764);
  603. tas2764->regmap = devm_regmap_init_i2c(client, &tas2764_i2c_regmap);
  604. if (IS_ERR(tas2764->regmap)) {
  605. result = PTR_ERR(tas2764->regmap);
  606. dev_err(&client->dev, "Failed to allocate register map: %d\n",
  607. result);
  608. return result;
  609. }
  610. if (client->dev.of_node) {
  611. result = tas2764_parse_dt(&client->dev, tas2764);
  612. if (result) {
  613. dev_err(tas2764->dev, "%s: Failed to parse devicetree\n",
  614. __func__);
  615. return result;
  616. }
  617. }
  618. return devm_snd_soc_register_component(tas2764->dev,
  619. &soc_component_driver_tas2764,
  620. tas2764_dai_driver,
  621. ARRAY_SIZE(tas2764_dai_driver));
  622. }
  623. static const struct i2c_device_id tas2764_i2c_id[] = {
  624. { "tas2764", 0},
  625. { }
  626. };
  627. MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id);
  628. #if defined(CONFIG_OF)
  629. static const struct of_device_id tas2764_of_match[] = {
  630. { .compatible = "ti,tas2764" },
  631. {},
  632. };
  633. MODULE_DEVICE_TABLE(of, tas2764_of_match);
  634. #endif
  635. static struct i2c_driver tas2764_i2c_driver = {
  636. .driver = {
  637. .name = "tas2764",
  638. .of_match_table = of_match_ptr(tas2764_of_match),
  639. },
  640. .probe_new = tas2764_i2c_probe,
  641. .id_table = tas2764_i2c_id,
  642. };
  643. module_i2c_driver(tas2764_i2c_driver);
  644. MODULE_AUTHOR("Dan Murphy <[email protected]>");
  645. MODULE_DESCRIPTION("TAS2764 I2C Smart Amplifier driver");
  646. MODULE_LICENSE("GPL v2");