hac.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Hitachi Audio Controller (AC97) support for SH7760/SH7780
  4. //
  5. // Copyright (c) 2007 Manuel Lauss <[email protected]>
  6. //
  7. // dont forget to set IPSEL/OMSEL register bits (in your board code) to
  8. // enable HAC output pins!
  9. /* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only
  10. * the FIRST can be used since ASoC does not pass any information to the
  11. * ac97_read/write() functions regarding WHICH unit to use. You'll have
  12. * to edit the code a bit to use the other AC97 unit. --mlau
  13. */
  14. #include <linux/init.h>
  15. #include <linux/module.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/wait.h>
  19. #include <linux/delay.h>
  20. #include <sound/core.h>
  21. #include <sound/pcm.h>
  22. #include <sound/ac97_codec.h>
  23. #include <sound/initval.h>
  24. #include <sound/soc.h>
  25. /* regs and bits */
  26. #define HACCR 0x08
  27. #define HACCSAR 0x20
  28. #define HACCSDR 0x24
  29. #define HACPCML 0x28
  30. #define HACPCMR 0x2C
  31. #define HACTIER 0x50
  32. #define HACTSR 0x54
  33. #define HACRIER 0x58
  34. #define HACRSR 0x5C
  35. #define HACACR 0x60
  36. #define CR_CR (1 << 15) /* "codec-ready" indicator */
  37. #define CR_CDRT (1 << 11) /* cold reset */
  38. #define CR_WMRT (1 << 10) /* warm reset */
  39. #define CR_B9 (1 << 9) /* the mysterious "bit 9" */
  40. #define CR_ST (1 << 5) /* AC97 link start bit */
  41. #define CSAR_RD (1 << 19) /* AC97 data read bit */
  42. #define CSAR_WR (0)
  43. #define TSR_CMDAMT (1 << 31)
  44. #define TSR_CMDDMT (1 << 30)
  45. #define RSR_STARY (1 << 22)
  46. #define RSR_STDRY (1 << 21)
  47. #define ACR_DMARX16 (1 << 30)
  48. #define ACR_DMATX16 (1 << 29)
  49. #define ACR_TX12ATOM (1 << 26)
  50. #define ACR_DMARX20 ((1 << 24) | (1 << 22))
  51. #define ACR_DMATX20 ((1 << 23) | (1 << 21))
  52. #define CSDR_SHIFT 4
  53. #define CSDR_MASK (0xffff << CSDR_SHIFT)
  54. #define CSAR_SHIFT 12
  55. #define CSAR_MASK (0x7f << CSAR_SHIFT)
  56. #define AC97_WRITE_RETRY 1
  57. #define AC97_READ_RETRY 5
  58. /* manual-suggested AC97 codec access timeouts (us) */
  59. #define TMO_E1 500 /* 21 < E1 < 1000 */
  60. #define TMO_E2 13 /* 13 < E2 */
  61. #define TMO_E3 21 /* 21 < E3 */
  62. #define TMO_E4 500 /* 21 < E4 < 1000 */
  63. struct hac_priv {
  64. unsigned long mmio; /* HAC base address */
  65. } hac_cpu_data[] = {
  66. #if defined(CONFIG_CPU_SUBTYPE_SH7760)
  67. {
  68. .mmio = 0xFE240000,
  69. },
  70. {
  71. .mmio = 0xFE250000,
  72. },
  73. #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
  74. {
  75. .mmio = 0xFFE40000,
  76. },
  77. #else
  78. #error "Unsupported SuperH SoC"
  79. #endif
  80. };
  81. #define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg)))
  82. /*
  83. * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906)
  84. */
  85. static int hac_get_codec_data(struct hac_priv *hac, unsigned short r,
  86. unsigned short *v)
  87. {
  88. unsigned int to1, to2, i;
  89. unsigned short adr;
  90. for (i = AC97_READ_RETRY; i; i--) {
  91. *v = 0;
  92. /* wait for HAC to receive something from the codec */
  93. for (to1 = TMO_E4;
  94. to1 && !(HACREG(HACRSR) & RSR_STARY);
  95. --to1)
  96. udelay(1);
  97. for (to2 = TMO_E4;
  98. to2 && !(HACREG(HACRSR) & RSR_STDRY);
  99. --to2)
  100. udelay(1);
  101. if (!to1 && !to2)
  102. return 0; /* codec comm is down */
  103. adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT);
  104. *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT);
  105. HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
  106. if (r == adr)
  107. break;
  108. /* manual says: wait at least 21 usec before retrying */
  109. udelay(21);
  110. }
  111. HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
  112. return i;
  113. }
  114. static unsigned short hac_read_codec_aux(struct hac_priv *hac,
  115. unsigned short reg)
  116. {
  117. unsigned short val;
  118. unsigned int i, to;
  119. for (i = AC97_READ_RETRY; i; i--) {
  120. /* send_read_request */
  121. local_irq_disable();
  122. HACREG(HACTSR) &= ~(TSR_CMDAMT);
  123. HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD;
  124. local_irq_enable();
  125. for (to = TMO_E3;
  126. to && !(HACREG(HACTSR) & TSR_CMDAMT);
  127. --to)
  128. udelay(1);
  129. HACREG(HACTSR) &= ~TSR_CMDAMT;
  130. val = 0;
  131. if (hac_get_codec_data(hac, reg, &val) != 0)
  132. break;
  133. }
  134. return i ? val : ~0;
  135. }
  136. static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
  137. unsigned short val)
  138. {
  139. int unit_id = 0 /* ac97->private_data */;
  140. struct hac_priv *hac = &hac_cpu_data[unit_id];
  141. unsigned int i, to;
  142. /* write_codec_aux */
  143. for (i = AC97_WRITE_RETRY; i; i--) {
  144. /* send_write_request */
  145. local_irq_disable();
  146. HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT);
  147. HACREG(HACCSDR) = (val << CSDR_SHIFT);
  148. HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD);
  149. local_irq_enable();
  150. /* poll-wait for CMDAMT and CMDDMT */
  151. for (to = TMO_E1;
  152. to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT));
  153. --to)
  154. udelay(1);
  155. HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT);
  156. if (to)
  157. break;
  158. /* timeout, try again */
  159. }
  160. }
  161. static unsigned short hac_ac97_read(struct snd_ac97 *ac97,
  162. unsigned short reg)
  163. {
  164. int unit_id = 0 /* ac97->private_data */;
  165. struct hac_priv *hac = &hac_cpu_data[unit_id];
  166. return hac_read_codec_aux(hac, reg);
  167. }
  168. static void hac_ac97_warmrst(struct snd_ac97 *ac97)
  169. {
  170. int unit_id = 0 /* ac97->private_data */;
  171. struct hac_priv *hac = &hac_cpu_data[unit_id];
  172. unsigned int tmo;
  173. HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9;
  174. msleep(10);
  175. HACREG(HACCR) = CR_ST | CR_B9;
  176. for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--)
  177. udelay(1);
  178. if (!tmo)
  179. printk(KERN_INFO "hac: reset: AC97 link down!\n");
  180. /* settings this bit lets us have a conversation with codec */
  181. HACREG(HACACR) |= ACR_TX12ATOM;
  182. }
  183. static void hac_ac97_coldrst(struct snd_ac97 *ac97)
  184. {
  185. int unit_id = 0 /* ac97->private_data */;
  186. struct hac_priv *hac;
  187. hac = &hac_cpu_data[unit_id];
  188. HACREG(HACCR) = 0;
  189. HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9;
  190. msleep(10);
  191. hac_ac97_warmrst(ac97);
  192. }
  193. static struct snd_ac97_bus_ops hac_ac97_ops = {
  194. .read = hac_ac97_read,
  195. .write = hac_ac97_write,
  196. .reset = hac_ac97_coldrst,
  197. .warm_reset = hac_ac97_warmrst,
  198. };
  199. static int hac_hw_params(struct snd_pcm_substream *substream,
  200. struct snd_pcm_hw_params *params,
  201. struct snd_soc_dai *dai)
  202. {
  203. struct hac_priv *hac = &hac_cpu_data[dai->id];
  204. int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
  205. switch (params->msbits) {
  206. case 16:
  207. HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16;
  208. HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20;
  209. break;
  210. case 20:
  211. HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16;
  212. HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20;
  213. break;
  214. default:
  215. pr_debug("hac: invalid depth %d bit\n", params->msbits);
  216. return -EINVAL;
  217. break;
  218. }
  219. return 0;
  220. }
  221. #define AC97_RATES \
  222. SNDRV_PCM_RATE_8000_192000
  223. #define AC97_FMTS \
  224. SNDRV_PCM_FMTBIT_S16_LE
  225. static const struct snd_soc_dai_ops hac_dai_ops = {
  226. .hw_params = hac_hw_params,
  227. };
  228. static struct snd_soc_dai_driver sh4_hac_dai[] = {
  229. {
  230. .name = "hac-dai.0",
  231. .playback = {
  232. .rates = AC97_RATES,
  233. .formats = AC97_FMTS,
  234. .channels_min = 2,
  235. .channels_max = 2,
  236. },
  237. .capture = {
  238. .rates = AC97_RATES,
  239. .formats = AC97_FMTS,
  240. .channels_min = 2,
  241. .channels_max = 2,
  242. },
  243. .ops = &hac_dai_ops,
  244. },
  245. #ifdef CONFIG_CPU_SUBTYPE_SH7760
  246. {
  247. .name = "hac-dai.1",
  248. .id = 1,
  249. .playback = {
  250. .rates = AC97_RATES,
  251. .formats = AC97_FMTS,
  252. .channels_min = 2,
  253. .channels_max = 2,
  254. },
  255. .capture = {
  256. .rates = AC97_RATES,
  257. .formats = AC97_FMTS,
  258. .channels_min = 2,
  259. .channels_max = 2,
  260. },
  261. .ops = &hac_dai_ops,
  262. },
  263. #endif
  264. };
  265. static const struct snd_soc_component_driver sh4_hac_component = {
  266. .name = "sh4-hac",
  267. .legacy_dai_naming = 1,
  268. };
  269. static int hac_soc_platform_probe(struct platform_device *pdev)
  270. {
  271. int ret;
  272. ret = snd_soc_set_ac97_ops(&hac_ac97_ops);
  273. if (ret != 0)
  274. return ret;
  275. return devm_snd_soc_register_component(&pdev->dev, &sh4_hac_component,
  276. sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
  277. }
  278. static int hac_soc_platform_remove(struct platform_device *pdev)
  279. {
  280. snd_soc_set_ac97_ops(NULL);
  281. return 0;
  282. }
  283. static struct platform_driver hac_pcm_driver = {
  284. .driver = {
  285. .name = "hac-pcm-audio",
  286. },
  287. .probe = hac_soc_platform_probe,
  288. .remove = hac_soc_platform_remove,
  289. };
  290. module_platform_driver(hac_pcm_driver);
  291. MODULE_LICENSE("GPL v2");
  292. MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
  293. MODULE_AUTHOR("Manuel Lauss <[email protected]>");