dev-audio.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /* linux/arch/arm/plat-s3c/dev-audio.c
  2. *
  3. * Copyright 2009 Wolfson Microelectronics
  4. * Mark Brown <broonie@opensource.wolfsonmicro.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/kernel.h>
  11. #include <linux/string.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/gpio.h>
  15. #include <mach/irqs.h>
  16. #include <mach/map.h>
  17. #include <mach/dma.h>
  18. #include <plat/devs.h>
  19. #include <plat/audio.h>
  20. #include <plat/gpio-cfg.h>
  21. static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
  22. {
  23. unsigned int base;
  24. switch (pdev->id) {
  25. case 0:
  26. base = S3C64XX_GPD(0);
  27. break;
  28. case 1:
  29. base = S3C64XX_GPE(0);
  30. break;
  31. default:
  32. printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
  33. pdev->id);
  34. return -EINVAL;
  35. }
  36. s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
  37. return 0;
  38. }
  39. static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
  40. {
  41. s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
  42. s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
  43. s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
  44. s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
  45. return 0;
  46. }
  47. static struct resource s3c64xx_iis0_resource[] = {
  48. [0] = {
  49. .start = S3C64XX_PA_IIS0,
  50. .end = S3C64XX_PA_IIS0 + 0x100 - 1,
  51. .flags = IORESOURCE_MEM,
  52. },
  53. [1] = {
  54. .start = DMACH_I2S0_OUT,
  55. .end = DMACH_I2S0_OUT,
  56. .flags = IORESOURCE_DMA,
  57. },
  58. [2] = {
  59. .start = DMACH_I2S0_IN,
  60. .end = DMACH_I2S0_IN,
  61. .flags = IORESOURCE_DMA,
  62. },
  63. };
  64. static struct s3c_audio_pdata s3c_i2s0_pdata = {
  65. .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
  66. };
  67. struct platform_device s3c64xx_device_iis0 = {
  68. .name = "s3c64xx-iis",
  69. .id = 0,
  70. .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
  71. .resource = s3c64xx_iis0_resource,
  72. .dev = {
  73. .platform_data = &s3c_i2s0_pdata,
  74. },
  75. };
  76. EXPORT_SYMBOL(s3c64xx_device_iis0);
  77. static struct resource s3c64xx_iis1_resource[] = {
  78. [0] = {
  79. .start = S3C64XX_PA_IIS1,
  80. .end = S3C64XX_PA_IIS1 + 0x100 - 1,
  81. .flags = IORESOURCE_MEM,
  82. },
  83. [1] = {
  84. .start = DMACH_I2S1_OUT,
  85. .end = DMACH_I2S1_OUT,
  86. .flags = IORESOURCE_DMA,
  87. },
  88. [2] = {
  89. .start = DMACH_I2S1_IN,
  90. .end = DMACH_I2S1_IN,
  91. .flags = IORESOURCE_DMA,
  92. },
  93. };
  94. static struct s3c_audio_pdata s3c_i2s1_pdata = {
  95. .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
  96. };
  97. struct platform_device s3c64xx_device_iis1 = {
  98. .name = "s3c64xx-iis",
  99. .id = 1,
  100. .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
  101. .resource = s3c64xx_iis1_resource,
  102. .dev = {
  103. .platform_data = &s3c_i2s1_pdata,
  104. },
  105. };
  106. EXPORT_SYMBOL(s3c64xx_device_iis1);
  107. static struct resource s3c64xx_iisv4_resource[] = {
  108. [0] = {
  109. .start = S3C64XX_PA_IISV4,
  110. .end = S3C64XX_PA_IISV4 + 0x100 - 1,
  111. .flags = IORESOURCE_MEM,
  112. },
  113. [1] = {
  114. .start = DMACH_HSI_I2SV40_TX,
  115. .end = DMACH_HSI_I2SV40_TX,
  116. .flags = IORESOURCE_DMA,
  117. },
  118. [2] = {
  119. .start = DMACH_HSI_I2SV40_RX,
  120. .end = DMACH_HSI_I2SV40_RX,
  121. .flags = IORESOURCE_DMA,
  122. },
  123. };
  124. static struct s3c_audio_pdata s3c_i2sv4_pdata = {
  125. .cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
  126. };
  127. struct platform_device s3c64xx_device_iisv4 = {
  128. .name = "s3c64xx-iis-v4",
  129. .id = -1,
  130. .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
  131. .resource = s3c64xx_iisv4_resource,
  132. .dev = {
  133. .platform_data = &s3c_i2sv4_pdata,
  134. },
  135. };
  136. EXPORT_SYMBOL(s3c64xx_device_iisv4);
  137. /* PCM Controller platform_devices */
  138. static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
  139. {
  140. unsigned int base;
  141. switch (pdev->id) {
  142. case 0:
  143. base = S3C64XX_GPD(0);
  144. break;
  145. case 1:
  146. base = S3C64XX_GPE(0);
  147. break;
  148. default:
  149. printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
  150. pdev->id);
  151. return -EINVAL;
  152. }
  153. s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
  154. return 0;
  155. }
  156. static struct resource s3c64xx_pcm0_resource[] = {
  157. [0] = {
  158. .start = S3C64XX_PA_PCM0,
  159. .end = S3C64XX_PA_PCM0 + 0x100 - 1,
  160. .flags = IORESOURCE_MEM,
  161. },
  162. [1] = {
  163. .start = DMACH_PCM0_TX,
  164. .end = DMACH_PCM0_TX,
  165. .flags = IORESOURCE_DMA,
  166. },
  167. [2] = {
  168. .start = DMACH_PCM0_RX,
  169. .end = DMACH_PCM0_RX,
  170. .flags = IORESOURCE_DMA,
  171. },
  172. };
  173. static struct s3c_audio_pdata s3c_pcm0_pdata = {
  174. .cfg_gpio = s3c64xx_pcm_cfg_gpio,
  175. };
  176. struct platform_device s3c64xx_device_pcm0 = {
  177. .name = "samsung-pcm",
  178. .id = 0,
  179. .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource),
  180. .resource = s3c64xx_pcm0_resource,
  181. .dev = {
  182. .platform_data = &s3c_pcm0_pdata,
  183. },
  184. };
  185. EXPORT_SYMBOL(s3c64xx_device_pcm0);
  186. static struct resource s3c64xx_pcm1_resource[] = {
  187. [0] = {
  188. .start = S3C64XX_PA_PCM1,
  189. .end = S3C64XX_PA_PCM1 + 0x100 - 1,
  190. .flags = IORESOURCE_MEM,
  191. },
  192. [1] = {
  193. .start = DMACH_PCM1_TX,
  194. .end = DMACH_PCM1_TX,
  195. .flags = IORESOURCE_DMA,
  196. },
  197. [2] = {
  198. .start = DMACH_PCM1_RX,
  199. .end = DMACH_PCM1_RX,
  200. .flags = IORESOURCE_DMA,
  201. },
  202. };
  203. static struct s3c_audio_pdata s3c_pcm1_pdata = {
  204. .cfg_gpio = s3c64xx_pcm_cfg_gpio,
  205. };
  206. struct platform_device s3c64xx_device_pcm1 = {
  207. .name = "samsung-pcm",
  208. .id = 1,
  209. .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource),
  210. .resource = s3c64xx_pcm1_resource,
  211. .dev = {
  212. .platform_data = &s3c_pcm1_pdata,
  213. },
  214. };
  215. EXPORT_SYMBOL(s3c64xx_device_pcm1);
  216. /* AC97 Controller platform devices */
  217. static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
  218. {
  219. return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
  220. }
  221. static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
  222. {
  223. return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
  224. }
  225. static struct resource s3c64xx_ac97_resource[] = {
  226. [0] = {
  227. .start = S3C64XX_PA_AC97,
  228. .end = S3C64XX_PA_AC97 + 0x100 - 1,
  229. .flags = IORESOURCE_MEM,
  230. },
  231. [1] = {
  232. .start = DMACH_AC97_PCMOUT,
  233. .end = DMACH_AC97_PCMOUT,
  234. .flags = IORESOURCE_DMA,
  235. },
  236. [2] = {
  237. .start = DMACH_AC97_PCMIN,
  238. .end = DMACH_AC97_PCMIN,
  239. .flags = IORESOURCE_DMA,
  240. },
  241. [3] = {
  242. .start = DMACH_AC97_MICIN,
  243. .end = DMACH_AC97_MICIN,
  244. .flags = IORESOURCE_DMA,
  245. },
  246. [4] = {
  247. .start = IRQ_AC97,
  248. .end = IRQ_AC97,
  249. .flags = IORESOURCE_IRQ,
  250. },
  251. };
  252. static struct s3c_audio_pdata s3c_ac97_pdata;
  253. static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
  254. struct platform_device s3c64xx_device_ac97 = {
  255. .name = "s3c-ac97",
  256. .id = -1,
  257. .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
  258. .resource = s3c64xx_ac97_resource,
  259. .dev = {
  260. .platform_data = &s3c_ac97_pdata,
  261. .dma_mask = &s3c64xx_ac97_dmamask,
  262. .coherent_dma_mask = DMA_BIT_MASK(32),
  263. },
  264. };
  265. EXPORT_SYMBOL(s3c64xx_device_ac97);
  266. void __init s3c64xx_ac97_setup_gpio(int num)
  267. {
  268. if (num == S3C64XX_AC97_GPD)
  269. s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
  270. else
  271. s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
  272. }
  273. static u64 s3c_device_audio_dmamask = 0xffffffffUL;
  274. struct platform_device s3c_device_pcm = {
  275. .name = "s3c24xx-pcm-audio",
  276. .id = -1,
  277. .dev = {
  278. .dma_mask = &s3c_device_audio_dmamask,
  279. .coherent_dma_mask = 0xffffffffUL
  280. }
  281. };
  282. EXPORT_SYMBOL(s3c_device_pcm);