blob: 93470b158a4eec73a4cd621e38b4be6b50344c94 [file] [log] [blame]
Mark Brown52da2192009-06-03 20:08:38 +01001/* linux/arch/arm/plat-s3c/dev-audio.c
2 *
3 * Copyright 2009 Wolfson Microelectronics
4 * Mark Brown <broonie@opensource.wolfsonmicro.com>
5 *
Mark Brown52da2192009-06-03 20:08:38 +01006 * 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
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/platform_device.h>
Jassi Brarde6985b2010-02-12 10:38:51 +000014#include <linux/dma-mapping.h>
Kukjin Kim1c739c72010-08-05 07:54:49 +090015#include <linux/gpio.h>
Paul Gortmakerdc280942011-07-31 16:17:29 -040016#include <linux/export.h>
Mark Brown52da2192009-06-03 20:08:38 +010017
18#include <mach/irqs.h>
19#include <mach/map.h>
Jassi Braracf1aef2009-11-17 16:53:56 +090020#include <mach/dma.h>
Mark Brown52da2192009-06-03 20:08:38 +010021
22#include <plat/devs.h>
Jassi Braracf1aef2009-11-17 16:53:56 +090023#include <plat/audio.h>
Jassi Braracf1aef2009-11-17 16:53:56 +090024#include <plat/gpio-cfg.h>
Mark Brown52da2192009-06-03 20:08:38 +010025
Jassi Brar6a62bee2010-11-19 08:49:44 +090026static const char *rclksrc[] = {
27 [0] = "iis",
28 [1] = "audio-bus",
29};
30
31static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
Jassi Brar71269362010-01-06 15:33:44 +090032{
Ben Dooks2618b552010-05-27 15:54:06 +090033 unsigned int base;
34
Jassi Brar71269362010-01-06 15:33:44 +090035 switch (pdev->id) {
36 case 0:
Ben Dooks2618b552010-05-27 15:54:06 +090037 base = S3C64XX_GPD(0);
Jassi Brar71269362010-01-06 15:33:44 +090038 break;
39 case 1:
Ben Dooks2618b552010-05-27 15:54:06 +090040 base = S3C64XX_GPE(0);
Dimitris Papastamose4b6b742010-08-26 16:07:23 +010041 break;
Jassi Brar6a62bee2010-11-19 08:49:44 +090042 case 2:
43 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
44 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
45 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
46 s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
47 return 0;
Jassi Brar71269362010-01-06 15:33:44 +090048 default:
Dimitris Papastamose4b6b742010-08-26 16:07:23 +010049 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
50 pdev->id);
Jassi Brar71269362010-01-06 15:33:44 +090051 return -EINVAL;
52 }
53
Ben Dooks2618b552010-05-27 15:54:06 +090054 s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
55
Jassi Brar71269362010-01-06 15:33:44 +090056 return 0;
57}
58
Mark Brown52da2192009-06-03 20:08:38 +010059static struct resource s3c64xx_iis0_resource[] = {
60 [0] = {
61 .start = S3C64XX_PA_IIS0,
62 .end = S3C64XX_PA_IIS0 + 0x100 - 1,
63 .flags = IORESOURCE_MEM,
64 },
Jassi Brar71269362010-01-06 15:33:44 +090065 [1] = {
66 .start = DMACH_I2S0_OUT,
67 .end = DMACH_I2S0_OUT,
68 .flags = IORESOURCE_DMA,
69 },
70 [2] = {
71 .start = DMACH_I2S0_IN,
72 .end = DMACH_I2S0_IN,
73 .flags = IORESOURCE_DMA,
74 },
75};
76
Jassi Brar6a62bee2010-11-19 08:49:44 +090077static struct s3c_audio_pdata i2sv3_pdata = {
78 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
79 .type = {
80 .i2s = {
81 .src_clk = rclksrc,
82 },
83 },
Mark Brown52da2192009-06-03 20:08:38 +010084};
85
86struct platform_device s3c64xx_device_iis0 = {
Jassi Brardaea9b42010-11-19 08:49:43 +090087 .name = "samsung-i2s",
Mark Brown52da2192009-06-03 20:08:38 +010088 .id = 0,
89 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
90 .resource = s3c64xx_iis0_resource,
Jassi Brar71269362010-01-06 15:33:44 +090091 .dev = {
Jassi Brar6a62bee2010-11-19 08:49:44 +090092 .platform_data = &i2sv3_pdata,
Jassi Brar71269362010-01-06 15:33:44 +090093 },
Mark Brown52da2192009-06-03 20:08:38 +010094};
95EXPORT_SYMBOL(s3c64xx_device_iis0);
96
97static struct resource s3c64xx_iis1_resource[] = {
98 [0] = {
99 .start = S3C64XX_PA_IIS1,
100 .end = S3C64XX_PA_IIS1 + 0x100 - 1,
101 .flags = IORESOURCE_MEM,
102 },
Jassi Brar71269362010-01-06 15:33:44 +0900103 [1] = {
104 .start = DMACH_I2S1_OUT,
105 .end = DMACH_I2S1_OUT,
106 .flags = IORESOURCE_DMA,
107 },
108 [2] = {
109 .start = DMACH_I2S1_IN,
110 .end = DMACH_I2S1_IN,
111 .flags = IORESOURCE_DMA,
112 },
113};
114
Mark Brown52da2192009-06-03 20:08:38 +0100115struct platform_device s3c64xx_device_iis1 = {
Jassi Brardaea9b42010-11-19 08:49:43 +0900116 .name = "samsung-i2s",
Mark Brown52da2192009-06-03 20:08:38 +0100117 .id = 1,
118 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
119 .resource = s3c64xx_iis1_resource,
Jassi Brar71269362010-01-06 15:33:44 +0900120 .dev = {
Jassi Brar6a62bee2010-11-19 08:49:44 +0900121 .platform_data = &i2sv3_pdata,
Jassi Brar71269362010-01-06 15:33:44 +0900122 },
Mark Brown52da2192009-06-03 20:08:38 +0100123};
124EXPORT_SYMBOL(s3c64xx_device_iis1);
Mark Brownd06a49e2009-06-03 20:08:39 +0100125
126static struct resource s3c64xx_iisv4_resource[] = {
127 [0] = {
128 .start = S3C64XX_PA_IISV4,
129 .end = S3C64XX_PA_IISV4 + 0x100 - 1,
130 .flags = IORESOURCE_MEM,
131 },
Jassi Brar71269362010-01-06 15:33:44 +0900132 [1] = {
133 .start = DMACH_HSI_I2SV40_TX,
134 .end = DMACH_HSI_I2SV40_TX,
135 .flags = IORESOURCE_DMA,
136 },
137 [2] = {
138 .start = DMACH_HSI_I2SV40_RX,
139 .end = DMACH_HSI_I2SV40_RX,
140 .flags = IORESOURCE_DMA,
141 },
142};
143
Jassi Brar6a62bee2010-11-19 08:49:44 +0900144static struct s3c_audio_pdata i2sv4_pdata = {
145 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
146 .type = {
147 .i2s = {
148 .quirks = QUIRK_PRI_6CHAN,
149 .src_clk = rclksrc,
150 },
151 },
Mark Brownd06a49e2009-06-03 20:08:39 +0100152};
153
154struct platform_device s3c64xx_device_iisv4 = {
Jassi Brar6a62bee2010-11-19 08:49:44 +0900155 .name = "samsung-i2s",
156 .id = 2,
Mark Brownd06a49e2009-06-03 20:08:39 +0100157 .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
158 .resource = s3c64xx_iisv4_resource,
Jassi Brar71269362010-01-06 15:33:44 +0900159 .dev = {
Jassi Brar6a62bee2010-11-19 08:49:44 +0900160 .platform_data = &i2sv4_pdata,
Jassi Brar71269362010-01-06 15:33:44 +0900161 },
Mark Brownd06a49e2009-06-03 20:08:39 +0100162};
163EXPORT_SYMBOL(s3c64xx_device_iisv4);
Jassi Braracf1aef2009-11-17 16:53:56 +0900164
165
166/* PCM Controller platform_devices */
167
168static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
169{
Ben Dooks2618b552010-05-27 15:54:06 +0900170 unsigned int base;
171
Jassi Braracf1aef2009-11-17 16:53:56 +0900172 switch (pdev->id) {
173 case 0:
Ben Dooks2618b552010-05-27 15:54:06 +0900174 base = S3C64XX_GPD(0);
Jassi Braracf1aef2009-11-17 16:53:56 +0900175 break;
176 case 1:
Ben Dooks2618b552010-05-27 15:54:06 +0900177 base = S3C64XX_GPE(0);
Jassi Braracf1aef2009-11-17 16:53:56 +0900178 break;
179 default:
Dimitris Papastamose4b6b742010-08-26 16:07:23 +0100180 printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
181 pdev->id);
Jassi Braracf1aef2009-11-17 16:53:56 +0900182 return -EINVAL;
183 }
184
Ben Dooks2618b552010-05-27 15:54:06 +0900185 s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
Jassi Braracf1aef2009-11-17 16:53:56 +0900186 return 0;
187}
188
189static struct resource s3c64xx_pcm0_resource[] = {
190 [0] = {
191 .start = S3C64XX_PA_PCM0,
192 .end = S3C64XX_PA_PCM0 + 0x100 - 1,
193 .flags = IORESOURCE_MEM,
194 },
195 [1] = {
196 .start = DMACH_PCM0_TX,
197 .end = DMACH_PCM0_TX,
198 .flags = IORESOURCE_DMA,
199 },
200 [2] = {
201 .start = DMACH_PCM0_RX,
202 .end = DMACH_PCM0_RX,
203 .flags = IORESOURCE_DMA,
204 },
205};
206
Mark Brown43f0de82009-11-27 16:43:53 +0000207static struct s3c_audio_pdata s3c_pcm0_pdata = {
Jassi Braracf1aef2009-11-17 16:53:56 +0900208 .cfg_gpio = s3c64xx_pcm_cfg_gpio,
209};
210
211struct platform_device s3c64xx_device_pcm0 = {
212 .name = "samsung-pcm",
213 .id = 0,
214 .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource),
215 .resource = s3c64xx_pcm0_resource,
216 .dev = {
217 .platform_data = &s3c_pcm0_pdata,
218 },
219};
220EXPORT_SYMBOL(s3c64xx_device_pcm0);
221
222static struct resource s3c64xx_pcm1_resource[] = {
223 [0] = {
224 .start = S3C64XX_PA_PCM1,
225 .end = S3C64XX_PA_PCM1 + 0x100 - 1,
226 .flags = IORESOURCE_MEM,
227 },
228 [1] = {
229 .start = DMACH_PCM1_TX,
230 .end = DMACH_PCM1_TX,
231 .flags = IORESOURCE_DMA,
232 },
233 [2] = {
234 .start = DMACH_PCM1_RX,
235 .end = DMACH_PCM1_RX,
236 .flags = IORESOURCE_DMA,
237 },
238};
239
Mark Brown43f0de82009-11-27 16:43:53 +0000240static struct s3c_audio_pdata s3c_pcm1_pdata = {
Jassi Braracf1aef2009-11-17 16:53:56 +0900241 .cfg_gpio = s3c64xx_pcm_cfg_gpio,
242};
243
244struct platform_device s3c64xx_device_pcm1 = {
245 .name = "samsung-pcm",
246 .id = 1,
247 .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource),
248 .resource = s3c64xx_pcm1_resource,
249 .dev = {
250 .platform_data = &s3c_pcm1_pdata,
251 },
252};
253EXPORT_SYMBOL(s3c64xx_device_pcm1);
Jassi Brarde6985b2010-02-12 10:38:51 +0000254
255/* AC97 Controller platform devices */
256
257static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
258{
Ben Dooks2618b552010-05-27 15:54:06 +0900259 return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
Jassi Brarde6985b2010-02-12 10:38:51 +0000260}
261
262static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
263{
Ben Dooks2618b552010-05-27 15:54:06 +0900264 return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
Jassi Brarde6985b2010-02-12 10:38:51 +0000265}
266
267static struct resource s3c64xx_ac97_resource[] = {
268 [0] = {
269 .start = S3C64XX_PA_AC97,
270 .end = S3C64XX_PA_AC97 + 0x100 - 1,
271 .flags = IORESOURCE_MEM,
272 },
273 [1] = {
274 .start = DMACH_AC97_PCMOUT,
275 .end = DMACH_AC97_PCMOUT,
276 .flags = IORESOURCE_DMA,
277 },
278 [2] = {
279 .start = DMACH_AC97_PCMIN,
280 .end = DMACH_AC97_PCMIN,
281 .flags = IORESOURCE_DMA,
282 },
283 [3] = {
284 .start = DMACH_AC97_MICIN,
285 .end = DMACH_AC97_MICIN,
286 .flags = IORESOURCE_DMA,
287 },
288 [4] = {
289 .start = IRQ_AC97,
290 .end = IRQ_AC97,
291 .flags = IORESOURCE_IRQ,
292 },
293};
294
295static struct s3c_audio_pdata s3c_ac97_pdata;
296
297static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
298
299struct platform_device s3c64xx_device_ac97 = {
Jassi Brare6104672010-11-22 15:36:00 +0900300 .name = "samsung-ac97",
Jassi Brarde6985b2010-02-12 10:38:51 +0000301 .id = -1,
302 .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
303 .resource = s3c64xx_ac97_resource,
304 .dev = {
305 .platform_data = &s3c_ac97_pdata,
306 .dma_mask = &s3c64xx_ac97_dmamask,
307 .coherent_dma_mask = DMA_BIT_MASK(32),
308 },
309};
310EXPORT_SYMBOL(s3c64xx_device_ac97);
311
312void __init s3c64xx_ac97_setup_gpio(int num)
313{
314 if (num == S3C64XX_AC97_GPD)
315 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
316 else
317 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
318}