linux/sound/soc/sh/fsi.c
<<
>>
Prefs
   1/*
   2 * Fifo-attached Serial Interface (FSI) support for SH7724
   3 *
   4 * Copyright (C) 2009 Renesas Solutions Corp.
   5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
   6 *
   7 * Based on ssi.c
   8 * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/init.h>
  16#include <linux/module.h>
  17#include <linux/platform_device.h>
  18#include <linux/delay.h>
  19#include <linux/list.h>
  20#include <linux/clk.h>
  21#include <linux/io.h>
  22#include <sound/core.h>
  23#include <sound/pcm.h>
  24#include <sound/initval.h>
  25#include <sound/soc.h>
  26#include <sound/pcm_params.h>
  27#include <sound/sh_fsi.h>
  28#include <asm/atomic.h>
  29#include <asm/dma.h>
  30#include <asm/dma-sh.h>
  31
  32#define DO_FMT          0x0000
  33#define DOFF_CTL        0x0004
  34#define DOFF_ST         0x0008
  35#define DI_FMT          0x000C
  36#define DIFF_CTL        0x0010
  37#define DIFF_ST         0x0014
  38#define CKG1            0x0018
  39#define CKG2            0x001C
  40#define DIDT            0x0020
  41#define DODT            0x0024
  42#define MUTE_ST         0x0028
  43#define REG_END         MUTE_ST
  44
  45#define INT_ST          0x0200
  46#define IEMSK           0x0204
  47#define IMSK            0x0208
  48#define MUTE            0x020C
  49#define CLK_RST         0x0210
  50#define SOFT_RST        0x0214
  51#define MREG_START      INT_ST
  52#define MREG_END        SOFT_RST
  53
  54/* DO_FMT */
  55/* DI_FMT */
  56#define CR_FMT(param) ((param) << 4)
  57# define CR_MONO        0x0
  58# define CR_MONO_D      0x1
  59# define CR_PCM         0x2
  60# define CR_I2S         0x3
  61# define CR_TDM         0x4
  62# define CR_TDM_D       0x5
  63
  64/* DOFF_CTL */
  65/* DIFF_CTL */
  66#define IRQ_HALF        0x00100000
  67#define FIFO_CLR        0x00000001
  68
  69/* DOFF_ST */
  70#define ERR_OVER        0x00000010
  71#define ERR_UNDER       0x00000001
  72
  73/* CLK_RST */
  74#define B_CLK           0x00000010
  75#define A_CLK           0x00000001
  76
  77/* INT_ST */
  78#define INT_B_IN        (1 << 12)
  79#define INT_B_OUT       (1 << 8)
  80#define INT_A_IN        (1 << 4)
  81#define INT_A_OUT       (1 << 0)
  82
  83#define FSI_RATES SNDRV_PCM_RATE_8000_96000
  84
  85#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
  86
  87/************************************************************************
  88
  89
  90                struct
  91
  92
  93************************************************************************/
  94struct fsi_priv {
  95        void __iomem *base;
  96        struct snd_pcm_substream *substream;
  97
  98        int fifo_max;
  99        int chan;
 100        int dma_chan;
 101
 102        int byte_offset;
 103        int period_len;
 104        int buffer_len;
 105        int periods;
 106};
 107
 108struct fsi_master {
 109        void __iomem *base;
 110        int irq;
 111        struct clk *clk;
 112        struct fsi_priv fsia;
 113        struct fsi_priv fsib;
 114        struct sh_fsi_platform_info *info;
 115};
 116
 117static struct fsi_master *master;
 118
 119/************************************************************************
 120
 121
 122                basic read write function
 123
 124
 125************************************************************************/
 126static int __fsi_reg_write(u32 reg, u32 data)
 127{
 128        /* valid data area is 24bit */
 129        data &= 0x00ffffff;
 130
 131        return ctrl_outl(data, reg);
 132}
 133
 134static u32 __fsi_reg_read(u32 reg)
 135{
 136        return ctrl_inl(reg);
 137}
 138
 139static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
 140{
 141        u32 val = __fsi_reg_read(reg);
 142
 143        val &= ~mask;
 144        val |= data & mask;
 145
 146        return __fsi_reg_write(reg, val);
 147}
 148
 149static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
 150{
 151        if (reg > REG_END)
 152                return -1;
 153
 154        return __fsi_reg_write((u32)(fsi->base + reg), data);
 155}
 156
 157static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
 158{
 159        if (reg > REG_END)
 160                return 0;
 161
 162        return __fsi_reg_read((u32)(fsi->base + reg));
 163}
 164
 165static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
 166{
 167        if (reg > REG_END)
 168                return -1;
 169
 170        return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
 171}
 172
 173static int fsi_master_write(u32 reg, u32 data)
 174{
 175        if ((reg < MREG_START) ||
 176            (reg > MREG_END))
 177                return -1;
 178
 179        return __fsi_reg_write((u32)(master->base + reg), data);
 180}
 181
 182static u32 fsi_master_read(u32 reg)
 183{
 184        if ((reg < MREG_START) ||
 185            (reg > MREG_END))
 186                return 0;
 187
 188        return __fsi_reg_read((u32)(master->base + reg));
 189}
 190
 191static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
 192{
 193        if ((reg < MREG_START) ||
 194            (reg > MREG_END))
 195                return -1;
 196
 197        return __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
 198}
 199
 200/************************************************************************
 201
 202
 203                basic function
 204
 205
 206************************************************************************/
 207static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream)
 208{
 209        struct snd_soc_pcm_runtime *rtd;
 210        struct fsi_priv *fsi = NULL;
 211
 212        if (!substream || !master)
 213                return NULL;
 214
 215        rtd = substream->private_data;
 216        switch (rtd->dai->cpu_dai->id) {
 217        case 0:
 218                fsi = &master->fsia;
 219                break;
 220        case 1:
 221                fsi = &master->fsib;
 222                break;
 223        }
 224
 225        return fsi;
 226}
 227
 228static int fsi_is_port_a(struct fsi_priv *fsi)
 229{
 230        /* return
 231         * 1 : port a
 232         * 0 : port b
 233         */
 234
 235        if (fsi == &master->fsia)
 236                return 1;
 237
 238        return 0;
 239}
 240
 241static u32 fsi_get_info_flags(struct fsi_priv *fsi)
 242{
 243        int is_porta = fsi_is_port_a(fsi);
 244
 245        return is_porta ? master->info->porta_flags :
 246                master->info->portb_flags;
 247}
 248
 249static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
 250{
 251        u32 mode;
 252        u32 flags = fsi_get_info_flags(fsi);
 253
 254        mode = is_play ? SH_FSI_OUT_SLAVE_MODE : SH_FSI_IN_SLAVE_MODE;
 255
 256        /* return
 257         * 1 : master mode
 258         * 0 : slave mode
 259         */
 260
 261        return (mode & flags) != mode;
 262}
 263
 264static u32 fsi_port_ab_io_bit(struct fsi_priv *fsi, int is_play)
 265{
 266        int is_porta = fsi_is_port_a(fsi);
 267        u32 data;
 268
 269        if (is_porta)
 270                data = is_play ? (1 << 0) : (1 << 4);
 271        else
 272                data = is_play ? (1 << 8) : (1 << 12);
 273
 274        return data;
 275}
 276
 277static void fsi_stream_push(struct fsi_priv *fsi,
 278                            struct snd_pcm_substream *substream,
 279                            u32 buffer_len,
 280                            u32 period_len)
 281{
 282        fsi->substream          = substream;
 283        fsi->buffer_len         = buffer_len;
 284        fsi->period_len         = period_len;
 285        fsi->byte_offset        = 0;
 286        fsi->periods            = 0;
 287}
 288
 289static void fsi_stream_pop(struct fsi_priv *fsi)
 290{
 291        fsi->substream          = NULL;
 292        fsi->buffer_len         = 0;
 293        fsi->period_len         = 0;
 294        fsi->byte_offset        = 0;
 295        fsi->periods            = 0;
 296}
 297
 298static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
 299{
 300        u32 status;
 301        u32 reg = is_play ? DOFF_ST : DIFF_ST;
 302        int residue;
 303
 304        status = fsi_reg_read(fsi, reg);
 305        residue = 0x1ff & (status >> 8);
 306        residue *= fsi->chan;
 307
 308        return residue;
 309}
 310
 311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
 312{
 313        int residue;
 314        int width;
 315        struct snd_pcm_runtime *runtime;
 316
 317        runtime = fsi->substream->runtime;
 318
 319        /* get 1 channel data width */
 320        width = frames_to_bytes(runtime, 1) / fsi->chan;
 321
 322        if (2 == width)
 323                residue = fsi_get_fifo_residue(fsi, is_play);
 324        else
 325                residue = get_dma_residue(fsi->dma_chan);
 326
 327        return residue;
 328}
 329
 330/************************************************************************
 331
 332
 333                basic dma function
 334
 335
 336************************************************************************/
 337#define PORTA_DMA 0
 338#define PORTB_DMA 1
 339
 340static int fsi_get_dma_chan(void)
 341{
 342        if (0 != request_dma(PORTA_DMA, "fsia"))
 343                return -EIO;
 344
 345        if (0 != request_dma(PORTB_DMA, "fsib")) {
 346                free_dma(PORTA_DMA);
 347                return -EIO;
 348        }
 349
 350        master->fsia.dma_chan = PORTA_DMA;
 351        master->fsib.dma_chan = PORTB_DMA;
 352
 353        return 0;
 354}
 355
 356static void fsi_free_dma_chan(void)
 357{
 358        dma_wait_for_completion(PORTA_DMA);
 359        dma_wait_for_completion(PORTB_DMA);
 360        free_dma(PORTA_DMA);
 361        free_dma(PORTB_DMA);
 362
 363        master->fsia.dma_chan = -1;
 364        master->fsib.dma_chan = -1;
 365}
 366
 367/************************************************************************
 368
 369
 370                ctrl function
 371
 372
 373************************************************************************/
 374static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
 375{
 376        u32 data = fsi_port_ab_io_bit(fsi, is_play);
 377
 378        fsi_master_mask_set(IMSK,  data, data);
 379        fsi_master_mask_set(IEMSK, data, data);
 380}
 381
 382static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
 383{
 384        u32 data = fsi_port_ab_io_bit(fsi, is_play);
 385
 386        fsi_master_mask_set(IMSK,  data, 0);
 387        fsi_master_mask_set(IEMSK, data, 0);
 388}
 389
 390static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
 391{
 392        u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
 393
 394        if (enable)
 395                fsi_master_mask_set(CLK_RST, val, val);
 396        else
 397                fsi_master_mask_set(CLK_RST, val, 0);
 398}
 399
 400static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
 401{
 402        u32 data;
 403        u32 ctrl;
 404
 405        data = fsi_port_ab_io_bit(fsi, is_play);
 406        ctrl = is_play ? DOFF_CTL : DIFF_CTL;
 407
 408        /* set IMSK */
 409        fsi_irq_disable(fsi, is_play);
 410
 411        /* set interrupt generation factor */
 412        fsi_reg_write(fsi, ctrl, IRQ_HALF);
 413
 414        /* clear FIFO */
 415        fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
 416
 417        /* clear interrupt factor */
 418        fsi_master_mask_set(INT_ST, data, 0);
 419}
 420
 421static void fsi_soft_all_reset(void)
 422{
 423        u32 status = fsi_master_read(SOFT_RST);
 424
 425        /* port AB reset */
 426        status &= 0x000000ff;
 427        fsi_master_write(SOFT_RST, status);
 428        mdelay(10);
 429
 430        /* soft reset */
 431        status &= 0x000000f0;
 432        fsi_master_write(SOFT_RST, status);
 433        status |= 0x00000001;
 434        fsi_master_write(SOFT_RST, status);
 435        mdelay(10);
 436}
 437
 438static void fsi_16data_push(struct fsi_priv *fsi,
 439                           struct snd_pcm_runtime *runtime,
 440                           int send)
 441{
 442        u16 *dma_start;
 443        u32 snd;
 444        int i;
 445
 446        /* get dma start position for FSI */
 447        dma_start = (u16 *)runtime->dma_area;
 448        dma_start += fsi->byte_offset / 2;
 449
 450        /*
 451         * soft dma
 452         * FSI can not use DMA when 16bpp
 453         */
 454        for (i = 0; i < send; i++) {
 455                snd = (u32)dma_start[i];
 456                fsi_reg_write(fsi, DODT, snd << 8);
 457        }
 458}
 459
 460static void fsi_32data_push(struct fsi_priv *fsi,
 461                           struct snd_pcm_runtime *runtime,
 462                           int send)
 463{
 464        u32 *dma_start;
 465
 466        /* get dma start position for FSI */
 467        dma_start = (u32 *)runtime->dma_area;
 468        dma_start += fsi->byte_offset / 4;
 469
 470        dma_wait_for_completion(fsi->dma_chan);
 471        dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
 472        dma_write(fsi->dma_chan, (u32)dma_start,
 473                  (u32)(fsi->base + DODT), send * 4);
 474}
 475
 476/* playback interrupt */
 477static int fsi_data_push(struct fsi_priv *fsi)
 478{
 479        struct snd_pcm_runtime *runtime;
 480        struct snd_pcm_substream *substream = NULL;
 481        int send;
 482        int fifo_free;
 483        int width;
 484
 485        if (!fsi                        ||
 486            !fsi->substream             ||
 487            !fsi->substream->runtime)
 488                return -EINVAL;
 489
 490        runtime = fsi->substream->runtime;
 491
 492        /* FSI FIFO has limit.
 493         * So, this driver can not send periods data at a time
 494         */
 495        if (fsi->byte_offset >=
 496            fsi->period_len * (fsi->periods + 1)) {
 497
 498                substream = fsi->substream;
 499                fsi->periods = (fsi->periods + 1) % runtime->periods;
 500
 501                if (0 == fsi->periods)
 502                        fsi->byte_offset = 0;
 503        }
 504
 505        /* get 1 channel data width */
 506        width = frames_to_bytes(runtime, 1) / fsi->chan;
 507
 508        /* get send size for alsa */
 509        send = (fsi->buffer_len - fsi->byte_offset) / width;
 510
 511        /*  get FIFO free size */
 512        fifo_free = (fsi->fifo_max * fsi->chan) - fsi_get_fifo_residue(fsi, 1);
 513
 514        /* size check */
 515        if (fifo_free < send)
 516                send = fifo_free;
 517
 518        if (2 == width)
 519                fsi_16data_push(fsi, runtime, send);
 520        else if (4 == width)
 521                fsi_32data_push(fsi, runtime, send);
 522        else
 523                return -EINVAL;
 524
 525        fsi->byte_offset += send * width;
 526
 527        fsi_irq_enable(fsi, 1);
 528
 529        if (substream)
 530                snd_pcm_period_elapsed(substream);
 531
 532        return 0;
 533}
 534
 535static irqreturn_t fsi_interrupt(int irq, void *data)
 536{
 537        u32 status = fsi_master_read(SOFT_RST) & ~0x00000010;
 538        u32 int_st = fsi_master_read(INT_ST);
 539
 540        /* clear irq status */
 541        fsi_master_write(SOFT_RST, status);
 542        fsi_master_write(SOFT_RST, status | 0x00000010);
 543
 544        if (int_st & INT_A_OUT)
 545                fsi_data_push(&master->fsia);
 546        if (int_st & INT_B_OUT)
 547                fsi_data_push(&master->fsib);
 548
 549        fsi_master_write(INT_ST, 0x0000000);
 550
 551        return IRQ_HANDLED;
 552}
 553
 554/************************************************************************
 555
 556
 557                dai ops
 558
 559
 560************************************************************************/
 561static int fsi_dai_startup(struct snd_pcm_substream *substream,
 562                           struct snd_soc_dai *dai)
 563{
 564        struct fsi_priv *fsi = fsi_get(substream);
 565        const char *msg;
 566        u32 flags = fsi_get_info_flags(fsi);
 567        u32 fmt;
 568        u32 reg;
 569        u32 data;
 570        int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 571        int is_master;
 572        int ret = 0;
 573
 574        clk_enable(master->clk);
 575
 576        /* CKG1 */
 577        data = is_play ? (1 << 0) : (1 << 4);
 578        is_master = fsi_is_master_mode(fsi, is_play);
 579        if (is_master)
 580                fsi_reg_mask_set(fsi, CKG1, data, data);
 581        else
 582                fsi_reg_mask_set(fsi, CKG1, data, 0);
 583
 584        /* clock inversion (CKG2) */
 585        data = 0;
 586        switch (SH_FSI_INVERSION_MASK & flags) {
 587        case SH_FSI_LRM_INV:
 588                data = 1 << 12;
 589                break;
 590        case SH_FSI_BRM_INV:
 591                data = 1 << 8;
 592                break;
 593        case SH_FSI_LRS_INV:
 594                data = 1 << 4;
 595                break;
 596        case SH_FSI_BRS_INV:
 597                data = 1 << 0;
 598                break;
 599        }
 600        fsi_reg_write(fsi, CKG2, data);
 601
 602        /* do fmt, di fmt */
 603        data = 0;
 604        reg = is_play ? DO_FMT : DI_FMT;
 605        fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
 606        switch (fmt) {
 607        case SH_FSI_FMT_MONO:
 608                msg = "MONO";
 609                data = CR_FMT(CR_MONO);
 610                fsi->chan = 1;
 611                break;
 612        case SH_FSI_FMT_MONO_DELAY:
 613                msg = "MONO Delay";
 614                data = CR_FMT(CR_MONO_D);
 615                fsi->chan = 1;
 616                break;
 617        case SH_FSI_FMT_PCM:
 618                msg = "PCM";
 619                data = CR_FMT(CR_PCM);
 620                fsi->chan = 2;
 621                break;
 622        case SH_FSI_FMT_I2S:
 623                msg = "I2S";
 624                data = CR_FMT(CR_I2S);
 625                fsi->chan = 2;
 626                break;
 627        case SH_FSI_FMT_TDM:
 628                msg = "TDM";
 629                data = CR_FMT(CR_TDM) | (fsi->chan - 1);
 630                fsi->chan = is_play ?
 631                        SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
 632                break;
 633        case SH_FSI_FMT_TDM_DELAY:
 634                msg = "TDM Delay";
 635                data = CR_FMT(CR_TDM_D) | (fsi->chan - 1);
 636                fsi->chan = is_play ?
 637                        SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
 638                break;
 639        default:
 640                dev_err(dai->dev, "unknown format.\n");
 641                return -EINVAL;
 642        }
 643
 644        switch (fsi->chan) {
 645        case 1:
 646                fsi->fifo_max = 256;
 647                break;
 648        case 2:
 649                fsi->fifo_max = 128;
 650                break;
 651        case 3:
 652        case 4:
 653                fsi->fifo_max = 64;
 654                break;
 655        case 5:
 656        case 6:
 657        case 7:
 658        case 8:
 659                fsi->fifo_max = 32;
 660                break;
 661        default:
 662                dev_err(dai->dev, "channel size error.\n");
 663                return -EINVAL;
 664        }
 665
 666        fsi_reg_write(fsi, reg, data);
 667        dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
 668                msg, fsi->chan, fsi->dma_chan);
 669
 670        /*
 671         * clear clk reset if master mode
 672         */
 673        if (is_master)
 674                fsi_clk_ctrl(fsi, 1);
 675
 676        /* irq setting */
 677        fsi_irq_init(fsi, is_play);
 678
 679        return ret;
 680}
 681
 682static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
 683                             struct snd_soc_dai *dai)
 684{
 685        struct fsi_priv *fsi = fsi_get(substream);
 686        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 687
 688        fsi_irq_disable(fsi, is_play);
 689        fsi_clk_ctrl(fsi, 0);
 690
 691        clk_disable(master->clk);
 692}
 693
 694static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 695                           struct snd_soc_dai *dai)
 696{
 697        struct fsi_priv *fsi = fsi_get(substream);
 698        struct snd_pcm_runtime *runtime = substream->runtime;
 699        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 700        int ret = 0;
 701
 702        /* capture not supported */
 703        if (!is_play)
 704                return -ENODEV;
 705
 706        switch (cmd) {
 707        case SNDRV_PCM_TRIGGER_START:
 708                fsi_stream_push(fsi, substream,
 709                                frames_to_bytes(runtime, runtime->buffer_size),
 710                                frames_to_bytes(runtime, runtime->period_size));
 711                ret = fsi_data_push(fsi);
 712                break;
 713        case SNDRV_PCM_TRIGGER_STOP:
 714                fsi_irq_disable(fsi, is_play);
 715                fsi_stream_pop(fsi);
 716                break;
 717        }
 718
 719        return ret;
 720}
 721
 722static struct snd_soc_dai_ops fsi_dai_ops = {
 723        .startup        = fsi_dai_startup,
 724        .shutdown       = fsi_dai_shutdown,
 725        .trigger        = fsi_dai_trigger,
 726};
 727
 728/************************************************************************
 729
 730
 731                pcm ops
 732
 733
 734************************************************************************/
 735static struct snd_pcm_hardware fsi_pcm_hardware = {
 736        .info =         SNDRV_PCM_INFO_INTERLEAVED      |
 737                        SNDRV_PCM_INFO_MMAP             |
 738                        SNDRV_PCM_INFO_MMAP_VALID       |
 739                        SNDRV_PCM_INFO_PAUSE,
 740        .formats                = FSI_FMTS,
 741        .rates                  = FSI_RATES,
 742        .rate_min               = 8000,
 743        .rate_max               = 192000,
 744        .channels_min           = 1,
 745        .channels_max           = 2,
 746        .buffer_bytes_max       = 64 * 1024,
 747        .period_bytes_min       = 32,
 748        .period_bytes_max       = 8192,
 749        .periods_min            = 1,
 750        .periods_max            = 32,
 751        .fifo_size              = 256,
 752};
 753
 754static int fsi_pcm_open(struct snd_pcm_substream *substream)
 755{
 756        struct snd_pcm_runtime *runtime = substream->runtime;
 757        int ret = 0;
 758
 759        snd_soc_set_runtime_hwparams(substream, &fsi_pcm_hardware);
 760
 761        ret = snd_pcm_hw_constraint_integer(runtime,
 762                                            SNDRV_PCM_HW_PARAM_PERIODS);
 763
 764        return ret;
 765}
 766
 767static int fsi_hw_params(struct snd_pcm_substream *substream,
 768                         struct snd_pcm_hw_params *hw_params)
 769{
 770        return snd_pcm_lib_malloc_pages(substream,
 771                                        params_buffer_bytes(hw_params));
 772}
 773
 774static int fsi_hw_free(struct snd_pcm_substream *substream)
 775{
 776        return snd_pcm_lib_free_pages(substream);
 777}
 778
 779static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
 780{
 781        struct snd_pcm_runtime *runtime = substream->runtime;
 782        struct fsi_priv *fsi = fsi_get(substream);
 783        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 784        long location;
 785
 786        location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play);
 787        if (location < 0)
 788                location = 0;
 789
 790        return bytes_to_frames(runtime, location);
 791}
 792
 793static struct snd_pcm_ops fsi_pcm_ops = {
 794        .open           = fsi_pcm_open,
 795        .ioctl          = snd_pcm_lib_ioctl,
 796        .hw_params      = fsi_hw_params,
 797        .hw_free        = fsi_hw_free,
 798        .pointer        = fsi_pointer,
 799};
 800
 801/************************************************************************
 802
 803
 804                snd_soc_platform
 805
 806
 807************************************************************************/
 808#define PREALLOC_BUFFER         (32 * 1024)
 809#define PREALLOC_BUFFER_MAX     (32 * 1024)
 810
 811static void fsi_pcm_free(struct snd_pcm *pcm)
 812{
 813        snd_pcm_lib_preallocate_free_for_all(pcm);
 814}
 815
 816static int fsi_pcm_new(struct snd_card *card,
 817                       struct snd_soc_dai *dai,
 818                       struct snd_pcm *pcm)
 819{
 820        /*
 821         * dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
 822         * in MMAP mode (i.e. aplay -M)
 823         */
 824        return snd_pcm_lib_preallocate_pages_for_all(
 825                pcm,
 826                SNDRV_DMA_TYPE_CONTINUOUS,
 827                snd_dma_continuous_data(GFP_KERNEL),
 828                PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
 829}
 830
 831/************************************************************************
 832
 833
 834                alsa struct
 835
 836
 837************************************************************************/
 838struct snd_soc_dai fsi_soc_dai[] = {
 839        {
 840                .name                   = "FSIA",
 841                .id                     = 0,
 842                .playback = {
 843                        .rates          = FSI_RATES,
 844                        .formats        = FSI_FMTS,
 845                        .channels_min   = 1,
 846                        .channels_max   = 8,
 847                },
 848                /* capture not supported */
 849                .ops = &fsi_dai_ops,
 850        },
 851        {
 852                .name                   = "FSIB",
 853                .id                     = 1,
 854                .playback = {
 855                        .rates          = FSI_RATES,
 856                        .formats        = FSI_FMTS,
 857                        .channels_min   = 1,
 858                        .channels_max   = 8,
 859                },
 860                /* capture not supported */
 861                .ops = &fsi_dai_ops,
 862        },
 863};
 864EXPORT_SYMBOL_GPL(fsi_soc_dai);
 865
 866struct snd_soc_platform fsi_soc_platform = {
 867        .name           = "fsi-pcm",
 868        .pcm_ops        = &fsi_pcm_ops,
 869        .pcm_new        = fsi_pcm_new,
 870        .pcm_free       = fsi_pcm_free,
 871};
 872EXPORT_SYMBOL_GPL(fsi_soc_platform);
 873
 874/************************************************************************
 875
 876
 877                platform function
 878
 879
 880************************************************************************/
 881static int fsi_probe(struct platform_device *pdev)
 882{
 883        struct resource *res;
 884        char clk_name[8];
 885        unsigned int irq;
 886        int ret;
 887
 888        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 889        irq = platform_get_irq(pdev, 0);
 890        if (!res || !irq) {
 891                dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
 892                ret = -ENODEV;
 893                goto exit;
 894        }
 895
 896        master = kzalloc(sizeof(*master), GFP_KERNEL);
 897        if (!master) {
 898                dev_err(&pdev->dev, "Could not allocate master\n");
 899                ret = -ENOMEM;
 900                goto exit;
 901        }
 902
 903        master->base = ioremap_nocache(res->start, resource_size(res));
 904        if (!master->base) {
 905                ret = -ENXIO;
 906                dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n");
 907                goto exit_kfree;
 908        }
 909
 910        master->irq             = irq;
 911        master->info            = pdev->dev.platform_data;
 912        master->fsia.base       = master->base;
 913        master->fsib.base       = master->base + 0x40;
 914
 915        master->fsia.dma_chan = -1;
 916        master->fsib.dma_chan = -1;
 917
 918        ret = fsi_get_dma_chan();
 919        if (ret < 0) {
 920                dev_err(&pdev->dev, "cannot get dma api\n");
 921                goto exit_iounmap;
 922        }
 923
 924        /* FSI is based on SPU mstp */
 925        snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
 926        master->clk = clk_get(NULL, clk_name);
 927        if (IS_ERR(master->clk)) {
 928                dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
 929                ret = -EIO;
 930                goto exit_free_dma;
 931        }
 932
 933        fsi_soc_dai[0].dev              = &pdev->dev;
 934        fsi_soc_dai[1].dev              = &pdev->dev;
 935
 936        fsi_soft_all_reset();
 937
 938        ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
 939        if (ret) {
 940                dev_err(&pdev->dev, "irq request err\n");
 941                goto exit_free_dma;
 942        }
 943
 944        ret = snd_soc_register_platform(&fsi_soc_platform);
 945        if (ret < 0) {
 946                dev_err(&pdev->dev, "cannot snd soc register\n");
 947                goto exit_free_irq;
 948        }
 949
 950        return snd_soc_register_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
 951
 952exit_free_irq:
 953        free_irq(irq, master);
 954exit_free_dma:
 955        fsi_free_dma_chan();
 956exit_iounmap:
 957        iounmap(master->base);
 958exit_kfree:
 959        kfree(master);
 960        master = NULL;
 961exit:
 962        return ret;
 963}
 964
 965static int fsi_remove(struct platform_device *pdev)
 966{
 967        snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
 968        snd_soc_unregister_platform(&fsi_soc_platform);
 969
 970        clk_put(master->clk);
 971
 972        fsi_free_dma_chan();
 973
 974        free_irq(master->irq, master);
 975
 976        iounmap(master->base);
 977        kfree(master);
 978        master = NULL;
 979        return 0;
 980}
 981
 982static struct platform_driver fsi_driver = {
 983        .driver         = {
 984                .name   = "sh_fsi",
 985        },
 986        .probe          = fsi_probe,
 987        .remove         = fsi_remove,
 988};
 989
 990static int __init fsi_mobile_init(void)
 991{
 992        return platform_driver_register(&fsi_driver);
 993}
 994
 995static void __exit fsi_mobile_exit(void)
 996{
 997        platform_driver_unregister(&fsi_driver);
 998}
 999module_init(fsi_mobile_init);
1000module_exit(fsi_mobile_exit);
1001
1002MODULE_LICENSE("GPL");
1003MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
1004MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
1005