ssi.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. * Serial Sound Interface (I2S) support for SH7760/SH7780
  3. *
  4. * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
  5. *
  6. * licensed under the terms outlined in the file COPYING at the root
  7. * of the linux kernel sources.
  8. *
  9. * dont forget to set IPSEL/OMSEL register bits (in your board code) to
  10. * enable SSI output pins!
  11. */
  12. /*
  13. * LIMITATIONS:
  14. * The SSI unit has only one physical data line, so full duplex is
  15. * impossible. This can be remedied on the SH7760 by using the
  16. * other SSI unit for recording; however the SH7780 has only 1 SSI
  17. * unit, and its pins are shared with the AC97 unit, among others.
  18. *
  19. * FEATURES:
  20. * The SSI features "compressed mode": in this mode it continuously
  21. * streams PCM data over the I2S lines and uses LRCK as a handshake
  22. * signal. Can be used to send compressed data (AC3/DTS) to a DSP.
  23. * The number of bits sent over the wire in a frame can be adjusted
  24. * and can be independent from the actual sample bit depth. This is
  25. * useful to support TDM mode codecs like the AD1939 which have a
  26. * fixed TDM slot size, regardless of sample resolution.
  27. */
  28. #include <linux/init.h>
  29. #include <linux/module.h>
  30. #include <linux/platform_device.h>
  31. #include <sound/core.h>
  32. #include <sound/pcm.h>
  33. #include <sound/initval.h>
  34. #include <sound/soc.h>
  35. #include <asm/io.h>
  36. #define SSICR 0x00
  37. #define SSISR 0x04
  38. #define CR_DMAEN (1 << 28)
  39. #define CR_CHNL_SHIFT 22
  40. #define CR_CHNL_MASK (3 << CR_CHNL_SHIFT)
  41. #define CR_DWL_SHIFT 19
  42. #define CR_DWL_MASK (7 << CR_DWL_SHIFT)
  43. #define CR_SWL_SHIFT 16
  44. #define CR_SWL_MASK (7 << CR_SWL_SHIFT)
  45. #define CR_SCK_MASTER (1 << 15) /* bitclock master bit */
  46. #define CR_SWS_MASTER (1 << 14) /* wordselect master bit */
  47. #define CR_SCKP (1 << 13) /* I2Sclock polarity */
  48. #define CR_SWSP (1 << 12) /* LRCK polarity */
  49. #define CR_SPDP (1 << 11)
  50. #define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */
  51. #define CR_PDTA (1 << 9) /* fifo data alignment */
  52. #define CR_DEL (1 << 8) /* delay data by 1 i2sclk */
  53. #define CR_BREN (1 << 7) /* clock gating in burst mode */
  54. #define CR_CKDIV_SHIFT 4
  55. #define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */
  56. #define CR_MUTE (1 << 3) /* SSI mute */
  57. #define CR_CPEN (1 << 2) /* compressed mode */
  58. #define CR_TRMD (1 << 1) /* transmit/receive select */
  59. #define CR_EN (1 << 0) /* enable SSI */
  60. #define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg)))
  61. struct ssi_priv {
  62. unsigned long mmio;
  63. unsigned long sysclk;
  64. int inuse;
  65. } ssi_cpu_data[] = {
  66. #if defined(CONFIG_CPU_SUBTYPE_SH7760)
  67. {
  68. .mmio = 0xFE680000,
  69. },
  70. {
  71. .mmio = 0xFE690000,
  72. },
  73. #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
  74. {
  75. .mmio = 0xFFE70000,
  76. },
  77. #else
  78. #error "Unsupported SuperH SoC"
  79. #endif
  80. };
  81. /*
  82. * track usage of the SSI; it is simplex-only so prevent attempts of
  83. * concurrent playback + capture. FIXME: any locking required?
  84. */
  85. static int ssi_startup(struct snd_pcm_substream *substream,
  86. struct snd_soc_dai *dai)
  87. {
  88. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  89. struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
  90. if (ssi->inuse) {
  91. pr_debug("ssi: already in use!\n");
  92. return -EBUSY;
  93. } else
  94. ssi->inuse = 1;
  95. return 0;
  96. }
  97. static void ssi_shutdown(struct snd_pcm_substream *substream,
  98. struct snd_soc_dai *dai)
  99. {
  100. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  101. struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
  102. ssi->inuse = 0;
  103. }
  104. static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
  105. struct snd_soc_dai *dai)
  106. {
  107. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  108. struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
  109. switch (cmd) {
  110. case SNDRV_PCM_TRIGGER_START:
  111. SSIREG(SSICR) |= CR_DMAEN | CR_EN;
  112. break;
  113. case SNDRV_PCM_TRIGGER_STOP:
  114. SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN);
  115. break;
  116. default:
  117. return -EINVAL;
  118. }
  119. return 0;
  120. }
  121. static int ssi_hw_params(struct snd_pcm_substream *substream,
  122. struct snd_pcm_hw_params *params,
  123. struct snd_soc_dai *dai)
  124. {
  125. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  126. struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
  127. unsigned long ssicr = SSIREG(SSICR);
  128. unsigned int bits, channels, swl, recv, i;
  129. channels = params_channels(params);
  130. bits = params->msbits;
  131. recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1;
  132. pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr);
  133. pr_debug("bits: %u channels: %u\n", bits, channels);
  134. ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA |
  135. CR_SWL_MASK);
  136. /* direction (send/receive) */
  137. if (!recv)
  138. ssicr |= CR_TRMD; /* transmit */
  139. /* channels */
  140. if ((channels < 2) || (channels > 8) || (channels & 1)) {
  141. pr_debug("ssi: invalid number of channels\n");
  142. return -EINVAL;
  143. }
  144. ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT;
  145. /* DATA WORD LENGTH (DWL): databits in audio sample */
  146. i = 0;
  147. switch (bits) {
  148. case 32: ++i;
  149. case 24: ++i;
  150. case 22: ++i;
  151. case 20: ++i;
  152. case 18: ++i;
  153. case 16: ++i;
  154. ssicr |= i << CR_DWL_SHIFT;
  155. case 8: break;
  156. default:
  157. pr_debug("ssi: invalid sample width\n");
  158. return -EINVAL;
  159. }
  160. /*
  161. * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S
  162. * wires. This is usually bits_per_sample x channels/2; i.e. in
  163. * Stereo mode the SWL equals DWL. SWL can be bigger than the
  164. * product of (channels_per_slot x samplebits), e.g. for codecs
  165. * like the AD1939 which only accept 32bit wide TDM slots. For
  166. * "standard" I2S operation we set SWL = chans / 2 * DWL here.
  167. * Waiting for ASoC to get TDM support ;-)
  168. */
  169. if ((bits > 16) && (bits <= 24)) {
  170. bits = 24; /* these are padded by the SSI */
  171. /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */
  172. }
  173. i = 0;
  174. swl = (bits * channels) / 2;
  175. switch (swl) {
  176. case 256: ++i;
  177. case 128: ++i;
  178. case 64: ++i;
  179. case 48: ++i;
  180. case 32: ++i;
  181. case 16: ++i;
  182. ssicr |= i << CR_SWL_SHIFT;
  183. case 8: break;
  184. default:
  185. pr_debug("ssi: invalid system word length computed\n");
  186. return -EINVAL;
  187. }
  188. SSIREG(SSICR) = ssicr;
  189. pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr);
  190. return 0;
  191. }
  192. static int ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
  193. unsigned int freq, int dir)
  194. {
  195. struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id];
  196. ssi->sysclk = freq;
  197. return 0;
  198. }
  199. /*
  200. * This divider is used to generate the SSI_SCK (I2S bitclock) from the
  201. * clock at the HAC_BIT_CLK ("oversampling clock") pin.
  202. */
  203. static int ssi_set_clkdiv(struct snd_soc_dai *dai, int did, int div)
  204. {
  205. struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
  206. unsigned long ssicr;
  207. int i;
  208. i = 0;
  209. ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK;
  210. switch (div) {
  211. case 16: ++i;
  212. case 8: ++i;
  213. case 4: ++i;
  214. case 2: ++i;
  215. SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT);
  216. case 1: break;
  217. default:
  218. pr_debug("ssi: invalid sck divider %d\n", div);
  219. return -EINVAL;
  220. }
  221. return 0;
  222. }
  223. static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  224. {
  225. struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
  226. unsigned long ssicr = SSIREG(SSICR);
  227. pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr);
  228. ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP |
  229. CR_SWS_MASTER | CR_SCK_MASTER);
  230. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  231. case SND_SOC_DAIFMT_I2S:
  232. break;
  233. case SND_SOC_DAIFMT_RIGHT_J:
  234. ssicr |= CR_DEL | CR_PDTA;
  235. break;
  236. case SND_SOC_DAIFMT_LEFT_J:
  237. ssicr |= CR_DEL;
  238. break;
  239. default:
  240. pr_debug("ssi: unsupported format\n");
  241. return -EINVAL;
  242. }
  243. switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
  244. case SND_SOC_DAIFMT_CONT:
  245. break;
  246. case SND_SOC_DAIFMT_GATED:
  247. ssicr |= CR_BREN;
  248. break;
  249. }
  250. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  251. case SND_SOC_DAIFMT_NB_NF:
  252. ssicr |= CR_SCKP; /* sample data at low clkedge */
  253. break;
  254. case SND_SOC_DAIFMT_NB_IF:
  255. ssicr |= CR_SCKP | CR_SWSP;
  256. break;
  257. case SND_SOC_DAIFMT_IB_NF:
  258. break;
  259. case SND_SOC_DAIFMT_IB_IF:
  260. ssicr |= CR_SWSP; /* word select starts low */
  261. break;
  262. default:
  263. pr_debug("ssi: invalid inversion\n");
  264. return -EINVAL;
  265. }
  266. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  267. case SND_SOC_DAIFMT_CBM_CFM:
  268. break;
  269. case SND_SOC_DAIFMT_CBS_CFM:
  270. ssicr |= CR_SCK_MASTER;
  271. break;
  272. case SND_SOC_DAIFMT_CBM_CFS:
  273. ssicr |= CR_SWS_MASTER;
  274. break;
  275. case SND_SOC_DAIFMT_CBS_CFS:
  276. ssicr |= CR_SWS_MASTER | CR_SCK_MASTER;
  277. break;
  278. default:
  279. pr_debug("ssi: invalid master/slave configuration\n");
  280. return -EINVAL;
  281. }
  282. SSIREG(SSICR) = ssicr;
  283. pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr);
  284. return 0;
  285. }
  286. /* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in
  287. * Master mode, so really this is board specific; the SSI can do any
  288. * rate with the right bitclk and divider settings.
  289. */
  290. #define SSI_RATES \
  291. SNDRV_PCM_RATE_8000_192000
  292. /* the SSI can do 8-32 bit samples, with 8 possible channels */
  293. #define SSI_FMTS \
  294. (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
  295. SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
  296. SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
  297. SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
  298. SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
  299. static struct snd_soc_dai_ops ssi_dai_ops = {
  300. .startup = ssi_startup,
  301. .shutdown = ssi_shutdown,
  302. .trigger = ssi_trigger,
  303. .hw_params = ssi_hw_params,
  304. .set_sysclk = ssi_set_sysclk,
  305. .set_clkdiv = ssi_set_clkdiv,
  306. .set_fmt = ssi_set_fmt,
  307. };
  308. struct snd_soc_dai sh4_ssi_dai[] = {
  309. {
  310. .name = "SSI0",
  311. .id = 0,
  312. .playback = {
  313. .rates = SSI_RATES,
  314. .formats = SSI_FMTS,
  315. .channels_min = 2,
  316. .channels_max = 8,
  317. },
  318. .capture = {
  319. .rates = SSI_RATES,
  320. .formats = SSI_FMTS,
  321. .channels_min = 2,
  322. .channels_max = 8,
  323. },
  324. .ops = &ssi_dai_ops,
  325. },
  326. #ifdef CONFIG_CPU_SUBTYPE_SH7760
  327. {
  328. .name = "SSI1",
  329. .id = 1,
  330. .playback = {
  331. .rates = SSI_RATES,
  332. .formats = SSI_FMTS,
  333. .channels_min = 2,
  334. .channels_max = 8,
  335. },
  336. .capture = {
  337. .rates = SSI_RATES,
  338. .formats = SSI_FMTS,
  339. .channels_min = 2,
  340. .channels_max = 8,
  341. },
  342. .ops = &ssi_dai_ops,
  343. },
  344. #endif
  345. };
  346. EXPORT_SYMBOL_GPL(sh4_ssi_dai);
  347. static int __init sh4_ssi_init(void)
  348. {
  349. return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
  350. }
  351. module_init(sh4_ssi_init);
  352. static void __exit sh4_ssi_exit(void)
  353. {
  354. snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
  355. }
  356. module_exit(sh4_ssi_exit);
  357. MODULE_LICENSE("GPL");
  358. MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
  359. MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");