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
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h>
15#include <linux/gpio.h>
16#include <linux/export.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20#include <mach/dma.h>
21
22#include <plat/devs.h>
23#include <linux/platform_data/asoc-s3c.h>
24#include <plat/gpio-cfg.h>
25#include <mach/gpio-samsung.h>
26
27static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
28{
29	unsigned int base;
30
31	switch (pdev->id) {
32	case 0:
33		base = S3C64XX_GPD(0);
34		break;
35	case 1:
36		base = S3C64XX_GPE(0);
37		break;
38	case 2:
39		s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
40		s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
41		s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
42		s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
43		return 0;
44	default:
45		printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
46			pdev->id);
47		return -EINVAL;
48	}
49
50	s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
51
52	return 0;
53}
54
55static struct resource s3c64xx_iis0_resource[] = {
56	[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
57};
58
59static struct s3c_audio_pdata i2s0_pdata = {
60	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
61	.dma_playback = DMACH_I2S0_OUT,
62	.dma_capture = DMACH_I2S0_IN,
63};
64
65struct platform_device s3c64xx_device_iis0 = {
66	.name		  = "samsung-i2s",
67	.id		  = 0,
68	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
69	.resource	  = s3c64xx_iis0_resource,
70	.dev = {
71		.platform_data = &i2s0_pdata,
72	},
73};
74EXPORT_SYMBOL(s3c64xx_device_iis0);
75
76static struct resource s3c64xx_iis1_resource[] = {
77	[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
78};
79
80static struct s3c_audio_pdata i2s1_pdata = {
81	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
82	.dma_playback = DMACH_I2S1_OUT,
83	.dma_capture = DMACH_I2S1_IN,
84};
85
86struct platform_device s3c64xx_device_iis1 = {
87	.name		  = "samsung-i2s",
88	.id		  = 1,
89	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
90	.resource	  = s3c64xx_iis1_resource,
91	.dev = {
92		.platform_data = &i2s1_pdata,
93	},
94};
95EXPORT_SYMBOL(s3c64xx_device_iis1);
96
97static struct resource s3c64xx_iisv4_resource[] = {
98	[0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
99};
100
101static struct s3c_audio_pdata i2sv4_pdata = {
102	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
103	.dma_playback = DMACH_HSI_I2SV40_TX,
104	.dma_capture = DMACH_HSI_I2SV40_RX,
105	.type = {
106		.i2s = {
107			.quirks = QUIRK_PRI_6CHAN,
108		},
109	},
110};
111
112struct platform_device s3c64xx_device_iisv4 = {
113	.name = "samsung-i2s",
114	.id = 2,
115	.num_resources	  = ARRAY_SIZE(s3c64xx_iisv4_resource),
116	.resource	  = s3c64xx_iisv4_resource,
117	.dev = {
118		.platform_data = &i2sv4_pdata,
119	},
120};
121EXPORT_SYMBOL(s3c64xx_device_iisv4);
122
123
124/* PCM Controller platform_devices */
125
126static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
127{
128	unsigned int base;
129
130	switch (pdev->id) {
131	case 0:
132		base = S3C64XX_GPD(0);
133		break;
134	case 1:
135		base = S3C64XX_GPE(0);
136		break;
137	default:
138		printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
139			pdev->id);
140		return -EINVAL;
141	}
142
143	s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
144	return 0;
145}
146
147static struct resource s3c64xx_pcm0_resource[] = {
148	[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
149};
150
151static struct s3c_audio_pdata s3c_pcm0_pdata = {
152	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
153	.dma_capture = DMACH_PCM0_RX,
154	.dma_playback = DMACH_PCM0_TX,
155};
156
157struct platform_device s3c64xx_device_pcm0 = {
158	.name		  = "samsung-pcm",
159	.id		  = 0,
160	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm0_resource),
161	.resource	  = s3c64xx_pcm0_resource,
162	.dev = {
163		.platform_data = &s3c_pcm0_pdata,
164	},
165};
166EXPORT_SYMBOL(s3c64xx_device_pcm0);
167
168static struct resource s3c64xx_pcm1_resource[] = {
169	[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
170};
171
172static struct s3c_audio_pdata s3c_pcm1_pdata = {
173	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
174	.dma_playback = DMACH_PCM1_TX,
175	.dma_capture = DMACH_PCM1_RX,
176};
177
178struct platform_device s3c64xx_device_pcm1 = {
179	.name		  = "samsung-pcm",
180	.id		  = 1,
181	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm1_resource),
182	.resource	  = s3c64xx_pcm1_resource,
183	.dev = {
184		.platform_data = &s3c_pcm1_pdata,
185	},
186};
187EXPORT_SYMBOL(s3c64xx_device_pcm1);
188
189/* AC97 Controller platform devices */
190
191static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
192{
193	return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
194}
195
196static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
197{
198	return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
199}
200
201static struct resource s3c64xx_ac97_resource[] = {
202	[0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
203	[1] = DEFINE_RES_IRQ(IRQ_AC97),
204};
205
206static struct s3c_audio_pdata s3c_ac97_pdata = {
207	.dma_playback = DMACH_AC97_PCMOUT,
208	.dma_capture = DMACH_AC97_PCMIN,
209	.dma_capture_mic = DMACH_AC97_MICIN,
210};
211
212static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
213
214struct platform_device s3c64xx_device_ac97 = {
215	.name		  = "samsung-ac97",
216	.id		  = -1,
217	.num_resources	  = ARRAY_SIZE(s3c64xx_ac97_resource),
218	.resource	  = s3c64xx_ac97_resource,
219	.dev = {
220		.platform_data = &s3c_ac97_pdata,
221		.dma_mask = &s3c64xx_ac97_dmamask,
222		.coherent_dma_mask = DMA_BIT_MASK(32),
223	},
224};
225EXPORT_SYMBOL(s3c64xx_device_ac97);
226
227void __init s3c64xx_ac97_setup_gpio(int num)
228{
229	if (num == S3C64XX_AC97_GPD)
230		s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
231	else
232		s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
233}
234