ssi.c 10.0 KB

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