linux/arch/arm/plat-omap/mcbsp.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/plat-omap/mcbsp.c
   3 *
   4 * Copyright (C) 2004 Nokia Corporation
   5 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
   6 *
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * Multichannel mode not supported.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/init.h>
  17#include <linux/device.h>
  18#include <linux/platform_device.h>
  19#include <linux/wait.h>
  20#include <linux/completion.h>
  21#include <linux/interrupt.h>
  22#include <linux/err.h>
  23#include <linux/clk.h>
  24#include <linux/delay.h>
  25#include <linux/io.h>
  26
  27#include <mach/dma.h>
  28#include <mach/mcbsp.h>
  29
  30struct omap_mcbsp **mcbsp_ptr;
  31int omap_mcbsp_count;
  32
  33void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
  34{
  35        if (cpu_class_is_omap1() || cpu_is_omap2420())
  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];
  56
  57static void omap_mcbsp_dump_reg(u8 id)
  58{
  59        struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
  60
  61        dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
  62        dev_dbg(mcbsp->dev, "DRR2:  0x%04x\n",
  63                        OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
  64        dev_dbg(mcbsp->dev, "DRR1:  0x%04x\n",
  65                        OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
  66        dev_dbg(mcbsp->dev, "DXR2:  0x%04x\n",
  67                        OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
  68        dev_dbg(mcbsp->dev, "DXR1:  0x%04x\n",
  69                        OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
  70        dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
  71                        OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
  72        dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
  73                        OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
  74        dev_dbg(mcbsp->dev, "RCR2:  0x%04x\n",
  75                        OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
  76        dev_dbg(mcbsp->dev, "RCR1:  0x%04x\n",
  77                        OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
  78        dev_dbg(mcbsp->dev, "XCR2:  0x%04x\n",
  79                        OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
  80        dev_dbg(mcbsp->dev, "XCR1:  0x%04x\n",
  81                        OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
  82        dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
  83                        OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
  84        dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
  85                        OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
  86        dev_dbg(mcbsp->dev, "PCR0:  0x%04x\n",
  87                        OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
  88        dev_dbg(mcbsp->dev, "***********************\n");
  89}
  90
  91static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
  92{
  93        struct omap_mcbsp *mcbsp_tx = dev_id;
  94        u16 irqst_spcr2;
  95
  96        irqst_spcr2 = OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2);
  97        dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
  98
  99        if (irqst_spcr2 & XSYNC_ERR) {
 100                dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
 101                        irqst_spcr2);
 102                /* Writing zero to XSYNC_ERR clears the IRQ */
 103                OMAP_MCBSP_WRITE(mcbsp_tx->io_base, SPCR2,
 104                        irqst_spcr2 & ~(XSYNC_ERR));
 105        } else {
 106                complete(&mcbsp_tx->tx_irq_completion);
 107        }
 108
 109        return IRQ_HANDLED;
 110}
 111
 112static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
 113{
 114        struct omap_mcbsp *mcbsp_rx = dev_id;
 115        u16 irqst_spcr1;
 116
 117        irqst_spcr1 = OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR1);
 118        dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
 119
 120        if (irqst_spcr1 & RSYNC_ERR) {
 121                dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
 122                        irqst_spcr1);
 123                /* Writing zero to RSYNC_ERR clears the IRQ */
 124                OMAP_MCBSP_WRITE(mcbsp_rx->io_base, SPCR1,
 125                        irqst_spcr1 & ~(RSYNC_ERR));
 126        } else {
 127                complete(&mcbsp_rx->tx_irq_completion);
 128        }
 129
 130        return IRQ_HANDLED;
 131}
 132
 133static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
 134{
 135        struct omap_mcbsp *mcbsp_dma_tx = data;
 136
 137        dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
 138                OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
 139
 140        /* We can free the channels */
 141        omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
 142        mcbsp_dma_tx->dma_tx_lch = -1;
 143
 144        complete(&mcbsp_dma_tx->tx_dma_completion);
 145}
 146
 147static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
 148{
 149        struct omap_mcbsp *mcbsp_dma_rx = data;
 150
 151        dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
 152                OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
 153
 154        /* We can free the channels */
 155        omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
 156        mcbsp_dma_rx->dma_rx_lch = -1;
 157
 158        complete(&mcbsp_dma_rx->rx_dma_completion);
 159}
 160
 161/*
 162 * omap_mcbsp_config simply write a config to the
 163 * appropriate McBSP.
 164 * You either call this function or set the McBSP registers
 165 * by yourself before calling omap_mcbsp_start().
 166 */
 167void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
 168{
 169        struct omap_mcbsp *mcbsp;
 170        void __iomem *io_base;
 171
 172        if (!omap_mcbsp_check_valid_id(id)) {
 173                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 174                return;
 175        }
 176        mcbsp = id_to_mcbsp_ptr(id);
 177
 178        io_base = mcbsp->io_base;
 179        dev_dbg(mcbsp->dev, "Configuring McBSP%d  phys_base: 0x%08lx\n",
 180                        mcbsp->id, mcbsp->phys_base);
 181
 182        /* We write the given config */
 183        OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
 184        OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
 185        OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
 186        OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
 187        OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
 188        OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
 189        OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
 190        OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
 191        OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
 192        OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
 193        OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
 194        if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
 195                OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr);
 196                OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr);
 197        }
 198}
 199EXPORT_SYMBOL(omap_mcbsp_config);
 200
 201#ifdef CONFIG_ARCH_OMAP34XX
 202/*
 203 * omap_mcbsp_set_tx_threshold configures how to deal
 204 * with transmit threshold. the threshold value and handler can be
 205 * configure in here.
 206 */
 207void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
 208{
 209        struct omap_mcbsp *mcbsp;
 210        void __iomem *io_base;
 211
 212        if (!cpu_is_omap34xx())
 213                return;
 214
 215        if (!omap_mcbsp_check_valid_id(id)) {
 216                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 217                return;
 218        }
 219        mcbsp = id_to_mcbsp_ptr(id);
 220        io_base = mcbsp->io_base;
 221
 222        OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
 223}
 224EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
 225
 226/*
 227 * omap_mcbsp_set_rx_threshold configures how to deal
 228 * with receive threshold. the threshold value and handler can be
 229 * configure in here.
 230 */
 231void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
 232{
 233        struct omap_mcbsp *mcbsp;
 234        void __iomem *io_base;
 235
 236        if (!cpu_is_omap34xx())
 237                return;
 238
 239        if (!omap_mcbsp_check_valid_id(id)) {
 240                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 241                return;
 242        }
 243        mcbsp = id_to_mcbsp_ptr(id);
 244        io_base = mcbsp->io_base;
 245
 246        OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
 247}
 248EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
 249
 250/*
 251 * omap_mcbsp_get_max_tx_thres just return the current configured
 252 * maximum threshold for transmission
 253 */
 254u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
 255{
 256        struct omap_mcbsp *mcbsp;
 257
 258        if (!omap_mcbsp_check_valid_id(id)) {
 259                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 260                return -ENODEV;
 261        }
 262        mcbsp = id_to_mcbsp_ptr(id);
 263
 264        return mcbsp->max_tx_thres;
 265}
 266EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
 267
 268/*
 269 * omap_mcbsp_get_max_rx_thres just return the current configured
 270 * maximum threshold for reception
 271 */
 272u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
 273{
 274        struct omap_mcbsp *mcbsp;
 275
 276        if (!omap_mcbsp_check_valid_id(id)) {
 277                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 278                return -ENODEV;
 279        }
 280        mcbsp = id_to_mcbsp_ptr(id);
 281
 282        return mcbsp->max_rx_thres;
 283}
 284EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
 285
 286/*
 287 * omap_mcbsp_get_dma_op_mode just return the current configured
 288 * operating mode for the mcbsp channel
 289 */
 290int omap_mcbsp_get_dma_op_mode(unsigned int id)
 291{
 292        struct omap_mcbsp *mcbsp;
 293        int dma_op_mode;
 294
 295        if (!omap_mcbsp_check_valid_id(id)) {
 296                printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
 297                return -ENODEV;
 298        }
 299        mcbsp = id_to_mcbsp_ptr(id);
 300
 301        spin_lock_irq(&mcbsp->lock);
 302        dma_op_mode = mcbsp->dma_op_mode;
 303        spin_unlock_irq(&mcbsp->lock);
 304
 305        return dma_op_mode;
 306}
 307EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
 308
 309static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
 310{
 311        /*
 312         * Enable wakup behavior, smart idle and all wakeups
 313         * REVISIT: some wakeups may be unnecessary
 314         */
 315        if (cpu_is_omap34xx()) {
 316                u16 syscon;
 317
 318                syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
 319                syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 320
 321                spin_lock_irq(&mcbsp->lock);
 322                if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
 323                        syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
 324                                        CLOCKACTIVITY(0x02));
 325                        OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN,
 326                                        XRDYEN | RRDYEN);
 327                } else {
 328                        syscon |= SIDLEMODE(0x01);
 329                }
 330                spin_unlock_irq(&mcbsp->lock);
 331
 332                OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 333        }
 334}
 335
 336static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
 337{
 338        /*
 339         * Disable wakup behavior, smart idle and all wakeups
 340         */
 341        if (cpu_is_omap34xx()) {
 342                u16 syscon;
 343
 344                syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
 345                syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 346                /*
 347                 * HW bug workaround - If no_idle mode is taken, we need to
 348                 * go to smart_idle before going to always_idle, or the
 349                 * device will not hit retention anymore.
 350                 */
 351                syscon |= SIDLEMODE(0x02);
 352                OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 353
 354                syscon &= ~(SIDLEMODE(0x03));
 355                OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 356
 357                OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);
 358        }
 359}
 360#else
 361static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
 362static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
 363#endif
 364
 365/*
 366 * We can choose between IRQ based or polled IO.
 367 * This needs to be called before omap_mcbsp_request().
 368 */
 369int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
 370{
 371        struct omap_mcbsp *mcbsp;
 372
 373        if (!omap_mcbsp_check_valid_id(id)) {
 374                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 375                return -ENODEV;
 376        }
 377        mcbsp = id_to_mcbsp_ptr(id);
 378
 379        spin_lock(&mcbsp->lock);
 380
 381        if (!mcbsp->free) {
 382                dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
 383                        mcbsp->id);
 384                spin_unlock(&mcbsp->lock);
 385                return -EINVAL;
 386        }
 387
 388        mcbsp->io_type = io_type;
 389
 390        spin_unlock(&mcbsp->lock);
 391
 392        return 0;
 393}
 394EXPORT_SYMBOL(omap_mcbsp_set_io_type);
 395
 396int omap_mcbsp_request(unsigned int id)
 397{
 398        struct omap_mcbsp *mcbsp;
 399        int err;
 400
 401        if (!omap_mcbsp_check_valid_id(id)) {
 402                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 403                return -ENODEV;
 404        }
 405        mcbsp = id_to_mcbsp_ptr(id);
 406
 407        spin_lock(&mcbsp->lock);
 408        if (!mcbsp->free) {
 409                dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
 410                        mcbsp->id);
 411                spin_unlock(&mcbsp->lock);
 412                return -EBUSY;
 413        }
 414
 415        mcbsp->free = 0;
 416        spin_unlock(&mcbsp->lock);
 417
 418        if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
 419                mcbsp->pdata->ops->request(id);
 420
 421        clk_enable(mcbsp->iclk);
 422        clk_enable(mcbsp->fclk);
 423
 424        /* Do procedure specific to omap34xx arch, if applicable */
 425        omap34xx_mcbsp_request(mcbsp);
 426
 427        /*
 428         * Make sure that transmitter, receiver and sample-rate generator are
 429         * not running before activating IRQs.
 430         */
 431        OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0);
 432        OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0);
 433
 434        if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
 435                /* We need to get IRQs here */
 436                init_completion(&mcbsp->tx_irq_completion);
 437                err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
 438                                        0, "McBSP", (void *)mcbsp);
 439                if (err != 0) {
 440                        dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
 441                                        "for McBSP%d\n", mcbsp->tx_irq,
 442                                        mcbsp->id);
 443                        return err;
 444                }
 445
 446                init_completion(&mcbsp->rx_irq_completion);
 447                err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler,
 448                                        0, "McBSP", (void *)mcbsp);
 449                if (err != 0) {
 450                        dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
 451                                        "for McBSP%d\n", mcbsp->rx_irq,
 452                                        mcbsp->id);
 453                        free_irq(mcbsp->tx_irq, (void *)mcbsp);
 454                        return err;
 455                }
 456        }
 457
 458        return 0;
 459}
 460EXPORT_SYMBOL(omap_mcbsp_request);
 461
 462void omap_mcbsp_free(unsigned int id)
 463{
 464        struct omap_mcbsp *mcbsp;
 465
 466        if (!omap_mcbsp_check_valid_id(id)) {
 467                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 468                return;
 469        }
 470        mcbsp = id_to_mcbsp_ptr(id);
 471
 472        if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
 473                mcbsp->pdata->ops->free(id);
 474
 475        /* Do procedure specific to omap34xx arch, if applicable */
 476        omap34xx_mcbsp_free(mcbsp);
 477
 478        clk_disable(mcbsp->fclk);
 479        clk_disable(mcbsp->iclk);
 480
 481        if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
 482                /* Free IRQs */
 483                free_irq(mcbsp->rx_irq, (void *)mcbsp);
 484                free_irq(mcbsp->tx_irq, (void *)mcbsp);
 485        }
 486
 487        spin_lock(&mcbsp->lock);
 488        if (mcbsp->free) {
 489                dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
 490                        mcbsp->id);
 491                spin_unlock(&mcbsp->lock);
 492                return;
 493        }
 494
 495        mcbsp->free = 1;
 496        spin_unlock(&mcbsp->lock);
 497}
 498EXPORT_SYMBOL(omap_mcbsp_free);
 499
 500/*
 501 * Here we start the McBSP, by enabling transmitter, receiver or both.
 502 * If no transmitter or receiver is active prior calling, then sample-rate
 503 * generator and frame sync are started.
 504 */
 505void omap_mcbsp_start(unsigned int id, int tx, int rx)
 506{
 507        struct omap_mcbsp *mcbsp;
 508        void __iomem *io_base;
 509        int idle;
 510        u16 w;
 511
 512        if (!omap_mcbsp_check_valid_id(id)) {
 513                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 514                return;
 515        }
 516        mcbsp = id_to_mcbsp_ptr(id);
 517        io_base = mcbsp->io_base;
 518
 519        mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
 520        mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
 521
 522        idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
 523                  OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
 524
 525        if (idle) {
 526                /* Start the sample generator */
 527                w = OMAP_MCBSP_READ(io_base, SPCR2);
 528                OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
 529        }
 530
 531        /* Enable transmitter and receiver */
 532        tx &= 1;
 533        w = OMAP_MCBSP_READ(io_base, SPCR2);
 534        OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);
 535
 536        rx &= 1;
 537        w = OMAP_MCBSP_READ(io_base, SPCR1);
 538        OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx);
 539
 540        /*
 541         * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
 542         * REVISIT: 100us may give enough time for two CLKSRG, however
 543         * due to some unknown PM related, clock gating etc. reason it
 544         * is now at 500us.
 545         */
 546        udelay(500);
 547
 548        if (idle) {
 549                /* Start frame sync */
 550                w = OMAP_MCBSP_READ(io_base, SPCR2);
 551                OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
 552        }
 553
 554        if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 555                /* Release the transmitter and receiver */
 556                w = OMAP_MCBSP_READ(io_base, XCCR);
 557                w &= ~(tx ? XDISABLE : 0);
 558                OMAP_MCBSP_WRITE(io_base, XCCR, w);
 559                w = OMAP_MCBSP_READ(io_base, RCCR);
 560                w &= ~(rx ? RDISABLE : 0);
 561                OMAP_MCBSP_WRITE(io_base, RCCR, w);
 562        }
 563
 564        /* Dump McBSP Regs */
 565        omap_mcbsp_dump_reg(id);
 566}
 567EXPORT_SYMBOL(omap_mcbsp_start);
 568
 569void omap_mcbsp_stop(unsigned int id, int tx, int rx)
 570{
 571        struct omap_mcbsp *mcbsp;
 572        void __iomem *io_base;
 573        int idle;
 574        u16 w;
 575
 576        if (!omap_mcbsp_check_valid_id(id)) {
 577                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 578                return;
 579        }
 580
 581        mcbsp = id_to_mcbsp_ptr(id);
 582        io_base = mcbsp->io_base;
 583
 584        /* Reset transmitter */
 585        tx &= 1;
 586        if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 587                w = OMAP_MCBSP_READ(io_base, XCCR);
 588                w |= (tx ? XDISABLE : 0);
 589                OMAP_MCBSP_WRITE(io_base, XCCR, w);
 590        }
 591        w = OMAP_MCBSP_READ(io_base, SPCR2);
 592        OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx);
 593
 594        /* Reset receiver */
 595        rx &= 1;
 596        if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 597                w = OMAP_MCBSP_READ(io_base, RCCR);
 598                w |= (rx ? RDISABLE : 0);
 599                OMAP_MCBSP_WRITE(io_base, RCCR, w);
 600        }
 601        w = OMAP_MCBSP_READ(io_base, SPCR1);
 602        OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx);
 603
 604        idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
 605                  OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
 606
 607        if (idle) {
 608                /* Reset the sample rate generator */
 609                w = OMAP_MCBSP_READ(io_base, SPCR2);
 610                OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
 611        }
 612}
 613EXPORT_SYMBOL(omap_mcbsp_stop);
 614
 615/* polled mcbsp i/o operations */
 616int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
 617{
 618        struct omap_mcbsp *mcbsp;
 619        void __iomem *base;
 620
 621        if (!omap_mcbsp_check_valid_id(id)) {
 622                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 623                return -ENODEV;
 624        }
 625
 626        mcbsp = id_to_mcbsp_ptr(id);
 627        base = mcbsp->io_base;
 628
 629        writew(buf, base + OMAP_MCBSP_REG_DXR1);
 630        /* if frame sync error - clear the error */
 631        if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
 632                /* clear error */
 633                writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
 634                       base + OMAP_MCBSP_REG_SPCR2);
 635                /* resend */
 636                return -1;
 637        } else {
 638                /* wait for transmit confirmation */
 639                int attemps = 0;
 640                while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
 641                        if (attemps++ > 1000) {
 642                                writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
 643                                       (~XRST),
 644                                       base + OMAP_MCBSP_REG_SPCR2);
 645                                udelay(10);
 646                                writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
 647                                       (XRST),
 648                                       base + OMAP_MCBSP_REG_SPCR2);
 649                                udelay(10);
 650                                dev_err(mcbsp->dev, "Could not write to"
 651                                        " McBSP%d Register\n", mcbsp->id);
 652                                return -2;
 653                        }
 654                }
 655        }
 656
 657        return 0;
 658}
 659EXPORT_SYMBOL(omap_mcbsp_pollwrite);
 660
 661int omap_mcbsp_pollread(unsigned int id, u16 *buf)
 662{
 663        struct omap_mcbsp *mcbsp;
 664        void __iomem *base;
 665
 666        if (!omap_mcbsp_check_valid_id(id)) {
 667                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 668                return -ENODEV;
 669        }
 670        mcbsp = id_to_mcbsp_ptr(id);
 671
 672        base = mcbsp->io_base;
 673        /* if frame sync error - clear the error */
 674        if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
 675                /* clear error */
 676                writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
 677                       base + OMAP_MCBSP_REG_SPCR1);
 678                /* resend */
 679                return -1;
 680        } else {
 681                /* wait for recieve confirmation */
 682                int attemps = 0;
 683                while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
 684                        if (attemps++ > 1000) {
 685                                writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
 686                                       (~RRST),
 687                                       base + OMAP_MCBSP_REG_SPCR1);
 688                                udelay(10);
 689                                writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
 690                                       (RRST),
 691                                       base + OMAP_MCBSP_REG_SPCR1);
 692                                udelay(10);
 693                                dev_err(mcbsp->dev, "Could not read from"
 694                                        " McBSP%d Register\n", mcbsp->id);
 695                                return -2;
 696                        }
 697                }
 698        }
 699        *buf = readw(base + OMAP_MCBSP_REG_DRR1);
 700
 701        return 0;
 702}
 703EXPORT_SYMBOL(omap_mcbsp_pollread);
 704
 705/*
 706 * IRQ based word transmission.
 707 */
 708void omap_mcbsp_xmit_word(unsigned int id, u32 word)
 709{
 710        struct omap_mcbsp *mcbsp;
 711        void __iomem *io_base;
 712        omap_mcbsp_word_length word_length;
 713
 714        if (!omap_mcbsp_check_valid_id(id)) {
 715                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 716                return;
 717        }
 718
 719        mcbsp = id_to_mcbsp_ptr(id);
 720        io_base = mcbsp->io_base;
 721        word_length = mcbsp->tx_word_length;
 722
 723        wait_for_completion(&mcbsp->tx_irq_completion);
 724
 725        if (word_length > OMAP_MCBSP_WORD_16)
 726                OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
 727        OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
 728}
 729EXPORT_SYMBOL(omap_mcbsp_xmit_word);
 730
 731u32 omap_mcbsp_recv_word(unsigned int id)
 732{
 733        struct omap_mcbsp *mcbsp;
 734        void __iomem *io_base;
 735        u16 word_lsb, word_msb = 0;
 736        omap_mcbsp_word_length word_length;
 737
 738        if (!omap_mcbsp_check_valid_id(id)) {
 739                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 740                return -ENODEV;
 741        }
 742        mcbsp = id_to_mcbsp_ptr(id);
 743
 744        word_length = mcbsp->rx_word_length;
 745        io_base = mcbsp->io_base;
 746
 747        wait_for_completion(&mcbsp->rx_irq_completion);
 748
 749        if (word_length > OMAP_MCBSP_WORD_16)
 750                word_msb = OMAP_MCBSP_READ(io_base, DRR2);
 751        word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
 752
 753        return (word_lsb | (word_msb << 16));
 754}
 755EXPORT_SYMBOL(omap_mcbsp_recv_word);
 756
 757int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
 758{
 759        struct omap_mcbsp *mcbsp;
 760        void __iomem *io_base;
 761        omap_mcbsp_word_length tx_word_length;
 762        omap_mcbsp_word_length rx_word_length;
 763        u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
 764
 765        if (!omap_mcbsp_check_valid_id(id)) {
 766                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 767                return -ENODEV;
 768        }
 769        mcbsp = id_to_mcbsp_ptr(id);
 770        io_base = mcbsp->io_base;
 771        tx_word_length = mcbsp->tx_word_length;
 772        rx_word_length = mcbsp->rx_word_length;
 773
 774        if (tx_word_length != rx_word_length)
 775                return -EINVAL;
 776
 777        /* First we wait for the transmitter to be ready */
 778        spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
 779        while (!(spcr2 & XRDY)) {
 780                spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
 781                if (attempts++ > 1000) {
 782                        /* We must reset the transmitter */
 783                        OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
 784                        udelay(10);
 785                        OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
 786                        udelay(10);
 787                        dev_err(mcbsp->dev, "McBSP%d transmitter not "
 788                                "ready\n", mcbsp->id);
 789                        return -EAGAIN;
 790                }
 791        }
 792
 793        /* Now we can push the data */
 794        if (tx_word_length > OMAP_MCBSP_WORD_16)
 795                OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
 796        OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
 797
 798        /* We wait for the receiver to be ready */
 799        spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
 800        while (!(spcr1 & RRDY)) {
 801                spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
 802                if (attempts++ > 1000) {
 803                        /* We must reset the receiver */
 804                        OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
 805                        udelay(10);
 806                        OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
 807                        udelay(10);
 808                        dev_err(mcbsp->dev, "McBSP%d receiver not "
 809                                "ready\n", mcbsp->id);
 810                        return -EAGAIN;
 811                }
 812        }
 813
 814        /* Receiver is ready, let's read the dummy data */
 815        if (rx_word_length > OMAP_MCBSP_WORD_16)
 816                word_msb = OMAP_MCBSP_READ(io_base, DRR2);
 817        word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
 818
 819        return 0;
 820}
 821EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
 822
 823int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
 824{
 825        struct omap_mcbsp *mcbsp;
 826        u32 clock_word = 0;
 827        void __iomem *io_base;
 828        omap_mcbsp_word_length tx_word_length;
 829        omap_mcbsp_word_length rx_word_length;
 830        u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
 831
 832        if (!omap_mcbsp_check_valid_id(id)) {
 833                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 834                return -ENODEV;
 835        }
 836
 837        mcbsp = id_to_mcbsp_ptr(id);
 838        io_base = mcbsp->io_base;
 839
 840        tx_word_length = mcbsp->tx_word_length;
 841        rx_word_length = mcbsp->rx_word_length;
 842
 843        if (tx_word_length != rx_word_length)
 844                return -EINVAL;
 845
 846        /* First we wait for the transmitter to be ready */
 847        spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
 848        while (!(spcr2 & XRDY)) {
 849                spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
 850                if (attempts++ > 1000) {
 851                        /* We must reset the transmitter */
 852                        OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
 853                        udelay(10);
 854                        OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
 855                        udelay(10);
 856                        dev_err(mcbsp->dev, "McBSP%d transmitter not "
 857                                "ready\n", mcbsp->id);
 858                        return -EAGAIN;
 859                }
 860        }
 861
 862        /* We first need to enable the bus clock */
 863        if (tx_word_length > OMAP_MCBSP_WORD_16)
 864                OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
 865        OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
 866
 867        /* We wait for the receiver to be ready */
 868        spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
 869        while (!(spcr1 & RRDY)) {
 870                spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
 871                if (attempts++ > 1000) {
 872                        /* We must reset the receiver */
 873                        OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
 874                        udelay(10);
 875                        OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
 876                        udelay(10);
 877                        dev_err(mcbsp->dev, "McBSP%d receiver not "
 878                                "ready\n", mcbsp->id);
 879                        return -EAGAIN;
 880                }
 881        }
 882
 883        /* Receiver is ready, there is something for us */
 884        if (rx_word_length > OMAP_MCBSP_WORD_16)
 885                word_msb = OMAP_MCBSP_READ(io_base, DRR2);
 886        word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
 887
 888        word[0] = (word_lsb | (word_msb << 16));
 889
 890        return 0;
 891}
 892EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
 893
 894/*
 895 * Simple DMA based buffer rx/tx routines.
 896 * Nothing fancy, just a single buffer tx/rx through DMA.
 897 * The DMA resources are released once the transfer is done.
 898 * For anything fancier, you should use your own customized DMA
 899 * routines and callbacks.
 900 */
 901int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
 902                                unsigned int length)
 903{
 904        struct omap_mcbsp *mcbsp;
 905        int dma_tx_ch;
 906        int src_port = 0;
 907        int dest_port = 0;
 908        int sync_dev = 0;
 909
 910        if (!omap_mcbsp_check_valid_id(id)) {
 911                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 912                return -ENODEV;
 913        }
 914        mcbsp = id_to_mcbsp_ptr(id);
 915
 916        if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
 917                                omap_mcbsp_tx_dma_callback,
 918                                mcbsp,
 919                                &dma_tx_ch)) {
 920                dev_err(mcbsp->dev, " Unable to request DMA channel for "
 921                                "McBSP%d TX. Trying IRQ based TX\n",
 922                                mcbsp->id);
 923                return -EAGAIN;
 924        }
 925        mcbsp->dma_tx_lch = dma_tx_ch;
 926
 927        dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
 928                dma_tx_ch);
 929
 930        init_completion(&mcbsp->tx_dma_completion);
 931
 932        if (cpu_class_is_omap1()) {
 933                src_port = OMAP_DMA_PORT_TIPB;
 934                dest_port = OMAP_DMA_PORT_EMIFF;
 935        }
 936        if (cpu_class_is_omap2())
 937                sync_dev = mcbsp->dma_tx_sync;
 938
 939        omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
 940                                     OMAP_DMA_DATA_TYPE_S16,
 941                                     length >> 1, 1,
 942                                     OMAP_DMA_SYNC_ELEMENT,
 943         sync_dev, 0);
 944
 945        omap_set_dma_dest_params(mcbsp->dma_tx_lch,
 946                                 src_port,
 947                                 OMAP_DMA_AMODE_CONSTANT,
 948                                 mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
 949                                 0, 0);
 950
 951        omap_set_dma_src_params(mcbsp->dma_tx_lch,
 952                                dest_port,
 953                                OMAP_DMA_AMODE_POST_INC,
 954                                buffer,
 955                                0, 0);
 956
 957        omap_start_dma(mcbsp->dma_tx_lch);
 958        wait_for_completion(&mcbsp->tx_dma_completion);
 959
 960        return 0;
 961}
 962EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
 963
 964int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
 965                                unsigned int length)
 966{
 967        struct omap_mcbsp *mcbsp;
 968        int dma_rx_ch;
 969        int src_port = 0;
 970        int dest_port = 0;
 971        int sync_dev = 0;
 972
 973        if (!omap_mcbsp_check_valid_id(id)) {
 974                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 975                return -ENODEV;
 976        }
 977        mcbsp = id_to_mcbsp_ptr(id);
 978
 979        if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
 980                                omap_mcbsp_rx_dma_callback,
 981                                mcbsp,
 982                                &dma_rx_ch)) {
 983                dev_err(mcbsp->dev, "Unable to request DMA channel for "
 984                                "McBSP%d RX. Trying IRQ based RX\n",
 985                                mcbsp->id);
 986                return -EAGAIN;
 987        }
 988        mcbsp->dma_rx_lch = dma_rx_ch;
 989
 990        dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
 991                dma_rx_ch);
 992
 993        init_completion(&mcbsp->rx_dma_completion);
 994
 995        if (cpu_class_is_omap1()) {
 996                src_port = OMAP_DMA_PORT_TIPB;
 997                dest_port = OMAP_DMA_PORT_EMIFF;
 998        }
 999        if (cpu_class_is_omap2())
1000                sync_dev = mcbsp->dma_rx_sync;
1001
1002        omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
1003                                        OMAP_DMA_DATA_TYPE_S16,
1004                                        length >> 1, 1,
1005                                        OMAP_DMA_SYNC_ELEMENT,
1006                                        sync_dev, 0);
1007
1008        omap_set_dma_src_params(mcbsp->dma_rx_lch,
1009                                src_port,
1010                                OMAP_DMA_AMODE_CONSTANT,
1011                                mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
1012                                0, 0);
1013
1014        omap_set_dma_dest_params(mcbsp->dma_rx_lch,
1015                                        dest_port,
1016                                        OMAP_DMA_AMODE_POST_INC,
1017                                        buffer,
1018                                        0, 0);
1019
1020        omap_start_dma(mcbsp->dma_rx_lch);
1021        wait_for_completion(&mcbsp->rx_dma_completion);
1022
1023        return 0;
1024}
1025EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
1026
1027/*
1028 * SPI wrapper.
1029 * Since SPI setup is much simpler than the generic McBSP one,
1030 * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
1031 * Once this is done, you can call omap_mcbsp_start().
1032 */
1033void omap_mcbsp_set_spi_mode(unsigned int id,
1034                                const struct omap_mcbsp_spi_cfg *spi_cfg)
1035{
1036        struct omap_mcbsp *mcbsp;
1037        struct omap_mcbsp_reg_cfg mcbsp_cfg;
1038
1039        if (!omap_mcbsp_check_valid_id(id)) {
1040                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
1041                return;
1042        }
1043        mcbsp = id_to_mcbsp_ptr(id);
1044
1045        memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
1046
1047        /* SPI has only one frame */
1048        mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
1049        mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
1050
1051        /* Clock stop mode */
1052        if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
1053                mcbsp_cfg.spcr1 |= (1 << 12);
1054        else
1055                mcbsp_cfg.spcr1 |= (3 << 11);
1056
1057        /* Set clock parities */
1058        if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
1059                mcbsp_cfg.pcr0 |= CLKRP;
1060        else
1061                mcbsp_cfg.pcr0 &= ~CLKRP;
1062
1063        if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
1064                mcbsp_cfg.pcr0 &= ~CLKXP;
1065        else
1066                mcbsp_cfg.pcr0 |= CLKXP;
1067
1068        /* Set SCLKME to 0 and CLKSM to 1 */
1069        mcbsp_cfg.pcr0 &= ~SCLKME;
1070        mcbsp_cfg.srgr2 |= CLKSM;
1071
1072        /* Set FSXP */
1073        if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
1074                mcbsp_cfg.pcr0 &= ~FSXP;
1075        else
1076                mcbsp_cfg.pcr0 |= FSXP;
1077
1078        if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
1079                mcbsp_cfg.pcr0 |= CLKXM;
1080                mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
1081                mcbsp_cfg.pcr0 |= FSXM;
1082                mcbsp_cfg.srgr2 &= ~FSGM;
1083                mcbsp_cfg.xcr2 |= XDATDLY(1);
1084                mcbsp_cfg.rcr2 |= RDATDLY(1);
1085        } else {
1086                mcbsp_cfg.pcr0 &= ~CLKXM;
1087                mcbsp_cfg.srgr1 |= CLKGDV(1);
1088                mcbsp_cfg.pcr0 &= ~FSXM;
1089                mcbsp_cfg.xcr2 &= ~XDATDLY(3);
1090                mcbsp_cfg.rcr2 &= ~RDATDLY(3);
1091        }
1092
1093        mcbsp_cfg.xcr2 &= ~XPHASE;
1094        mcbsp_cfg.rcr2 &= ~RPHASE;
1095
1096        omap_mcbsp_config(id, &mcbsp_cfg);
1097}
1098EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
1099
1100#ifdef CONFIG_ARCH_OMAP34XX
1101#define max_thres(m)                    (mcbsp->pdata->buffer_size)
1102#define valid_threshold(m, val)         ((val) <= max_thres(m))
1103#define THRESHOLD_PROP_BUILDER(prop)                                    \
1104static ssize_t prop##_show(struct device *dev,                          \
1105                        struct device_attribute *attr, char *buf)       \
1106{                                                                       \
1107        struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);                \
1108                                                                        \
1109        return sprintf(buf, "%u\n", mcbsp->prop);                       \
1110}                                                                       \
1111                                                                        \
1112static ssize_t prop##_store(struct device *dev,                         \
1113                                struct device_attribute *attr,          \
1114                                const char *buf, size_t size)           \
1115{                                                                       \
1116        struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);                \
1117        unsigned long val;                                              \
1118        int status;                                                     \
1119                                                                        \
1120        status = strict_strtoul(buf, 0, &val);                          \
1121        if (status)                                                     \
1122                return status;                                          \
1123                                                                        \
1124        if (!valid_threshold(mcbsp, val))                               \
1125                return -EDOM;                                           \
1126                                                                        \
1127        mcbsp->prop = val;                                              \
1128        return size;                                                    \
1129}                                                                       \
1130                                                                        \
1131static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
1132
1133THRESHOLD_PROP_BUILDER(max_tx_thres);
1134THRESHOLD_PROP_BUILDER(max_rx_thres);
1135
1136static const char *dma_op_modes[] = {
1137        "element", "threshold", "frame",
1138};
1139
1140static ssize_t dma_op_mode_show(struct device *dev,
1141                        struct device_attribute *attr, char *buf)
1142{
1143        struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1144        int dma_op_mode, i = 0;
1145        ssize_t len = 0;
1146        const char * const *s;
1147
1148        spin_lock_irq(&mcbsp->lock);
1149        dma_op_mode = mcbsp->dma_op_mode;
1150        spin_unlock_irq(&mcbsp->lock);
1151
1152        for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
1153                if (dma_op_mode == i)
1154                        len += sprintf(buf + len, "[%s] ", *s);
1155                else
1156                        len += sprintf(buf + len, "%s ", *s);
1157        }
1158        len += sprintf(buf + len, "\n");
1159
1160        return len;
1161}
1162
1163static ssize_t dma_op_mode_store(struct device *dev,
1164                                struct device_attribute *attr,
1165                                const char *buf, size_t size)
1166{
1167        struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1168        const char * const *s;
1169        int i = 0;
1170
1171        for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
1172                if (sysfs_streq(buf, *s))
1173                        break;
1174
1175        if (i == ARRAY_SIZE(dma_op_modes))
1176                return -EINVAL;
1177
1178        spin_lock_irq(&mcbsp->lock);
1179        if (!mcbsp->free) {
1180                size = -EBUSY;
1181                goto unlock;
1182        }
1183        mcbsp->dma_op_mode = i;
1184
1185unlock:
1186        spin_unlock_irq(&mcbsp->lock);
1187
1188        return size;
1189}
1190
1191static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1192
1193static const struct attribute *additional_attrs[] = {
1194        &dev_attr_max_tx_thres.attr,
1195        &dev_attr_max_rx_thres.attr,
1196        &dev_attr_dma_op_mode.attr,
1197        NULL,
1198};
1199
1200static const struct attribute_group additional_attr_group = {
1201        .attrs = (struct attribute **)additional_attrs,
1202};
1203
1204static inline int __devinit omap_additional_add(struct device *dev)
1205{
1206        return sysfs_create_group(&dev->kobj, &additional_attr_group);
1207}
1208
1209static inline void __devexit omap_additional_remove(struct device *dev)
1210{
1211        sysfs_remove_group(&dev->kobj, &additional_attr_group);
1212}
1213
1214static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1215{
1216        mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1217        if (cpu_is_omap34xx()) {
1218                mcbsp->max_tx_thres = max_thres(mcbsp);
1219                mcbsp->max_rx_thres = max_thres(mcbsp);
1220                /*
1221                 * REVISIT: Set dmap_op_mode to THRESHOLD as default
1222                 * for mcbsp2 instances.
1223                 */
1224                if (omap_additional_add(mcbsp->dev))
1225                        dev_warn(mcbsp->dev,
1226                                "Unable to create additional controls\n");
1227        } else {
1228                mcbsp->max_tx_thres = -EINVAL;
1229                mcbsp->max_rx_thres = -EINVAL;
1230        }
1231}
1232
1233static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
1234{
1235        if (cpu_is_omap34xx())
1236                omap_additional_remove(mcbsp->dev);
1237}
1238#else
1239static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
1240static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
1241#endif /* CONFIG_ARCH_OMAP34XX */
1242
1243/*
1244 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
1245 * 730 has only 2 McBSP, and both of them are MPU peripherals.
1246 */
1247static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
1248{
1249        struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
1250        struct omap_mcbsp *mcbsp;
1251        int id = pdev->id - 1;
1252        int ret = 0;
1253
1254        if (!pdata) {
1255                dev_err(&pdev->dev, "McBSP device initialized without"
1256                                "platform data\n");
1257                ret = -EINVAL;
1258                goto exit;
1259        }
1260
1261        dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
1262
1263        if (id >= omap_mcbsp_count) {
1264                dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
1265                ret = -EINVAL;
1266                goto exit;
1267        }
1268
1269        mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
1270        if (!mcbsp) {
1271                ret = -ENOMEM;
1272                goto exit;
1273        }
1274
1275        spin_lock_init(&mcbsp->lock);
1276        mcbsp->id = id + 1;
1277        mcbsp->free = 1;
1278        mcbsp->dma_tx_lch = -1;
1279        mcbsp->dma_rx_lch = -1;
1280
1281        mcbsp->phys_base = pdata->phys_base;
1282        mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
1283        if (!mcbsp->io_base) {
1284                ret = -ENOMEM;
1285                goto err_ioremap;
1286        }
1287
1288        /* Default I/O is IRQ based */
1289        mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
1290        mcbsp->tx_irq = pdata->tx_irq;
1291        mcbsp->rx_irq = pdata->rx_irq;
1292        mcbsp->dma_rx_sync = pdata->dma_rx_sync;
1293        mcbsp->dma_tx_sync = pdata->dma_tx_sync;
1294
1295        mcbsp->iclk = clk_get(&pdev->dev, "ick");
1296        if (IS_ERR(mcbsp->iclk)) {
1297                ret = PTR_ERR(mcbsp->iclk);
1298                dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
1299                goto err_iclk;
1300        }
1301
1302        mcbsp->fclk = clk_get(&pdev->dev, "fck");
1303        if (IS_ERR(mcbsp->fclk)) {
1304                ret = PTR_ERR(mcbsp->fclk);
1305                dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
1306                goto err_fclk;
1307        }
1308
1309        mcbsp->pdata = pdata;
1310        mcbsp->dev = &pdev->dev;
1311        mcbsp_ptr[id] = mcbsp;
1312        platform_set_drvdata(pdev, mcbsp);
1313
1314        /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
1315        omap34xx_device_init(mcbsp);
1316
1317        return 0;
1318
1319err_fclk:
1320        clk_put(mcbsp->iclk);
1321err_iclk:
1322        iounmap(mcbsp->io_base);
1323err_ioremap:
1324        kfree(mcbsp);
1325exit:
1326        return ret;
1327}
1328
1329static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
1330{
1331        struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
1332
1333        platform_set_drvdata(pdev, NULL);
1334        if (mcbsp) {
1335
1336                if (mcbsp->pdata && mcbsp->pdata->ops &&
1337                                mcbsp->pdata->ops->free)
1338                        mcbsp->pdata->ops->free(mcbsp->id);
1339
1340                omap34xx_device_exit(mcbsp);
1341
1342                clk_disable(mcbsp->fclk);
1343                clk_disable(mcbsp->iclk);
1344                clk_put(mcbsp->fclk);
1345                clk_put(mcbsp->iclk);
1346
1347                iounmap(mcbsp->io_base);
1348
1349                mcbsp->fclk = NULL;
1350                mcbsp->iclk = NULL;
1351                mcbsp->free = 0;
1352                mcbsp->dev = NULL;
1353        }
1354
1355        return 0;
1356}
1357
1358static struct platform_driver omap_mcbsp_driver = {
1359        .probe          = omap_mcbsp_probe,
1360        .remove         = __devexit_p(omap_mcbsp_remove),
1361        .driver         = {
1362                .name   = "omap-mcbsp",
1363        },
1364};
1365
1366int __init omap_mcbsp_init(void)
1367{
1368        /* Register the McBSP driver */
1369        return platform_driver_register(&omap_mcbsp_driver);
1370}
1371