dev-audio.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. static int s5pv210_cfg_i2s(struct platform_device *pdev)
  19. {
  20. /* configure GPIO for i2s port */
  21. switch (pdev->id) {
  22. case 1:
  23. s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2));
  24. s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
  25. s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
  26. s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
  27. s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
  28. break;
  29. case 2:
  30. s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4));
  31. s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
  32. s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
  33. s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
  34. s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
  35. break;
  36. case -1:
  37. s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2));
  38. s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
  39. s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
  40. s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
  41. s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
  42. s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
  43. s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
  44. break;
  45. default:
  46. printk(KERN_ERR "Invalid Device %d\n", pdev->id);
  47. return -EINVAL;
  48. }
  49. return 0;
  50. }
  51. static struct s3c_audio_pdata s3c_i2s_pdata = {
  52. .cfg_gpio = s5pv210_cfg_i2s,
  53. };
  54. static struct resource s5pv210_iis0_resource[] = {
  55. [0] = {
  56. .start = S5PV210_PA_IIS0,
  57. .end = S5PV210_PA_IIS0 + 0x100 - 1,
  58. .flags = IORESOURCE_MEM,
  59. },
  60. [1] = {
  61. .start = DMACH_I2S0_TX,
  62. .end = DMACH_I2S0_TX,
  63. .flags = IORESOURCE_DMA,
  64. },
  65. [2] = {
  66. .start = DMACH_I2S0_RX,
  67. .end = DMACH_I2S0_RX,
  68. .flags = IORESOURCE_DMA,
  69. },
  70. };
  71. struct platform_device s5pv210_device_iis0 = {
  72. .name = "s3c64xx-iis-v4",
  73. .id = -1,
  74. .num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
  75. .resource = s5pv210_iis0_resource,
  76. .dev = {
  77. .platform_data = &s3c_i2s_pdata,
  78. },
  79. };
  80. static struct resource s5pv210_iis1_resource[] = {
  81. [0] = {
  82. .start = S5PV210_PA_IIS1,
  83. .end = S5PV210_PA_IIS1 + 0x100 - 1,
  84. .flags = IORESOURCE_MEM,
  85. },
  86. [1] = {
  87. .start = DMACH_I2S1_TX,
  88. .end = DMACH_I2S1_TX,
  89. .flags = IORESOURCE_DMA,
  90. },
  91. [2] = {
  92. .start = DMACH_I2S1_RX,
  93. .end = DMACH_I2S1_RX,
  94. .flags = IORESOURCE_DMA,
  95. },
  96. };
  97. struct platform_device s5pv210_device_iis1 = {
  98. .name = "s3c64xx-iis",
  99. .id = 1,
  100. .num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
  101. .resource = s5pv210_iis1_resource,
  102. .dev = {
  103. .platform_data = &s3c_i2s_pdata,
  104. },
  105. };
  106. static struct resource s5pv210_iis2_resource[] = {
  107. [0] = {
  108. .start = S5PV210_PA_IIS2,
  109. .end = S5PV210_PA_IIS2 + 0x100 - 1,
  110. .flags = IORESOURCE_MEM,
  111. },
  112. [1] = {
  113. .start = DMACH_I2S2_TX,
  114. .end = DMACH_I2S2_TX,
  115. .flags = IORESOURCE_DMA,
  116. },
  117. [2] = {
  118. .start = DMACH_I2S2_RX,
  119. .end = DMACH_I2S2_RX,
  120. .flags = IORESOURCE_DMA,
  121. },
  122. };
  123. struct platform_device s5pv210_device_iis2 = {
  124. .name = "s3c64xx-iis",
  125. .id = 2,
  126. .num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
  127. .resource = s5pv210_iis2_resource,
  128. .dev = {
  129. .platform_data = &s3c_i2s_pdata,
  130. },
  131. };
  132. /* PCM Controller platform_devices */
  133. static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
  134. {
  135. switch (pdev->id) {
  136. case 0:
  137. s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3));
  138. s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
  139. s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
  140. s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
  141. s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
  142. break;
  143. case 1:
  144. s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3));
  145. s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
  146. s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
  147. s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
  148. s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
  149. break;
  150. case 2:
  151. s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2));
  152. s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
  153. s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
  154. s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
  155. s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2));
  156. break;
  157. default:
  158. printk(KERN_DEBUG "Invalid PCM Controller number!");
  159. return -EINVAL;
  160. }
  161. return 0;
  162. }
  163. static struct s3c_audio_pdata s3c_pcm_pdata = {
  164. .cfg_gpio = s5pv210_pcm_cfg_gpio,
  165. };
  166. static struct resource s5pv210_pcm0_resource[] = {
  167. [0] = {
  168. .start = S5PV210_PA_PCM0,
  169. .end = S5PV210_PA_PCM0 + 0x100 - 1,
  170. .flags = IORESOURCE_MEM,
  171. },
  172. [1] = {
  173. .start = DMACH_PCM0_TX,
  174. .end = DMACH_PCM0_TX,
  175. .flags = IORESOURCE_DMA,
  176. },
  177. [2] = {
  178. .start = DMACH_PCM0_RX,
  179. .end = DMACH_PCM0_RX,
  180. .flags = IORESOURCE_DMA,
  181. },
  182. };
  183. struct platform_device s5pv210_device_pcm0 = {
  184. .name = "samsung-pcm",
  185. .id = 0,
  186. .num_resources = ARRAY_SIZE(s5pv210_pcm0_resource),
  187. .resource = s5pv210_pcm0_resource,
  188. .dev = {
  189. .platform_data = &s3c_pcm_pdata,
  190. },
  191. };
  192. static struct resource s5pv210_pcm1_resource[] = {
  193. [0] = {
  194. .start = S5PV210_PA_PCM1,
  195. .end = S5PV210_PA_PCM1 + 0x100 - 1,
  196. .flags = IORESOURCE_MEM,
  197. },
  198. [1] = {
  199. .start = DMACH_PCM1_TX,
  200. .end = DMACH_PCM1_TX,
  201. .flags = IORESOURCE_DMA,
  202. },
  203. [2] = {
  204. .start = DMACH_PCM1_RX,
  205. .end = DMACH_PCM1_RX,
  206. .flags = IORESOURCE_DMA,
  207. },
  208. };
  209. struct platform_device s5pv210_device_pcm1 = {
  210. .name = "samsung-pcm",
  211. .id = 1,
  212. .num_resources = ARRAY_SIZE(s5pv210_pcm1_resource),
  213. .resource = s5pv210_pcm1_resource,
  214. .dev = {
  215. .platform_data = &s3c_pcm_pdata,
  216. },
  217. };
  218. static struct resource s5pv210_pcm2_resource[] = {
  219. [0] = {
  220. .start = S5PV210_PA_PCM2,
  221. .end = S5PV210_PA_PCM2 + 0x100 - 1,
  222. .flags = IORESOURCE_MEM,
  223. },
  224. [1] = {
  225. .start = DMACH_PCM2_TX,
  226. .end = DMACH_PCM2_TX,
  227. .flags = IORESOURCE_DMA,
  228. },
  229. [2] = {
  230. .start = DMACH_PCM2_RX,
  231. .end = DMACH_PCM2_RX,
  232. .flags = IORESOURCE_DMA,
  233. },
  234. };
  235. struct platform_device s5pv210_device_pcm2 = {
  236. .name = "samsung-pcm",
  237. .id = 2,
  238. .num_resources = ARRAY_SIZE(s5pv210_pcm2_resource),
  239. .resource = s5pv210_pcm2_resource,
  240. .dev = {
  241. .platform_data = &s3c_pcm_pdata,
  242. },
  243. };
  244. /* AC97 Controller platform devices */
  245. static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
  246. {
  247. s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4));
  248. s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
  249. s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
  250. s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
  251. s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
  252. return 0;
  253. }
  254. static struct resource s5pv210_ac97_resource[] = {
  255. [0] = {
  256. .start = S5PV210_PA_AC97,
  257. .end = S5PV210_PA_AC97 + 0x100 - 1,
  258. .flags = IORESOURCE_MEM,
  259. },
  260. [1] = {
  261. .start = DMACH_AC97_PCMOUT,
  262. .end = DMACH_AC97_PCMOUT,
  263. .flags = IORESOURCE_DMA,
  264. },
  265. [2] = {
  266. .start = DMACH_AC97_PCMIN,
  267. .end = DMACH_AC97_PCMIN,
  268. .flags = IORESOURCE_DMA,
  269. },
  270. [3] = {
  271. .start = DMACH_AC97_MICIN,
  272. .end = DMACH_AC97_MICIN,
  273. .flags = IORESOURCE_DMA,
  274. },
  275. [4] = {
  276. .start = IRQ_AC97,
  277. .end = IRQ_AC97,
  278. .flags = IORESOURCE_IRQ,
  279. },
  280. };
  281. static struct s3c_audio_pdata s3c_ac97_pdata = {
  282. .cfg_gpio = s5pv210_ac97_cfg_gpio,
  283. };
  284. static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
  285. struct platform_device s5pv210_device_ac97 = {
  286. .name = "s3c-ac97",
  287. .id = -1,
  288. .num_resources = ARRAY_SIZE(s5pv210_ac97_resource),
  289. .resource = s5pv210_ac97_resource,
  290. .dev = {
  291. .platform_data = &s3c_ac97_pdata,
  292. .dma_mask = &s5pv210_ac97_dmamask,
  293. .coherent_dma_mask = DMA_BIT_MASK(32),
  294. },
  295. };