diff options
Diffstat (limited to 'sound/soc/s3c24xx/s3c64xx-i2s.c')
| -rw-r--r-- | sound/soc/s3c24xx/s3c64xx-i2s.c | 157 |
1 files changed, 103 insertions, 54 deletions
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 33c5de7e255f..3c06c401d0fb 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c | |||
| @@ -108,48 +108,19 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, | |||
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | 111 | struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) | |
| 112 | unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai) | ||
| 113 | { | 112 | { |
| 114 | struct s3c_i2sv2_info *i2s = to_info(dai); | 113 | struct s3c_i2sv2_info *i2s = to_info(dai); |
| 115 | 114 | ||
| 116 | return clk_get_rate(i2s->iis_cclk); | 115 | return i2s->iis_cclk; |
| 117 | } | 116 | } |
| 118 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); | 117 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); |
| 119 | 118 | ||
| 120 | static int s3c64xx_i2s_probe(struct platform_device *pdev, | 119 | static int s3c64xx_i2s_probe(struct platform_device *pdev, |
| 121 | struct snd_soc_dai *dai) | 120 | struct snd_soc_dai *dai) |
| 122 | { | 121 | { |
| 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 */ | 122 | /* configure GPIO for i2s port */ |
| 152 | switch (pdev->id) { | 123 | switch (dai->id) { |
| 153 | case 0: | 124 | case 0: |
| 154 | s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); | 125 | s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); |
| 155 | s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); | 126 | s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); |
| @@ -175,41 +146,122 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev, | |||
| 175 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | 146 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) |
| 176 | 147 | ||
| 177 | #define S3C64XX_I2S_FMTS \ | 148 | #define S3C64XX_I2S_FMTS \ |
| 178 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) | 149 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ |
| 150 | SNDRV_PCM_FMTBIT_S24_LE) | ||
| 179 | 151 | ||
| 180 | static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { | 152 | 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 | ||
| 184 | struct snd_soc_dai s3c64xx_i2s_dai = { | 156 | struct 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, | ||
| 174 | .symmetric_rates = 1, | ||
| 193 | }, | 175 | }, |
| 194 | .capture = { | 176 | { |
| 195 | .channels_min = 2, | 177 | .name = "s3c64xx-i2s", |
| 196 | .channels_max = 2, | 178 | .id = 1, |
| 197 | .rates = S3C64XX_I2S_RATES, | 179 | .probe = s3c64xx_i2s_probe, |
| 198 | .formats = S3C64XX_I2S_FMTS, | 180 | .playback = { |
| 181 | .channels_min = 2, | ||
| 182 | .channels_max = 2, | ||
| 183 | .rates = S3C64XX_I2S_RATES, | ||
| 184 | .formats = S3C64XX_I2S_FMTS, | ||
| 185 | }, | ||
| 186 | .capture = { | ||
| 187 | .channels_min = 2, | ||
| 188 | .channels_max = 2, | ||
| 189 | .rates = S3C64XX_I2S_RATES, | ||
| 190 | .formats = S3C64XX_I2S_FMTS, | ||
| 191 | }, | ||
| 192 | .ops = &s3c64xx_i2s_dai_ops, | ||
| 193 | .symmetric_rates = 1, | ||
| 199 | }, | 194 | }, |
| 200 | .ops = &s3c64xx_i2s_dai_ops, | ||
| 201 | }; | 195 | }; |
| 202 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); | 196 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); |
| 203 | 197 | ||
| 198 | static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) | ||
| 199 | { | ||
| 200 | struct s3c_i2sv2_info *i2s; | ||
| 201 | struct snd_soc_dai *dai; | ||
| 202 | int ret; | ||
| 203 | |||
| 204 | if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { | ||
| 205 | dev_err(&pdev->dev, "id %d out of range\n", pdev->id); | ||
| 206 | return -EINVAL; | ||
| 207 | } | ||
| 208 | |||
| 209 | i2s = &s3c64xx_i2s[pdev->id]; | ||
| 210 | dai = &s3c64xx_i2s_dai[pdev->id]; | ||
| 211 | dai->dev = &pdev->dev; | ||
| 212 | |||
| 213 | i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; | ||
| 214 | i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; | ||
| 215 | |||
| 216 | i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); | ||
| 217 | if (IS_ERR(i2s->iis_cclk)) { | ||
| 218 | dev_err(&pdev->dev, "failed to get audio-bus\n"); | ||
| 219 | ret = PTR_ERR(i2s->iis_cclk); | ||
| 220 | goto err; | ||
| 221 | } | ||
| 222 | |||
| 223 | ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); | ||
| 224 | if (ret) | ||
| 225 | goto err_clk; | ||
| 226 | |||
| 227 | ret = s3c_i2sv2_register_dai(dai); | ||
| 228 | if (ret != 0) | ||
| 229 | goto err_i2sv2; | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | |||
| 233 | err_i2sv2: | ||
| 234 | /* Not implemented for I2Sv2 core yet */ | ||
| 235 | err_clk: | ||
| 236 | clk_put(i2s->iis_cclk); | ||
| 237 | err: | ||
| 238 | return ret; | ||
| 239 | } | ||
| 240 | |||
| 241 | static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) | ||
| 242 | { | ||
| 243 | dev_err(&pdev->dev, "Device removal not yet supported\n"); | ||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | static struct platform_driver s3c64xx_iis_driver = { | ||
| 248 | .probe = s3c64xx_iis_dev_probe, | ||
| 249 | .remove = s3c64xx_iis_dev_remove, | ||
| 250 | .driver = { | ||
| 251 | .name = "s3c64xx-iis", | ||
| 252 | .owner = THIS_MODULE, | ||
| 253 | }, | ||
| 254 | }; | ||
| 255 | |||
| 204 | static int __init s3c64xx_i2s_init(void) | 256 | static int __init s3c64xx_i2s_init(void) |
| 205 | { | 257 | { |
| 206 | return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); | 258 | return platform_driver_register(&s3c64xx_iis_driver); |
| 207 | } | 259 | } |
| 208 | module_init(s3c64xx_i2s_init); | 260 | module_init(s3c64xx_i2s_init); |
| 209 | 261 | ||
| 210 | static void __exit s3c64xx_i2s_exit(void) | 262 | static void __exit s3c64xx_i2s_exit(void) |
| 211 | { | 263 | { |
| 212 | snd_soc_unregister_dai(&s3c64xx_i2s_dai); | 264 | platform_driver_unregister(&s3c64xx_iis_driver); |
| 213 | } | 265 | } |
| 214 | module_exit(s3c64xx_i2s_exit); | 266 | module_exit(s3c64xx_i2s_exit); |
| 215 | 267 | ||
| @@ -217,6 +269,3 @@ module_exit(s3c64xx_i2s_exit); | |||
| 217 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | 269 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
| 218 | MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); | 270 | MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); |
| 219 | MODULE_LICENSE("GPL"); | 271 | MODULE_LICENSE("GPL"); |
| 220 | |||
| 221 | |||
| 222 | |||
