Commit 1520ffd218f4aa53bc7652c0f6454da3cb428337

Authored by Mark Brown
1 parent e584f9b4c2

ASoC: dwc: Staticise non-exported i2s_start()

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

Showing 1 changed file with 2 additions and 1 deletions Inline Diff

sound/soc/dwc/designware_i2s.c
1 /* 1 /*
2 * ALSA SoC Synopsys I2S Audio Layer 2 * ALSA SoC Synopsys I2S Audio Layer
3 * 3 *
4 * sound/soc/spear/designware_i2s.c 4 * sound/soc/spear/designware_i2s.c
5 * 5 *
6 * Copyright (C) 2010 ST Microelectronics 6 * Copyright (C) 2010 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com> 7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
8 * 8 *
9 * This file is licensed under the terms of the GNU General Public 9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any 10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied. 11 * warranty of any kind, whether express or implied.
12 */ 12 */
13 13
14 #include <linux/clk.h> 14 #include <linux/clk.h>
15 #include <linux/device.h> 15 #include <linux/device.h>
16 #include <linux/init.h> 16 #include <linux/init.h>
17 #include <linux/io.h> 17 #include <linux/io.h>
18 #include <linux/interrupt.h> 18 #include <linux/interrupt.h>
19 #include <linux/module.h> 19 #include <linux/module.h>
20 #include <linux/slab.h> 20 #include <linux/slab.h>
21 #include <sound/designware_i2s.h> 21 #include <sound/designware_i2s.h>
22 #include <sound/pcm.h> 22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h> 23 #include <sound/pcm_params.h>
24 #include <sound/soc.h> 24 #include <sound/soc.h>
25 25
26 /* common register for all channel */ 26 /* common register for all channel */
27 #define IER 0x000 27 #define IER 0x000
28 #define IRER 0x004 28 #define IRER 0x004
29 #define ITER 0x008 29 #define ITER 0x008
30 #define CER 0x00C 30 #define CER 0x00C
31 #define CCR 0x010 31 #define CCR 0x010
32 #define RXFFR 0x014 32 #define RXFFR 0x014
33 #define TXFFR 0x018 33 #define TXFFR 0x018
34 34
35 /* I2STxRxRegisters for all channels */ 35 /* I2STxRxRegisters for all channels */
36 #define LRBR_LTHR(x) (0x40 * x + 0x020) 36 #define LRBR_LTHR(x) (0x40 * x + 0x020)
37 #define RRBR_RTHR(x) (0x40 * x + 0x024) 37 #define RRBR_RTHR(x) (0x40 * x + 0x024)
38 #define RER(x) (0x40 * x + 0x028) 38 #define RER(x) (0x40 * x + 0x028)
39 #define TER(x) (0x40 * x + 0x02C) 39 #define TER(x) (0x40 * x + 0x02C)
40 #define RCR(x) (0x40 * x + 0x030) 40 #define RCR(x) (0x40 * x + 0x030)
41 #define TCR(x) (0x40 * x + 0x034) 41 #define TCR(x) (0x40 * x + 0x034)
42 #define ISR(x) (0x40 * x + 0x038) 42 #define ISR(x) (0x40 * x + 0x038)
43 #define IMR(x) (0x40 * x + 0x03C) 43 #define IMR(x) (0x40 * x + 0x03C)
44 #define ROR(x) (0x40 * x + 0x040) 44 #define ROR(x) (0x40 * x + 0x040)
45 #define TOR(x) (0x40 * x + 0x044) 45 #define TOR(x) (0x40 * x + 0x044)
46 #define RFCR(x) (0x40 * x + 0x048) 46 #define RFCR(x) (0x40 * x + 0x048)
47 #define TFCR(x) (0x40 * x + 0x04C) 47 #define TFCR(x) (0x40 * x + 0x04C)
48 #define RFF(x) (0x40 * x + 0x050) 48 #define RFF(x) (0x40 * x + 0x050)
49 #define TFF(x) (0x40 * x + 0x054) 49 #define TFF(x) (0x40 * x + 0x054)
50 50
51 /* I2SCOMPRegisters */ 51 /* I2SCOMPRegisters */
52 #define I2S_COMP_PARAM_2 0x01F0 52 #define I2S_COMP_PARAM_2 0x01F0
53 #define I2S_COMP_PARAM_1 0x01F4 53 #define I2S_COMP_PARAM_1 0x01F4
54 #define I2S_COMP_VERSION 0x01F8 54 #define I2S_COMP_VERSION 0x01F8
55 #define I2S_COMP_TYPE 0x01FC 55 #define I2S_COMP_TYPE 0x01FC
56 56
57 #define MAX_CHANNEL_NUM 8 57 #define MAX_CHANNEL_NUM 8
58 #define MIN_CHANNEL_NUM 2 58 #define MIN_CHANNEL_NUM 2
59 59
60 struct dw_i2s_dev { 60 struct dw_i2s_dev {
61 void __iomem *i2s_base; 61 void __iomem *i2s_base;
62 struct clk *clk; 62 struct clk *clk;
63 int active; 63 int active;
64 unsigned int capability; 64 unsigned int capability;
65 struct device *dev; 65 struct device *dev;
66 66
67 /* data related to DMA transfers b/w i2s and DMAC */ 67 /* data related to DMA transfers b/w i2s and DMAC */
68 struct i2s_dma_data play_dma_data; 68 struct i2s_dma_data play_dma_data;
69 struct i2s_dma_data capture_dma_data; 69 struct i2s_dma_data capture_dma_data;
70 struct i2s_clk_config_data config; 70 struct i2s_clk_config_data config;
71 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); 71 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
72 }; 72 };
73 73
74 static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val) 74 static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
75 { 75 {
76 writel(val, io_base + reg); 76 writel(val, io_base + reg);
77 } 77 }
78 78
79 static inline u32 i2s_read_reg(void __iomem *io_base, int reg) 79 static inline u32 i2s_read_reg(void __iomem *io_base, int reg)
80 { 80 {
81 return readl(io_base + reg); 81 return readl(io_base + reg);
82 } 82 }
83 83
84 static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream) 84 static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream)
85 { 85 {
86 u32 i = 0; 86 u32 i = 0;
87 87
88 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 88 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
89 for (i = 0; i < 4; i++) 89 for (i = 0; i < 4; i++)
90 i2s_write_reg(dev->i2s_base, TER(i), 0); 90 i2s_write_reg(dev->i2s_base, TER(i), 0);
91 } else { 91 } else {
92 for (i = 0; i < 4; i++) 92 for (i = 0; i < 4; i++)
93 i2s_write_reg(dev->i2s_base, RER(i), 0); 93 i2s_write_reg(dev->i2s_base, RER(i), 0);
94 } 94 }
95 } 95 }
96 96
97 static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream) 97 static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
98 { 98 {
99 u32 i = 0; 99 u32 i = 0;
100 100
101 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 101 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
102 for (i = 0; i < 4; i++) 102 for (i = 0; i < 4; i++)
103 i2s_write_reg(dev->i2s_base, TOR(i), 0); 103 i2s_write_reg(dev->i2s_base, TOR(i), 0);
104 } else { 104 } else {
105 for (i = 0; i < 4; i++) 105 for (i = 0; i < 4; i++)
106 i2s_write_reg(dev->i2s_base, ROR(i), 0); 106 i2s_write_reg(dev->i2s_base, ROR(i), 0);
107 } 107 }
108 } 108 }
109 109
110 void i2s_start(struct dw_i2s_dev *dev, struct snd_pcm_substream *substream) 110 static void i2s_start(struct dw_i2s_dev *dev,
111 struct snd_pcm_substream *substream)
111 { 112 {
112 113
113 i2s_write_reg(dev->i2s_base, IER, 1); 114 i2s_write_reg(dev->i2s_base, IER, 1);
114 115
115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 116 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
116 i2s_write_reg(dev->i2s_base, ITER, 1); 117 i2s_write_reg(dev->i2s_base, ITER, 1);
117 else 118 else
118 i2s_write_reg(dev->i2s_base, IRER, 1); 119 i2s_write_reg(dev->i2s_base, IRER, 1);
119 120
120 i2s_write_reg(dev->i2s_base, CER, 1); 121 i2s_write_reg(dev->i2s_base, CER, 1);
121 } 122 }
122 123
123 static void i2s_stop(struct dw_i2s_dev *dev, 124 static void i2s_stop(struct dw_i2s_dev *dev,
124 struct snd_pcm_substream *substream) 125 struct snd_pcm_substream *substream)
125 { 126 {
126 u32 i = 0, irq; 127 u32 i = 0, irq;
127 128
128 i2s_clear_irqs(dev, substream->stream); 129 i2s_clear_irqs(dev, substream->stream);
129 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 130 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
130 i2s_write_reg(dev->i2s_base, ITER, 0); 131 i2s_write_reg(dev->i2s_base, ITER, 0);
131 132
132 for (i = 0; i < 4; i++) { 133 for (i = 0; i < 4; i++) {
133 irq = i2s_read_reg(dev->i2s_base, IMR(i)); 134 irq = i2s_read_reg(dev->i2s_base, IMR(i));
134 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30); 135 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
135 } 136 }
136 } else { 137 } else {
137 i2s_write_reg(dev->i2s_base, IRER, 0); 138 i2s_write_reg(dev->i2s_base, IRER, 0);
138 139
139 for (i = 0; i < 4; i++) { 140 for (i = 0; i < 4; i++) {
140 irq = i2s_read_reg(dev->i2s_base, IMR(i)); 141 irq = i2s_read_reg(dev->i2s_base, IMR(i));
141 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03); 142 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
142 } 143 }
143 } 144 }
144 145
145 if (!dev->active) { 146 if (!dev->active) {
146 i2s_write_reg(dev->i2s_base, CER, 0); 147 i2s_write_reg(dev->i2s_base, CER, 0);
147 i2s_write_reg(dev->i2s_base, IER, 0); 148 i2s_write_reg(dev->i2s_base, IER, 0);
148 } 149 }
149 } 150 }
150 151
151 static int dw_i2s_startup(struct snd_pcm_substream *substream, 152 static int dw_i2s_startup(struct snd_pcm_substream *substream,
152 struct snd_soc_dai *cpu_dai) 153 struct snd_soc_dai *cpu_dai)
153 { 154 {
154 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); 155 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
155 struct i2s_dma_data *dma_data = NULL; 156 struct i2s_dma_data *dma_data = NULL;
156 157
157 if (!(dev->capability & DWC_I2S_RECORD) && 158 if (!(dev->capability & DWC_I2S_RECORD) &&
158 (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) 159 (substream->stream == SNDRV_PCM_STREAM_CAPTURE))
159 return -EINVAL; 160 return -EINVAL;
160 161
161 if (!(dev->capability & DWC_I2S_PLAY) && 162 if (!(dev->capability & DWC_I2S_PLAY) &&
162 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) 163 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
163 return -EINVAL; 164 return -EINVAL;
164 165
165 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
166 dma_data = &dev->play_dma_data; 167 dma_data = &dev->play_dma_data;
167 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 168 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
168 dma_data = &dev->capture_dma_data; 169 dma_data = &dev->capture_dma_data;
169 170
170 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data); 171 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
171 172
172 return 0; 173 return 0;
173 } 174 }
174 175
175 static int dw_i2s_hw_params(struct snd_pcm_substream *substream, 176 static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
176 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 177 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
177 { 178 {
178 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 179 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
179 struct i2s_clk_config_data *config = &dev->config; 180 struct i2s_clk_config_data *config = &dev->config;
180 u32 ccr, xfer_resolution, ch_reg, irq; 181 u32 ccr, xfer_resolution, ch_reg, irq;
181 int ret; 182 int ret;
182 183
183 switch (params_format(params)) { 184 switch (params_format(params)) {
184 case SNDRV_PCM_FORMAT_S16_LE: 185 case SNDRV_PCM_FORMAT_S16_LE:
185 config->data_width = 16; 186 config->data_width = 16;
186 ccr = 0x00; 187 ccr = 0x00;
187 xfer_resolution = 0x02; 188 xfer_resolution = 0x02;
188 break; 189 break;
189 190
190 case SNDRV_PCM_FORMAT_S24_LE: 191 case SNDRV_PCM_FORMAT_S24_LE:
191 config->data_width = 24; 192 config->data_width = 24;
192 ccr = 0x08; 193 ccr = 0x08;
193 xfer_resolution = 0x04; 194 xfer_resolution = 0x04;
194 break; 195 break;
195 196
196 case SNDRV_PCM_FORMAT_S32_LE: 197 case SNDRV_PCM_FORMAT_S32_LE:
197 config->data_width = 32; 198 config->data_width = 32;
198 ccr = 0x10; 199 ccr = 0x10;
199 xfer_resolution = 0x05; 200 xfer_resolution = 0x05;
200 break; 201 break;
201 202
202 default: 203 default:
203 dev_err(dev->dev, "designware-i2s: unsuppted PCM fmt"); 204 dev_err(dev->dev, "designware-i2s: unsuppted PCM fmt");
204 return -EINVAL; 205 return -EINVAL;
205 } 206 }
206 207
207 config->chan_nr = params_channels(params); 208 config->chan_nr = params_channels(params);
208 209
209 switch (config->chan_nr) { 210 switch (config->chan_nr) {
210 case EIGHT_CHANNEL_SUPPORT: 211 case EIGHT_CHANNEL_SUPPORT:
211 ch_reg = 3; 212 ch_reg = 3;
212 case SIX_CHANNEL_SUPPORT: 213 case SIX_CHANNEL_SUPPORT:
213 ch_reg = 2; 214 ch_reg = 2;
214 case FOUR_CHANNEL_SUPPORT: 215 case FOUR_CHANNEL_SUPPORT:
215 ch_reg = 1; 216 ch_reg = 1;
216 case TWO_CHANNEL_SUPPORT: 217 case TWO_CHANNEL_SUPPORT:
217 ch_reg = 0; 218 ch_reg = 0;
218 break; 219 break;
219 default: 220 default:
220 dev_err(dev->dev, "channel not supported\n"); 221 dev_err(dev->dev, "channel not supported\n");
221 } 222 }
222 223
223 i2s_disable_channels(dev, substream->stream); 224 i2s_disable_channels(dev, substream->stream);
224 225
225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
226 i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution); 227 i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution);
227 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); 228 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
228 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); 229 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
229 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); 230 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
230 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); 231 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
231 } else { 232 } else {
232 i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution); 233 i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution);
233 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); 234 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
234 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); 235 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
235 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); 236 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
236 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); 237 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
237 } 238 }
238 239
239 i2s_write_reg(dev->i2s_base, CCR, ccr); 240 i2s_write_reg(dev->i2s_base, CCR, ccr);
240 241
241 config->sample_rate = params_rate(params); 242 config->sample_rate = params_rate(params);
242 243
243 if (!dev->i2s_clk_cfg) 244 if (!dev->i2s_clk_cfg)
244 return -EINVAL; 245 return -EINVAL;
245 246
246 ret = dev->i2s_clk_cfg(config); 247 ret = dev->i2s_clk_cfg(config);
247 if (ret < 0) { 248 if (ret < 0) {
248 dev_err(dev->dev, "runtime audio clk config fail\n"); 249 dev_err(dev->dev, "runtime audio clk config fail\n");
249 return ret; 250 return ret;
250 } 251 }
251 252
252 return 0; 253 return 0;
253 } 254 }
254 255
255 static void dw_i2s_shutdown(struct snd_pcm_substream *substream, 256 static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
256 struct snd_soc_dai *dai) 257 struct snd_soc_dai *dai)
257 { 258 {
258 snd_soc_dai_set_dma_data(dai, substream, NULL); 259 snd_soc_dai_set_dma_data(dai, substream, NULL);
259 } 260 }
260 261
261 static int dw_i2s_trigger(struct snd_pcm_substream *substream, 262 static int dw_i2s_trigger(struct snd_pcm_substream *substream,
262 int cmd, struct snd_soc_dai *dai) 263 int cmd, struct snd_soc_dai *dai)
263 { 264 {
264 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 265 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
265 int ret = 0; 266 int ret = 0;
266 267
267 switch (cmd) { 268 switch (cmd) {
268 case SNDRV_PCM_TRIGGER_START: 269 case SNDRV_PCM_TRIGGER_START:
269 case SNDRV_PCM_TRIGGER_RESUME: 270 case SNDRV_PCM_TRIGGER_RESUME:
270 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 271 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
271 dev->active++; 272 dev->active++;
272 i2s_start(dev, substream); 273 i2s_start(dev, substream);
273 break; 274 break;
274 275
275 case SNDRV_PCM_TRIGGER_STOP: 276 case SNDRV_PCM_TRIGGER_STOP:
276 case SNDRV_PCM_TRIGGER_SUSPEND: 277 case SNDRV_PCM_TRIGGER_SUSPEND:
277 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 278 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
278 dev->active--; 279 dev->active--;
279 i2s_stop(dev, substream); 280 i2s_stop(dev, substream);
280 break; 281 break;
281 default: 282 default:
282 ret = -EINVAL; 283 ret = -EINVAL;
283 break; 284 break;
284 } 285 }
285 return ret; 286 return ret;
286 } 287 }
287 288
288 static struct snd_soc_dai_ops dw_i2s_dai_ops = { 289 static struct snd_soc_dai_ops dw_i2s_dai_ops = {
289 .startup = dw_i2s_startup, 290 .startup = dw_i2s_startup,
290 .shutdown = dw_i2s_shutdown, 291 .shutdown = dw_i2s_shutdown,
291 .hw_params = dw_i2s_hw_params, 292 .hw_params = dw_i2s_hw_params,
292 .trigger = dw_i2s_trigger, 293 .trigger = dw_i2s_trigger,
293 }; 294 };
294 295
295 #ifdef CONFIG_PM 296 #ifdef CONFIG_PM
296 297
297 static int dw_i2s_suspend(struct snd_soc_dai *dai) 298 static int dw_i2s_suspend(struct snd_soc_dai *dai)
298 { 299 {
299 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 300 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
300 301
301 clk_disable(dev->clk); 302 clk_disable(dev->clk);
302 return 0; 303 return 0;
303 } 304 }
304 305
305 static int dw_i2s_resume(struct snd_soc_dai *dai) 306 static int dw_i2s_resume(struct snd_soc_dai *dai)
306 { 307 {
307 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 308 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
308 309
309 clk_enable(dev->clk); 310 clk_enable(dev->clk);
310 return 0; 311 return 0;
311 } 312 }
312 313
313 #else 314 #else
314 #define dw_i2s_suspend NULL 315 #define dw_i2s_suspend NULL
315 #define dw_i2s_resume NULL 316 #define dw_i2s_resume NULL
316 #endif 317 #endif
317 318
318 static int dw_i2s_probe(struct platform_device *pdev) 319 static int dw_i2s_probe(struct platform_device *pdev)
319 { 320 {
320 const struct i2s_platform_data *pdata = pdev->dev.platform_data; 321 const struct i2s_platform_data *pdata = pdev->dev.platform_data;
321 struct dw_i2s_dev *dev; 322 struct dw_i2s_dev *dev;
322 struct resource *res; 323 struct resource *res;
323 int ret; 324 int ret;
324 unsigned int cap; 325 unsigned int cap;
325 struct snd_soc_dai_driver *dw_i2s_dai; 326 struct snd_soc_dai_driver *dw_i2s_dai;
326 327
327 if (!pdata) { 328 if (!pdata) {
328 dev_err(&pdev->dev, "Invalid platform data\n"); 329 dev_err(&pdev->dev, "Invalid platform data\n");
329 return -EINVAL; 330 return -EINVAL;
330 } 331 }
331 332
332 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 333 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
333 if (!res) { 334 if (!res) {
334 dev_err(&pdev->dev, "no i2s resource defined\n"); 335 dev_err(&pdev->dev, "no i2s resource defined\n");
335 return -ENODEV; 336 return -ENODEV;
336 } 337 }
337 338
338 if (!devm_request_mem_region(&pdev->dev, res->start, 339 if (!devm_request_mem_region(&pdev->dev, res->start,
339 resource_size(res), pdev->name)) { 340 resource_size(res), pdev->name)) {
340 dev_err(&pdev->dev, "i2s region already claimed\n"); 341 dev_err(&pdev->dev, "i2s region already claimed\n");
341 return -EBUSY; 342 return -EBUSY;
342 } 343 }
343 344
344 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 345 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
345 if (!dev) { 346 if (!dev) {
346 dev_warn(&pdev->dev, "kzalloc fail\n"); 347 dev_warn(&pdev->dev, "kzalloc fail\n");
347 return -ENOMEM; 348 return -ENOMEM;
348 } 349 }
349 350
350 dev->i2s_base = devm_ioremap(&pdev->dev, res->start, 351 dev->i2s_base = devm_ioremap(&pdev->dev, res->start,
351 resource_size(res)); 352 resource_size(res));
352 if (!dev->i2s_base) { 353 if (!dev->i2s_base) {
353 dev_err(&pdev->dev, "ioremap fail for i2s_region\n"); 354 dev_err(&pdev->dev, "ioremap fail for i2s_region\n");
354 return -ENOMEM; 355 return -ENOMEM;
355 } 356 }
356 357
357 cap = pdata->cap; 358 cap = pdata->cap;
358 dev->capability = cap; 359 dev->capability = cap;
359 dev->i2s_clk_cfg = pdata->i2s_clk_cfg; 360 dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
360 361
361 /* Set DMA slaves info */ 362 /* Set DMA slaves info */
362 363
363 dev->play_dma_data.data = pdata->play_dma_data; 364 dev->play_dma_data.data = pdata->play_dma_data;
364 dev->capture_dma_data.data = pdata->capture_dma_data; 365 dev->capture_dma_data.data = pdata->capture_dma_data;
365 dev->play_dma_data.addr = res->start + I2S_TXDMA; 366 dev->play_dma_data.addr = res->start + I2S_TXDMA;
366 dev->capture_dma_data.addr = res->start + I2S_RXDMA; 367 dev->capture_dma_data.addr = res->start + I2S_RXDMA;
367 dev->play_dma_data.max_burst = 16; 368 dev->play_dma_data.max_burst = 16;
368 dev->capture_dma_data.max_burst = 16; 369 dev->capture_dma_data.max_burst = 16;
369 dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 370 dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
370 dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 371 dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
371 dev->play_dma_data.filter = pdata->filter; 372 dev->play_dma_data.filter = pdata->filter;
372 dev->capture_dma_data.filter = pdata->filter; 373 dev->capture_dma_data.filter = pdata->filter;
373 374
374 dev->clk = clk_get(&pdev->dev, NULL); 375 dev->clk = clk_get(&pdev->dev, NULL);
375 if (IS_ERR(dev->clk)) 376 if (IS_ERR(dev->clk))
376 return PTR_ERR(dev->clk); 377 return PTR_ERR(dev->clk);
377 378
378 ret = clk_enable(dev->clk); 379 ret = clk_enable(dev->clk);
379 if (ret < 0) 380 if (ret < 0)
380 goto err_clk_put; 381 goto err_clk_put;
381 382
382 dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); 383 dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
383 if (!dw_i2s_dai) { 384 if (!dw_i2s_dai) {
384 dev_err(&pdev->dev, "mem allocation failed for dai driver\n"); 385 dev_err(&pdev->dev, "mem allocation failed for dai driver\n");
385 ret = -ENOMEM; 386 ret = -ENOMEM;
386 goto err_clk_disable; 387 goto err_clk_disable;
387 } 388 }
388 389
389 if (cap & DWC_I2S_PLAY) { 390 if (cap & DWC_I2S_PLAY) {
390 dev_dbg(&pdev->dev, " SPEAr: play supported\n"); 391 dev_dbg(&pdev->dev, " SPEAr: play supported\n");
391 dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; 392 dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
392 dw_i2s_dai->playback.channels_max = pdata->channel; 393 dw_i2s_dai->playback.channels_max = pdata->channel;
393 dw_i2s_dai->playback.formats = pdata->snd_fmts; 394 dw_i2s_dai->playback.formats = pdata->snd_fmts;
394 dw_i2s_dai->playback.rates = pdata->snd_rates; 395 dw_i2s_dai->playback.rates = pdata->snd_rates;
395 } 396 }
396 397
397 if (cap & DWC_I2S_RECORD) { 398 if (cap & DWC_I2S_RECORD) {
398 dev_dbg(&pdev->dev, "SPEAr: record supported\n"); 399 dev_dbg(&pdev->dev, "SPEAr: record supported\n");
399 dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; 400 dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
400 dw_i2s_dai->capture.channels_max = pdata->channel; 401 dw_i2s_dai->capture.channels_max = pdata->channel;
401 dw_i2s_dai->capture.formats = pdata->snd_fmts; 402 dw_i2s_dai->capture.formats = pdata->snd_fmts;
402 dw_i2s_dai->capture.rates = pdata->snd_rates; 403 dw_i2s_dai->capture.rates = pdata->snd_rates;
403 } 404 }
404 405
405 dw_i2s_dai->ops = &dw_i2s_dai_ops; 406 dw_i2s_dai->ops = &dw_i2s_dai_ops;
406 dw_i2s_dai->suspend = dw_i2s_suspend; 407 dw_i2s_dai->suspend = dw_i2s_suspend;
407 dw_i2s_dai->resume = dw_i2s_resume; 408 dw_i2s_dai->resume = dw_i2s_resume;
408 409
409 dev->dev = &pdev->dev; 410 dev->dev = &pdev->dev;
410 dev_set_drvdata(&pdev->dev, dev); 411 dev_set_drvdata(&pdev->dev, dev);
411 ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai); 412 ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai);
412 if (ret != 0) { 413 if (ret != 0) {
413 dev_err(&pdev->dev, "not able to register dai\n"); 414 dev_err(&pdev->dev, "not able to register dai\n");
414 goto err_set_drvdata; 415 goto err_set_drvdata;
415 } 416 }
416 417
417 return 0; 418 return 0;
418 419
419 err_set_drvdata: 420 err_set_drvdata:
420 dev_set_drvdata(&pdev->dev, NULL); 421 dev_set_drvdata(&pdev->dev, NULL);
421 err_clk_disable: 422 err_clk_disable:
422 clk_disable(dev->clk); 423 clk_disable(dev->clk);
423 err_clk_put: 424 err_clk_put:
424 clk_put(dev->clk); 425 clk_put(dev->clk);
425 return ret; 426 return ret;
426 } 427 }
427 428
428 static int dw_i2s_remove(struct platform_device *pdev) 429 static int dw_i2s_remove(struct platform_device *pdev)
429 { 430 {
430 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 431 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
431 432
432 snd_soc_unregister_dai(&pdev->dev); 433 snd_soc_unregister_dai(&pdev->dev);
433 dev_set_drvdata(&pdev->dev, NULL); 434 dev_set_drvdata(&pdev->dev, NULL);
434 435
435 clk_put(dev->clk); 436 clk_put(dev->clk);
436 437
437 return 0; 438 return 0;
438 } 439 }
439 440
440 static struct platform_driver dw_i2s_driver = { 441 static struct platform_driver dw_i2s_driver = {
441 .probe = dw_i2s_probe, 442 .probe = dw_i2s_probe,
442 .remove = dw_i2s_remove, 443 .remove = dw_i2s_remove,
443 .driver = { 444 .driver = {
444 .name = "designware-i2s", 445 .name = "designware-i2s",
445 .owner = THIS_MODULE, 446 .owner = THIS_MODULE,
446 }, 447 },
447 }; 448 };
448 449
449 module_platform_driver(dw_i2s_driver); 450 module_platform_driver(dw_i2s_driver);
450 451
451 MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); 452 MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
452 MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface"); 453 MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
453 MODULE_LICENSE("GPL"); 454 MODULE_LICENSE("GPL");
454 MODULE_ALIAS("platform:designware_i2s"); 455 MODULE_ALIAS("platform:designware_i2s");
455 456