hi6210-i2s.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /*
  2. * linux/sound/soc/m8m/hi6210_i2s.c - I2S IP driver
  3. *
  4. * Copyright (C) 2015 Linaro, Ltd
  5. * Author: Andy Green <andy.green@linaro.org>
  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, version 2 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * This driver only deals with S2 interface (BT)
  17. */
  18. #include <linux/init.h>
  19. #include <linux/module.h>
  20. #include <linux/device.h>
  21. #include <linux/delay.h>
  22. #include <linux/clk.h>
  23. #include <linux/jiffies.h>
  24. #include <linux/io.h>
  25. #include <linux/gpio.h>
  26. #include <sound/core.h>
  27. #include <sound/pcm.h>
  28. #include <sound/pcm_params.h>
  29. #include <sound/dmaengine_pcm.h>
  30. #include <sound/initval.h>
  31. #include <sound/soc.h>
  32. #include <linux/interrupt.h>
  33. #include <linux/reset.h>
  34. #include <linux/of_address.h>
  35. #include <linux/of_irq.h>
  36. #include <linux/mfd/syscon.h>
  37. #include <linux/reset-controller.h>
  38. #include "hi6210-i2s.h"
  39. struct hi6210_i2s {
  40. struct device *dev;
  41. struct reset_control *rc;
  42. struct clk *clk[8];
  43. int clocks;
  44. struct snd_soc_dai_driver dai;
  45. void __iomem *base;
  46. struct regmap *sysctrl;
  47. phys_addr_t base_phys;
  48. struct snd_dmaengine_dai_dma_data dma_data[2];
  49. int clk_rate;
  50. spinlock_t lock;
  51. int rate;
  52. int format;
  53. u8 bits;
  54. u8 channels;
  55. u8 id;
  56. u8 channel_length;
  57. u8 use;
  58. u32 master:1;
  59. u32 status:1;
  60. };
  61. #define SC_PERIPH_CLKEN1 0x210
  62. #define SC_PERIPH_CLKDIS1 0x214
  63. #define SC_PERIPH_CLKEN3 0x230
  64. #define SC_PERIPH_CLKDIS3 0x234
  65. #define SC_PERIPH_CLKEN12 0x270
  66. #define SC_PERIPH_CLKDIS12 0x274
  67. #define SC_PERIPH_RSTEN1 0x310
  68. #define SC_PERIPH_RSTDIS1 0x314
  69. #define SC_PERIPH_RSTSTAT1 0x318
  70. #define SC_PERIPH_RSTEN2 0x320
  71. #define SC_PERIPH_RSTDIS2 0x324
  72. #define SC_PERIPH_RSTSTAT2 0x328
  73. #define SOC_PMCTRL_BBPPLLALIAS 0x48
  74. enum {
  75. CLK_DACODEC,
  76. CLK_I2S_BASE,
  77. };
  78. static inline void hi6210_write_reg(struct hi6210_i2s *i2s, int reg, u32 val)
  79. {
  80. writel(val, i2s->base + reg);
  81. }
  82. static inline u32 hi6210_read_reg(struct hi6210_i2s *i2s, int reg)
  83. {
  84. return readl(i2s->base + reg);
  85. }
  86. static int hi6210_i2s_startup(struct snd_pcm_substream *substream,
  87. struct snd_soc_dai *cpu_dai)
  88. {
  89. struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  90. int ret, n;
  91. u32 val;
  92. /* deassert reset on ABB */
  93. regmap_read(i2s->sysctrl, SC_PERIPH_RSTSTAT2, &val);
  94. if (val & BIT(4))
  95. regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS2, BIT(4));
  96. for (n = 0; n < i2s->clocks; n++) {
  97. ret = clk_prepare_enable(i2s->clk[n]);
  98. if (ret) {
  99. while (n--)
  100. clk_disable_unprepare(i2s->clk[n]);
  101. return ret;
  102. }
  103. }
  104. ret = clk_set_rate(i2s->clk[CLK_I2S_BASE], 49152000);
  105. if (ret) {
  106. dev_err(i2s->dev, "%s: setting 49.152MHz base rate failed %d\n",
  107. __func__, ret);
  108. return ret;
  109. }
  110. /* enable clock before frequency division */
  111. regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN12, BIT(9));
  112. /* enable codec working clock / == "codec bus clock" */
  113. regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN1, BIT(5));
  114. /* deassert reset on codec / interface clock / working clock */
  115. regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
  116. regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS1, BIT(5));
  117. /* not interested in i2s irqs */
  118. val = hi6210_read_reg(i2s, HII2S_CODEC_IRQ_MASK);
  119. val |= 0x3f;
  120. hi6210_write_reg(i2s, HII2S_CODEC_IRQ_MASK, val);
  121. /* reset the stereo downlink fifo */
  122. val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
  123. val |= (BIT(5) | BIT(4));
  124. hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
  125. val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
  126. val &= ~(BIT(5) | BIT(4));
  127. hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
  128. val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
  129. val &= ~(HII2S_SW_RST_N__ST_DL_WORDLEN_MASK <<
  130. HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
  131. val |= (HII2S_BITS_16 << HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
  132. hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
  133. val = hi6210_read_reg(i2s, HII2S_MISC_CFG);
  134. /* mux 11/12 = APB not i2s */
  135. val &= ~HII2S_MISC_CFG__ST_DL_TEST_SEL;
  136. /* BT R ch 0 = mixer op of DACR ch */
  137. val &= ~HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
  138. val &= ~HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
  139. val |= HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
  140. /* BT L ch = 1 = mux 7 = "mixer output of DACL */
  141. val |= HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
  142. hi6210_write_reg(i2s, HII2S_MISC_CFG, val);
  143. val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
  144. val |= HII2S_SW_RST_N__SW_RST_N;
  145. hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
  146. return 0;
  147. }
  148. static void hi6210_i2s_shutdown(struct snd_pcm_substream *substream,
  149. struct snd_soc_dai *cpu_dai)
  150. {
  151. struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  152. int n;
  153. for (n = 0; n < i2s->clocks; n++)
  154. clk_disable_unprepare(i2s->clk[n]);
  155. regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
  156. }
  157. static void hi6210_i2s_txctrl(struct snd_soc_dai *cpu_dai, int on)
  158. {
  159. struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  160. u32 val;
  161. spin_lock(&i2s->lock);
  162. if (on) {
  163. /* enable S2 TX */
  164. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  165. val |= HII2S_I2S_CFG__S2_IF_TX_EN;
  166. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  167. } else {
  168. /* disable S2 TX */
  169. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  170. val &= ~HII2S_I2S_CFG__S2_IF_TX_EN;
  171. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  172. }
  173. spin_unlock(&i2s->lock);
  174. }
  175. static void hi6210_i2s_rxctrl(struct snd_soc_dai *cpu_dai, int on)
  176. {
  177. struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  178. u32 val;
  179. spin_lock(&i2s->lock);
  180. if (on) {
  181. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  182. val |= HII2S_I2S_CFG__S2_IF_RX_EN;
  183. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  184. } else {
  185. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  186. val &= ~HII2S_I2S_CFG__S2_IF_RX_EN;
  187. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  188. }
  189. spin_unlock(&i2s->lock);
  190. }
  191. static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
  192. {
  193. struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  194. /*
  195. * We don't actually set the hardware until the hw_params
  196. * call, but we need to validate the user input here.
  197. */
  198. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  199. case SND_SOC_DAIFMT_CBM_CFM:
  200. case SND_SOC_DAIFMT_CBS_CFS:
  201. break;
  202. default:
  203. return -EINVAL;
  204. }
  205. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  206. case SND_SOC_DAIFMT_I2S:
  207. case SND_SOC_DAIFMT_LEFT_J:
  208. case SND_SOC_DAIFMT_RIGHT_J:
  209. break;
  210. default:
  211. return -EINVAL;
  212. }
  213. i2s->format = fmt;
  214. i2s->master = (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) ==
  215. SND_SOC_DAIFMT_CBS_CFS;
  216. return 0;
  217. }
  218. static int hi6210_i2s_hw_params(struct snd_pcm_substream *substream,
  219. struct snd_pcm_hw_params *params,
  220. struct snd_soc_dai *cpu_dai)
  221. {
  222. struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
  223. u32 bits = 0, rate = 0, signed_data = 0, fmt = 0;
  224. u32 val;
  225. struct snd_dmaengine_dai_dma_data *dma_data;
  226. switch (params_format(params)) {
  227. case SNDRV_PCM_FORMAT_U16_LE:
  228. signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
  229. /* fall through */
  230. case SNDRV_PCM_FORMAT_S16_LE:
  231. bits = HII2S_BITS_16;
  232. break;
  233. case SNDRV_PCM_FORMAT_U24_LE:
  234. signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
  235. /* fall through */
  236. case SNDRV_PCM_FORMAT_S24_LE:
  237. bits = HII2S_BITS_24;
  238. break;
  239. default:
  240. dev_err(cpu_dai->dev, "Bad format\n");
  241. return -EINVAL;
  242. }
  243. switch (params_rate(params)) {
  244. case 8000:
  245. rate = HII2S_FS_RATE_8KHZ;
  246. break;
  247. case 16000:
  248. rate = HII2S_FS_RATE_16KHZ;
  249. break;
  250. case 32000:
  251. rate = HII2S_FS_RATE_32KHZ;
  252. break;
  253. case 48000:
  254. rate = HII2S_FS_RATE_48KHZ;
  255. break;
  256. case 96000:
  257. rate = HII2S_FS_RATE_96KHZ;
  258. break;
  259. case 192000:
  260. rate = HII2S_FS_RATE_192KHZ;
  261. break;
  262. default:
  263. dev_err(cpu_dai->dev, "Bad rate: %d\n", params_rate(params));
  264. return -EINVAL;
  265. }
  266. if (!(params_channels(params))) {
  267. dev_err(cpu_dai->dev, "Bad channels\n");
  268. return -EINVAL;
  269. }
  270. dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
  271. switch (bits) {
  272. case HII2S_BITS_24:
  273. i2s->bits = 32;
  274. dma_data->addr_width = 3;
  275. break;
  276. default:
  277. i2s->bits = 16;
  278. dma_data->addr_width = 2;
  279. break;
  280. }
  281. i2s->rate = params_rate(params);
  282. i2s->channels = params_channels(params);
  283. i2s->channel_length = i2s->channels * i2s->bits;
  284. val = hi6210_read_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG);
  285. val &= ~((HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK <<
  286. HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
  287. (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK <<
  288. HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
  289. (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK <<
  290. HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
  291. (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK <<
  292. HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
  293. val |= ((16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
  294. (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
  295. (16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
  296. (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
  297. hi6210_write_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG, val);
  298. val = hi6210_read_reg(i2s, HII2S_IF_CLK_EN_CFG);
  299. val |= (BIT(19) | BIT(18) | BIT(17) |
  300. HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN |
  301. HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN |
  302. HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN |
  303. HII2S_IF_CLK_EN_CFG__ST_DL_R_EN |
  304. HII2S_IF_CLK_EN_CFG__ST_DL_L_EN);
  305. hi6210_write_reg(i2s, HII2S_IF_CLK_EN_CFG, val);
  306. val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG);
  307. val &= ~(HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN |
  308. HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN |
  309. HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN |
  310. HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN |
  311. HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN |
  312. HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN);
  313. val |= (HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN |
  314. HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN);
  315. hi6210_write_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG, val);
  316. val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG);
  317. val &= ~(HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE |
  318. HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE);
  319. hi6210_write_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG, val);
  320. val = hi6210_read_reg(i2s, HII2S_MUX_TOP_MODULE_CFG);
  321. val &= ~(HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE |
  322. HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE |
  323. HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE |
  324. HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE);
  325. hi6210_write_reg(i2s, HII2S_MUX_TOP_MODULE_CFG, val);
  326. switch (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) {
  327. case SND_SOC_DAIFMT_CBM_CFM:
  328. i2s->master = false;
  329. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  330. val |= HII2S_I2S_CFG__S2_MST_SLV;
  331. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  332. break;
  333. case SND_SOC_DAIFMT_CBS_CFS:
  334. i2s->master = true;
  335. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  336. val &= ~HII2S_I2S_CFG__S2_MST_SLV;
  337. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  338. break;
  339. default:
  340. WARN_ONCE(1, "Invalid i2s->fmt MASTER_MASK. This shouldn't happen\n");
  341. return -EINVAL;
  342. }
  343. switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
  344. case SND_SOC_DAIFMT_I2S:
  345. fmt = HII2S_FORMAT_I2S;
  346. break;
  347. case SND_SOC_DAIFMT_LEFT_J:
  348. fmt = HII2S_FORMAT_LEFT_JUST;
  349. break;
  350. case SND_SOC_DAIFMT_RIGHT_J:
  351. fmt = HII2S_FORMAT_RIGHT_JUST;
  352. break;
  353. default:
  354. WARN_ONCE(1, "Invalid i2s->fmt FORMAT_MASK. This shouldn't happen\n");
  355. return -EINVAL;
  356. }
  357. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  358. val &= ~(HII2S_I2S_CFG__S2_FUNC_MODE_MASK <<
  359. HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT);
  360. val |= fmt << HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT;
  361. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  362. val = hi6210_read_reg(i2s, HII2S_CLK_SEL);
  363. val &= ~(HII2S_CLK_SEL__I2S_BT_FM_SEL | /* BT gets the I2S */
  364. HII2S_CLK_SEL__EXT_12_288MHZ_SEL);
  365. hi6210_write_reg(i2s, HII2S_CLK_SEL, val);
  366. dma_data->maxburst = 2;
  367. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  368. dma_data->addr = i2s->base_phys + HII2S_ST_DL_CHANNEL;
  369. else
  370. dma_data->addr = i2s->base_phys + HII2S_STEREO_UPLINK_CHANNEL;
  371. switch (i2s->channels) {
  372. case 1:
  373. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  374. val |= HII2S_I2S_CFG__S2_FRAME_MODE;
  375. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  376. break;
  377. default:
  378. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  379. val &= ~HII2S_I2S_CFG__S2_FRAME_MODE;
  380. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  381. break;
  382. }
  383. /* clear loopback, set signed type and word length */
  384. val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
  385. val &= ~HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
  386. val &= ~(HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK <<
  387. HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
  388. val &= ~(HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK <<
  389. HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT);
  390. val |= signed_data;
  391. val |= (bits << HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
  392. hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
  393. if (!i2s->master)
  394. return 0;
  395. /* set DAC and related units to correct rate */
  396. val = hi6210_read_reg(i2s, HII2S_FS_CFG);
  397. val &= ~(HII2S_FS_CFG__FS_S2_MASK << HII2S_FS_CFG__FS_S2_SHIFT);
  398. val &= ~(HII2S_FS_CFG__FS_DACLR_MASK << HII2S_FS_CFG__FS_DACLR_SHIFT);
  399. val &= ~(HII2S_FS_CFG__FS_ST_DL_R_MASK <<
  400. HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
  401. val &= ~(HII2S_FS_CFG__FS_ST_DL_L_MASK <<
  402. HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
  403. val |= (rate << HII2S_FS_CFG__FS_S2_SHIFT);
  404. val |= (rate << HII2S_FS_CFG__FS_DACLR_SHIFT);
  405. val |= (rate << HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
  406. val |= (rate << HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
  407. hi6210_write_reg(i2s, HII2S_FS_CFG, val);
  408. return 0;
  409. }
  410. static int hi6210_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
  411. struct snd_soc_dai *cpu_dai)
  412. {
  413. pr_debug("%s\n", __func__);
  414. switch (cmd) {
  415. case SNDRV_PCM_TRIGGER_START:
  416. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  417. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  418. hi6210_i2s_rxctrl(cpu_dai, 1);
  419. else
  420. hi6210_i2s_txctrl(cpu_dai, 1);
  421. break;
  422. case SNDRV_PCM_TRIGGER_STOP:
  423. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  424. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  425. hi6210_i2s_rxctrl(cpu_dai, 0);
  426. else
  427. hi6210_i2s_txctrl(cpu_dai, 0);
  428. break;
  429. default:
  430. dev_err(cpu_dai->dev, "unknown cmd\n");
  431. return -EINVAL;
  432. }
  433. return 0;
  434. }
  435. static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai)
  436. {
  437. struct hi6210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
  438. snd_soc_dai_init_dma_data(dai,
  439. &i2s->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
  440. &i2s->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
  441. return 0;
  442. }
  443. static const struct snd_soc_dai_ops hi6210_i2s_dai_ops = {
  444. .trigger = hi6210_i2s_trigger,
  445. .hw_params = hi6210_i2s_hw_params,
  446. .set_fmt = hi6210_i2s_set_fmt,
  447. .startup = hi6210_i2s_startup,
  448. .shutdown = hi6210_i2s_shutdown,
  449. };
  450. static const struct snd_soc_dai_driver hi6210_i2s_dai_init = {
  451. .probe = hi6210_i2s_dai_probe,
  452. .playback = {
  453. .channels_min = 2,
  454. .channels_max = 2,
  455. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  456. SNDRV_PCM_FMTBIT_U16_LE,
  457. .rates = SNDRV_PCM_RATE_48000,
  458. },
  459. .capture = {
  460. .channels_min = 2,
  461. .channels_max = 2,
  462. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  463. SNDRV_PCM_FMTBIT_U16_LE,
  464. .rates = SNDRV_PCM_RATE_48000,
  465. },
  466. .ops = &hi6210_i2s_dai_ops,
  467. };
  468. static const struct snd_soc_component_driver hi6210_i2s_i2s_comp = {
  469. .name = "hi6210_i2s-i2s",
  470. };
  471. static int hi6210_i2s_probe(struct platform_device *pdev)
  472. {
  473. struct device_node *node = pdev->dev.of_node;
  474. struct device *dev = &pdev->dev;
  475. struct hi6210_i2s *i2s;
  476. struct resource *res;
  477. int ret;
  478. i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
  479. if (!i2s)
  480. return -ENOMEM;
  481. i2s->dev = dev;
  482. spin_lock_init(&i2s->lock);
  483. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  484. i2s->base = devm_ioremap_resource(dev, res);
  485. if (IS_ERR(i2s->base))
  486. return PTR_ERR(i2s->base);
  487. i2s->base_phys = (phys_addr_t)res->start;
  488. i2s->dai = hi6210_i2s_dai_init;
  489. dev_set_drvdata(&pdev->dev, i2s);
  490. i2s->sysctrl = syscon_regmap_lookup_by_phandle(node,
  491. "hisilicon,sysctrl-syscon");
  492. if (IS_ERR(i2s->sysctrl))
  493. return PTR_ERR(i2s->sysctrl);
  494. i2s->clk[CLK_DACODEC] = devm_clk_get(&pdev->dev, "dacodec");
  495. if (IS_ERR_OR_NULL(i2s->clk[CLK_DACODEC]))
  496. return PTR_ERR(i2s->clk[CLK_DACODEC]);
  497. i2s->clocks++;
  498. i2s->clk[CLK_I2S_BASE] = devm_clk_get(&pdev->dev, "i2s-base");
  499. if (IS_ERR_OR_NULL(i2s->clk[CLK_I2S_BASE]))
  500. return PTR_ERR(i2s->clk[CLK_I2S_BASE]);
  501. i2s->clocks++;
  502. ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
  503. if (ret)
  504. return ret;
  505. ret = devm_snd_soc_register_component(&pdev->dev, &hi6210_i2s_i2s_comp,
  506. &i2s->dai, 1);
  507. return ret;
  508. }
  509. static const struct of_device_id hi6210_i2s_dt_ids[] = {
  510. { .compatible = "hisilicon,hi6210-i2s" },
  511. { /* sentinel */ }
  512. };
  513. MODULE_DEVICE_TABLE(of, hi6210_i2s_dt_ids);
  514. static struct platform_driver hi6210_i2s_driver = {
  515. .probe = hi6210_i2s_probe,
  516. .driver = {
  517. .name = "hi6210_i2s",
  518. .of_match_table = hi6210_i2s_dt_ids,
  519. },
  520. };
  521. module_platform_driver(hi6210_i2s_driver);
  522. MODULE_DESCRIPTION("Hisilicon HI6210 I2S driver");
  523. MODULE_AUTHOR("Andy Green <andy.green@linaro.org>");
  524. MODULE_LICENSE("GPL");