Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/sound/soc/samsung/s3c2412-i2s.c

  1 /* sound/soc/samsung/s3c2412-i2s.c
  2  *
  3  * ALSA Soc Audio Layer - S3C2412 I2S driver
  4  *
  5  * Copyright (c) 2006 Wolfson Microelectronics PLC.
  6  *      Graeme Gregory graeme.gregory@wolfsonmicro.com
  7  *      linux@wolfsonmicro.com
  8  *
  9  * Copyright (c) 2007, 2004-2005 Simtec Electronics
 10  *      http://armlinux.simtec.co.uk/
 11  *      Ben Dooks <ben@simtec.co.uk>
 12  *
 13  * This program is free software; you can redistribute  it and/or modify it
 14  * under  the terms of  the GNU General  Public License as published by the
 15  * Free Software Foundation;  either version 2 of the  License, or (at your
 16  * option) any later version.
 17  */
 18 
 19 #include <linux/delay.h>
 20 #include <linux/gpio.h>
 21 #include <linux/clk.h>
 22 #include <linux/io.h>
 23 #include <linux/module.h>
 24 
 25 #include <sound/soc.h>
 26 #include <sound/pcm_params.h>
 27 
 28 #include <mach/gpio-samsung.h>
 29 #include <plat/gpio-cfg.h>
 30 
 31 #include "dma.h"
 32 #include "regs-i2s-v2.h"
 33 #include "s3c2412-i2s.h"
 34 
 35 #include <linux/platform_data/asoc-s3c.h>
 36 
 37 static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = {
 38         .addr_width     = 4,
 39 };
 40 
 41 static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = {
 42         .addr_width     = 4,
 43 };
 44 
 45 static struct s3c_i2sv2_info s3c2412_i2s;
 46 
 47 static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
 48 {
 49         int ret;
 50 
 51         pr_debug("Entered %s\n", __func__);
 52 
 53         snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
 54                                         &s3c2412_i2s_pcm_stereo_in);
 55 
 56         ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
 57         if (ret)
 58                 return ret;
 59 
 60         s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
 61         s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
 62 
 63         s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk");
 64         if (IS_ERR(s3c2412_i2s.iis_cclk)) {
 65                 pr_err("failed to get i2sclk clock\n");
 66                 return PTR_ERR(s3c2412_i2s.iis_cclk);
 67         }
 68 
 69         /* Set MPLL as the source for IIS CLK */
 70 
 71         clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll"));
 72         clk_prepare_enable(s3c2412_i2s.iis_cclk);
 73 
 74         s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;
 75 
 76         /* Configure the I2S pins (GPE0...GPE4) in correct mode */
 77         s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
 78                               S3C_GPIO_PULL_NONE);
 79 
 80         return 0;
 81 }
 82 
 83 static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
 84 {
 85         clk_disable_unprepare(s3c2412_i2s.iis_cclk);
 86 
 87         return 0;
 88 }
 89 
 90 static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
 91                                  struct snd_pcm_hw_params *params,
 92                                  struct snd_soc_dai *cpu_dai)
 93 {
 94         struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
 95         u32 iismod;
 96 
 97         pr_debug("Entered %s\n", __func__);
 98 
 99         iismod = readl(i2s->regs + S3C2412_IISMOD);
100         pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
101 
102         switch (params_width(params)) {
103         case 8:
104                 iismod |= S3C2412_IISMOD_8BIT;
105                 break;
106         case 16:
107                 iismod &= ~S3C2412_IISMOD_8BIT;
108                 break;
109         }
110 
111         writel(iismod, i2s->regs + S3C2412_IISMOD);
112         pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
113 
114         return 0;
115 }
116 
117 #define S3C2412_I2S_RATES \
118         (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
119         SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
120         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
121 
122 static const struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
123         .hw_params      = s3c2412_i2s_hw_params,
124 };
125 
126 static struct snd_soc_dai_driver s3c2412_i2s_dai = {
127         .probe          = s3c2412_i2s_probe,
128         .remove = s3c2412_i2s_remove,
129         .playback = {
130                 .channels_min   = 2,
131                 .channels_max   = 2,
132                 .rates          = S3C2412_I2S_RATES,
133                 .formats        = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,
134         },
135         .capture = {
136                 .channels_min   = 2,
137                 .channels_max   = 2,
138                 .rates          = S3C2412_I2S_RATES,
139                 .formats        = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,
140         },
141         .ops = &s3c2412_i2s_dai_ops,
142 };
143 
144 static const struct snd_soc_component_driver s3c2412_i2s_component = {
145         .name           = "s3c2412-i2s",
146 };
147 
148 static int s3c2412_iis_dev_probe(struct platform_device *pdev)
149 {
150         int ret = 0;
151         struct resource *res;
152         struct s3c_audio_pdata *pdata = dev_get_platdata(&pdev->dev);
153 
154         if (!pdata) {
155                 dev_err(&pdev->dev, "missing platform data");
156                 return -ENXIO;
157         }
158 
159         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
160         s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
161         if (IS_ERR(s3c2412_i2s.regs))
162                 return PTR_ERR(s3c2412_i2s.regs);
163 
164         s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD;
165         s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
166         s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD;
167         s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
168 
169         ret = samsung_asoc_dma_platform_register(&pdev->dev,
170                                                  pdata->dma_filter,
171                                                  NULL, NULL);
172         if (ret) {
173                 pr_err("failed to register the DMA: %d\n", ret);
174                 return ret;
175         }
176 
177         ret = s3c_i2sv2_register_component(&pdev->dev, -1,
178                                            &s3c2412_i2s_component,
179                                            &s3c2412_i2s_dai);
180         if (ret)
181                 pr_err("failed to register the dai\n");
182 
183         return ret;
184 }
185 
186 static struct platform_driver s3c2412_iis_driver = {
187         .probe  = s3c2412_iis_dev_probe,
188         .driver = {
189                 .name = "s3c2412-iis",
190         },
191 };
192 
193 module_platform_driver(s3c2412_iis_driver);
194 
195 /* Module information */
196 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
197 MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
198 MODULE_LICENSE("GPL");
199 MODULE_ALIAS("platform:s3c2412-iis");
200 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us