1 /* linux/arch/arm/mach-s5p64x0/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 
11 #include <linux/platform_device.h>
12 #include <linux/dma-mapping.h>
13 #include <linux/gpio.h>
14 
15 #include <plat/gpio-cfg.h>
16 #include <plat/audio.h>
17 
18 #include <mach/map.h>
19 #include <mach/dma.h>
20 #include <mach/irqs.h>
21 
22 static const char *rclksrc[] = {
23 	[0] = "iis",
24 	[1] = "sclk_audio2",
25 };
26 
s5p6440_cfg_i2s(struct platform_device * pdev)27 static int s5p6440_cfg_i2s(struct platform_device *pdev)
28 {
29 	switch (pdev->id) {
30 	case 0:
31 		s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5));
32 		s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5));
33 		s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5));
34 		break;
35 	default:
36 		printk(KERN_ERR "Invalid Device %d\n", pdev->id);
37 		return -EINVAL;
38 	}
39 
40 	return 0;
41 }
42 
43 static struct s3c_audio_pdata s5p6440_i2s_pdata = {
44 	.cfg_gpio = s5p6440_cfg_i2s,
45 	.type = {
46 		.i2s = {
47 			.quirks = QUIRK_PRI_6CHAN,
48 			.src_clk = rclksrc,
49 		},
50 	},
51 };
52 
53 static struct resource s5p64x0_i2s0_resource[] = {
54 	[0] = {
55 		.start	= S5P64X0_PA_I2S,
56 		.end	= S5P64X0_PA_I2S + 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 };
70 
71 struct platform_device s5p6440_device_iis = {
72 	.name		= "samsung-i2s",
73 	.id		= 0,
74 	.num_resources	= ARRAY_SIZE(s5p64x0_i2s0_resource),
75 	.resource	= s5p64x0_i2s0_resource,
76 	.dev = {
77 		.platform_data = &s5p6440_i2s_pdata,
78 	},
79 };
80 
s5p6450_cfg_i2s(struct platform_device * pdev)81 static int s5p6450_cfg_i2s(struct platform_device *pdev)
82 {
83 	switch (pdev->id) {
84 	case 0:
85 		s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
86 		s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
87 		break;
88 	case 1:
89 		s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5));
90 		s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5));
91 		break;
92 	case 2:
93 		s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5));
94 		break;
95 	default:
96 		printk(KERN_ERR "Invalid Device %d\n", pdev->id);
97 		return -EINVAL;
98 	}
99 
100 	return 0;
101 }
102 
103 static struct s3c_audio_pdata s5p6450_i2s0_pdata = {
104 	.cfg_gpio = s5p6450_cfg_i2s,
105 	.type = {
106 		.i2s = {
107 			.quirks = QUIRK_PRI_6CHAN,
108 			.src_clk = rclksrc,
109 		},
110 	},
111 };
112 
113 struct platform_device s5p6450_device_iis0 = {
114 	.name		= "samsung-i2s",
115 	.id		= 0,
116 	.num_resources	= ARRAY_SIZE(s5p64x0_i2s0_resource),
117 	.resource	= s5p64x0_i2s0_resource,
118 	.dev = {
119 		.platform_data = &s5p6450_i2s0_pdata,
120 	},
121 };
122 
123 static struct s3c_audio_pdata s5p6450_i2s_pdata = {
124 	.cfg_gpio = s5p6450_cfg_i2s,
125 	.type = {
126 		.i2s = {
127 			.src_clk = rclksrc,
128 		},
129 	},
130 };
131 
132 static struct resource s5p6450_i2s1_resource[] = {
133 	[0] = {
134 		.start	= S5P6450_PA_I2S1,
135 		.end	= S5P6450_PA_I2S1 + 0x100 - 1,
136 		.flags	= IORESOURCE_MEM,
137 	},
138 	[1] = {
139 		.start	= DMACH_I2S1_TX,
140 		.end	= DMACH_I2S1_TX,
141 		.flags	= IORESOURCE_DMA,
142 	},
143 	[2] = {
144 		.start	= DMACH_I2S1_RX,
145 		.end	= DMACH_I2S1_RX,
146 		.flags	= IORESOURCE_DMA,
147 	},
148 };
149 
150 struct platform_device s5p6450_device_iis1 = {
151 	.name		= "samsung-i2s",
152 	.id		= 1,
153 	.num_resources	= ARRAY_SIZE(s5p6450_i2s1_resource),
154 	.resource	= s5p6450_i2s1_resource,
155 	.dev = {
156 		.platform_data = &s5p6450_i2s_pdata,
157 	},
158 };
159 
160 static struct resource s5p6450_i2s2_resource[] = {
161 	[0] = {
162 		.start	= S5P6450_PA_I2S2,
163 		.end	= S5P6450_PA_I2S2 + 0x100 - 1,
164 		.flags	= IORESOURCE_MEM,
165 	},
166 	[1] = {
167 		.start	= DMACH_I2S2_TX,
168 		.end	= DMACH_I2S2_TX,
169 		.flags	= IORESOURCE_DMA,
170 	},
171 	[2] = {
172 		.start	= DMACH_I2S2_RX,
173 		.end	= DMACH_I2S2_RX,
174 		.flags	= IORESOURCE_DMA,
175 	},
176 };
177 
178 struct platform_device s5p6450_device_iis2 = {
179 	.name		= "samsung-i2s",
180 	.id		= 2,
181 	.num_resources	= ARRAY_SIZE(s5p6450_i2s2_resource),
182 	.resource	= s5p6450_i2s2_resource,
183 	.dev = {
184 		.platform_data = &s5p6450_i2s_pdata,
185 	},
186 };
187 
188 /* PCM Controller platform_devices */
189 
s5p6440_pcm_cfg_gpio(struct platform_device * pdev)190 static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
191 {
192 	switch (pdev->id) {
193 	case 0:
194 		s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
195 		s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2));
196 		break;
197 
198 	default:
199 		printk(KERN_DEBUG "Invalid PCM Controller number!");
200 		return -EINVAL;
201 	}
202 
203 	return 0;
204 }
205 
206 static struct s3c_audio_pdata s5p6440_pcm_pdata = {
207 	.cfg_gpio = s5p6440_pcm_cfg_gpio,
208 };
209 
210 static struct resource s5p6440_pcm0_resource[] = {
211 	[0] = {
212 		.start	= S5P64X0_PA_PCM,
213 		.end	= S5P64X0_PA_PCM + 0x100 - 1,
214 		.flags	= IORESOURCE_MEM,
215 	},
216 	[1] = {
217 		.start	= DMACH_PCM0_TX,
218 		.end	= DMACH_PCM0_TX,
219 		.flags	= IORESOURCE_DMA,
220 	},
221 	[2] = {
222 		.start	= DMACH_PCM0_RX,
223 		.end	= DMACH_PCM0_RX,
224 		.flags	= IORESOURCE_DMA,
225 	},
226 };
227 
228 struct platform_device s5p6440_device_pcm = {
229 	.name		= "samsung-pcm",
230 	.id		= 0,
231 	.num_resources	= ARRAY_SIZE(s5p6440_pcm0_resource),
232 	.resource	= s5p6440_pcm0_resource,
233 	.dev = {
234 		.platform_data = &s5p6440_pcm_pdata,
235 	},
236 };
237