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"); |
