dev-audio.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /* linux/arch/arm/mach-s5pv210/dev-audio.c
  2. *
  3. * Copyright (c) 2010 Samsung Electronics Co. Ltd
  4. * Jaswinder Singh <jassi.brar@samsung.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/platform_device.h>
  11. #include <linux/dma-mapping.h>
  12. #include <linux/gpio.h>
  13. #include <plat/gpio-cfg.h>
  14. #include <plat/audio.h>
  15. #include <mach/map.h>
  16. #include <mach/dma.h>
  17. #include <mach/irqs.h>
  18. #include <mach/regs-audss.h>
  19. static const char *rclksrc[] = {
  20. [0] = "busclk",
  21. [1] = "i2sclk",
  22. };
  23. static int s5pv210_cfg_i2s(struct platform_device *pdev)
  24. {
  25. /* configure GPIO for i2s port */
  26. switch (pdev->id) {
  27. case 0:
  28. s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
  29. break;
  30. case 1:
  31. s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
  32. break;
  33. case 2:
  34. s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
  35. break;
  36. default:
  37. printk(KERN_ERR "Invalid Device %d\n", pdev->id);
  38. return -EINVAL;
  39. }
  40. return 0;
  41. }
  42. static struct s3c_audio_pdata i2sv5_pdata = {
  43. .cfg_gpio = s5pv210_cfg_i2s,
  44. .type = {
  45. .i2s = {
  46. .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
  47. | QUIRK_NEED_RSTCLR,
  48. .src_clk = rclksrc,
  49. .idma_addr = S5PV210_AUDSS_INT_MEM,
  50. },
  51. },
  52. };
  53. static struct resource s5pv210_iis0_resource[] = {
  54. [0] = {
  55. .start = S5PV210_PA_IIS0,
  56. .end = S5PV210_PA_IIS0 + 0x100 - 1,
  57. .flags = IORESOURCE_MEM,
  58. },
  59. [1] = {
  60. .start = DMACH_I2S0_TX,
  61. .end = DMACH_I2S0_TX,
  62. .flags = IORESOURCE_DMA,
  63. },
  64. [2] = {
  65. .start = DMACH_I2S0_RX,
  66. .end = DMACH_I2S0_RX,
  67. .flags = IORESOURCE_DMA,
  68. },
  69. [3] = {
  70. .start = DMACH_I2S0S_TX,
  71. .end = DMACH_I2S0S_TX,
  72. .flags = IORESOURCE_DMA,
  73. },
  74. };
  75. struct platform_device s5pv210_device_iis0 = {
  76. .name = "samsung-i2s",
  77. .id = 0,
  78. .num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
  79. .resource = s5pv210_iis0_resource,
  80. .dev = {
  81. .platform_data = &i2sv5_pdata,
  82. },
  83. };
  84. static const char *rclksrc_v3[] = {
  85. [0] = "iis",
  86. [1] = "audio-bus",
  87. };
  88. static struct s3c_audio_pdata i2sv3_pdata = {
  89. .cfg_gpio = s5pv210_cfg_i2s,
  90. .type = {
  91. .i2s = {
  92. .src_clk = rclksrc_v3,
  93. },
  94. },
  95. };
  96. static struct resource s5pv210_iis1_resource[] = {
  97. [0] = {
  98. .start = S5PV210_PA_IIS1,
  99. .end = S5PV210_PA_IIS1 + 0x100 - 1,
  100. .flags = IORESOURCE_MEM,
  101. },
  102. [1] = {
  103. .start = DMACH_I2S1_TX,
  104. .end = DMACH_I2S1_TX,
  105. .flags = IORESOURCE_DMA,
  106. },
  107. [2] = {
  108. .start = DMACH_I2S1_RX,
  109. .end = DMACH_I2S1_RX,
  110. .flags = IORESOURCE_DMA,
  111. },
  112. };
  113. struct platform_device s5pv210_device_iis1 = {
  114. .name = "samsung-i2s",
  115. .id = 1,
  116. .num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
  117. .resource = s5pv210_iis1_resource,
  118. .dev = {
  119. .platform_data = &i2sv3_pdata,
  120. },
  121. };
  122. static struct resource s5pv210_iis2_resource[] = {
  123. [0] = {
  124. .start = S5PV210_PA_IIS2,
  125. .end = S5PV210_PA_IIS2 + 0x100 - 1,
  126. .flags = IORESOURCE_MEM,
  127. },
  128. [1] = {
  129. .start = DMACH_I2S2_TX,
  130. .end = DMACH_I2S2_TX,
  131. .flags = IORESOURCE_DMA,
  132. },
  133. [2] = {
  134. .start = DMACH_I2S2_RX,
  135. .end = DMACH_I2S2_RX,
  136. .flags = IORESOURCE_DMA,
  137. },
  138. };
  139. struct platform_device s5pv210_device_iis2 = {
  140. .name = "samsung-i2s",
  141. .id = 2,
  142. .num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
  143. .resource = s5pv210_iis2_resource,
  144. .dev = {
  145. .platform_data = &i2sv3_pdata,
  146. },
  147. };
  148. /* PCM Controller platform_devices */
  149. static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
  150. {
  151. switch (pdev->id) {
  152. case 0:
  153. s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
  154. break;
  155. case 1:
  156. s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
  157. break;
  158. case 2:
  159. s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
  160. break;
  161. default:
  162. printk(KERN_DEBUG "Invalid PCM Controller number!");
  163. return -EINVAL;
  164. }
  165. return 0;
  166. }
  167. static struct s3c_audio_pdata s3c_pcm_pdata = {
  168. .cfg_gpio = s5pv210_pcm_cfg_gpio,
  169. };
  170. static struct resource s5pv210_pcm0_resource[] = {
  171. [0] = {
  172. .start = S5PV210_PA_PCM0,
  173. .end = S5PV210_PA_PCM0 + 0x100 - 1,
  174. .flags = IORESOURCE_MEM,
  175. },
  176. [1] = {
  177. .start = DMACH_PCM0_TX,
  178. .end = DMACH_PCM0_TX,
  179. .flags = IORESOURCE_DMA,
  180. },
  181. [2] = {
  182. .start = DMACH_PCM0_RX,
  183. .end = DMACH_PCM0_RX,
  184. .flags = IORESOURCE_DMA,
  185. },
  186. };
  187. struct platform_device s5pv210_device_pcm0 = {
  188. .name = "samsung-pcm",
  189. .id = 0,
  190. .num_resources = ARRAY_SIZE(s5pv210_pcm0_resource),
  191. .resource = s5pv210_pcm0_resource,
  192. .dev = {
  193. .platform_data = &s3c_pcm_pdata,
  194. },
  195. };
  196. static struct resource s5pv210_pcm1_resource[] = {
  197. [0] = {
  198. .start = S5PV210_PA_PCM1,
  199. .end = S5PV210_PA_PCM1 + 0x100 - 1,
  200. .flags = IORESOURCE_MEM,
  201. },
  202. [1] = {
  203. .start = DMACH_PCM1_TX,
  204. .end = DMACH_PCM1_TX,
  205. .flags = IORESOURCE_DMA,
  206. },
  207. [2] = {
  208. .start = DMACH_PCM1_RX,
  209. .end = DMACH_PCM1_RX,
  210. .flags = IORESOURCE_DMA,
  211. },
  212. };
  213. struct platform_device s5pv210_device_pcm1 = {
  214. .name = "samsung-pcm",
  215. .id = 1,
  216. .num_resources = ARRAY_SIZE(s5pv210_pcm1_resource),
  217. .resource = s5pv210_pcm1_resource,
  218. .dev = {
  219. .platform_data = &s3c_pcm_pdata,
  220. },
  221. };
  222. static struct resource s5pv210_pcm2_resource[] = {
  223. [0] = {
  224. .start = S5PV210_PA_PCM2,
  225. .end = S5PV210_PA_PCM2 + 0x100 - 1,
  226. .flags = IORESOURCE_MEM,
  227. },
  228. [1] = {
  229. .start = DMACH_PCM2_TX,
  230. .end = DMACH_PCM2_TX,
  231. .flags = IORESOURCE_DMA,
  232. },
  233. [2] = {
  234. .start = DMACH_PCM2_RX,
  235. .end = DMACH_PCM2_RX,
  236. .flags = IORESOURCE_DMA,
  237. },
  238. };
  239. struct platform_device s5pv210_device_pcm2 = {
  240. .name = "samsung-pcm",
  241. .id = 2,
  242. .num_resources = ARRAY_SIZE(s5pv210_pcm2_resource),
  243. .resource = s5pv210_pcm2_resource,
  244. .dev = {
  245. .platform_data = &s3c_pcm_pdata,
  246. },
  247. };
  248. /* AC97 Controller platform devices */
  249. static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
  250. {
  251. return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
  252. }
  253. static struct resource s5pv210_ac97_resource[] = {
  254. [0] = {
  255. .start = S5PV210_PA_AC97,
  256. .end = S5PV210_PA_AC97 + 0x100 - 1,
  257. .flags = IORESOURCE_MEM,
  258. },
  259. [1] = {
  260. .start = DMACH_AC97_PCMOUT,
  261. .end = DMACH_AC97_PCMOUT,
  262. .flags = IORESOURCE_DMA,
  263. },
  264. [2] = {
  265. .start = DMACH_AC97_PCMIN,
  266. .end = DMACH_AC97_PCMIN,
  267. .flags = IORESOURCE_DMA,
  268. },
  269. [3] = {
  270. .start = DMACH_AC97_MICIN,
  271. .end = DMACH_AC97_MICIN,
  272. .flags = IORESOURCE_DMA,
  273. },
  274. [4] = {
  275. .start = IRQ_AC97,
  276. .end = IRQ_AC97,
  277. .flags = IORESOURCE_IRQ,
  278. },
  279. };
  280. static struct s3c_audio_pdata s3c_ac97_pdata = {
  281. .cfg_gpio = s5pv210_ac97_cfg_gpio,
  282. };
  283. static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
  284. struct platform_device s5pv210_device_ac97 = {
  285. .name = "samsung-ac97",
  286. .id = -1,
  287. .num_resources = ARRAY_SIZE(s5pv210_ac97_resource),
  288. .resource = s5pv210_ac97_resource,
  289. .dev = {
  290. .platform_data = &s3c_ac97_pdata,
  291. .dma_mask = &s5pv210_ac97_dmamask,
  292. .coherent_dma_mask = DMA_BIT_MASK(32),
  293. },
  294. };
  295. /* S/PDIF Controller platform_device */
  296. static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev)
  297. {
  298. s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3));
  299. return 0;
  300. }
  301. static struct resource s5pv210_spdif_resource[] = {
  302. [0] = {
  303. .start = S5PV210_PA_SPDIF,
  304. .end = S5PV210_PA_SPDIF + 0x100 - 1,
  305. .flags = IORESOURCE_MEM,
  306. },
  307. [1] = {
  308. .start = DMACH_SPDIF,
  309. .end = DMACH_SPDIF,
  310. .flags = IORESOURCE_DMA,
  311. },
  312. };
  313. static struct s3c_audio_pdata samsung_spdif_pdata = {
  314. .cfg_gpio = s5pv210_spdif_cfg_gpio,
  315. };
  316. static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32);
  317. struct platform_device s5pv210_device_spdif = {
  318. .name = "samsung-spdif",
  319. .id = -1,
  320. .num_resources = ARRAY_SIZE(s5pv210_spdif_resource),
  321. .resource = s5pv210_spdif_resource,
  322. .dev = {
  323. .platform_data = &samsung_spdif_pdata,
  324. .dma_mask = &s5pv210_spdif_dmamask,
  325. .coherent_dma_mask = DMA_BIT_MASK(32),
  326. },
  327. };