linux/arch/cris/arch-v10/drivers/sync_serial.c
<<
>>
Prefs
   1/*
   2 * Simple synchronous serial port driver for ETRAX 100LX.
   3 *
   4 * Synchronous serial ports are used for continuous streamed data like audio.
   5 * The default setting for this driver is compatible with the STA 013 MP3
   6 * decoder. The driver can easily be tuned to fit other audio encoder/decoders
   7 * and SPI
   8 *
   9 * Copyright (c) 2001-2008 Axis Communications AB
  10 *
  11 * Author: Mikael Starvik, Johan Adolfsson
  12 *
  13 */
  14#include <linux/module.h>
  15#include <linux/kernel.h>
  16#include <linux/types.h>
  17#include <linux/errno.h>
  18#include <linux/major.h>
  19#include <linux/sched.h>
  20#include <linux/slab.h>
  21#include <linux/interrupt.h>
  22#include <linux/poll.h>
  23#include <linux/init.h>
  24#include <linux/smp_lock.h>
  25#include <linux/timer.h>
  26#include <asm/irq.h>
  27#include <asm/dma.h>
  28#include <asm/io.h>
  29#include <arch/svinto.h>
  30#include <asm/uaccess.h>
  31#include <asm/system.h>
  32#include <asm/sync_serial.h>
  33#include <arch/io_interface_mux.h>
  34
  35/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
  36/*                                                                       */
  37/* Three DMA descriptors are linked together. Each DMA descriptor is     */
  38/* responsible for port->bufchunk of a common buffer.                    */
  39/*                                                                       */
  40/* +---------------------------------------------+                       */
  41/* |   +----------+   +----------+   +----------+ |                      */
  42/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+                      */
  43/*     +----------+   +----------+   +----------+                        */
  44/*         |            |              |                                 */
  45/*         v            v              v                                 */
  46/*   +-------------------------------------+                             */
  47/*   |        BUFFER                       |                             */
  48/*   +-------------------------------------+                             */
  49/*      |<- data_avail ->|                                               */
  50/*    readp          writep                                              */
  51/*                                                                       */
  52/* If the application keeps up the pace readp will be right after writep.*/
  53/* If the application can't keep the pace we have to throw away data.    */
  54/* The idea is that readp should be ready with the data pointed out by   */
  55/* Descr[i] when the DMA has filled in Descr[i+1].                       */
  56/* Otherwise we will discard                                             */
  57/* the rest of the data pointed out by Descr1 and set readp to the start */
  58/* of Descr2                                                             */
  59
  60#define SYNC_SERIAL_MAJOR 125
  61
  62/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
  63/* words can be handled */
  64#define IN_BUFFER_SIZE 12288
  65#define IN_DESCR_SIZE 256
  66#define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
  67#define OUT_BUFFER_SIZE 4096
  68
  69#define DEFAULT_FRAME_RATE 0
  70#define DEFAULT_WORD_RATE 7
  71
  72/* NOTE: Enabling some debug will likely cause overrun or underrun,
  73 * especially if manual mode is use.
  74 */
  75#define DEBUG(x)
  76#define DEBUGREAD(x)
  77#define DEBUGWRITE(x)
  78#define DEBUGPOLL(x)
  79#define DEBUGRXINT(x)
  80#define DEBUGTXINT(x)
  81
  82/* Define some macros to access ETRAX 100 registers */
  83#define SETF(var, reg, field, val) \
  84        do { \
  85                var = (var & ~IO_MASK_(reg##_, field##_)) | \
  86                        IO_FIELD_(reg##_, field##_, val); \
  87        } while (0)
  88
  89#define SETS(var, reg, field, val) \
  90        do { \
  91                var = (var & ~IO_MASK_(reg##_, field##_)) | \
  92                        IO_STATE_(reg##_, field##_, _##val); \
  93        } while (0)
  94
  95struct sync_port {
  96        /* Etrax registers and bits*/
  97        const volatile unsigned *const status;
  98        volatile unsigned *const ctrl_data;
  99        volatile unsigned *const output_dma_first;
 100        volatile unsigned char *const output_dma_cmd;
 101        volatile unsigned char *const output_dma_clr_irq;
 102        volatile unsigned *const input_dma_first;
 103        volatile unsigned char *const input_dma_cmd;
 104        volatile unsigned *const input_dma_descr;
 105        /* 8*4 */
 106        volatile unsigned char *const input_dma_clr_irq;
 107        volatile unsigned *const data_out;
 108        const volatile unsigned *const data_in;
 109        char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
 110        char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */
 111        char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */
 112
 113        char output_dma_bit; /* In R_IRQ_MASK2_RD */
 114        /* End of fields initialised in array */
 115        char started; /* 1 if port has been started */
 116        char port_nbr; /* Port 0 or 1 */
 117        char busy; /* 1 if port is busy */
 118
 119        char enabled;  /* 1 if port is enabled */
 120        char use_dma;  /* 1 if port uses dma */
 121        char tr_running;
 122
 123        char init_irqs;
 124
 125        /* Register shadow */
 126        unsigned int ctrl_data_shadow;
 127        /* Remaining bytes for current transfer */
 128        volatile unsigned int out_count;
 129        /* Current position in out_buffer */
 130        unsigned char *outp;
 131        /* 16*4 */
 132        /* Next byte to be read by application */
 133        volatile unsigned char *volatile readp;
 134        /* Next byte to be written by etrax */
 135        volatile unsigned char *volatile writep;
 136
 137        unsigned int in_buffer_size;
 138        unsigned int inbufchunk;
 139        struct etrax_dma_descr out_descr __attribute__ ((aligned(32)));
 140        struct etrax_dma_descr in_descr[NUM_IN_DESCR] __attribute__ ((aligned(32)));
 141        unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
 142        unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32)));
 143        unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
 144        struct etrax_dma_descr *next_rx_desc;
 145        struct etrax_dma_descr *prev_rx_desc;
 146        int full;
 147
 148        wait_queue_head_t out_wait_q;
 149        wait_queue_head_t in_wait_q;
 150};
 151
 152
 153static int etrax_sync_serial_init(void);
 154static void initialize_port(int portnbr);
 155static inline int sync_data_avail(struct sync_port *port);
 156
 157static int sync_serial_open(struct inode *inode, struct file *file);
 158static int sync_serial_release(struct inode *inode, struct file *file);
 159static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
 160
 161static int sync_serial_ioctl(struct inode *inode, struct file *file,
 162        unsigned int cmd, unsigned long arg);
 163static ssize_t sync_serial_write(struct file *file, const char *buf,
 164        size_t count, loff_t *ppos);
 165static ssize_t sync_serial_read(struct file *file, char *buf,
 166        size_t count, loff_t *ppos);
 167
 168#if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
 169     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
 170    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
 171     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)))
 172#define SYNC_SER_DMA
 173#endif
 174
 175static void send_word(struct sync_port *port);
 176static void start_dma(struct sync_port *port, const char *data, int count);
 177static void start_dma_in(struct sync_port *port);
 178#ifdef SYNC_SER_DMA
 179static irqreturn_t tr_interrupt(int irq, void *dev_id);
 180static irqreturn_t rx_interrupt(int irq, void *dev_id);
 181#endif
 182#if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
 183     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
 184    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
 185     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)))
 186#define SYNC_SER_MANUAL
 187#endif
 188#ifdef SYNC_SER_MANUAL
 189static irqreturn_t manual_interrupt(int irq, void *dev_id);
 190#endif
 191
 192/* The ports */
 193static struct sync_port ports[] = {
 194        {
 195                .status                = R_SYNC_SERIAL1_STATUS,
 196                .ctrl_data             = R_SYNC_SERIAL1_CTRL,
 197                .output_dma_first      = R_DMA_CH8_FIRST,
 198                .output_dma_cmd        = R_DMA_CH8_CMD,
 199                .output_dma_clr_irq    = R_DMA_CH8_CLR_INTR,
 200                .input_dma_first       = R_DMA_CH9_FIRST,
 201                .input_dma_cmd         = R_DMA_CH9_CMD,
 202                .input_dma_descr       = R_DMA_CH9_DESCR,
 203                .input_dma_clr_irq     = R_DMA_CH9_CLR_INTR,
 204                .data_out              = R_SYNC_SERIAL1_TR_DATA,
 205                .data_in               = R_SYNC_SERIAL1_REC_DATA,
 206                .data_avail_bit        = IO_BITNR(R_IRQ_MASK1_RD, ser1_data),
 207                .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready),
 208                .input_dma_descr_bit   = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr),
 209                .output_dma_bit        = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),
 210                .init_irqs             = 1,
 211#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
 212                .use_dma               = 1,
 213#else
 214                .use_dma               = 0,
 215#endif
 216        },
 217        {
 218                .status                = R_SYNC_SERIAL3_STATUS,
 219                .ctrl_data             = R_SYNC_SERIAL3_CTRL,
 220                .output_dma_first      = R_DMA_CH4_FIRST,
 221                .output_dma_cmd        = R_DMA_CH4_CMD,
 222                .output_dma_clr_irq    = R_DMA_CH4_CLR_INTR,
 223                .input_dma_first       = R_DMA_CH5_FIRST,
 224                .input_dma_cmd         = R_DMA_CH5_CMD,
 225                .input_dma_descr       = R_DMA_CH5_DESCR,
 226                .input_dma_clr_irq     = R_DMA_CH5_CLR_INTR,
 227                .data_out              = R_SYNC_SERIAL3_TR_DATA,
 228                .data_in               = R_SYNC_SERIAL3_REC_DATA,
 229                .data_avail_bit        = IO_BITNR(R_IRQ_MASK1_RD, ser3_data),
 230                .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready),
 231                .input_dma_descr_bit   = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),
 232                .output_dma_bit        = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),
 233                .init_irqs             = 1,
 234#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
 235                .use_dma               = 1,
 236#else
 237                .use_dma               = 0,
 238#endif
 239        }
 240};
 241
 242/* Register shadows */
 243static unsigned sync_serial_prescale_shadow;
 244
 245#define NUMBER_OF_PORTS 2
 246
 247static const struct file_operations sync_serial_fops = {
 248        .owner   = THIS_MODULE,
 249        .write   = sync_serial_write,
 250        .read    = sync_serial_read,
 251        .poll    = sync_serial_poll,
 252        .ioctl   = sync_serial_ioctl,
 253        .open    = sync_serial_open,
 254        .release = sync_serial_release
 255};
 256
 257static int __init etrax_sync_serial_init(void)
 258{
 259        ports[0].enabled = 0;
 260        ports[1].enabled = 0;
 261
 262#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
 263        if (cris_request_io_interface(if_sync_serial_1, "sync_ser1")) {
 264                printk(KERN_CRIT "ETRAX100LX sync_serial: "
 265                        "Could not allocate IO group for port %d\n", 0);
 266                return -EBUSY;
 267        }
 268#endif
 269#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
 270        if (cris_request_io_interface(if_sync_serial_3, "sync_ser3")) {
 271#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
 272                cris_free_io_interface(if_sync_serial_1);
 273#endif
 274                printk(KERN_CRIT "ETRAX100LX sync_serial: "
 275                        "Could not allocate IO group for port %d\n", 1);
 276                return -EBUSY;
 277        }
 278#endif
 279
 280        if (register_chrdev(SYNC_SERIAL_MAJOR, "sync serial",
 281                        &sync_serial_fops) < 0) {
 282#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
 283                cris_free_io_interface(if_sync_serial_3);
 284#endif
 285#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
 286                cris_free_io_interface(if_sync_serial_1);
 287#endif
 288                printk("unable to get major for synchronous serial port\n");
 289                return -EBUSY;
 290        }
 291
 292        /* Deselect synchronous serial ports while configuring. */
 293        SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
 294        SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
 295        *R_GEN_CONFIG_II = gen_config_ii_shadow;
 296
 297        /* Initialize Ports */
 298#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
 299        ports[0].enabled = 1;
 300        SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra);
 301        SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
 302#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
 303        ports[0].use_dma = 1;
 304#else
 305        ports[0].use_dma = 0;
 306#endif
 307        initialize_port(0);
 308#endif
 309
 310#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
 311        ports[1].enabled = 1;
 312        SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser3, ss3extra);
 313        SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
 314#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
 315        ports[1].use_dma = 1;
 316#else
 317        ports[1].use_dma = 0;
 318#endif
 319        initialize_port(1);
 320#endif
 321
 322        *R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */
 323
 324        /* Set up timing */
 325        *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow = (
 326                IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec) |
 327                IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u1, external) |
 328                IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) |
 329                IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) |
 330                IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) |
 331                IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate,
 332                        DEFAULT_FRAME_RATE) |
 333                IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, DEFAULT_WORD_RATE) |
 334                IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal));
 335
 336        /* Select synchronous ports */
 337        *R_GEN_CONFIG_II = gen_config_ii_shadow;
 338
 339        printk(KERN_INFO "ETRAX 100LX synchronous serial port driver\n");
 340        return 0;
 341}
 342
 343static void __init initialize_port(int portnbr)
 344{
 345        struct sync_port *port = &ports[portnbr];
 346
 347        DEBUG(printk(KERN_DEBUG "Init sync serial port %d\n", portnbr));
 348
 349        port->started = 0;
 350        port->port_nbr = portnbr;
 351        port->busy = 0;
 352        port->tr_running = 0;
 353
 354        port->out_count = 0;
 355        port->outp = port->out_buffer;
 356
 357        port->readp = port->flip;
 358        port->writep = port->flip;
 359        port->in_buffer_size = IN_BUFFER_SIZE;
 360        port->inbufchunk = IN_DESCR_SIZE;
 361        port->next_rx_desc = &port->in_descr[0];
 362        port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1];
 363        port->prev_rx_desc->ctrl = d_eol;
 364
 365        init_waitqueue_head(&port->out_wait_q);
 366        init_waitqueue_head(&port->in_wait_q);
 367
 368        port->ctrl_data_shadow =
 369                IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz)   |
 370                IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) |
 371                IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore)       |
 372                IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) |
 373                IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal)  |
 374                IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word)    |
 375                IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on)            |
 376                IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal)    |
 377                IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped)   |
 378                IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb)         |
 379                IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable)  |
 380                IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit)  |
 381                IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8)    |
 382                IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8)     |
 383                IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled)  |
 384                IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg)   |
 385                IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)|
 386                IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)|
 387                IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal)   |
 388                IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) |
 389                IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)|
 390                IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high);
 391
 392        if (port->use_dma)
 393                port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL,
 394                        dma_enable, on);
 395        else
 396                port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL,
 397                        dma_enable, off);
 398
 399        *port->ctrl_data = port->ctrl_data_shadow;
 400}
 401
 402static inline int sync_data_avail(struct sync_port *port)
 403{
 404        int avail;
 405        unsigned char *start;
 406        unsigned char *end;
 407
 408        start = (unsigned char *)port->readp; /* cast away volatile */
 409        end = (unsigned char *)port->writep;  /* cast away volatile */
 410        /* 0123456789  0123456789
 411         *  -----      -    -----
 412         *  ^rp  ^wp    ^wp ^rp
 413         */
 414        if (end >= start)
 415                avail = end - start;
 416        else
 417                avail = port->in_buffer_size - (start - end);
 418        return avail;
 419}
 420
 421static inline int sync_data_avail_to_end(struct sync_port *port)
 422{
 423        int avail;
 424        unsigned char *start;
 425        unsigned char *end;
 426
 427        start = (unsigned char *)port->readp; /* cast away volatile */
 428        end = (unsigned char *)port->writep;  /* cast away volatile */
 429        /* 0123456789  0123456789
 430         *  -----           -----
 431         *  ^rp  ^wp    ^wp ^rp
 432         */
 433
 434        if (end >= start)
 435                avail = end - start;
 436        else
 437                avail = port->flip + port->in_buffer_size - start;
 438        return avail;
 439}
 440
 441
 442static int sync_serial_open(struct inode *inode, struct file *file)
 443{
 444        int dev = MINOR(inode->i_rdev);
 445        struct sync_port *port;
 446        int mode;
 447        int err = -EBUSY;
 448
 449        lock_kernel();
 450        DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
 451
 452        if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
 453                DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
 454                err = -ENODEV;
 455                goto out;
 456        }
 457        port = &ports[dev];
 458        /* Allow open this device twice (assuming one reader and one writer) */
 459        if (port->busy == 2) {
 460                DEBUG(printk(KERN_DEBUG "Device is busy.. \n"));
 461                goto out;
 462        }
 463        if (port->init_irqs) {
 464                if (port->use_dma) {
 465                        if (port == &ports[0]) {
 466#ifdef SYNC_SER_DMA
 467                                if (request_irq(24, tr_interrupt, 0,
 468                                                "synchronous serial 1 dma tr",
 469                                                &ports[0])) {
 470                                        printk(KERN_CRIT "Can't alloc "
 471                                                "sync serial port 1 IRQ");
 472                                        goto out;
 473                                } else if (request_irq(25, rx_interrupt, 0,
 474                                                "synchronous serial 1 dma rx",
 475                                                &ports[0])) {
 476                                        free_irq(24, &port[0]);
 477                                        printk(KERN_CRIT "Can't alloc "
 478                                                "sync serial port 1 IRQ");
 479                                        goto out;
 480                                } else if (cris_request_dma(8,
 481                                                "synchronous serial 1 dma tr",
 482                                                DMA_VERBOSE_ON_ERROR,
 483                                                dma_ser1)) {
 484                                        free_irq(24, &port[0]);
 485                                        free_irq(25, &port[0]);
 486                                        printk(KERN_CRIT "Can't alloc "
 487                                                "sync serial port 1 "
 488                                                "TX DMA channel");
 489                                        goto out;
 490                                } else if (cris_request_dma(9,
 491                                                "synchronous serial 1 dma rec",
 492                                                DMA_VERBOSE_ON_ERROR,
 493                                                dma_ser1)) {
 494                                        cris_free_dma(8, NULL);
 495                                        free_irq(24, &port[0]);
 496                                        free_irq(25, &port[0]);
 497                                        printk(KERN_CRIT "Can't alloc "
 498                                                "sync serial port 1 "
 499                                                "RX DMA channel");
 500                                        goto out;
 501                                }
 502#endif
 503                                RESET_DMA(8); WAIT_DMA(8);
 504                                RESET_DMA(9); WAIT_DMA(9);
 505                                *R_DMA_CH8_CLR_INTR =
 506                                        IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop,
 507                                                do) |
 508                                        IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr,
 509                                                do);
 510                                *R_DMA_CH9_CLR_INTR =
 511                                        IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop,
 512                                                do) |
 513                                        IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr,
 514                                                do);
 515                                *R_IRQ_MASK2_SET =
 516                                        IO_STATE(R_IRQ_MASK2_SET, dma8_eop,
 517                                                set) |
 518                                        IO_STATE(R_IRQ_MASK2_SET, dma9_descr,
 519                                                set);
 520                        } else if (port == &ports[1]) {
 521#ifdef SYNC_SER_DMA
 522                                if (request_irq(20, tr_interrupt, 0,
 523                                                "synchronous serial 3 dma tr",
 524                                                &ports[1])) {
 525                                        printk(KERN_CRIT "Can't alloc "
 526                                                "sync serial port 3 IRQ");
 527                                        goto out;
 528                                } else if (request_irq(21, rx_interrupt, 0,
 529                                                "synchronous serial 3 dma rx",
 530                                                &ports[1])) {
 531                                        free_irq(20, &ports[1]);
 532                                        printk(KERN_CRIT "Can't alloc "
 533                                                "sync serial port 3 IRQ");
 534                                        goto out;
 535                                } else if (cris_request_dma(4,
 536                                                "synchronous serial 3 dma tr",
 537                                                DMA_VERBOSE_ON_ERROR,
 538                                                dma_ser3)) {
 539                                        free_irq(21, &ports[1]);
 540                                        free_irq(20, &ports[1]);
 541                                        printk(KERN_CRIT "Can't alloc "
 542                                                "sync serial port 3 "
 543                                                "TX DMA channel");
 544                                        goto out;
 545                                } else if (cris_request_dma(5,
 546                                                "synchronous serial 3 dma rec",
 547                                                DMA_VERBOSE_ON_ERROR,
 548                                                dma_ser3)) {
 549                                        cris_free_dma(4, NULL);
 550                                        free_irq(21, &ports[1]);
 551                                        free_irq(20, &ports[1]);
 552                                        printk(KERN_CRIT "Can't alloc "
 553                                                "sync serial port 3 "
 554                                                "RX DMA channel");
 555                                        goto out;
 556                                }
 557#endif
 558                                RESET_DMA(4); WAIT_DMA(4);
 559                                RESET_DMA(5); WAIT_DMA(5);
 560                                *R_DMA_CH4_CLR_INTR =
 561                                        IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop,
 562                                                do) |
 563                                        IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr,
 564                                                do);
 565                                *R_DMA_CH5_CLR_INTR =
 566                                        IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop,
 567                                                do) |
 568                                        IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr,
 569                                                do);
 570                                *R_IRQ_MASK2_SET =
 571                                        IO_STATE(R_IRQ_MASK2_SET, dma4_eop,
 572                                                set) |
 573                                        IO_STATE(R_IRQ_MASK2_SET, dma5_descr,
 574                                                set);
 575                        }
 576                        start_dma_in(port);
 577                        port->init_irqs = 0;
 578                } else { /* !port->use_dma */
 579#ifdef SYNC_SER_MANUAL
 580                        if (port == &ports[0]) {
 581                                if (request_irq(8,
 582                                                manual_interrupt,
 583                                                IRQF_SHARED | IRQF_DISABLED,
 584                                                "synchronous serial manual irq",
 585                                                &ports[0])) {
 586                                        printk(KERN_CRIT "Can't alloc "
 587                                                "sync serial manual irq");
 588                                        goto out;
 589                                }
 590                        } else if (port == &ports[1]) {
 591                                if (request_irq(8,
 592                                                manual_interrupt,
 593                                                IRQF_SHARED | IRQF_DISABLED,
 594                                                "synchronous serial manual irq",
 595                                                &ports[1])) {
 596                                        printk(KERN_CRIT "Can't alloc "
 597                                                "sync serial manual irq");
 598                                        goto out;
 599                                }
 600                        }
 601                        port->init_irqs = 0;
 602#else
 603                        panic("sync_serial: Manual mode not supported.\n");
 604#endif /* SYNC_SER_MANUAL */
 605                }
 606        } /* port->init_irqs */
 607
 608        port->busy++;
 609        /* Start port if we use it as input */
 610        mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow);
 611        if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) ||
 612            mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) ||
 613            mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) ||
 614            mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) {
 615                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt,
 616                        running);
 617                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable,
 618                        enable);
 619                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable,
 620                        enable);
 621                port->started = 1;
 622                *port->ctrl_data = port->ctrl_data_shadow;
 623                if (!port->use_dma)
 624                        *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
 625                DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev));
 626        }
 627        ret = 0;
 628        
 629out:
 630        unlock_kernel();
 631        return ret;
 632}
 633
 634static int sync_serial_release(struct inode *inode, struct file *file)
 635{
 636        int dev = MINOR(inode->i_rdev);
 637        struct sync_port *port;
 638
 639        if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
 640                DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
 641                return -ENODEV;
 642        }
 643        port = &ports[dev];
 644        if (port->busy)
 645                port->busy--;
 646        if (!port->busy)
 647                *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) |
 648                                    (1 << port->transmitter_ready_bit));
 649
 650        return 0;
 651}
 652
 653
 654
 655static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
 656{
 657        int dev = MINOR(file->f_dentry->d_inode->i_rdev);
 658        unsigned int mask = 0;
 659        struct sync_port *port;
 660        DEBUGPOLL(static unsigned int prev_mask = 0);
 661
 662        port = &ports[dev];
 663        poll_wait(file, &port->out_wait_q, wait);
 664        poll_wait(file, &port->in_wait_q, wait);
 665        /* Some room to write */
 666        if (port->out_count < OUT_BUFFER_SIZE)
 667                mask |=  POLLOUT | POLLWRNORM;
 668        /* At least an inbufchunk of data */
 669        if (sync_data_avail(port) >= port->inbufchunk)
 670                mask |= POLLIN | POLLRDNORM;
 671
 672        DEBUGPOLL(if (mask != prev_mask)
 673                printk(KERN_DEBUG "sync_serial_poll: mask 0x%08X %s %s\n",
 674                        mask,
 675                        mask & POLLOUT ? "POLLOUT" : "",
 676                        mask & POLLIN ? "POLLIN" : "");
 677                prev_mask = mask;
 678        );
 679        return mask;
 680}
 681
 682static int sync_serial_ioctl(struct inode *inode, struct file *file,
 683                  unsigned int cmd, unsigned long arg)
 684{
 685        int return_val = 0;
 686        unsigned long flags;
 687
 688        int dev = MINOR(file->f_dentry->d_inode->i_rdev);
 689        struct sync_port *port;
 690
 691        if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
 692                DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
 693                return -1;
 694        }
 695        port = &ports[dev];
 696
 697        local_irq_save(flags);
 698        /* Disable port while changing config */
 699        if (dev) {
 700                if (port->use_dma) {
 701                        RESET_DMA(4); WAIT_DMA(4);
 702                        port->tr_running = 0;
 703                        port->out_count = 0;
 704                        port->outp = port->out_buffer;
 705                        *R_DMA_CH4_CLR_INTR =
 706                                IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
 707                                IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
 708                }
 709                SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
 710        } else {
 711                if (port->use_dma) {
 712                        RESET_DMA(8); WAIT_DMA(8);
 713                        port->tr_running = 0;
 714                        port->out_count = 0;
 715                        port->outp = port->out_buffer;
 716                        *R_DMA_CH8_CLR_INTR =
 717                                IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
 718                                IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do);
 719                }
 720                SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
 721        }
 722        *R_GEN_CONFIG_II = gen_config_ii_shadow;
 723        local_irq_restore(flags);
 724
 725        switch (cmd) {
 726        case SSP_SPEED:
 727                if (GET_SPEED(arg) == CODEC) {
 728                        if (dev)
 729                                SETS(sync_serial_prescale_shadow,
 730                                        R_SYNC_SERIAL_PRESCALE, clk_sel_u3,
 731                                        codec);
 732                        else
 733                                SETS(sync_serial_prescale_shadow,
 734                                        R_SYNC_SERIAL_PRESCALE, clk_sel_u1,
 735                                        codec);
 736
 737                        SETF(sync_serial_prescale_shadow,
 738                                R_SYNC_SERIAL_PRESCALE, prescaler,
 739                                GET_FREQ(arg));
 740                        SETF(sync_serial_prescale_shadow,
 741                                R_SYNC_SERIAL_PRESCALE, frame_rate,
 742                                GET_FRAME_RATE(arg));
 743                        SETF(sync_serial_prescale_shadow,
 744                                R_SYNC_SERIAL_PRESCALE, word_rate,
 745                                GET_WORD_RATE(arg));
 746                } else {
 747                        SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 748                                tr_baud, GET_SPEED(arg));
 749                        if (dev)
 750                                SETS(sync_serial_prescale_shadow,
 751                                        R_SYNC_SERIAL_PRESCALE, clk_sel_u3,
 752                                        baudrate);
 753                        else
 754                                SETS(sync_serial_prescale_shadow,
 755                                        R_SYNC_SERIAL_PRESCALE, clk_sel_u1,
 756                                        baudrate);
 757                }
 758                break;
 759        case SSP_MODE:
 760                if (arg > 5)
 761                        return -EINVAL;
 762                if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)
 763                        *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit;
 764                else if (!port->use_dma)
 765                        *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
 766                SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg);
 767                break;
 768        case SSP_FRAME_SYNC:
 769                if (arg & NORMAL_SYNC)
 770                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 771                                f_synctype, normal);
 772                else if (arg & EARLY_SYNC)
 773                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 774                                f_synctype, early);
 775
 776                if (arg & BIT_SYNC)
 777                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 778                                f_syncsize, bit);
 779                else if (arg & WORD_SYNC)
 780                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 781                                f_syncsize, word);
 782                else if (arg & EXTENDED_SYNC)
 783                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 784                                f_syncsize, extended);
 785
 786                if (arg & SYNC_ON)
 787                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 788                                f_sync, on);
 789                else if (arg & SYNC_OFF)
 790                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 791                                f_sync, off);
 792
 793                if (arg & WORD_SIZE_8)
 794                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 795                                wordsize, size8bit);
 796                else if (arg & WORD_SIZE_12)
 797                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 798                                wordsize, size12bit);
 799                else if (arg & WORD_SIZE_16)
 800                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 801                                wordsize, size16bit);
 802                else if (arg & WORD_SIZE_24)
 803                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 804                                wordsize, size24bit);
 805                else if (arg & WORD_SIZE_32)
 806                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 807                                wordsize, size32bit);
 808
 809                if (arg & BIT_ORDER_MSB)
 810                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 811                                bitorder, msb);
 812                else if (arg & BIT_ORDER_LSB)
 813                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 814                                bitorder, lsb);
 815
 816                if (arg & FLOW_CONTROL_ENABLE)
 817                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 818                                flow_ctrl, enabled);
 819                else if (arg & FLOW_CONTROL_DISABLE)
 820                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 821                                flow_ctrl, disabled);
 822
 823                if (arg & CLOCK_NOT_GATED)
 824                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 825                                clk_mode, normal);
 826                else if (arg & CLOCK_GATED)
 827                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 828                                clk_mode, gated);
 829
 830                break;
 831        case SSP_IPOLARITY:
 832                /* NOTE!! negedge is considered NORMAL */
 833                if (arg & CLOCK_NORMAL)
 834                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 835                                clk_polarity, neg);
 836                else if (arg & CLOCK_INVERT)
 837                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 838                                clk_polarity, pos);
 839
 840                if (arg & FRAME_NORMAL)
 841                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 842                                frame_polarity, normal);
 843                else if (arg & FRAME_INVERT)
 844                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 845                                frame_polarity, inverted);
 846
 847                if (arg & STATUS_NORMAL)
 848                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 849                                status_polarity, normal);
 850                else if (arg & STATUS_INVERT)
 851                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 852                                status_polarity, inverted);
 853                break;
 854        case SSP_OPOLARITY:
 855                if (arg & CLOCK_NORMAL)
 856                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 857                                clk_driver, normal);
 858                else if (arg & CLOCK_INVERT)
 859                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 860                                clk_driver, inverted);
 861
 862                if (arg & FRAME_NORMAL)
 863                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 864                                frame_driver, normal);
 865                else if (arg & FRAME_INVERT)
 866                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 867                                frame_driver, inverted);
 868
 869                if (arg & STATUS_NORMAL)
 870                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 871                                status_driver, normal);
 872                else if (arg & STATUS_INVERT)
 873                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 874                                status_driver, inverted);
 875                break;
 876        case SSP_SPI:
 877                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl,
 878                        disabled);
 879                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder,
 880                        msb);
 881                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize,
 882                        size8bit);
 883                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
 884                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize,
 885                        word);
 886                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype,
 887                        normal);
 888                if (arg & SPI_SLAVE) {
 889                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 890                                frame_polarity, inverted);
 891                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 892                                clk_polarity, neg);
 893                        SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 894                                mode, SLAVE_INPUT);
 895                } else {
 896                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 897                                frame_driver, inverted);
 898                        SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 899                                clk_driver, inverted);
 900                        SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL,
 901                                mode, MASTER_OUTPUT);
 902                }
 903                break;
 904        case SSP_INBUFCHUNK:
 905#if 0
 906                if (arg > port->in_buffer_size/NUM_IN_DESCR)
 907                        return -EINVAL;
 908                port->inbufchunk = arg;
 909                /* Make sure in_buffer_size is a multiple of inbufchunk */
 910                port->in_buffer_size =
 911                        (port->in_buffer_size/port->inbufchunk) *
 912                        port->inbufchunk;
 913                DEBUG(printk(KERN_DEBUG "inbufchunk %i in_buffer_size: %i\n",
 914                        port->inbufchunk, port->in_buffer_size));
 915                if (port->use_dma) {
 916                        if (port->port_nbr == 0) {
 917                                RESET_DMA(9);
 918                                WAIT_DMA(9);
 919                        } else {
 920                                RESET_DMA(5);
 921                                WAIT_DMA(5);
 922                        }
 923                        start_dma_in(port);
 924                }
 925#endif
 926                break;
 927        default:
 928                return_val = -1;
 929        }
 930        /* Make sure we write the config without interruption */
 931        local_irq_save(flags);
 932        /* Set config and enable port */
 933        *port->ctrl_data = port->ctrl_data_shadow;
 934        nop(); nop(); nop(); nop();
 935        *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow;
 936        nop(); nop(); nop(); nop();
 937        if (dev)
 938                SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
 939        else
 940                SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
 941
 942        *R_GEN_CONFIG_II = gen_config_ii_shadow;
 943        /* Reset DMA. At readout from serial port the data could be shifted
 944         * one byte if not resetting DMA.
 945         */
 946        if (port->use_dma) {
 947                if (port->port_nbr == 0) {
 948                        RESET_DMA(9);
 949                        WAIT_DMA(9);
 950                } else {
 951                        RESET_DMA(5);
 952                        WAIT_DMA(5);
 953                }
 954                start_dma_in(port);
 955        }
 956        local_irq_restore(flags);
 957        return return_val;
 958}
 959
 960
 961static ssize_t sync_serial_write(struct file *file, const char *buf,
 962        size_t count, loff_t *ppos)
 963{
 964        int dev = MINOR(file->f_dentry->d_inode->i_rdev);
 965        DECLARE_WAITQUEUE(wait, current);
 966        struct sync_port *port;
 967        unsigned long flags;
 968        unsigned long c, c1;
 969        unsigned long free_outp;
 970        unsigned long outp;
 971        unsigned long out_buffer;
 972
 973        if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
 974                DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
 975                return -ENODEV;
 976        }
 977        port = &ports[dev];
 978
 979        DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu (%d/%d)\n",
 980                port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
 981        /* Space to end of buffer */
 982        /*
 983         * out_buffer <c1>012345<-   c    ->OUT_BUFFER_SIZE
 984         *            outp^    +out_count
 985         *                      ^free_outp
 986         * out_buffer 45<-     c      ->0123OUT_BUFFER_SIZE
 987         *             +out_count   outp^
 988         *              free_outp
 989         *
 990         */
 991
 992        /* Read variables that may be updated by interrupts */
 993        local_irq_save(flags);
 994        if (count > OUT_BUFFER_SIZE - port->out_count)
 995                count = OUT_BUFFER_SIZE - port->out_count;
 996
 997        outp = (unsigned long)port->outp;
 998        free_outp = outp + port->out_count;
 999        local_irq_restore(flags);
1000        out_buffer = (unsigned long)port->out_buffer;
1001
1002        /* Find out where and how much to write */
1003        if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
1004                free_outp -= OUT_BUFFER_SIZE;
1005        if (free_outp >= outp)
1006                c = out_buffer + OUT_BUFFER_SIZE - free_outp;
1007        else
1008                c = outp - free_outp;
1009        if (c > count)
1010                c = count;
1011
1012        DEBUGWRITE(printk(KERN_DEBUG "w op %08lX fop %08lX c %lu\n",
1013                outp, free_outp, c));
1014        if (copy_from_user((void *)free_outp, buf, c))
1015                return -EFAULT;
1016
1017        if (c != count) {
1018                buf += c;
1019                c1 = count - c;
1020                DEBUGWRITE(printk(KERN_DEBUG "w2 fi %lu c %lu c1 %lu\n",
1021                        free_outp-out_buffer, c, c1));
1022                if (copy_from_user((void *)out_buffer, buf, c1))
1023                        return -EFAULT;
1024        }
1025        local_irq_save(flags);
1026        port->out_count += count;
1027        local_irq_restore(flags);
1028
1029        /* Make sure transmitter/receiver is running */
1030        if (!port->started) {
1031                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt,
1032                        running);
1033                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable,
1034                        enable);
1035                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable,
1036                        enable);
1037                port->started = 1;
1038        }
1039
1040        *port->ctrl_data = port->ctrl_data_shadow;
1041
1042        if (file->f_flags & O_NONBLOCK) {
1043                local_irq_save(flags);
1044                if (!port->tr_running) {
1045                        if (!port->use_dma) {
1046                                /* Start sender by writing data */
1047                                send_word(port);
1048                                /* and enable transmitter ready IRQ */
1049                                *R_IRQ_MASK1_SET = 1 <<
1050                                        port->transmitter_ready_bit;
1051                        } else
1052                                start_dma(port,
1053                                        (unsigned char *volatile)port->outp, c);
1054                }
1055                local_irq_restore(flags);
1056                DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu NB\n",
1057                        port->port_nbr, count));
1058                return count;
1059        }
1060
1061        /* Sleep until all sent */
1062        add_wait_queue(&port->out_wait_q, &wait);
1063        set_current_state(TASK_INTERRUPTIBLE);
1064        local_irq_save(flags);
1065        if (!port->tr_running) {
1066                if (!port->use_dma) {
1067                        /* Start sender by writing data */
1068                        send_word(port);
1069                        /* and enable transmitter ready IRQ */
1070                        *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit;
1071                } else
1072                        start_dma(port, port->outp, c);
1073        }
1074        local_irq_restore(flags);
1075        schedule();
1076        set_current_state(TASK_RUNNING);
1077        remove_wait_queue(&port->out_wait_q, &wait);
1078        if (signal_pending(current))
1079                return -EINTR;
1080
1081        DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n", port->port_nbr, count));
1082        return count;
1083}
1084
1085static ssize_t sync_serial_read(struct file *file, char *buf,
1086                                size_t count, loff_t *ppos)
1087{
1088        int dev = MINOR(file->f_dentry->d_inode->i_rdev);
1089        int avail;
1090        struct sync_port *port;
1091        unsigned char *start;
1092        unsigned char *end;
1093        unsigned long flags;
1094
1095        if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
1096                DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
1097                return -ENODEV;
1098        }
1099        port = &ports[dev];
1100
1101        DEBUGREAD(printk(KERN_DEBUG "R%d c %d ri %lu wi %lu /%lu\n",
1102                dev, count, port->readp - port->flip,
1103                port->writep - port->flip, port->in_buffer_size));
1104
1105        if (!port->started) {
1106                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt,
1107                        running);
1108                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable,
1109                        enable);
1110                SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable,
1111                        enable);
1112                port->started = 1;
1113        }
1114        *port->ctrl_data = port->ctrl_data_shadow;
1115
1116        /* Calculate number of available bytes */
1117        /* Save pointers to avoid that they are modified by interrupt */
1118        local_irq_save(flags);
1119        start = (unsigned char *)port->readp; /* cast away volatile */
1120        end = (unsigned char *)port->writep;  /* cast away volatile */
1121        local_irq_restore(flags);
1122        while (start == end && !port->full) {
1123                /* No data */
1124                if (file->f_flags & O_NONBLOCK)
1125                        return -EAGAIN;
1126
1127                interruptible_sleep_on(&port->in_wait_q);
1128                if (signal_pending(current))
1129                        return -EINTR;
1130
1131                local_irq_save(flags);
1132                start = (unsigned char *)port->readp; /* cast away volatile */
1133                end = (unsigned char *)port->writep;  /* cast away volatile */
1134                local_irq_restore(flags);
1135        }
1136
1137        /* Lazy read, never return wrapped data. */
1138        if (port->full)
1139                avail = port->in_buffer_size;
1140        else if (end > start)
1141                avail = end - start;
1142        else
1143                avail = port->flip + port->in_buffer_size - start;
1144
1145        count = count > avail ? avail : count;
1146        if (copy_to_user(buf, start, count))
1147                return -EFAULT;
1148        /* Disable interrupts while updating readp */
1149        local_irq_save(flags);
1150        port->readp += count;
1151        if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
1152                port->readp = port->flip;
1153        port->full = 0;
1154        local_irq_restore(flags);
1155        DEBUGREAD(printk(KERN_DEBUG "r %d\n", count));
1156        return count;
1157}
1158
1159static void send_word(struct sync_port *port)
1160{
1161        switch (IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize,
1162                        port->ctrl_data_shadow)) {
1163        case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
1164                 port->out_count--;
1165                 *port->data_out = *port->outp++;
1166                 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
1167                         port->outp = port->out_buffer;
1168                 break;
1169        case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
1170        {
1171                int data = (*port->outp++) << 8;
1172                data |= *port->outp++;
1173                port->out_count -= 2;
1174                *port->data_out = data;
1175                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
1176                        port->outp = port->out_buffer;
1177                break;
1178        }
1179        case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
1180                port->out_count -= 2;
1181                *port->data_out = *(unsigned short *)port->outp;
1182                port->outp += 2;
1183                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
1184                        port->outp = port->out_buffer;
1185                break;
1186        case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
1187                port->out_count -= 3;
1188                *port->data_out = *(unsigned int *)port->outp;
1189                port->outp += 3;
1190                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
1191                        port->outp = port->out_buffer;
1192                break;
1193        case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
1194                port->out_count -= 4;
1195                *port->data_out = *(unsigned int *)port->outp;
1196                port->outp += 4;
1197                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
1198                        port->outp = port->out_buffer;
1199                break;
1200        }
1201}
1202
1203
1204static void start_dma(struct sync_port *port, const char *data, int count)
1205{
1206        port->tr_running = 1;
1207        port->out_descr.hw_len = 0;
1208        port->out_descr.next = 0;
1209        port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */
1210        port->out_descr.sw_len = count;
1211        port->out_descr.buf = virt_to_phys(data);
1212        port->out_descr.status = 0;
1213
1214        *port->output_dma_first = virt_to_phys(&port->out_descr);
1215        *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
1216        DEBUGTXINT(printk(KERN_DEBUG "dma %08lX c %d\n",
1217                (unsigned long)data, count));
1218}
1219
1220static void start_dma_in(struct sync_port *port)
1221{
1222        int i;
1223        unsigned long buf;
1224        port->writep = port->flip;
1225
1226        if (port->writep > port->flip + port->in_buffer_size) {
1227                panic("Offset too large in sync serial driver\n");
1228                return;
1229        }
1230        buf = virt_to_phys(port->in_buffer);
1231        for (i = 0; i < NUM_IN_DESCR; i++) {
1232                port->in_descr[i].sw_len = port->inbufchunk;
1233                port->in_descr[i].ctrl = d_int;
1234                port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]);
1235                port->in_descr[i].buf = buf;
1236                port->in_descr[i].hw_len = 0;
1237                port->in_descr[i].status = 0;
1238                port->in_descr[i].fifo_len = 0;
1239                buf += port->inbufchunk;
1240                prepare_rx_descriptor(&port->in_descr[i]);
1241        }
1242        /* Link the last descriptor to the first */
1243        port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]);
1244        port->in_descr[i-1].ctrl |= d_eol;
1245        port->next_rx_desc = &port->in_descr[0];
1246        port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1];
1247        *port->input_dma_first = virt_to_phys(port->next_rx_desc);
1248        *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
1249}
1250
1251#ifdef SYNC_SER_DMA
1252static irqreturn_t tr_interrupt(int irq, void *dev_id)
1253{
1254        unsigned long ireg = *R_IRQ_MASK2_RD;
1255        struct etrax_dma_descr *descr;
1256        unsigned int sentl;
1257        int handled = 0;
1258        int i;
1259
1260        for (i = 0; i < NUMBER_OF_PORTS; i++) {
1261                struct sync_port *port = &ports[i];
1262                if (!port->enabled  || !port->use_dma)
1263                        continue;
1264
1265                /* IRQ active for the port? */
1266                if (!(ireg & (1 << port->output_dma_bit)))
1267                        continue;
1268
1269                handled = 1;
1270
1271                /* Clear IRQ */
1272                *port->output_dma_clr_irq =
1273                        IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) |
1274                        IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
1275
1276                descr = &port->out_descr;
1277                if (!(descr->status & d_stop))
1278                        sentl = descr->sw_len;
1279                else
1280                        /* Otherwise find amount of data sent here */
1281                        sentl = descr->hw_len;
1282
1283                port->out_count -= sentl;
1284                port->outp += sentl;
1285                if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
1286                        port->outp = port->out_buffer;
1287                if (port->out_count) {
1288                        int c = port->out_buffer + OUT_BUFFER_SIZE - port->outp;
1289                        if (c > port->out_count)
1290                                c = port->out_count;
1291                        DEBUGTXINT(printk(KERN_DEBUG
1292                                "tx_int DMAWRITE %i %i\n", sentl, c));
1293                        start_dma(port, port->outp, c);
1294                } else  {
1295                        DEBUGTXINT(printk(KERN_DEBUG
1296                                "tx_int DMA stop %i\n", sentl));
1297                        port->tr_running = 0;
1298                }
1299                /* wake up the waiting process */
1300                wake_up_interruptible(&port->out_wait_q);
1301        }
1302        return IRQ_RETVAL(handled);
1303} /* tr_interrupt */
1304
1305static irqreturn_t rx_interrupt(int irq, void *dev_id)
1306{
1307        unsigned long ireg = *R_IRQ_MASK2_RD;
1308        int i;
1309        int handled = 0;
1310
1311        for (i = 0; i < NUMBER_OF_PORTS; i++) {
1312                struct sync_port *port = &ports[i];
1313
1314                if (!port->enabled || !port->use_dma)
1315                        continue;
1316
1317                if (!(ireg & (1 << port->input_dma_descr_bit)))
1318                        continue;
1319
1320                /* Descriptor interrupt */
1321                handled = 1;
1322                while (*port->input_dma_descr !=
1323                                virt_to_phys(port->next_rx_desc)) {
1324                        if (port->writep + port->inbufchunk > port->flip +
1325                                        port->in_buffer_size) {
1326                                int first_size = port->flip +
1327                                        port->in_buffer_size - port->writep;
1328                                memcpy(port->writep,
1329                                        phys_to_virt(port->next_rx_desc->buf),
1330                                        first_size);
1331                                memcpy(port->flip,
1332                                        phys_to_virt(port->next_rx_desc->buf +
1333                                        first_size),
1334                                        port->inbufchunk - first_size);
1335                                port->writep = port->flip +
1336                                        port->inbufchunk - first_size;
1337                        } else {
1338                                memcpy(port->writep,
1339                                        phys_to_virt(port->next_rx_desc->buf),
1340                                        port->inbufchunk);
1341                                port->writep += port->inbufchunk;
1342                                if (port->writep >= port->flip
1343                                                + port->in_buffer_size)
1344                                        port->writep = port->flip;
1345                        }
1346                        if (port->writep == port->readp)
1347                                port->full = 1;
1348                        prepare_rx_descriptor(port->next_rx_desc);
1349                        port->next_rx_desc->ctrl |= d_eol;
1350                        port->prev_rx_desc->ctrl &= ~d_eol;
1351                        port->prev_rx_desc = phys_to_virt((unsigned)
1352                                port->next_rx_desc);
1353                        port->next_rx_desc = phys_to_virt((unsigned)
1354                                port->next_rx_desc->next);
1355                        /* Wake up the waiting process */
1356                        wake_up_interruptible(&port->in_wait_q);
1357                        *port->input_dma_cmd = IO_STATE(R_DMA_CH1_CMD,
1358                                cmd, restart);
1359                        /* DMA has reached end of descriptor */
1360                        *port->input_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR,
1361                                clr_descr, do);
1362                }
1363        }
1364        return IRQ_RETVAL(handled);
1365} /* rx_interrupt */
1366#endif /* SYNC_SER_DMA */
1367
1368#ifdef SYNC_SER_MANUAL
1369static irqreturn_t manual_interrupt(int irq, void *dev_id)
1370{
1371        int i;
1372        int handled = 0;
1373
1374        for (i = 0; i < NUMBER_OF_PORTS; i++) {
1375                struct sync_port *port = &ports[i];
1376
1377                if (!port->enabled || port->use_dma)
1378                        continue;
1379
1380                /* Data received? */
1381                if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit)) {
1382                        handled = 1;
1383                        /* Read data */
1384                        switch (port->ctrl_data_shadow &
1385                                IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) {
1386                        case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
1387                                *port->writep++ =
1388                                        *(volatile char *)port->data_in;
1389                                break;
1390                        case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
1391                        {
1392                                int data = *(unsigned short *)port->data_in;
1393                                *port->writep = (data & 0x0ff0) >> 4;
1394                                *(port->writep + 1) = data & 0x0f;
1395                                port->writep += 2;
1396                                break;
1397                        }
1398                        case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
1399                                *(unsigned short *)port->writep =
1400                                        *(volatile unsigned short *)port->data_in;
1401                                port->writep += 2;
1402                                break;
1403                        case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
1404                                *(unsigned int *)port->writep = *port->data_in;
1405                                port->writep += 3;
1406                                break;
1407                        case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
1408                                *(unsigned int *)port->writep = *port->data_in;
1409                                port->writep += 4;
1410                                break;
1411                        }
1412
1413                        /* Wrap? */
1414                        if (port->writep >= port->flip + port->in_buffer_size)
1415                                port->writep = port->flip;
1416                        if (port->writep == port->readp) {
1417                                /* Receive buffer overrun, discard oldest */
1418                                port->readp++;
1419                                /* Wrap? */
1420                                if (port->readp >= port->flip +
1421                                                port->in_buffer_size)
1422                                        port->readp = port->flip;
1423                        }
1424                        if (sync_data_avail(port) >= port->inbufchunk) {
1425                                /* Wake up application */
1426                                wake_up_interruptible(&port->in_wait_q);
1427                        }
1428                }
1429
1430                /* Transmitter ready? */
1431                if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) {
1432                        if (port->out_count > 0) {
1433                                /* More data to send */
1434                                send_word(port);
1435                        } else {
1436                                /* Transmission finished */
1437                                /* Turn off IRQ */
1438                                *R_IRQ_MASK1_CLR = 1 <<
1439                                        port->transmitter_ready_bit;
1440                                /* Wake up application */
1441                                wake_up_interruptible(&port->out_wait_q);
1442                        }
1443                }
1444        }
1445        return IRQ_RETVAL(handled);
1446}
1447#endif
1448
1449module_init(etrax_sync_serial_init);
1450