aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s3c24xx
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-24 11:33:10 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-24 12:39:38 -0400
commit172fd9e26200668ebaf3e1d6d09b36d5d531bfa6 (patch)
tree882a34484549fc258e0eca25dbf7588bcfb4fd13 /sound/soc/s3c24xx
parent7629ad24f2b3df95c8b4cd8869e3c04e1df6c442 (diff)
ASoC: Fix S3C64xx IIS device registration and support both ports
The S3C64xx IIS code had a number of problems with device registration. The hardware has two IIS ports of which the driver supported only one at once via a single exported DAI, attempting to identify the DAI to use based on the dev->id of the ASoC platform device. As well as limiting the driver to only supporting one IIS port at once this also meant that the ID of the soc-audio device (or in future the card device) had to match the IIS ID. Fix both problems by converting the driver to register the DAIs based on probing of platform devices registered by the arch/arm code, using those platform devices to interact with the clock API. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/s3c24xx')
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c146
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h2
2 files changed, 98 insertions, 50 deletions
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 33c5de7e255f..a84c4bec56b9 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -120,36 +120,8 @@ EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate);
120static int s3c64xx_i2s_probe(struct platform_device *pdev, 120static int s3c64xx_i2s_probe(struct platform_device *pdev,
121 struct snd_soc_dai *dai) 121 struct snd_soc_dai *dai)
122{ 122{
123 struct device *dev = &pdev->dev;
124 struct s3c_i2sv2_info *i2s;
125 int ret;
126
127 dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id);
128
129 if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) {
130 dev_err(dev, "id %d out of range\n", pdev->id);
131 return -EINVAL;
132 }
133
134 i2s = &s3c64xx_i2s[pdev->id];
135
136 ret = s3c_i2sv2_probe(pdev, dai, i2s,
137 pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0);
138 if (ret)
139 return ret;
140
141 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
142 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
143
144 i2s->iis_cclk = clk_get(dev, "audio-bus");
145 if (IS_ERR(i2s->iis_cclk)) {
146 dev_err(dev, "failed to get audio-bus");
147 iounmap(i2s->regs);
148 return -ENODEV;
149 }
150
151 /* configure GPIO for i2s port */ 123 /* configure GPIO for i2s port */
152 switch (pdev->id) { 124 switch (dai->id) {
153 case 0: 125 case 0:
154 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); 126 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
155 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); 127 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
@@ -181,35 +153,114 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
181 .set_sysclk = s3c64xx_i2s_set_sysclk, 153 .set_sysclk = s3c64xx_i2s_set_sysclk,
182}; 154};
183 155
184struct snd_soc_dai s3c64xx_i2s_dai = { 156struct snd_soc_dai s3c64xx_i2s_dai[] = {
185 .name = "s3c64xx-i2s", 157 {
186 .id = 0, 158 .name = "s3c64xx-i2s",
187 .probe = s3c64xx_i2s_probe, 159 .id = 0,
188 .playback = { 160 .probe = s3c64xx_i2s_probe,
189 .channels_min = 2, 161 .playback = {
190 .channels_max = 2, 162 .channels_min = 2,
191 .rates = S3C64XX_I2S_RATES, 163 .channels_max = 2,
192 .formats = S3C64XX_I2S_FMTS, 164 .rates = S3C64XX_I2S_RATES,
165 .formats = S3C64XX_I2S_FMTS,
166 },
167 .capture = {
168 .channels_min = 2,
169 .channels_max = 2,
170 .rates = S3C64XX_I2S_RATES,
171 .formats = S3C64XX_I2S_FMTS,
172 },
173 .ops = &s3c64xx_i2s_dai_ops,
193 }, 174 },
194 .capture = { 175 {
195 .channels_min = 2, 176 .name = "s3c64xx-i2s",
196 .channels_max = 2, 177 .id = 1,
197 .rates = S3C64XX_I2S_RATES, 178 .probe = s3c64xx_i2s_probe,
198 .formats = S3C64XX_I2S_FMTS, 179 .playback = {
180 .channels_min = 2,
181 .channels_max = 2,
182 .rates = S3C64XX_I2S_RATES,
183 .formats = S3C64XX_I2S_FMTS,
184 },
185 .capture = {
186 .channels_min = 2,
187 .channels_max = 2,
188 .rates = S3C64XX_I2S_RATES,
189 .formats = S3C64XX_I2S_FMTS,
190 },
191 .ops = &s3c64xx_i2s_dai_ops,
199 }, 192 },
200 .ops = &s3c64xx_i2s_dai_ops,
201}; 193};
202EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); 194EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
203 195
196static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
197{
198 struct s3c_i2sv2_info *i2s;
199 struct snd_soc_dai *dai;
200 int ret;
201
202 if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) {
203 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
204 return -EINVAL;
205 }
206
207 i2s = &s3c64xx_i2s[pdev->id];
208 dai = &s3c64xx_i2s_dai[pdev->id];
209 dai->dev = &pdev->dev;
210
211 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
212 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
213
214 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
215 if (IS_ERR(i2s->iis_cclk)) {
216 dev_err(&pdev->dev, "failed to get audio-bus");
217 ret = PTR_ERR(i2s->iis_cclk);
218 goto err;
219 }
220
221 ret = s3c_i2sv2_probe(pdev, dai, i2s,
222 dai->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0);
223 if (ret)
224 goto err_clk;
225
226 ret = snd_soc_register_dai(dai);
227 if (ret != 0)
228 goto err_i2sv2;
229
230 return 0;
231
232err_i2sv2:
233 /* Not implemented for I2Sv2 core yet */
234err_clk:
235 clk_put(i2s->iis_cclk);
236err:
237 return ret;
238}
239
240static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
241{
242 dev_err(&pdev->dev, "Device removal not yet supported\n");
243 return 0;
244}
245
246static struct platform_driver s3c64xx_iis_driver = {
247 .probe = s3c64xx_iis_dev_probe,
248 .remove = s3c64xx_iis_dev_remove,
249 .driver = {
250 .name = "s3c64xx-iis",
251 .owner = THIS_MODULE,
252 },
253};
254
204static int __init s3c64xx_i2s_init(void) 255static int __init s3c64xx_i2s_init(void)
205{ 256{
206 return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); 257 return platform_driver_register(&s3c64xx_iis_driver);
207} 258}
208module_init(s3c64xx_i2s_init); 259module_init(s3c64xx_i2s_init);
209 260
210static void __exit s3c64xx_i2s_exit(void) 261static void __exit s3c64xx_i2s_exit(void)
211{ 262{
212 snd_soc_unregister_dai(&s3c64xx_i2s_dai); 263 platform_driver_unregister(&s3c64xx_iis_driver);
213} 264}
214module_exit(s3c64xx_i2s_exit); 265module_exit(s3c64xx_i2s_exit);
215 266
@@ -217,6 +268,3 @@ module_exit(s3c64xx_i2s_exit);
217MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 268MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
218MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); 269MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
219MODULE_LICENSE("GPL"); 270MODULE_LICENSE("GPL");
220
221
222
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index b7ffe3c38b66..597822a4658f 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -24,7 +24,7 @@
24#define S3C64XX_CLKSRC_PCLK (0) 24#define S3C64XX_CLKSRC_PCLK (0)
25#define S3C64XX_CLKSRC_MUX (1) 25#define S3C64XX_CLKSRC_MUX (1)
26 26
27extern struct snd_soc_dai s3c64xx_i2s_dai; 27extern struct snd_soc_dai s3c64xx_i2s_dai[];
28 28
29extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); 29extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai);
30 30