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