linux/sound/soc/blackfin/bf5xx-sport.c
<<
>>
Prefs
   1/*
   2 * File:         bf5xx_sport.c
   3 * Based on:
   4 * Author:       Roy Huang <roy.huang@analog.com>
   5 *
   6 * Created:      Tue Sep 21 10:52:42 CEST 2004
   7 * Description:
   8 *               Blackfin SPORT Driver
   9 *
  10 *               Copyright 2004-2007 Analog Devices Inc.
  11 *
  12 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  13 *
  14 * This program is free software; you can redistribute it and/or modify
  15 * it under the terms of the GNU General Public License as published by
  16 * the Free Software Foundation; either version 2 of the License, or
  17 * (at your option) any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 * GNU General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, see the file COPYING, or write
  26 * to the Free Software Foundation, Inc.,
  27 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  28 */
  29
  30#include <linux/kernel.h>
  31#include <linux/slab.h>
  32#include <linux/delay.h>
  33#include <linux/dma-mapping.h>
  34#include <linux/gpio.h>
  35#include <linux/bug.h>
  36#include <linux/module.h>
  37#include <asm/portmux.h>
  38#include <asm/dma.h>
  39#include <asm/blackfin.h>
  40#include <asm/cacheflush.h>
  41
  42#include "bf5xx-sport.h"
  43/* delay between frame sync pulse and first data bit in multichannel mode */
  44#define FRAME_DELAY (1<<12)
  45
  46/* note: multichannel is in units of 8 channels,
  47 * tdm_count is # channels NOT / 8 ! */
  48int sport_set_multichannel(struct sport_device *sport,
  49                int tdm_count, u32 tx_mask, u32 rx_mask, int packed)
  50{
  51        pr_debug("%s tdm_count=%d tx_mask:0x%08x rx_mask:0x%08x packed=%d\n",
  52                        __func__, tdm_count, tx_mask, rx_mask, packed);
  53
  54        if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
  55                return -EBUSY;
  56
  57        if (tdm_count & 0x7)
  58                return -EINVAL;
  59
  60        if (tdm_count > 32)
  61                return -EINVAL; /* Only support less than 32 channels now */
  62
  63        if (tdm_count) {
  64                sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
  65                sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
  66                                (packed ? (MCDTXPE|MCDRXPE) : 0);
  67
  68                sport->regs->mtcs0 = tx_mask;
  69                sport->regs->mrcs0 = rx_mask;
  70                sport->regs->mtcs1 = 0;
  71                sport->regs->mrcs1 = 0;
  72                sport->regs->mtcs2 = 0;
  73                sport->regs->mrcs2 = 0;
  74                sport->regs->mtcs3 = 0;
  75                sport->regs->mrcs3 = 0;
  76        } else {
  77                sport->regs->mcmc1 = 0;
  78                sport->regs->mcmc2 = 0;
  79
  80                sport->regs->mtcs0 = 0;
  81                sport->regs->mrcs0 = 0;
  82        }
  83
  84        sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
  85        sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;
  86
  87        SSYNC();
  88
  89        return 0;
  90}
  91EXPORT_SYMBOL(sport_set_multichannel);
  92
  93int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
  94                unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
  95{
  96        if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
  97                return -EBUSY;
  98
  99        sport->regs->rcr1 = rcr1;
 100        sport->regs->rcr2 = rcr2;
 101        sport->regs->rclkdiv = clkdiv;
 102        sport->regs->rfsdiv = fsdiv;
 103
 104        SSYNC();
 105
 106        return 0;
 107}
 108EXPORT_SYMBOL(sport_config_rx);
 109
 110int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
 111                unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
 112{
 113        if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
 114                return -EBUSY;
 115
 116        sport->regs->tcr1 = tcr1;
 117        sport->regs->tcr2 = tcr2;
 118        sport->regs->tclkdiv = clkdiv;
 119        sport->regs->tfsdiv = fsdiv;
 120
 121        SSYNC();
 122
 123        return 0;
 124}
 125EXPORT_SYMBOL(sport_config_tx);
 126
 127static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
 128                size_t fragsize, unsigned int cfg,
 129                unsigned int x_count, unsigned int ycount, size_t wdsize)
 130{
 131
 132        int i;
 133
 134        for (i = 0; i < fragcount; ++i) {
 135                desc[i].next_desc_addr  = &(desc[i + 1]);
 136                desc[i].start_addr = (unsigned long)buf + i*fragsize;
 137                desc[i].cfg = cfg;
 138                desc[i].x_count = x_count;
 139                desc[i].x_modify = wdsize;
 140                desc[i].y_count = ycount;
 141                desc[i].y_modify = wdsize;
 142        }
 143
 144        /* make circular */
 145        desc[fragcount-1].next_desc_addr = desc;
 146
 147        pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p,"
 148                "next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
 149                desc, desc[0].next_desc_addr,
 150                desc+1, desc[1].next_desc_addr,
 151                desc[0].x_count, desc[0].y_count,
 152                desc[0].start_addr, desc[0].cfg);
 153}
 154
 155static int sport_start(struct sport_device *sport)
 156{
 157        enable_dma(sport->dma_rx_chan);
 158        enable_dma(sport->dma_tx_chan);
 159        sport->regs->rcr1 |= RSPEN;
 160        sport->regs->tcr1 |= TSPEN;
 161        SSYNC();
 162
 163        return 0;
 164}
 165
 166static int sport_stop(struct sport_device *sport)
 167{
 168        sport->regs->tcr1 &= ~TSPEN;
 169        sport->regs->rcr1 &= ~RSPEN;
 170        SSYNC();
 171
 172        disable_dma(sport->dma_rx_chan);
 173        disable_dma(sport->dma_tx_chan);
 174        return 0;
 175}
 176
 177static inline int sport_hook_rx_dummy(struct sport_device *sport)
 178{
 179        struct dmasg *desc, temp_desc;
 180        unsigned long flags;
 181
 182        BUG_ON(sport->dummy_rx_desc == NULL);
 183        BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc);
 184
 185        /* Maybe the dummy buffer descriptor ring is damaged */
 186        sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1;
 187
 188        local_irq_save(flags);
 189        desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
 190        /* Copy the descriptor which will be damaged to backup */
 191        temp_desc = *desc;
 192        desc->x_count = sport->dummy_count / 2;
 193        desc->y_count = 0;
 194        desc->next_desc_addr = sport->dummy_rx_desc;
 195        local_irq_restore(flags);
 196        /* Waiting for dummy buffer descriptor is already hooked*/
 197        while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
 198                        sizeof(struct dmasg)) != sport->dummy_rx_desc)
 199                continue;
 200        sport->curr_rx_desc = sport->dummy_rx_desc;
 201        /* Restore the damaged descriptor */
 202        *desc = temp_desc;
 203
 204        return 0;
 205}
 206
 207static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
 208{
 209        if (dummy) {
 210                sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc;
 211                sport->curr_rx_desc = sport->dummy_rx_desc;
 212        } else
 213                sport->curr_rx_desc = sport->dma_rx_desc;
 214
 215        set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc);
 216        set_dma_x_count(sport->dma_rx_chan, 0);
 217        set_dma_x_modify(sport->dma_rx_chan, 0);
 218        set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
 219                                WDSIZE_32 | WNR));
 220        set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
 221        SSYNC();
 222
 223        return 0;
 224}
 225
 226static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
 227{
 228        if (dummy) {
 229                sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc;
 230                sport->curr_tx_desc = sport->dummy_tx_desc;
 231        } else
 232                sport->curr_tx_desc = sport->dma_tx_desc;
 233
 234        set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc);
 235        set_dma_x_count(sport->dma_tx_chan, 0);
 236        set_dma_x_modify(sport->dma_tx_chan, 0);
 237        set_dma_config(sport->dma_tx_chan,
 238                        (DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
 239        set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
 240        SSYNC();
 241
 242        return 0;
 243}
 244
 245int sport_rx_start(struct sport_device *sport)
 246{
 247        unsigned long flags;
 248        pr_debug("%s enter\n", __func__);
 249        if (sport->rx_run)
 250                return -EBUSY;
 251        if (sport->tx_run) {
 252                /* tx is running, rx is not running */
 253                BUG_ON(sport->dma_rx_desc == NULL);
 254                BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
 255                local_irq_save(flags);
 256                while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
 257                        sizeof(struct dmasg)) != sport->dummy_rx_desc)
 258                        continue;
 259                sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc;
 260                local_irq_restore(flags);
 261                sport->curr_rx_desc = sport->dma_rx_desc;
 262        } else {
 263                sport_tx_dma_start(sport, 1);
 264                sport_rx_dma_start(sport, 0);
 265                sport_start(sport);
 266        }
 267
 268        sport->rx_run = 1;
 269
 270        return 0;
 271}
 272EXPORT_SYMBOL(sport_rx_start);
 273
 274int sport_rx_stop(struct sport_device *sport)
 275{
 276        pr_debug("%s enter\n", __func__);
 277
 278        if (!sport->rx_run)
 279                return 0;
 280        if (sport->tx_run) {
 281                /* TX dma is still running, hook the dummy buffer */
 282                sport_hook_rx_dummy(sport);
 283        } else {
 284                /* Both rx and tx dma will be stopped */
 285                sport_stop(sport);
 286                sport->curr_rx_desc = NULL;
 287                sport->curr_tx_desc = NULL;
 288        }
 289
 290        sport->rx_run = 0;
 291
 292        return 0;
 293}
 294EXPORT_SYMBOL(sport_rx_stop);
 295
 296static inline int sport_hook_tx_dummy(struct sport_device *sport)
 297{
 298        struct dmasg *desc, temp_desc;
 299        unsigned long flags;
 300
 301        BUG_ON(sport->dummy_tx_desc == NULL);
 302        BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);
 303
 304        sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1;
 305
 306        /* Shorten the time on last normal descriptor */
 307        local_irq_save(flags);
 308        desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
 309        /* Store the descriptor which will be damaged */
 310        temp_desc = *desc;
 311        desc->x_count = sport->dummy_count / 2;
 312        desc->y_count = 0;
 313        desc->next_desc_addr = sport->dummy_tx_desc;
 314        local_irq_restore(flags);
 315        /* Waiting for dummy buffer descriptor is already hooked*/
 316        while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
 317                        sizeof(struct dmasg)) != sport->dummy_tx_desc)
 318                continue;
 319        sport->curr_tx_desc = sport->dummy_tx_desc;
 320        /* Restore the damaged descriptor */
 321        *desc = temp_desc;
 322
 323        return 0;
 324}
 325
 326int sport_tx_start(struct sport_device *sport)
 327{
 328        unsigned long flags;
 329        pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
 330                        sport->tx_run, sport->rx_run);
 331        if (sport->tx_run)
 332                return -EBUSY;
 333        if (sport->rx_run) {
 334                BUG_ON(sport->dma_tx_desc == NULL);
 335                BUG_ON(sport->curr_tx_desc != sport->dummy_tx_desc);
 336                /* Hook the normal buffer descriptor */
 337                local_irq_save(flags);
 338                while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
 339                        sizeof(struct dmasg)) != sport->dummy_tx_desc)
 340                        continue;
 341                sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc;
 342                local_irq_restore(flags);
 343                sport->curr_tx_desc = sport->dma_tx_desc;
 344        } else {
 345
 346                sport_tx_dma_start(sport, 0);
 347                /* Let rx dma run the dummy buffer */
 348                sport_rx_dma_start(sport, 1);
 349                sport_start(sport);
 350        }
 351        sport->tx_run = 1;
 352        return 0;
 353}
 354EXPORT_SYMBOL(sport_tx_start);
 355
 356int sport_tx_stop(struct sport_device *sport)
 357{
 358        if (!sport->tx_run)
 359                return 0;
 360        if (sport->rx_run) {
 361                /* RX is still running, hook the dummy buffer */
 362                sport_hook_tx_dummy(sport);
 363        } else {
 364                /* Both rx and tx dma stopped */
 365                sport_stop(sport);
 366                sport->curr_rx_desc = NULL;
 367                sport->curr_tx_desc = NULL;
 368        }
 369
 370        sport->tx_run = 0;
 371
 372        return 0;
 373}
 374EXPORT_SYMBOL(sport_tx_stop);
 375
 376static inline int compute_wdsize(size_t wdsize)
 377{
 378        switch (wdsize) {
 379        case 1:
 380                return WDSIZE_8;
 381        case 2:
 382                return WDSIZE_16;
 383        case 4:
 384        default:
 385                return WDSIZE_32;
 386        }
 387}
 388
 389int sport_config_rx_dma(struct sport_device *sport, void *buf,
 390                int fragcount, size_t fragsize)
 391{
 392        unsigned int x_count;
 393        unsigned int y_count;
 394        unsigned int cfg;
 395        dma_addr_t addr;
 396
 397        pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
 398                        buf, fragcount, fragsize);
 399
 400        x_count = fragsize / sport->wdsize;
 401        y_count = 0;
 402
 403        /* for fragments larger than 64k words we use 2d dma,
 404         * denote fragecount as two numbers' mutliply and both of them
 405         * are less than 64k.*/
 406        if (x_count >= 0x10000) {
 407                int i, count = x_count;
 408
 409                for (i = 16; i > 0; i--) {
 410                        x_count = 1 << i;
 411                        if ((count & (x_count - 1)) == 0) {
 412                                y_count = count >> i;
 413                                if (y_count < 0x10000)
 414                                        break;
 415                        }
 416                }
 417                if (i == 0)
 418                        return -EINVAL;
 419        }
 420        pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
 421                        x_count, y_count);
 422
 423        if (sport->dma_rx_desc)
 424                dma_free_coherent(NULL, sport->rx_desc_bytes,
 425                                        sport->dma_rx_desc, 0);
 426
 427        /* Allocate a new descritor ring as current one. */
 428        sport->dma_rx_desc = dma_alloc_coherent(NULL, \
 429                        fragcount * sizeof(struct dmasg), &addr, 0);
 430        sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);
 431
 432        if (!sport->dma_rx_desc) {
 433                pr_err("Failed to allocate memory for rx desc\n");
 434                return -ENOMEM;
 435        }
 436
 437        sport->rx_buf = buf;
 438        sport->rx_fragsize = fragsize;
 439        sport->rx_frags = fragcount;
 440
 441        cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
 442                  (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
 443
 444        if (y_count != 0)
 445                cfg |= DMA2D;
 446
 447        setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
 448                        cfg|DMAEN, x_count, y_count, sport->wdsize);
 449
 450        return 0;
 451}
 452EXPORT_SYMBOL(sport_config_rx_dma);
 453
 454int sport_config_tx_dma(struct sport_device *sport, void *buf, \
 455                int fragcount, size_t fragsize)
 456{
 457        unsigned int x_count;
 458        unsigned int y_count;
 459        unsigned int cfg;
 460        dma_addr_t addr;
 461
 462        pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
 463                        __func__, buf, fragcount, fragsize);
 464
 465        x_count = fragsize/sport->wdsize;
 466        y_count = 0;
 467
 468        /* for fragments larger than 64k words we use 2d dma,
 469         * denote fragecount as two numbers' mutliply and both of them
 470         * are less than 64k.*/
 471        if (x_count >= 0x10000) {
 472                int i, count = x_count;
 473
 474                for (i = 16; i > 0; i--) {
 475                        x_count = 1 << i;
 476                        if ((count & (x_count - 1)) == 0) {
 477                                y_count = count >> i;
 478                                if (y_count < 0x10000)
 479                                        break;
 480                        }
 481                }
 482                if (i == 0)
 483                        return -EINVAL;
 484        }
 485        pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
 486                        x_count, y_count);
 487
 488
 489        if (sport->dma_tx_desc) {
 490                dma_free_coherent(NULL, sport->tx_desc_bytes, \
 491                                sport->dma_tx_desc, 0);
 492        }
 493
 494        sport->dma_tx_desc = dma_alloc_coherent(NULL, \
 495                        fragcount * sizeof(struct dmasg), &addr, 0);
 496        sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
 497        if (!sport->dma_tx_desc) {
 498                pr_err("Failed to allocate memory for tx desc\n");
 499                return -ENOMEM;
 500        }
 501
 502        sport->tx_buf = buf;
 503        sport->tx_fragsize = fragsize;
 504        sport->tx_frags = fragcount;
 505        cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
 506                  (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
 507
 508        if (y_count != 0)
 509                cfg |= DMA2D;
 510
 511        setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
 512                        cfg|DMAEN, x_count, y_count, sport->wdsize);
 513
 514        return 0;
 515}
 516EXPORT_SYMBOL(sport_config_tx_dma);
 517
 518/* setup dummy dma descriptor ring, which don't generate interrupts,
 519 * the x_modify is set to 0 */
 520static int sport_config_rx_dummy(struct sport_device *sport)
 521{
 522        struct dmasg *desc;
 523        unsigned config;
 524
 525        pr_debug("%s entered\n", __func__);
 526        if (L1_DATA_A_LENGTH)
 527                desc = l1_data_sram_zalloc(2 * sizeof(*desc));
 528        else {
 529                dma_addr_t addr;
 530                desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
 531                memset(desc, 0, 2 * sizeof(*desc));
 532        }
 533        if (desc == NULL) {
 534                pr_err("Failed to allocate memory for dummy rx desc\n");
 535                return -ENOMEM;
 536        }
 537        sport->dummy_rx_desc = desc;
 538        desc->start_addr = (unsigned long)sport->dummy_buf;
 539        config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
 540                 | WNR | DMAEN;
 541        desc->cfg = config;
 542        desc->x_count = sport->dummy_count/sport->wdsize;
 543        desc->x_modify = sport->wdsize;
 544        desc->y_count = 0;
 545        desc->y_modify = 0;
 546        memcpy(desc+1, desc, sizeof(*desc));
 547        desc->next_desc_addr = desc + 1;
 548        desc[1].next_desc_addr = desc;
 549        return 0;
 550}
 551
 552static int sport_config_tx_dummy(struct sport_device *sport)
 553{
 554        struct dmasg *desc;
 555        unsigned int config;
 556
 557        pr_debug("%s entered\n", __func__);
 558
 559        if (L1_DATA_A_LENGTH)
 560                desc = l1_data_sram_zalloc(2 * sizeof(*desc));
 561        else {
 562                dma_addr_t addr;
 563                desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
 564                memset(desc, 0, 2 * sizeof(*desc));
 565        }
 566        if (!desc) {
 567                pr_err("Failed to allocate memory for dummy tx desc\n");
 568                return -ENOMEM;
 569        }
 570        sport->dummy_tx_desc = desc;
 571        desc->start_addr = (unsigned long)sport->dummy_buf + \
 572                sport->dummy_count;
 573        config = DMAFLOW_LARGE | NDSIZE_9 |
 574                 compute_wdsize(sport->wdsize) | DMAEN;
 575        desc->cfg = config;
 576        desc->x_count = sport->dummy_count/sport->wdsize;
 577        desc->x_modify = sport->wdsize;
 578        desc->y_count = 0;
 579        desc->y_modify = 0;
 580        memcpy(desc+1, desc, sizeof(*desc));
 581        desc->next_desc_addr = desc + 1;
 582        desc[1].next_desc_addr = desc;
 583        return 0;
 584}
 585
 586unsigned long sport_curr_offset_rx(struct sport_device *sport)
 587{
 588        unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);
 589
 590        return (unsigned char *)curr - sport->rx_buf;
 591}
 592EXPORT_SYMBOL(sport_curr_offset_rx);
 593
 594unsigned long sport_curr_offset_tx(struct sport_device *sport)
 595{
 596        unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);
 597
 598        return (unsigned char *)curr - sport->tx_buf;
 599}
 600EXPORT_SYMBOL(sport_curr_offset_tx);
 601
 602void sport_incfrag(struct sport_device *sport, int *frag, int tx)
 603{
 604        ++(*frag);
 605        if (tx == 1 && *frag == sport->tx_frags)
 606                *frag = 0;
 607
 608        if (tx == 0 && *frag == sport->rx_frags)
 609                *frag = 0;
 610}
 611EXPORT_SYMBOL(sport_incfrag);
 612
 613void sport_decfrag(struct sport_device *sport, int *frag, int tx)
 614{
 615        --(*frag);
 616        if (tx == 1 && *frag == 0)
 617                *frag = sport->tx_frags;
 618
 619        if (tx == 0 && *frag == 0)
 620                *frag = sport->rx_frags;
 621}
 622EXPORT_SYMBOL(sport_decfrag);
 623
 624static int sport_check_status(struct sport_device *sport,
 625                unsigned int *sport_stat,
 626                unsigned int *rx_stat,
 627                unsigned int *tx_stat)
 628{
 629        int status = 0;
 630
 631        if (sport_stat) {
 632                SSYNC();
 633                status = sport->regs->stat;
 634                if (status & (TOVF|TUVF|ROVF|RUVF))
 635                        sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
 636                SSYNC();
 637                *sport_stat = status;
 638        }
 639
 640        if (rx_stat) {
 641                SSYNC();
 642                status = get_dma_curr_irqstat(sport->dma_rx_chan);
 643                if (status & (DMA_DONE|DMA_ERR))
 644                        clear_dma_irqstat(sport->dma_rx_chan);
 645                SSYNC();
 646                *rx_stat = status;
 647        }
 648
 649        if (tx_stat) {
 650                SSYNC();
 651                status = get_dma_curr_irqstat(sport->dma_tx_chan);
 652                if (status & (DMA_DONE|DMA_ERR))
 653                        clear_dma_irqstat(sport->dma_tx_chan);
 654                SSYNC();
 655                *tx_stat = status;
 656        }
 657
 658        return 0;
 659}
 660
 661int  sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
 662{
 663        int ret;
 664
 665        ret = snprintf(buf, len,
 666                        "sts: 0x%04x\n"
 667                        "rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
 668                        sport->regs->stat,
 669                        sport->dma_rx_chan,
 670                        get_dma_curr_irqstat(sport->dma_rx_chan),
 671                        sport->dma_tx_chan,
 672                        get_dma_curr_irqstat(sport->dma_tx_chan));
 673        buf += ret;
 674        len -= ret;
 675
 676        ret += snprintf(buf, len,
 677                        "curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
 678                        "dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
 679                        "dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
 680                        sport->curr_rx_desc, sport->curr_tx_desc,
 681                        sport->dma_rx_desc, sport->dma_tx_desc,
 682                        sport->dummy_rx_desc, sport->dummy_tx_desc);
 683
 684        return ret;
 685}
 686
 687static irqreturn_t rx_handler(int irq, void *dev_id)
 688{
 689        unsigned int rx_stat;
 690        struct sport_device *sport = dev_id;
 691
 692        pr_debug("%s enter\n", __func__);
 693        sport_check_status(sport, NULL, &rx_stat, NULL);
 694        if (!(rx_stat & DMA_DONE))
 695                pr_err("rx dma is already stopped\n");
 696
 697        if (sport->rx_callback) {
 698                sport->rx_callback(sport->rx_data);
 699                return IRQ_HANDLED;
 700        }
 701
 702        return IRQ_NONE;
 703}
 704
 705static irqreturn_t tx_handler(int irq, void *dev_id)
 706{
 707        unsigned int tx_stat;
 708        struct sport_device *sport = dev_id;
 709        pr_debug("%s enter\n", __func__);
 710        sport_check_status(sport, NULL, NULL, &tx_stat);
 711        if (!(tx_stat & DMA_DONE)) {
 712                pr_err("tx dma is already stopped\n");
 713                return IRQ_HANDLED;
 714        }
 715        if (sport->tx_callback) {
 716                sport->tx_callback(sport->tx_data);
 717                return IRQ_HANDLED;
 718        }
 719
 720        return IRQ_NONE;
 721}
 722
 723static irqreturn_t err_handler(int irq, void *dev_id)
 724{
 725        unsigned int status = 0;
 726        struct sport_device *sport = dev_id;
 727
 728        pr_debug("%s\n", __func__);
 729        if (sport_check_status(sport, &status, NULL, NULL)) {
 730                pr_err("error checking status ??");
 731                return IRQ_NONE;
 732        }
 733
 734        if (status & (TOVF|TUVF|ROVF|RUVF)) {
 735                pr_info("sport status error:%s%s%s%s\n",
 736                                status & TOVF ? " TOVF" : "",
 737                                status & TUVF ? " TUVF" : "",
 738                                status & ROVF ? " ROVF" : "",
 739                                status & RUVF ? " RUVF" : "");
 740                if (status & TOVF || status & TUVF) {
 741                        disable_dma(sport->dma_tx_chan);
 742                        if (sport->tx_run)
 743                                sport_tx_dma_start(sport, 0);
 744                        else
 745                                sport_tx_dma_start(sport, 1);
 746                        enable_dma(sport->dma_tx_chan);
 747                } else {
 748                        disable_dma(sport->dma_rx_chan);
 749                        if (sport->rx_run)
 750                                sport_rx_dma_start(sport, 0);
 751                        else
 752                                sport_rx_dma_start(sport, 1);
 753                        enable_dma(sport->dma_rx_chan);
 754                }
 755        }
 756        status = sport->regs->stat;
 757        if (status & (TOVF|TUVF|ROVF|RUVF))
 758                sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
 759        SSYNC();
 760
 761        if (sport->err_callback)
 762                sport->err_callback(sport->err_data);
 763
 764        return IRQ_HANDLED;
 765}
 766
 767int sport_set_rx_callback(struct sport_device *sport,
 768                       void (*rx_callback)(void *), void *rx_data)
 769{
 770        BUG_ON(rx_callback == NULL);
 771        sport->rx_callback = rx_callback;
 772        sport->rx_data = rx_data;
 773
 774        return 0;
 775}
 776EXPORT_SYMBOL(sport_set_rx_callback);
 777
 778int sport_set_tx_callback(struct sport_device *sport,
 779                void (*tx_callback)(void *), void *tx_data)
 780{
 781        BUG_ON(tx_callback == NULL);
 782        sport->tx_callback = tx_callback;
 783        sport->tx_data = tx_data;
 784
 785        return 0;
 786}
 787EXPORT_SYMBOL(sport_set_tx_callback);
 788
 789int sport_set_err_callback(struct sport_device *sport,
 790                void (*err_callback)(void *), void *err_data)
 791{
 792        BUG_ON(err_callback == NULL);
 793        sport->err_callback = err_callback;
 794        sport->err_data = err_data;
 795
 796        return 0;
 797}
 798EXPORT_SYMBOL(sport_set_err_callback);
 799
 800static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
 801{
 802        /* Extract settings from platform data */
 803        struct device *dev = &pdev->dev;
 804        struct bfin_snd_platform_data *pdata = dev->platform_data;
 805        struct resource *res;
 806
 807        param->num = pdev->id;
 808
 809        if (!pdata) {
 810                dev_err(dev, "no platform_data\n");
 811                return -ENODEV;
 812        }
 813        param->pin_req = pdata->pin_req;
 814
 815        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 816        if (!res) {
 817                dev_err(dev, "no MEM resource\n");
 818                return -ENODEV;
 819        }
 820        param->regs = (struct sport_register *)res->start;
 821
 822        /* first RX, then TX */
 823        res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 824        if (!res) {
 825                dev_err(dev, "no rx DMA resource\n");
 826                return -ENODEV;
 827        }
 828        param->dma_rx_chan = res->start;
 829
 830        res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
 831        if (!res) {
 832                dev_err(dev, "no tx DMA resource\n");
 833                return -ENODEV;
 834        }
 835        param->dma_tx_chan = res->start;
 836
 837        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 838        if (!res) {
 839                dev_err(dev, "no irq resource\n");
 840                return -ENODEV;
 841        }
 842        param->err_irq = res->start;
 843
 844        return 0;
 845}
 846
 847struct sport_device *sport_init(struct platform_device *pdev,
 848        unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
 849{
 850        struct device *dev = &pdev->dev;
 851        struct sport_param param;
 852        struct sport_device *sport;
 853        int ret;
 854
 855        dev_dbg(dev, "%s enter\n", __func__);
 856
 857        param.wdsize = wdsize;
 858        param.dummy_count = dummy_count;
 859        BUG_ON(param.wdsize == 0 || param.dummy_count == 0);
 860
 861        ret = sport_config_pdev(pdev, &param);
 862        if (ret)
 863                return NULL;
 864
 865        if (peripheral_request_list(param.pin_req, "soc-audio")) {
 866                dev_err(dev, "requesting Peripherals failed\n");
 867                return NULL;
 868        }
 869
 870        sport = kzalloc(sizeof(*sport), GFP_KERNEL);
 871        if (!sport) {
 872                dev_err(dev, "failed to allocate for sport device\n");
 873                goto __init_err0;
 874        }
 875
 876        sport->num = param.num;
 877        sport->dma_rx_chan = param.dma_rx_chan;
 878        sport->dma_tx_chan = param.dma_tx_chan;
 879        sport->err_irq = param.err_irq;
 880        sport->regs = param.regs;
 881        sport->pin_req = param.pin_req;
 882
 883        if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
 884                dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
 885                goto __init_err1;
 886        }
 887        if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
 888                dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
 889                goto __init_err2;
 890        }
 891
 892        if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
 893                dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
 894                goto __init_err2;
 895        }
 896
 897        if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
 898                dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
 899                goto __init_err3;
 900        }
 901
 902        if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
 903                        sport) < 0) {
 904                dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
 905                goto __init_err3;
 906        }
 907
 908        dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
 909                        sport->dma_rx_chan, sport->dma_tx_chan,
 910                        sport->err_irq, sport->regs);
 911
 912        sport->wdsize = param.wdsize;
 913        sport->dummy_count = param.dummy_count;
 914
 915        sport->private_data = kzalloc(priv_size, GFP_KERNEL);
 916        if (!sport->private_data) {
 917                dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
 918                goto __init_err4;
 919        }
 920
 921        if (L1_DATA_A_LENGTH)
 922                sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
 923        else
 924                sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
 925        if (sport->dummy_buf == NULL) {
 926                dev_err(dev, "failed to allocate dummy buffer\n");
 927                goto __error1;
 928        }
 929
 930        ret = sport_config_rx_dummy(sport);
 931        if (ret) {
 932                dev_err(dev, "failed to config rx dummy ring\n");
 933                goto __error2;
 934        }
 935        ret = sport_config_tx_dummy(sport);
 936        if (ret) {
 937                dev_err(dev, "failed to config tx dummy ring\n");
 938                goto __error3;
 939        }
 940
 941        platform_set_drvdata(pdev, sport);
 942
 943        return sport;
 944__error3:
 945        if (L1_DATA_A_LENGTH)
 946                l1_data_sram_free(sport->dummy_rx_desc);
 947        else
 948                dma_free_coherent(NULL, 2*sizeof(struct dmasg),
 949                                sport->dummy_rx_desc, 0);
 950__error2:
 951        if (L1_DATA_A_LENGTH)
 952                l1_data_sram_free(sport->dummy_buf);
 953        else
 954                kfree(sport->dummy_buf);
 955__error1:
 956        kfree(sport->private_data);
 957__init_err4:
 958        free_irq(sport->err_irq, sport);
 959__init_err3:
 960        free_dma(sport->dma_tx_chan);
 961__init_err2:
 962        free_dma(sport->dma_rx_chan);
 963__init_err1:
 964        kfree(sport);
 965__init_err0:
 966        peripheral_free_list(param.pin_req);
 967        return NULL;
 968}
 969EXPORT_SYMBOL(sport_init);
 970
 971void sport_done(struct sport_device *sport)
 972{
 973        if (sport == NULL)
 974                return;
 975
 976        sport_stop(sport);
 977        if (sport->dma_rx_desc)
 978                dma_free_coherent(NULL, sport->rx_desc_bytes,
 979                        sport->dma_rx_desc, 0);
 980        if (sport->dma_tx_desc)
 981                dma_free_coherent(NULL, sport->tx_desc_bytes,
 982                        sport->dma_tx_desc, 0);
 983
 984#if L1_DATA_A_LENGTH != 0
 985        l1_data_sram_free(sport->dummy_rx_desc);
 986        l1_data_sram_free(sport->dummy_tx_desc);
 987        l1_data_sram_free(sport->dummy_buf);
 988#else
 989        dma_free_coherent(NULL, 2*sizeof(struct dmasg),
 990                sport->dummy_rx_desc, 0);
 991        dma_free_coherent(NULL, 2*sizeof(struct dmasg),
 992                sport->dummy_tx_desc, 0);
 993        kfree(sport->dummy_buf);
 994#endif
 995        free_dma(sport->dma_rx_chan);
 996        free_dma(sport->dma_tx_chan);
 997        free_irq(sport->err_irq, sport);
 998
 999        kfree(sport->private_data);
1000        peripheral_free_list(sport->pin_req);
1001        kfree(sport);
1002}
1003EXPORT_SYMBOL(sport_done);
1004
1005/*
1006* It is only used to send several bytes when dma is not enabled
1007 * sport controller is configured but not enabled.
1008 * Multichannel cannot works with pio mode */
1009/* Used by ac97 to write and read codec register */
1010int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
1011                u8 *in_data, int len)
1012{
1013        unsigned short dma_config;
1014        unsigned short status;
1015        unsigned long flags;
1016        unsigned long wait = 0;
1017
1018        pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
1019                        __func__, out_data, in_data, len);
1020        pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
1021                        "mcmc1:0x%04x, mcmc2:0x%04x\n",
1022                        sport->regs->tcr1, sport->regs->tcr2,
1023                        sport->regs->tclkdiv, sport->regs->tfsdiv,
1024                        sport->regs->mcmc1, sport->regs->mcmc2);
1025        flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));
1026
1027        /* Enable tx dma */
1028        dma_config = (RESTART | WDSIZE_16 | DI_EN);
1029        set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
1030        set_dma_x_count(sport->dma_tx_chan, len/2);
1031        set_dma_x_modify(sport->dma_tx_chan, 2);
1032        set_dma_config(sport->dma_tx_chan, dma_config);
1033        enable_dma(sport->dma_tx_chan);
1034
1035        if (in_data != NULL) {
1036                invalidate_dcache_range((unsigned)in_data, \
1037                                (unsigned)(in_data + len));
1038                /* Enable rx dma */
1039                dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
1040                set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
1041                set_dma_x_count(sport->dma_rx_chan, len/2);
1042                set_dma_x_modify(sport->dma_rx_chan, 2);
1043                set_dma_config(sport->dma_rx_chan, dma_config);
1044                enable_dma(sport->dma_rx_chan);
1045        }
1046
1047        local_irq_save(flags);
1048        sport->regs->tcr1 |= TSPEN;
1049        sport->regs->rcr1 |= RSPEN;
1050        SSYNC();
1051
1052        status = get_dma_curr_irqstat(sport->dma_tx_chan);
1053        while (status & DMA_RUN) {
1054                udelay(1);
1055                status = get_dma_curr_irqstat(sport->dma_tx_chan);
1056                pr_debug("DMA status:0x%04x\n", status);
1057                if (wait++ > 100)
1058                        goto __over;
1059        }
1060        status = sport->regs->stat;
1061        wait = 0;
1062
1063        while (!(status & TXHRE)) {
1064                pr_debug("sport status:0x%04x\n", status);
1065                udelay(1);
1066                status = *(unsigned short *)&sport->regs->stat;
1067                if (wait++ > 1000)
1068                        goto __over;
1069        }
1070        /* Wait for the last byte sent out */
1071        udelay(20);
1072        pr_debug("sport status:0x%04x\n", status);
1073
1074__over:
1075        sport->regs->tcr1 &= ~TSPEN;
1076        sport->regs->rcr1 &= ~RSPEN;
1077        SSYNC();
1078        disable_dma(sport->dma_tx_chan);
1079        /* Clear the status */
1080        clear_dma_irqstat(sport->dma_tx_chan);
1081        if (in_data != NULL) {
1082                disable_dma(sport->dma_rx_chan);
1083                clear_dma_irqstat(sport->dma_rx_chan);
1084        }
1085        SSYNC();
1086        local_irq_restore(flags);
1087
1088        return 0;
1089}
1090EXPORT_SYMBOL(sport_send_and_recv);
1091
1092MODULE_AUTHOR("Roy Huang");
1093MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
1094MODULE_LICENSE("GPL");
1095