aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r--arch/arm/plat-omap/mcbsp.c388
1 files changed, 225 insertions, 163 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e0803a8344be..f27e641bf814 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -27,43 +27,65 @@
27#include <mach/dma.h> 27#include <mach/dma.h>
28#include <mach/mcbsp.h> 28#include <mach/mcbsp.h>
29 29
30static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; 30struct omap_mcbsp **mcbsp_ptr;
31int omap_mcbsp_count;
31 32
32#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ 33void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
33 mcbsp[id].pdata->ops && \ 34{
34 mcbsp[id].pdata->ops->check && \ 35 if (cpu_class_is_omap1() || cpu_is_omap2420())
35 (mcbsp[id].pdata->ops->check(id) == 0)) 36 __raw_writew((u16)val, io_base + reg);
37 else
38 __raw_writel(val, io_base + reg);
39}
40
41int omap_mcbsp_read(void __iomem *io_base, u16 reg)
42{
43 if (cpu_class_is_omap1() || cpu_is_omap2420())
44 return __raw_readw(io_base + reg);
45 else
46 return __raw_readl(io_base + reg);
47}
48
49#define OMAP_MCBSP_READ(base, reg) \
50 omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg)
51#define OMAP_MCBSP_WRITE(base, reg, val) \
52 omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val)
53
54#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
55#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
36 56
37static void omap_mcbsp_dump_reg(u8 id) 57static void omap_mcbsp_dump_reg(u8 id)
38{ 58{
39 dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); 59 struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
40 dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", 60
41 OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); 61 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
42 dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", 62 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
43 OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); 63 OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
44 dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", 64 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
45 OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); 65 OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
46 dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", 66 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
47 OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); 67 OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
48 dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", 68 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
49 OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); 69 OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
50 dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", 70 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
51 OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); 71 OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
52 dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", 72 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
53 OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); 73 OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
54 dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", 74 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
55 OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); 75 OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
56 dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", 76 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
57 OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); 77 OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
58 dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", 78 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
59 OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); 79 OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
60 dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", 80 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
61 OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); 81 OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
62 dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", 82 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
63 OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); 83 OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
64 dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", 84 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
65 OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); 85 OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
66 dev_dbg(mcbsp[id].dev, "***********************\n"); 86 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
87 OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
88 dev_dbg(mcbsp->dev, "***********************\n");
67} 89}
68 90
69static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) 91static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
@@ -126,16 +148,18 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
126 */ 148 */
127void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) 149void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
128{ 150{
151 struct omap_mcbsp *mcbsp;
129 void __iomem *io_base; 152 void __iomem *io_base;
130 153
131 if (!omap_mcbsp_check_valid_id(id)) { 154 if (!omap_mcbsp_check_valid_id(id)) {
132 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 155 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
133 return; 156 return;
134 } 157 }
158 mcbsp = id_to_mcbsp_ptr(id);
135 159
136 io_base = mcbsp[id].io_base; 160 io_base = mcbsp->io_base;
137 dev_dbg(mcbsp[id].dev, "Configuring McBSP%d phys_base: 0x%08lx\n", 161 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
138 mcbsp[id].id, mcbsp[id].phys_base); 162 mcbsp->id, mcbsp->phys_base);
139 163
140 /* We write the given config */ 164 /* We write the given config */
141 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); 165 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
@@ -158,23 +182,26 @@ EXPORT_SYMBOL(omap_mcbsp_config);
158 */ 182 */
159int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) 183int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
160{ 184{
185 struct omap_mcbsp *mcbsp;
186
161 if (!omap_mcbsp_check_valid_id(id)) { 187 if (!omap_mcbsp_check_valid_id(id)) {
162 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 188 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
163 return -ENODEV; 189 return -ENODEV;
164 } 190 }
191 mcbsp = id_to_mcbsp_ptr(id);
165 192
166 spin_lock(&mcbsp[id].lock); 193 spin_lock(&mcbsp->lock);
167 194
168 if (!mcbsp[id].free) { 195 if (!mcbsp->free) {
169 dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", 196 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
170 mcbsp[id].id); 197 mcbsp->id);
171 spin_unlock(&mcbsp[id].lock); 198 spin_unlock(&mcbsp->lock);
172 return -EINVAL; 199 return -EINVAL;
173 } 200 }
174 201
175 mcbsp[id].io_type = io_type; 202 mcbsp->io_type = io_type;
176 203
177 spin_unlock(&mcbsp[id].lock); 204 spin_unlock(&mcbsp->lock);
178 205
179 return 0; 206 return 0;
180} 207}
@@ -182,53 +209,55 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
182 209
183int omap_mcbsp_request(unsigned int id) 210int omap_mcbsp_request(unsigned int id)
184{ 211{
212 struct omap_mcbsp *mcbsp;
185 int err; 213 int err;
186 214
187 if (!omap_mcbsp_check_valid_id(id)) { 215 if (!omap_mcbsp_check_valid_id(id)) {
188 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 216 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
189 return -ENODEV; 217 return -ENODEV;
190 } 218 }
219 mcbsp = id_to_mcbsp_ptr(id);
191 220
192 if (mcbsp[id].pdata->ops->request) 221 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
193 mcbsp[id].pdata->ops->request(id); 222 mcbsp->pdata->ops->request(id);
194 223
195 clk_enable(mcbsp[id].clk); 224 clk_enable(mcbsp->clk);
196 225
197 spin_lock(&mcbsp[id].lock); 226 spin_lock(&mcbsp->lock);
198 if (!mcbsp[id].free) { 227 if (!mcbsp->free) {
199 dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", 228 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
200 mcbsp[id].id); 229 mcbsp->id);
201 spin_unlock(&mcbsp[id].lock); 230 spin_unlock(&mcbsp->lock);
202 return -1; 231 return -1;
203 } 232 }
204 233
205 mcbsp[id].free = 0; 234 mcbsp->free = 0;
206 spin_unlock(&mcbsp[id].lock); 235 spin_unlock(&mcbsp->lock);
207 236
208 if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { 237 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
209 /* We need to get IRQs here */ 238 /* We need to get IRQs here */
210 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 239 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
211 0, "McBSP", (void *) (&mcbsp[id])); 240 0, "McBSP", (void *)mcbsp);
212 if (err != 0) { 241 if (err != 0) {
213 dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " 242 dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
214 "for McBSP%d\n", mcbsp[id].tx_irq, 243 "for McBSP%d\n", mcbsp->tx_irq,
215 mcbsp[id].id); 244 mcbsp->id);
216 return err; 245 return err;
217 } 246 }
218 247
219 init_completion(&(mcbsp[id].tx_irq_completion)); 248 init_completion(&mcbsp->tx_irq_completion);
220 249
221 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 250 err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler,
222 0, "McBSP", (void *) (&mcbsp[id])); 251 0, "McBSP", (void *)mcbsp);
223 if (err != 0) { 252 if (err != 0) {
224 dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " 253 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
225 "for McBSP%d\n", mcbsp[id].rx_irq, 254 "for McBSP%d\n", mcbsp->rx_irq,
226 mcbsp[id].id); 255 mcbsp->id);
227 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 256 free_irq(mcbsp->tx_irq, (void *)mcbsp);
228 return err; 257 return err;
229 } 258 }
230 259
231 init_completion(&(mcbsp[id].rx_irq_completion)); 260 init_completion(&mcbsp->rx_irq_completion);
232 } 261 }
233 262
234 return 0; 263 return 0;
@@ -237,31 +266,34 @@ EXPORT_SYMBOL(omap_mcbsp_request);
237 266
238void omap_mcbsp_free(unsigned int id) 267void omap_mcbsp_free(unsigned int id)
239{ 268{
269 struct omap_mcbsp *mcbsp;
270
240 if (!omap_mcbsp_check_valid_id(id)) { 271 if (!omap_mcbsp_check_valid_id(id)) {
241 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 272 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
242 return; 273 return;
243 } 274 }
275 mcbsp = id_to_mcbsp_ptr(id);
244 276
245 if (mcbsp[id].pdata->ops->free) 277 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
246 mcbsp[id].pdata->ops->free(id); 278 mcbsp->pdata->ops->free(id);
247 279
248 clk_disable(mcbsp[id].clk); 280 clk_disable(mcbsp->clk);
249 281
250 spin_lock(&mcbsp[id].lock); 282 spin_lock(&mcbsp->lock);
251 if (mcbsp[id].free) { 283 if (mcbsp->free) {
252 dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", 284 dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
253 mcbsp[id].id); 285 mcbsp->id);
254 spin_unlock(&mcbsp[id].lock); 286 spin_unlock(&mcbsp->lock);
255 return; 287 return;
256 } 288 }
257 289
258 mcbsp[id].free = 1; 290 mcbsp->free = 1;
259 spin_unlock(&mcbsp[id].lock); 291 spin_unlock(&mcbsp->lock);
260 292
261 if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { 293 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
262 /* Free IRQs */ 294 /* Free IRQs */
263 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); 295 free_irq(mcbsp->rx_irq, (void *)mcbsp);
264 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 296 free_irq(mcbsp->tx_irq, (void *)mcbsp);
265 } 297 }
266} 298}
267EXPORT_SYMBOL(omap_mcbsp_free); 299EXPORT_SYMBOL(omap_mcbsp_free);
@@ -273,6 +305,7 @@ EXPORT_SYMBOL(omap_mcbsp_free);
273 */ 305 */
274void omap_mcbsp_start(unsigned int id) 306void omap_mcbsp_start(unsigned int id)
275{ 307{
308 struct omap_mcbsp *mcbsp;
276 void __iomem *io_base; 309 void __iomem *io_base;
277 u16 w; 310 u16 w;
278 311
@@ -280,11 +313,11 @@ void omap_mcbsp_start(unsigned int id)
280 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 313 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
281 return; 314 return;
282 } 315 }
316 mcbsp = id_to_mcbsp_ptr(id);
317 io_base = mcbsp->io_base;
283 318
284 io_base = mcbsp[id].io_base; 319 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
285 320 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
286 mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
287 mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
288 321
289 /* Start the sample generator */ 322 /* Start the sample generator */
290 w = OMAP_MCBSP_READ(io_base, SPCR2); 323 w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -310,6 +343,7 @@ EXPORT_SYMBOL(omap_mcbsp_start);
310 343
311void omap_mcbsp_stop(unsigned int id) 344void omap_mcbsp_stop(unsigned int id)
312{ 345{
346 struct omap_mcbsp *mcbsp;
313 void __iomem *io_base; 347 void __iomem *io_base;
314 u16 w; 348 u16 w;
315 349
@@ -318,7 +352,8 @@ void omap_mcbsp_stop(unsigned int id)
318 return; 352 return;
319 } 353 }
320 354
321 io_base = mcbsp[id].io_base; 355 mcbsp = id_to_mcbsp_ptr(id);
356 io_base = mcbsp->io_base;
322 357
323 /* Reset transmitter */ 358 /* Reset transmitter */
324 w = OMAP_MCBSP_READ(io_base, SPCR2); 359 w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -337,6 +372,7 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
337/* polled mcbsp i/o operations */ 372/* polled mcbsp i/o operations */
338int omap_mcbsp_pollwrite(unsigned int id, u16 buf) 373int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
339{ 374{
375 struct omap_mcbsp *mcbsp;
340 void __iomem *base; 376 void __iomem *base;
341 377
342 if (!omap_mcbsp_check_valid_id(id)) { 378 if (!omap_mcbsp_check_valid_id(id)) {
@@ -344,7 +380,9 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
344 return -ENODEV; 380 return -ENODEV;
345 } 381 }
346 382
347 base = mcbsp[id].io_base; 383 mcbsp = id_to_mcbsp_ptr(id);
384 base = mcbsp->io_base;
385
348 writew(buf, base + OMAP_MCBSP_REG_DXR1); 386 writew(buf, base + OMAP_MCBSP_REG_DXR1);
349 /* if frame sync error - clear the error */ 387 /* if frame sync error - clear the error */
350 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { 388 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
@@ -366,8 +404,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
366 (XRST), 404 (XRST),
367 base + OMAP_MCBSP_REG_SPCR2); 405 base + OMAP_MCBSP_REG_SPCR2);
368 udelay(10); 406 udelay(10);
369 dev_err(mcbsp[id].dev, "Could not write to" 407 dev_err(mcbsp->dev, "Could not write to"
370 " McBSP%d Register\n", mcbsp[id].id); 408 " McBSP%d Register\n", mcbsp->id);
371 return -2; 409 return -2;
372 } 410 }
373 } 411 }
@@ -379,14 +417,16 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
379 417
380int omap_mcbsp_pollread(unsigned int id, u16 *buf) 418int omap_mcbsp_pollread(unsigned int id, u16 *buf)
381{ 419{
420 struct omap_mcbsp *mcbsp;
382 void __iomem *base; 421 void __iomem *base;
383 422
384 if (!omap_mcbsp_check_valid_id(id)) { 423 if (!omap_mcbsp_check_valid_id(id)) {
385 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 424 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
386 return -ENODEV; 425 return -ENODEV;
387 } 426 }
427 mcbsp = id_to_mcbsp_ptr(id);
388 428
389 base = mcbsp[id].io_base; 429 base = mcbsp->io_base;
390 /* if frame sync error - clear the error */ 430 /* if frame sync error - clear the error */
391 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { 431 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
392 /* clear error */ 432 /* clear error */
@@ -407,8 +447,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
407 (RRST), 447 (RRST),
408 base + OMAP_MCBSP_REG_SPCR1); 448 base + OMAP_MCBSP_REG_SPCR1);
409 udelay(10); 449 udelay(10);
410 dev_err(mcbsp[id].dev, "Could not read from" 450 dev_err(mcbsp->dev, "Could not read from"
411 " McBSP%d Register\n", mcbsp[id].id); 451 " McBSP%d Register\n", mcbsp->id);
412 return -2; 452 return -2;
413 } 453 }
414 } 454 }
@@ -424,6 +464,7 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
424 */ 464 */
425void omap_mcbsp_xmit_word(unsigned int id, u32 word) 465void omap_mcbsp_xmit_word(unsigned int id, u32 word)
426{ 466{
467 struct omap_mcbsp *mcbsp;
427 void __iomem *io_base; 468 void __iomem *io_base;
428 omap_mcbsp_word_length word_length; 469 omap_mcbsp_word_length word_length;
429 470
@@ -432,10 +473,11 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
432 return; 473 return;
433 } 474 }
434 475
435 io_base = mcbsp[id].io_base; 476 mcbsp = id_to_mcbsp_ptr(id);
436 word_length = mcbsp[id].tx_word_length; 477 io_base = mcbsp->io_base;
478 word_length = mcbsp->tx_word_length;
437 479
438 wait_for_completion(&(mcbsp[id].tx_irq_completion)); 480 wait_for_completion(&mcbsp->tx_irq_completion);
439 481
440 if (word_length > OMAP_MCBSP_WORD_16) 482 if (word_length > OMAP_MCBSP_WORD_16)
441 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); 483 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
@@ -445,6 +487,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word);
445 487
446u32 omap_mcbsp_recv_word(unsigned int id) 488u32 omap_mcbsp_recv_word(unsigned int id)
447{ 489{
490 struct omap_mcbsp *mcbsp;
448 void __iomem *io_base; 491 void __iomem *io_base;
449 u16 word_lsb, word_msb = 0; 492 u16 word_lsb, word_msb = 0;
450 omap_mcbsp_word_length word_length; 493 omap_mcbsp_word_length word_length;
@@ -453,11 +496,12 @@ u32 omap_mcbsp_recv_word(unsigned int id)
453 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 496 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
454 return -ENODEV; 497 return -ENODEV;
455 } 498 }
499 mcbsp = id_to_mcbsp_ptr(id);
456 500
457 word_length = mcbsp[id].rx_word_length; 501 word_length = mcbsp->rx_word_length;
458 io_base = mcbsp[id].io_base; 502 io_base = mcbsp->io_base;
459 503
460 wait_for_completion(&(mcbsp[id].rx_irq_completion)); 504 wait_for_completion(&mcbsp->rx_irq_completion);
461 505
462 if (word_length > OMAP_MCBSP_WORD_16) 506 if (word_length > OMAP_MCBSP_WORD_16)
463 word_msb = OMAP_MCBSP_READ(io_base, DRR2); 507 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
@@ -469,6 +513,7 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
469 513
470int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) 514int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
471{ 515{
516 struct omap_mcbsp *mcbsp;
472 void __iomem *io_base; 517 void __iomem *io_base;
473 omap_mcbsp_word_length tx_word_length; 518 omap_mcbsp_word_length tx_word_length;
474 omap_mcbsp_word_length rx_word_length; 519 omap_mcbsp_word_length rx_word_length;
@@ -478,10 +523,10 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
478 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 523 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
479 return -ENODEV; 524 return -ENODEV;
480 } 525 }
481 526 mcbsp = id_to_mcbsp_ptr(id);
482 io_base = mcbsp[id].io_base; 527 io_base = mcbsp->io_base;
483 tx_word_length = mcbsp[id].tx_word_length; 528 tx_word_length = mcbsp->tx_word_length;
484 rx_word_length = mcbsp[id].rx_word_length; 529 rx_word_length = mcbsp->rx_word_length;
485 530
486 if (tx_word_length != rx_word_length) 531 if (tx_word_length != rx_word_length)
487 return -EINVAL; 532 return -EINVAL;
@@ -496,8 +541,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
496 udelay(10); 541 udelay(10);
497 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 542 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
498 udelay(10); 543 udelay(10);
499 dev_err(mcbsp[id].dev, "McBSP%d transmitter not " 544 dev_err(mcbsp->dev, "McBSP%d transmitter not "
500 "ready\n", mcbsp[id].id); 545 "ready\n", mcbsp->id);
501 return -EAGAIN; 546 return -EAGAIN;
502 } 547 }
503 } 548 }
@@ -517,8 +562,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
517 udelay(10); 562 udelay(10);
518 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 563 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
519 udelay(10); 564 udelay(10);
520 dev_err(mcbsp[id].dev, "McBSP%d receiver not " 565 dev_err(mcbsp->dev, "McBSP%d receiver not "
521 "ready\n", mcbsp[id].id); 566 "ready\n", mcbsp->id);
522 return -EAGAIN; 567 return -EAGAIN;
523 } 568 }
524 } 569 }
@@ -534,6 +579,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
534 579
535int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) 580int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
536{ 581{
582 struct omap_mcbsp *mcbsp;
537 u32 clock_word = 0; 583 u32 clock_word = 0;
538 void __iomem *io_base; 584 void __iomem *io_base;
539 omap_mcbsp_word_length tx_word_length; 585 omap_mcbsp_word_length tx_word_length;
@@ -545,9 +591,11 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
545 return -ENODEV; 591 return -ENODEV;
546 } 592 }
547 593
548 io_base = mcbsp[id].io_base; 594 mcbsp = id_to_mcbsp_ptr(id);
549 tx_word_length = mcbsp[id].tx_word_length; 595 io_base = mcbsp->io_base;
550 rx_word_length = mcbsp[id].rx_word_length; 596
597 tx_word_length = mcbsp->tx_word_length;
598 rx_word_length = mcbsp->rx_word_length;
551 599
552 if (tx_word_length != rx_word_length) 600 if (tx_word_length != rx_word_length)
553 return -EINVAL; 601 return -EINVAL;
@@ -562,8 +610,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
562 udelay(10); 610 udelay(10);
563 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 611 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
564 udelay(10); 612 udelay(10);
565 dev_err(mcbsp[id].dev, "McBSP%d transmitter not " 613 dev_err(mcbsp->dev, "McBSP%d transmitter not "
566 "ready\n", mcbsp[id].id); 614 "ready\n", mcbsp->id);
567 return -EAGAIN; 615 return -EAGAIN;
568 } 616 }
569 } 617 }
@@ -583,8 +631,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
583 udelay(10); 631 udelay(10);
584 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 632 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
585 udelay(10); 633 udelay(10);
586 dev_err(mcbsp[id].dev, "McBSP%d receiver not " 634 dev_err(mcbsp->dev, "McBSP%d receiver not "
587 "ready\n", mcbsp[id].id); 635 "ready\n", mcbsp->id);
588 return -EAGAIN; 636 return -EAGAIN;
589 } 637 }
590 } 638 }
@@ -610,6 +658,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
610int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, 658int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
611 unsigned int length) 659 unsigned int length)
612{ 660{
661 struct omap_mcbsp *mcbsp;
613 int dma_tx_ch; 662 int dma_tx_ch;
614 int src_port = 0; 663 int src_port = 0;
615 int dest_port = 0; 664 int dest_port = 0;
@@ -619,50 +668,51 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
619 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 668 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
620 return -ENODEV; 669 return -ENODEV;
621 } 670 }
671 mcbsp = id_to_mcbsp_ptr(id);
622 672
623 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", 673 if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
624 omap_mcbsp_tx_dma_callback, 674 omap_mcbsp_tx_dma_callback,
625 &mcbsp[id], 675 mcbsp,
626 &dma_tx_ch)) { 676 &dma_tx_ch)) {
627 dev_err(mcbsp[id].dev, " Unable to request DMA channel for " 677 dev_err(mcbsp->dev, " Unable to request DMA channel for "
628 "McBSP%d TX. Trying IRQ based TX\n", 678 "McBSP%d TX. Trying IRQ based TX\n",
629 mcbsp[id].id); 679 mcbsp->id);
630 return -EAGAIN; 680 return -EAGAIN;
631 } 681 }
632 mcbsp[id].dma_tx_lch = dma_tx_ch; 682 mcbsp->dma_tx_lch = dma_tx_ch;
633 683
634 dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, 684 dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
635 dma_tx_ch); 685 dma_tx_ch);
636 686
637 init_completion(&(mcbsp[id].tx_dma_completion)); 687 init_completion(&mcbsp->tx_dma_completion);
638 688
639 if (cpu_class_is_omap1()) { 689 if (cpu_class_is_omap1()) {
640 src_port = OMAP_DMA_PORT_TIPB; 690 src_port = OMAP_DMA_PORT_TIPB;
641 dest_port = OMAP_DMA_PORT_EMIFF; 691 dest_port = OMAP_DMA_PORT_EMIFF;
642 } 692 }
643 if (cpu_class_is_omap2()) 693 if (cpu_class_is_omap2())
644 sync_dev = mcbsp[id].dma_tx_sync; 694 sync_dev = mcbsp->dma_tx_sync;
645 695
646 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, 696 omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
647 OMAP_DMA_DATA_TYPE_S16, 697 OMAP_DMA_DATA_TYPE_S16,
648 length >> 1, 1, 698 length >> 1, 1,
649 OMAP_DMA_SYNC_ELEMENT, 699 OMAP_DMA_SYNC_ELEMENT,
650 sync_dev, 0); 700 sync_dev, 0);
651 701
652 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, 702 omap_set_dma_dest_params(mcbsp->dma_tx_lch,
653 src_port, 703 src_port,
654 OMAP_DMA_AMODE_CONSTANT, 704 OMAP_DMA_AMODE_CONSTANT,
655 mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1, 705 mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
656 0, 0); 706 0, 0);
657 707
658 omap_set_dma_src_params(mcbsp[id].dma_tx_lch, 708 omap_set_dma_src_params(mcbsp->dma_tx_lch,
659 dest_port, 709 dest_port,
660 OMAP_DMA_AMODE_POST_INC, 710 OMAP_DMA_AMODE_POST_INC,
661 buffer, 711 buffer,
662 0, 0); 712 0, 0);
663 713
664 omap_start_dma(mcbsp[id].dma_tx_lch); 714 omap_start_dma(mcbsp->dma_tx_lch);
665 wait_for_completion(&(mcbsp[id].tx_dma_completion)); 715 wait_for_completion(&mcbsp->tx_dma_completion);
666 716
667 return 0; 717 return 0;
668} 718}
@@ -671,6 +721,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
671int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, 721int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
672 unsigned int length) 722 unsigned int length)
673{ 723{
724 struct omap_mcbsp *mcbsp;
674 int dma_rx_ch; 725 int dma_rx_ch;
675 int src_port = 0; 726 int src_port = 0;
676 int dest_port = 0; 727 int dest_port = 0;
@@ -680,50 +731,51 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
680 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 731 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
681 return -ENODEV; 732 return -ENODEV;
682 } 733 }
734 mcbsp = id_to_mcbsp_ptr(id);
683 735
684 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", 736 if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
685 omap_mcbsp_rx_dma_callback, 737 omap_mcbsp_rx_dma_callback,
686 &mcbsp[id], 738 mcbsp,
687 &dma_rx_ch)) { 739 &dma_rx_ch)) {
688 dev_err(mcbsp[id].dev, "Unable to request DMA channel for " 740 dev_err(mcbsp->dev, "Unable to request DMA channel for "
689 "McBSP%d RX. Trying IRQ based RX\n", 741 "McBSP%d RX. Trying IRQ based RX\n",
690 mcbsp[id].id); 742 mcbsp->id);
691 return -EAGAIN; 743 return -EAGAIN;
692 } 744 }
693 mcbsp[id].dma_rx_lch = dma_rx_ch; 745 mcbsp->dma_rx_lch = dma_rx_ch;
694 746
695 dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, 747 dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
696 dma_rx_ch); 748 dma_rx_ch);
697 749
698 init_completion(&(mcbsp[id].rx_dma_completion)); 750 init_completion(&mcbsp->rx_dma_completion);
699 751
700 if (cpu_class_is_omap1()) { 752 if (cpu_class_is_omap1()) {
701 src_port = OMAP_DMA_PORT_TIPB; 753 src_port = OMAP_DMA_PORT_TIPB;
702 dest_port = OMAP_DMA_PORT_EMIFF; 754 dest_port = OMAP_DMA_PORT_EMIFF;
703 } 755 }
704 if (cpu_class_is_omap2()) 756 if (cpu_class_is_omap2())
705 sync_dev = mcbsp[id].dma_rx_sync; 757 sync_dev = mcbsp->dma_rx_sync;
706 758
707 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 759 omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
708 OMAP_DMA_DATA_TYPE_S16, 760 OMAP_DMA_DATA_TYPE_S16,
709 length >> 1, 1, 761 length >> 1, 1,
710 OMAP_DMA_SYNC_ELEMENT, 762 OMAP_DMA_SYNC_ELEMENT,
711 sync_dev, 0); 763 sync_dev, 0);
712 764
713 omap_set_dma_src_params(mcbsp[id].dma_rx_lch, 765 omap_set_dma_src_params(mcbsp->dma_rx_lch,
714 src_port, 766 src_port,
715 OMAP_DMA_AMODE_CONSTANT, 767 OMAP_DMA_AMODE_CONSTANT,
716 mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1, 768 mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
717 0, 0); 769 0, 0);
718 770
719 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, 771 omap_set_dma_dest_params(mcbsp->dma_rx_lch,
720 dest_port, 772 dest_port,
721 OMAP_DMA_AMODE_POST_INC, 773 OMAP_DMA_AMODE_POST_INC,
722 buffer, 774 buffer,
723 0, 0); 775 0, 0);
724 776
725 omap_start_dma(mcbsp[id].dma_rx_lch); 777 omap_start_dma(mcbsp->dma_rx_lch);
726 wait_for_completion(&(mcbsp[id].rx_dma_completion)); 778 wait_for_completion(&mcbsp->rx_dma_completion);
727 779
728 return 0; 780 return 0;
729} 781}
@@ -738,12 +790,14 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
738void omap_mcbsp_set_spi_mode(unsigned int id, 790void omap_mcbsp_set_spi_mode(unsigned int id,
739 const struct omap_mcbsp_spi_cfg *spi_cfg) 791 const struct omap_mcbsp_spi_cfg *spi_cfg)
740{ 792{
793 struct omap_mcbsp *mcbsp;
741 struct omap_mcbsp_reg_cfg mcbsp_cfg; 794 struct omap_mcbsp_reg_cfg mcbsp_cfg;
742 795
743 if (!omap_mcbsp_check_valid_id(id)) { 796 if (!omap_mcbsp_check_valid_id(id)) {
744 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 797 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
745 return; 798 return;
746 } 799 }
800 mcbsp = id_to_mcbsp_ptr(id);
747 801
748 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); 802 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
749 803
@@ -807,6 +861,7 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
807static int __devinit omap_mcbsp_probe(struct platform_device *pdev) 861static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
808{ 862{
809 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; 863 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
864 struct omap_mcbsp *mcbsp;
810 int id = pdev->id - 1; 865 int id = pdev->id - 1;
811 int ret = 0; 866 int ret = 0;
812 867
@@ -819,51 +874,58 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
819 874
820 dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); 875 dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
821 876
822 if (id >= OMAP_MAX_MCBSP_COUNT) { 877 if (id >= omap_mcbsp_count) {
823 dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); 878 dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
824 ret = -EINVAL; 879 ret = -EINVAL;
825 goto exit; 880 goto exit;
826 } 881 }
827 882
828 spin_lock_init(&mcbsp[id].lock); 883 mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
829 mcbsp[id].id = id + 1; 884 if (!mcbsp) {
830 mcbsp[id].free = 1; 885 ret = -ENOMEM;
831 mcbsp[id].dma_tx_lch = -1; 886 goto exit;
832 mcbsp[id].dma_rx_lch = -1; 887 }
888 mcbsp_ptr[id] = mcbsp;
889
890 spin_lock_init(&mcbsp->lock);
891 mcbsp->id = id + 1;
892 mcbsp->free = 1;
893 mcbsp->dma_tx_lch = -1;
894 mcbsp->dma_rx_lch = -1;
833 895
834 mcbsp[id].phys_base = pdata->phys_base; 896 mcbsp->phys_base = pdata->phys_base;
835 mcbsp[id].io_base = ioremap(pdata->phys_base, SZ_4K); 897 mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
836 if (!mcbsp[id].io_base) { 898 if (!mcbsp->io_base) {
837 ret = -ENOMEM; 899 ret = -ENOMEM;
838 goto err_ioremap; 900 goto err_ioremap;
839 } 901 }
840 902
841 /* Default I/O is IRQ based */ 903 /* Default I/O is IRQ based */
842 mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; 904 mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
843 mcbsp[id].tx_irq = pdata->tx_irq; 905 mcbsp->tx_irq = pdata->tx_irq;
844 mcbsp[id].rx_irq = pdata->rx_irq; 906 mcbsp->rx_irq = pdata->rx_irq;
845 mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; 907 mcbsp->dma_rx_sync = pdata->dma_rx_sync;
846 mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; 908 mcbsp->dma_tx_sync = pdata->dma_tx_sync;
847 909
848 if (pdata->clk_name) 910 if (pdata->clk_name)
849 mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); 911 mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name);
850 if (IS_ERR(mcbsp[id].clk)) { 912 if (IS_ERR(mcbsp->clk)) {
851 dev_err(&pdev->dev, 913 dev_err(&pdev->dev,
852 "Invalid clock configuration for McBSP%d.\n", 914 "Invalid clock configuration for McBSP%d.\n",
853 mcbsp[id].id); 915 mcbsp->id);
854 ret = PTR_ERR(mcbsp[id].clk); 916 ret = PTR_ERR(mcbsp->clk);
855 goto err_clk; 917 goto err_clk;
856 } 918 }
857 919
858 mcbsp[id].pdata = pdata; 920 mcbsp->pdata = pdata;
859 mcbsp[id].dev = &pdev->dev; 921 mcbsp->dev = &pdev->dev;
860 platform_set_drvdata(pdev, &mcbsp[id]); 922 platform_set_drvdata(pdev, mcbsp);
861 return 0; 923 return 0;
862 924
863err_clk: 925err_clk:
864 iounmap(mcbsp[id].io_base); 926 iounmap(mcbsp->io_base);
865err_ioremap: 927err_ioremap:
866 mcbsp[id].free = 0; 928 mcbsp->free = 0;
867exit: 929exit:
868 return ret; 930 return ret;
869} 931}