diff options
Diffstat (limited to 'sound/soc/s3c24xx/s3c64xx-i2s.c')
-rw-r--r-- | sound/soc/s3c24xx/s3c64xx-i2s.c | 120 |
1 files changed, 41 insertions, 79 deletions
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index cc7edb5f792d..93ed3aad1631 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c | |||
@@ -15,16 +15,10 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/delay.h> | ||
19 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
20 | #include <linux/kernel.h> | ||
21 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
22 | #include <linux/io.h> | 20 | #include <linux/io.h> |
23 | 21 | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/initval.h> | ||
28 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
29 | 23 | ||
30 | #include <plat/regs-s3c2412-iis.h> | 24 | #include <plat/regs-s3c2412-iis.h> |
@@ -38,6 +32,11 @@ | |||
38 | #include "s3c-dma.h" | 32 | #include "s3c-dma.h" |
39 | #include "s3c64xx-i2s.h" | 33 | #include "s3c64xx-i2s.h" |
40 | 34 | ||
35 | /* The value should be set to maximum of the total number | ||
36 | * of I2Sv3 controllers that any supported SoC has. | ||
37 | */ | ||
38 | #define MAX_I2SV3 2 | ||
39 | |||
41 | static struct s3c2410_dma_client s3c64xx_dma_client_out = { | 40 | static struct s3c2410_dma_client s3c64xx_dma_client_out = { |
42 | .name = "I2S PCM Stereo out" | 41 | .name = "I2S PCM Stereo out" |
43 | }; | 42 | }; |
@@ -46,37 +45,12 @@ static struct s3c2410_dma_client s3c64xx_dma_client_in = { | |||
46 | .name = "I2S PCM Stereo in" | 45 | .name = "I2S PCM Stereo in" |
47 | }; | 46 | }; |
48 | 47 | ||
49 | static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { | 48 | static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3]; |
50 | [0] = { | 49 | static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3]; |
51 | .channel = DMACH_I2S0_OUT, | 50 | static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3]; |
52 | .client = &s3c64xx_dma_client_out, | ||
53 | .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD, | ||
54 | .dma_size = 4, | ||
55 | }, | ||
56 | [1] = { | ||
57 | .channel = DMACH_I2S1_OUT, | ||
58 | .client = &s3c64xx_dma_client_out, | ||
59 | .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD, | ||
60 | .dma_size = 4, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[2] = { | ||
65 | [0] = { | ||
66 | .channel = DMACH_I2S0_IN, | ||
67 | .client = &s3c64xx_dma_client_in, | ||
68 | .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD, | ||
69 | .dma_size = 4, | ||
70 | }, | ||
71 | [1] = { | ||
72 | .channel = DMACH_I2S1_IN, | ||
73 | .client = &s3c64xx_dma_client_in, | ||
74 | .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD, | ||
75 | .dma_size = 4, | ||
76 | }, | ||
77 | }; | ||
78 | 51 | ||
79 | static struct s3c_i2sv2_info s3c64xx_i2s[2]; | 52 | struct snd_soc_dai s3c64xx_i2s_dai[MAX_I2SV3]; |
53 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); | ||
80 | 54 | ||
81 | static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) | 55 | static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) |
82 | { | 56 | { |
@@ -169,55 +143,13 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { | |||
169 | .set_sysclk = s3c64xx_i2s_set_sysclk, | 143 | .set_sysclk = s3c64xx_i2s_set_sysclk, |
170 | }; | 144 | }; |
171 | 145 | ||
172 | struct snd_soc_dai s3c64xx_i2s_dai[] = { | ||
173 | { | ||
174 | .name = "s3c64xx-i2s", | ||
175 | .id = 0, | ||
176 | .probe = s3c64xx_i2s_probe, | ||
177 | .playback = { | ||
178 | .channels_min = 2, | ||
179 | .channels_max = 2, | ||
180 | .rates = S3C64XX_I2S_RATES, | ||
181 | .formats = S3C64XX_I2S_FMTS, | ||
182 | }, | ||
183 | .capture = { | ||
184 | .channels_min = 2, | ||
185 | .channels_max = 2, | ||
186 | .rates = S3C64XX_I2S_RATES, | ||
187 | .formats = S3C64XX_I2S_FMTS, | ||
188 | }, | ||
189 | .ops = &s3c64xx_i2s_dai_ops, | ||
190 | .symmetric_rates = 1, | ||
191 | }, | ||
192 | { | ||
193 | .name = "s3c64xx-i2s", | ||
194 | .id = 1, | ||
195 | .probe = s3c64xx_i2s_probe, | ||
196 | .playback = { | ||
197 | .channels_min = 2, | ||
198 | .channels_max = 2, | ||
199 | .rates = S3C64XX_I2S_RATES, | ||
200 | .formats = S3C64XX_I2S_FMTS, | ||
201 | }, | ||
202 | .capture = { | ||
203 | .channels_min = 2, | ||
204 | .channels_max = 2, | ||
205 | .rates = S3C64XX_I2S_RATES, | ||
206 | .formats = S3C64XX_I2S_FMTS, | ||
207 | }, | ||
208 | .ops = &s3c64xx_i2s_dai_ops, | ||
209 | .symmetric_rates = 1, | ||
210 | }, | ||
211 | }; | ||
212 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); | ||
213 | |||
214 | static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) | 146 | static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) |
215 | { | 147 | { |
216 | struct s3c_i2sv2_info *i2s; | 148 | struct s3c_i2sv2_info *i2s; |
217 | struct snd_soc_dai *dai; | 149 | struct snd_soc_dai *dai; |
218 | int ret; | 150 | int ret; |
219 | 151 | ||
220 | if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { | 152 | if (pdev->id >= MAX_I2SV3) { |
221 | dev_err(&pdev->dev, "id %d out of range\n", pdev->id); | 153 | dev_err(&pdev->dev, "id %d out of range\n", pdev->id); |
222 | return -EINVAL; | 154 | return -EINVAL; |
223 | } | 155 | } |
@@ -225,10 +157,40 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) | |||
225 | i2s = &s3c64xx_i2s[pdev->id]; | 157 | i2s = &s3c64xx_i2s[pdev->id]; |
226 | dai = &s3c64xx_i2s_dai[pdev->id]; | 158 | dai = &s3c64xx_i2s_dai[pdev->id]; |
227 | dai->dev = &pdev->dev; | 159 | dai->dev = &pdev->dev; |
160 | dai->name = "s3c64xx-i2s"; | ||
161 | dai->id = pdev->id; | ||
162 | dai->symmetric_rates = 1; | ||
163 | dai->playback.channels_min = 2; | ||
164 | dai->playback.channels_max = 2; | ||
165 | dai->playback.rates = S3C64XX_I2S_RATES; | ||
166 | dai->playback.formats = S3C64XX_I2S_FMTS; | ||
167 | dai->capture.channels_min = 2; | ||
168 | dai->capture.channels_max = 2; | ||
169 | dai->capture.rates = S3C64XX_I2S_RATES; | ||
170 | dai->capture.formats = S3C64XX_I2S_FMTS; | ||
171 | dai->probe = s3c64xx_i2s_probe; | ||
172 | dai->ops = &s3c64xx_i2s_dai_ops; | ||
228 | 173 | ||
229 | i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; | 174 | i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; |
230 | i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; | 175 | i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; |
231 | 176 | ||
177 | if (pdev->id == 0) { | ||
178 | i2s->dma_capture->channel = DMACH_I2S0_IN; | ||
179 | i2s->dma_capture->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD; | ||
180 | i2s->dma_playback->channel = DMACH_I2S0_OUT; | ||
181 | i2s->dma_playback->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD; | ||
182 | } else { | ||
183 | i2s->dma_capture->channel = DMACH_I2S1_IN; | ||
184 | i2s->dma_capture->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD; | ||
185 | i2s->dma_playback->channel = DMACH_I2S1_OUT; | ||
186 | i2s->dma_playback->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD; | ||
187 | } | ||
188 | |||
189 | i2s->dma_capture->client = &s3c64xx_dma_client_in; | ||
190 | i2s->dma_capture->dma_size = 4; | ||
191 | i2s->dma_playback->client = &s3c64xx_dma_client_out; | ||
192 | i2s->dma_playback->dma_size = 4; | ||
193 | |||
232 | i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); | 194 | i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); |
233 | if (IS_ERR(i2s->iis_cclk)) { | 195 | if (IS_ERR(i2s->iis_cclk)) { |
234 | dev_err(&pdev->dev, "failed to get audio-bus\n"); | 196 | dev_err(&pdev->dev, "failed to get audio-bus\n"); |