Merge tag 'omap-devel-am33xx-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / drivers / staging / ipack / devices / ipoctal.c
CommitLineData
ba4dc61f
SIG
1/**
2 * ipoctal.c
3 *
4 * driver for the GE IP-OCTAL boards
5 * Copyright (c) 2009 Nicolas Serafini, EIC2 SA
6 * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
7 * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
32254363 11 * Software Foundation; version 2 of the License.
ba4dc61f
SIG
12 */
13
ba4dc61f
SIG
14#include <linux/device.h>
15#include <linux/module.h>
ba4dc61f 16#include <linux/interrupt.h>
ba4dc61f
SIG
17#include <linux/sched.h>
18#include <linux/tty.h>
19#include <linux/serial.h>
20#include <linux/tty_flip.h>
21#include <linux/slab.h>
ba4dc61f
SIG
22#include <linux/atomic.h>
23#include "../ipack.h"
24#include "ipoctal.h"
25#include "scc2698.h"
26
27#define IP_OCTAL_MANUFACTURER_ID 0xF0
28#define IP_OCTAL_232_ID 0x22
29#define IP_OCTAL_422_ID 0x2A
30#define IP_OCTAL_485_ID 0x48
31
32#define IP_OCTAL_ID_SPACE_VECTOR 0x41
33#define IP_OCTAL_NB_BLOCKS 4
34
35static struct ipack_driver driver;
36static const struct tty_operations ipoctal_fops;
37
38struct ipoctal {
39 struct list_head list;
40 struct ipack_device *dev;
41 unsigned int board_id;
42 struct scc2698_channel *chan_regs;
43 struct scc2698_block *block_regs;
44 struct ipoctal_stats chan_stats[NR_CHANNELS];
ba4dc61f
SIG
45 unsigned int nb_bytes[NR_CHANNELS];
46 unsigned int count_wr[NR_CHANNELS];
ba4dc61f 47 wait_queue_head_t queue[NR_CHANNELS];
ba4dc61f
SIG
48 spinlock_t lock[NR_CHANNELS];
49 unsigned int pointer_read[NR_CHANNELS];
50 unsigned int pointer_write[NR_CHANNELS];
51 atomic_t open[NR_CHANNELS];
52 unsigned char write;
53 struct tty_port tty_port[NR_CHANNELS];
54 struct tty_driver *tty_drv;
55};
56
57/* Linked list to save the registered devices */
58static LIST_HEAD(ipoctal_list);
59
60static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal,
61 unsigned char *dest,
62 unsigned char value)
63{
64 unsigned long offset;
65
5a81b4a0 66 offset = ((void __iomem *) dest) - ipoctal->dev->io_space.address;
ec440335
SIG
67 ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_IO_SPACE, offset,
68 value);
ba4dc61f
SIG
69}
70
71static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal,
72 unsigned char *dest,
73 unsigned char value)
74{
75 ipoctal_write_io_reg(ipoctal, dest, value);
76}
77
78static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal,
79 unsigned char *src)
80{
81 unsigned long offset;
82 unsigned char value;
83
5a81b4a0 84 offset = ((void __iomem *) src) - ipoctal->dev->io_space.address;
ec440335
SIG
85 ipoctal->dev->bus->ops->read8(ipoctal->dev, IPACK_IO_SPACE, offset,
86 &value);
ba4dc61f
SIG
87 return value;
88}
89
90static struct ipoctal *ipoctal_find_board(struct tty_struct *tty)
91{
92 struct ipoctal *p;
93
94 list_for_each_entry(p, &ipoctal_list, list) {
95 if (tty->driver->major == p->tty_drv->major)
96 return p;
97 }
98
99 return NULL;
100}
101
102static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
103{
104 struct ipoctal *ipoctal;
105 int channel = tty->index;
106
107 ipoctal = ipoctal_find_board(tty);
108
109 if (ipoctal == NULL) {
42b38207
SIG
110 dev_err(tty->dev, "Device not found. Major %d\n",
111 tty->driver->major);
ba4dc61f
SIG
112 return -ENODEV;
113 }
114
115 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
116 CR_ENABLE_RX);
ba4dc61f
SIG
117 return 0;
118}
119
120static int ipoctal_open(struct tty_struct *tty, struct file *file)
121{
122 int channel = tty->index;
123 int res;
124 struct ipoctal *ipoctal;
125
126 ipoctal = ipoctal_find_board(tty);
127
128 if (ipoctal == NULL) {
42b38207
SIG
129 dev_err(tty->dev, "Device not found. Major %d\n",
130 tty->driver->major);
ba4dc61f
SIG
131 return -ENODEV;
132 }
133
134 if (atomic_read(&ipoctal->open[channel]))
135 return -EBUSY;
136
1337b07e
SIG
137 tty->driver_data = ipoctal;
138
ba4dc61f
SIG
139 res = tty_port_open(&ipoctal->tty_port[channel], tty, file);
140 if (res)
141 return res;
142
143 atomic_inc(&ipoctal->open[channel]);
144 return 0;
145}
146
147static void ipoctal_reset_stats(struct ipoctal_stats *stats)
148{
149 stats->tx = 0;
150 stats->rx = 0;
151 stats->rcv_break = 0;
152 stats->framing_err = 0;
153 stats->overrun_err = 0;
154 stats->parity_err = 0;
155}
156
157static void ipoctal_free_channel(struct tty_struct *tty)
158{
159 int channel = tty->index;
160 struct ipoctal *ipoctal = tty->driver_data;
161
162 if (ipoctal == NULL)
163 return;
164
165 ipoctal_reset_stats(&ipoctal->chan_stats[channel]);
166 ipoctal->pointer_read[channel] = 0;
167 ipoctal->pointer_write[channel] = 0;
168 ipoctal->nb_bytes[channel] = 0;
169}
170
171static void ipoctal_close(struct tty_struct *tty, struct file *filp)
172{
173 int channel = tty->index;
174 struct ipoctal *ipoctal = tty->driver_data;
175
176 tty_port_close(&ipoctal->tty_port[channel], tty, filp);
177
178 if (atomic_dec_and_test(&ipoctal->open[channel]))
179 ipoctal_free_channel(tty);
180}
181
182static int ipoctal_get_icount(struct tty_struct *tty,
183 struct serial_icounter_struct *icount)
184{
185 struct ipoctal *ipoctal = tty->driver_data;
186 int channel = tty->index;
187
188 icount->cts = 0;
189 icount->dsr = 0;
190 icount->rng = 0;
191 icount->dcd = 0;
192 icount->rx = ipoctal->chan_stats[channel].rx;
193 icount->tx = ipoctal->chan_stats[channel].tx;
194 icount->frame = ipoctal->chan_stats[channel].framing_err;
195 icount->parity = ipoctal->chan_stats[channel].parity_err;
196 icount->brk = ipoctal->chan_stats[channel].rcv_break;
197 return 0;
198}
199
200static int ipoctal_irq_handler(void *arg)
201{
202 unsigned int channel;
203 unsigned int block;
204 unsigned char isr;
205 unsigned char sr;
206 unsigned char isr_tx_rdy, isr_rx_rdy;
207 unsigned char value;
208 unsigned char flag;
209 struct tty_struct *tty;
210 struct ipoctal *ipoctal = (struct ipoctal *) arg;
211
212 /* Check all channels */
213 for (channel = 0; channel < NR_CHANNELS; channel++) {
214 /* If there is no client, skip the check */
215 if (!atomic_read(&ipoctal->open[channel]))
216 continue;
217
218 tty = tty_port_tty_get(&ipoctal->tty_port[channel]);
219 if (!tty)
220 continue;
221
222 /*
223 * The HW is organized in pair of channels.
224 * See which register we need to read from
225 */
226 block = channel / 2;
227 isr = ipoctal_read_io_reg(ipoctal,
228 &ipoctal->block_regs[block].u.r.isr);
229 sr = ipoctal_read_io_reg(ipoctal,
230 &ipoctal->chan_regs[channel].u.r.sr);
231
232 if ((channel % 2) == 1) {
233 isr_tx_rdy = isr & ISR_TxRDY_B;
234 isr_rx_rdy = isr & ISR_RxRDY_FFULL_B;
235 } else {
236 isr_tx_rdy = isr & ISR_TxRDY_A;
237 isr_rx_rdy = isr & ISR_RxRDY_FFULL_A;
238 }
239
240 /* In case of RS-485, change from TX to RX when finishing TX.
241 * Half-duplex.
242 */
243 if ((ipoctal->board_id == IP_OCTAL_485_ID) &&
244 (sr & SR_TX_EMPTY) &&
245 (ipoctal->nb_bytes[channel] == 0)) {
246 ipoctal_write_io_reg(ipoctal,
247 &ipoctal->chan_regs[channel].u.w.cr,
248 CR_DISABLE_TX);
249 ipoctal_write_cr_cmd(ipoctal,
250 &ipoctal->chan_regs[channel].u.w.cr,
251 CR_CMD_NEGATE_RTSN);
252 ipoctal_write_io_reg(ipoctal,
253 &ipoctal->chan_regs[channel].u.w.cr,
254 CR_ENABLE_RX);
255 ipoctal->write = 1;
256 wake_up_interruptible(&ipoctal->queue[channel]);
257 }
258
259 /* RX data */
260 if (isr_rx_rdy && (sr & SR_RX_READY)) {
261 value = ipoctal_read_io_reg(ipoctal,
262 &ipoctal->chan_regs[channel].u.r.rhr);
263 flag = TTY_NORMAL;
264
265 /* Error: count statistics */
266 if (sr & SR_ERROR) {
267 ipoctal_write_cr_cmd(ipoctal,
268 &ipoctal->chan_regs[channel].u.w.cr,
269 CR_CMD_RESET_ERR_STATUS);
270
271 if (sr & SR_OVERRUN_ERROR) {
ba4dc61f
SIG
272 ipoctal->chan_stats[channel].overrun_err++;
273 /* Overrun doesn't affect the current character*/
274 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
275 }
276 if (sr & SR_PARITY_ERROR) {
ba4dc61f
SIG
277 ipoctal->chan_stats[channel].parity_err++;
278 flag = TTY_PARITY;
279 }
280 if (sr & SR_FRAMING_ERROR) {
ba4dc61f
SIG
281 ipoctal->chan_stats[channel].framing_err++;
282 flag = TTY_FRAME;
283 }
284 if (sr & SR_RECEIVED_BREAK) {
ba4dc61f
SIG
285 ipoctal->chan_stats[channel].rcv_break++;
286 flag = TTY_BREAK;
287 }
288 }
289
290 tty_insert_flip_char(tty, value, flag);
291 }
292
293 /* TX of each character */
294 if (isr_tx_rdy && (sr & SR_TX_READY)) {
295 unsigned int *pointer_write =
296 &ipoctal->pointer_write[channel];
297
298 if (ipoctal->nb_bytes[channel] <= 0) {
299 ipoctal->nb_bytes[channel] = 0;
300 continue;
301 }
59d6a29e 302
db1db294 303 value = ipoctal->tty_port[channel].xmit_buf[*pointer_write];
ba4dc61f
SIG
304 ipoctal_write_io_reg(ipoctal,
305 &ipoctal->chan_regs[channel].u.w.thr,
306 value);
307 ipoctal->chan_stats[channel].tx++;
308 ipoctal->count_wr[channel]++;
309 (*pointer_write)++;
310 *pointer_write = *pointer_write % PAGE_SIZE;
311 ipoctal->nb_bytes[channel]--;
ba4dc61f
SIG
312
313 if ((ipoctal->nb_bytes[channel] == 0) &&
314 (waitqueue_active(&ipoctal->queue[channel]))) {
315
316 if (ipoctal->board_id != IP_OCTAL_485_ID) {
317 ipoctal->write = 1;
318 wake_up_interruptible(&ipoctal->queue[channel]);
319 }
320 }
321 }
322
323 tty_flip_buffer_push(tty);
324 tty_kref_put(tty);
325 }
326 return IRQ_HANDLED;
327}
328
329static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id)
330{
331 unsigned char manufacturerID;
332 unsigned char board_id;
333
ec440335 334 dev->bus->ops->read8(dev, IPACK_ID_SPACE,
ba4dc61f
SIG
335 IPACK_IDPROM_OFFSET_MANUFACTURER_ID, &manufacturerID);
336 if (manufacturerID != IP_OCTAL_MANUFACTURER_ID)
337 return -ENODEV;
338
ec440335 339 dev->bus->ops->read8(dev, IPACK_ID_SPACE,
ba4dc61f
SIG
340 IPACK_IDPROM_OFFSET_MODEL, (unsigned char *)&board_id);
341
342 switch (board_id) {
343 case IP_OCTAL_232_ID:
344 case IP_OCTAL_422_ID:
345 case IP_OCTAL_485_ID:
346 *id = board_id;
347 break;
348 default:
349 return -ENODEV;
350 }
351
352 return 0;
353}
354
355static const struct tty_port_operations ipoctal_tty_port_ops = {
356 .dtr_rts = NULL,
357 .activate = ipoctal_port_activate,
358};
359
360static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
361 unsigned int slot, unsigned int vector)
362{
363 int res = 0;
364 int i;
365 struct tty_driver *tty;
366 char name[20];
367 unsigned char board_id;
368
ec440335
SIG
369 res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
370 IPACK_ID_SPACE);
ba4dc61f 371 if (res) {
42b38207
SIG
372 dev_err(&ipoctal->dev->dev,
373 "Unable to map slot [%d:%d] ID space!\n",
374 bus_nr, slot);
ba4dc61f
SIG
375 return res;
376 }
377
378 res = ipoctal_check_model(ipoctal->dev, &board_id);
379 if (res) {
ec440335
SIG
380 ipoctal->dev->bus->ops->unmap_space(ipoctal->dev,
381 IPACK_ID_SPACE);
ba4dc61f
SIG
382 goto out_unregister_id_space;
383 }
384 ipoctal->board_id = board_id;
385
ec440335
SIG
386 res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
387 IPACK_IO_SPACE);
ba4dc61f 388 if (res) {
42b38207
SIG
389 dev_err(&ipoctal->dev->dev,
390 "Unable to map slot [%d:%d] IO space!\n",
391 bus_nr, slot);
ba4dc61f
SIG
392 goto out_unregister_id_space;
393 }
394
ec440335 395 res = ipoctal->dev->bus->ops->map_space(ipoctal->dev,
ba4dc61f
SIG
396 0x8000, IPACK_MEM_SPACE);
397 if (res) {
42b38207
SIG
398 dev_err(&ipoctal->dev->dev,
399 "Unable to map slot [%d:%d] MEM space!\n",
400 bus_nr, slot);
ba4dc61f
SIG
401 goto out_unregister_io_space;
402 }
403
404 /* Save the virtual address to access the registers easily */
405 ipoctal->chan_regs =
406 (struct scc2698_channel *) ipoctal->dev->io_space.address;
407 ipoctal->block_regs =
408 (struct scc2698_block *) ipoctal->dev->io_space.address;
409
410 /* Disable RX and TX before touching anything */
411 for (i = 0; i < NR_CHANNELS ; i++) {
412 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
413 CR_DISABLE_RX | CR_DISABLE_TX);
4eed84a8
SIG
414 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
415 CR_CMD_RESET_RX);
416 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
417 CR_CMD_RESET_TX);
418 ipoctal_write_io_reg(ipoctal,
419 &ipoctal->chan_regs[i].u.w.mr,
420 MR1_CHRL_8_BITS | MR1_ERROR_CHAR |
421 MR1_RxINT_RxRDY); /* mr1 */
422 ipoctal_write_io_reg(ipoctal,
423 &ipoctal->chan_regs[i].u.w.mr,
424 0); /* mr2 */
425 ipoctal_write_io_reg(ipoctal,
426 &ipoctal->chan_regs[i].u.w.csr,
427 TX_CLK_9600 | RX_CLK_9600);
ba4dc61f
SIG
428 }
429
430 for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
431 ipoctal_write_io_reg(ipoctal,
432 &ipoctal->block_regs[i].u.w.acr,
433 ACR_BRG_SET2);
434 ipoctal_write_io_reg(ipoctal,
435 &ipoctal->block_regs[i].u.w.opcr,
436 OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN |
437 OPCR_MPOb_RTSN);
438 ipoctal_write_io_reg(ipoctal,
439 &ipoctal->block_regs[i].u.w.imr,
440 IMR_TxRDY_A | IMR_RxRDY_FFULL_A |
441 IMR_DELTA_BREAK_A | IMR_TxRDY_B |
442 IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B);
443 }
444
445 /*
446 * IP-OCTAL has different addresses to copy its IRQ vector.
447 * Depending of the carrier these addresses are accesible or not.
448 * More info in the datasheet.
449 */
ec440335 450 ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector,
ba4dc61f 451 ipoctal_irq_handler, ipoctal);
7183f337
SIG
452 ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_MEM_SPACE, 0,
453 vector);
ba4dc61f
SIG
454
455 /* Register the TTY device */
456
457 /* Each IP-OCTAL channel is a TTY port */
458 tty = alloc_tty_driver(NR_CHANNELS);
459
460 if (!tty) {
461 res = -ENOMEM;
462 goto out_unregister_slot_unmap;
463 }
464
465 /* Fill struct tty_driver with ipoctal data */
466 tty->owner = THIS_MODULE;
467 tty->driver_name = "ipoctal";
468 sprintf(name, "ipoctal.%d.%d.", bus_nr, slot);
469 tty->name = name;
470 tty->major = 0;
471
472 tty->minor_start = 0;
473 tty->type = TTY_DRIVER_TYPE_SERIAL;
474 tty->subtype = SERIAL_TYPE_NORMAL;
475 tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
476 tty->init_termios = tty_std_termios;
477 tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
478 tty->init_termios.c_ispeed = 9600;
479 tty->init_termios.c_ospeed = 9600;
480
481 tty_set_operations(tty, &ipoctal_fops);
482 res = tty_register_driver(tty);
483 if (res) {
42b38207 484 dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
ba4dc61f
SIG
485 put_tty_driver(tty);
486 goto out_unregister_slot_unmap;
487 }
488
489 /* Save struct tty_driver for use it when uninstalling the device */
490 ipoctal->tty_drv = tty;
491
492 for (i = 0; i < NR_CHANNELS; i++) {
493 tty_port_init(&ipoctal->tty_port[i]);
494 tty_port_alloc_xmit_buf(&ipoctal->tty_port[i]);
495 ipoctal->tty_port[i].ops = &ipoctal_tty_port_ops;
496
497 ipoctal_reset_stats(&ipoctal->chan_stats[i]);
498 ipoctal->nb_bytes[i] = 0;
499 init_waitqueue_head(&ipoctal->queue[i]);
ba4dc61f
SIG
500
501 spin_lock_init(&ipoctal->lock[i]);
502 ipoctal->pointer_read[i] = 0;
503 ipoctal->pointer_write[i] = 0;
504 ipoctal->nb_bytes[i] = 0;
734cc178 505 tty_port_register_device(&ipoctal->tty_port[i], tty, i, NULL);
ba4dc61f
SIG
506
507 /*
508 * Enable again the RX. TX will be enabled when
509 * there is something to send
510 */
511 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr,
512 CR_ENABLE_RX);
513 }
514
515 return 0;
516
517out_unregister_slot_unmap:
ec440335 518 ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE);
ba4dc61f 519out_unregister_io_space:
ec440335 520 ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE);
ba4dc61f 521out_unregister_id_space:
ec440335 522 ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE);
ba4dc61f
SIG
523 return res;
524}
525
526static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal,
527 unsigned int channel,
528 const unsigned char *buf,
529 int count)
530{
531 unsigned long flags;
532 int i;
533 unsigned int *pointer_read = &ipoctal->pointer_read[channel];
534
535 /* Copy the bytes from the user buffer to the internal one */
536 for (i = 0; i < count; i++) {
537 if (i <= (PAGE_SIZE - ipoctal->nb_bytes[channel])) {
538 spin_lock_irqsave(&ipoctal->lock[channel], flags);
539 ipoctal->tty_port[channel].xmit_buf[*pointer_read] = buf[i];
540 *pointer_read = (*pointer_read + 1) % PAGE_SIZE;
541 ipoctal->nb_bytes[channel]++;
542 spin_unlock_irqrestore(&ipoctal->lock[channel], flags);
543 } else {
544 break;
545 }
546 }
547 return i;
548}
549
550static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
551 const unsigned char *buf, int count)
552{
553 ipoctal->nb_bytes[channel] = 0;
554 ipoctal->count_wr[channel] = 0;
555
556 ipoctal_copy_write_buffer(ipoctal, channel, buf, count);
557
ba4dc61f
SIG
558 /* As the IP-OCTAL 485 only supports half duplex, do it manually */
559 if (ipoctal->board_id == IP_OCTAL_485_ID) {
560 ipoctal_write_io_reg(ipoctal,
561 &ipoctal->chan_regs[channel].u.w.cr,
562 CR_DISABLE_RX);
563 ipoctal_write_cr_cmd(ipoctal,
564 &ipoctal->chan_regs[channel].u.w.cr,
565 CR_CMD_ASSERT_RTSN);
566 }
567
568 /*
569 * Send a packet and then disable TX to avoid failure after several send
570 * operations
571 */
572 ipoctal_write_io_reg(ipoctal,
573 &ipoctal->chan_regs[channel].u.w.cr,
574 CR_ENABLE_TX);
575 wait_event_interruptible(ipoctal->queue[channel], ipoctal->write);
576 ipoctal_write_io_reg(ipoctal,
577 &ipoctal->chan_regs[channel].u.w.cr,
578 CR_DISABLE_TX);
579
580 ipoctal->write = 0;
581 return ipoctal->count_wr[channel];
582}
583
584static int ipoctal_write_tty(struct tty_struct *tty,
585 const unsigned char *buf, int count)
586{
587 unsigned int channel = tty->index;
588 struct ipoctal *ipoctal = tty->driver_data;
589
590 return ipoctal_write(ipoctal, channel, buf, count);
591}
592
593static int ipoctal_write_room(struct tty_struct *tty)
594{
595 int channel = tty->index;
596 struct ipoctal *ipoctal = tty->driver_data;
597
598 return PAGE_SIZE - ipoctal->nb_bytes[channel];
599}
600
601static int ipoctal_chars_in_buffer(struct tty_struct *tty)
602{
603 int channel = tty->index;
604 struct ipoctal *ipoctal = tty->driver_data;
605
606 return ipoctal->nb_bytes[channel];
607}
608
609static void ipoctal_set_termios(struct tty_struct *tty,
610 struct ktermios *old_termios)
611{
612 unsigned int cflag;
613 unsigned char mr1 = 0;
614 unsigned char mr2 = 0;
615 unsigned char csr = 0;
616 unsigned int channel = tty->index;
617 struct ipoctal *ipoctal = tty->driver_data;
618 speed_t baud;
619
857196e2 620 cflag = tty->termios.c_cflag;
ba4dc61f
SIG
621
622 /* Disable and reset everything before change the setup */
623 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
624 CR_DISABLE_RX | CR_DISABLE_TX);
625 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
626 CR_CMD_RESET_RX);
627 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
628 CR_CMD_RESET_TX);
629 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
630 CR_CMD_RESET_ERR_STATUS);
631 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
632 CR_CMD_RESET_MR);
633
634 /* Set Bits per chars */
635 switch (cflag & CSIZE) {
636 case CS6:
637 mr1 |= MR1_CHRL_6_BITS;
638 break;
639 case CS7:
640 mr1 |= MR1_CHRL_7_BITS;
641 break;
642 case CS8:
643 default:
644 mr1 |= MR1_CHRL_8_BITS;
645 /* By default, select CS8 */
857196e2 646 tty->termios.c_cflag = (cflag & ~CSIZE) | CS8;
ba4dc61f
SIG
647 break;
648 }
649
650 /* Set Parity */
651 if (cflag & PARENB)
652 if (cflag & PARODD)
653 mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD;
654 else
655 mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN;
656 else
657 mr1 |= MR1_PARITY_OFF;
658
659 /* Mark or space parity is not supported */
857196e2 660 tty->termios.c_cflag &= ~CMSPAR;
ba4dc61f
SIG
661
662 /* Set stop bits */
663 if (cflag & CSTOPB)
664 mr2 |= MR2_STOP_BITS_LENGTH_2;
665 else
666 mr2 |= MR2_STOP_BITS_LENGTH_1;
667
668 /* Set the flow control */
669 switch (ipoctal->board_id) {
670 case IP_OCTAL_232_ID:
671 if (cflag & CRTSCTS) {
672 mr1 |= MR1_RxRTS_CONTROL_ON;
673 mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON;
ba4dc61f
SIG
674 } else {
675 mr1 |= MR1_RxRTS_CONTROL_OFF;
676 mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
ba4dc61f
SIG
677 }
678 break;
679 case IP_OCTAL_422_ID:
680 mr1 |= MR1_RxRTS_CONTROL_OFF;
681 mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
ba4dc61f
SIG
682 break;
683 case IP_OCTAL_485_ID:
684 mr1 |= MR1_RxRTS_CONTROL_OFF;
685 mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF;
ba4dc61f
SIG
686 break;
687 default:
688 return;
689 break;
690 }
691
692 baud = tty_get_baud_rate(tty);
857196e2 693 tty_termios_encode_baud_rate(&tty->termios, baud, baud);
ba4dc61f
SIG
694
695 /* Set baud rate */
857196e2 696 switch (baud) {
ba4dc61f
SIG
697 case 75:
698 csr |= TX_CLK_75 | RX_CLK_75;
699 break;
700 case 110:
701 csr |= TX_CLK_110 | RX_CLK_110;
702 break;
703 case 150:
704 csr |= TX_CLK_150 | RX_CLK_150;
705 break;
706 case 300:
707 csr |= TX_CLK_300 | RX_CLK_300;
708 break;
709 case 600:
710 csr |= TX_CLK_600 | RX_CLK_600;
711 break;
712 case 1200:
713 csr |= TX_CLK_1200 | RX_CLK_1200;
714 break;
715 case 1800:
716 csr |= TX_CLK_1800 | RX_CLK_1800;
717 break;
718 case 2000:
719 csr |= TX_CLK_2000 | RX_CLK_2000;
720 break;
721 case 2400:
722 csr |= TX_CLK_2400 | RX_CLK_2400;
723 break;
724 case 4800:
725 csr |= TX_CLK_4800 | RX_CLK_4800;
726 break;
727 case 9600:
728 csr |= TX_CLK_9600 | RX_CLK_9600;
729 break;
730 case 19200:
731 csr |= TX_CLK_19200 | RX_CLK_19200;
732 break;
733 case 38400:
734 default:
735 csr |= TX_CLK_38400 | RX_CLK_38400;
736 /* In case of default, we establish 38400 bps */
857196e2 737 tty_termios_encode_baud_rate(&tty->termios, 38400, 38400);
ba4dc61f
SIG
738 break;
739 }
740
741 mr1 |= MR1_ERROR_CHAR;
742 mr1 |= MR1_RxINT_RxRDY;
743
744 /* Write the control registers */
745 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr1);
746 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr2);
747 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.csr, csr);
748
ba4dc61f
SIG
749 /* Enable again the RX */
750 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
751 CR_ENABLE_RX);
752}
753
754static void ipoctal_hangup(struct tty_struct *tty)
755{
756 unsigned long flags;
757 int channel = tty->index;
758 struct ipoctal *ipoctal = tty->driver_data;
759
760 if (ipoctal == NULL)
761 return;
762
763 spin_lock_irqsave(&ipoctal->lock[channel], flags);
764 ipoctal->nb_bytes[channel] = 0;
765 ipoctal->pointer_read[channel] = 0;
766 ipoctal->pointer_write[channel] = 0;
767 spin_unlock_irqrestore(&ipoctal->lock[channel], flags);
768
769 tty_port_hangup(&ipoctal->tty_port[channel]);
770
771 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
772 CR_DISABLE_RX | CR_DISABLE_TX);
773 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
774 CR_CMD_RESET_RX);
775 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
776 CR_CMD_RESET_TX);
777 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
778 CR_CMD_RESET_ERR_STATUS);
779 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr,
780 CR_CMD_RESET_MR);
781
782 clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags);
783 wake_up_interruptible(&ipoctal->tty_port[channel].open_wait);
784}
785
786static const struct tty_operations ipoctal_fops = {
787 .ioctl = NULL,
788 .open = ipoctal_open,
789 .close = ipoctal_close,
790 .write = ipoctal_write_tty,
791 .set_termios = ipoctal_set_termios,
792 .write_room = ipoctal_write_room,
793 .chars_in_buffer = ipoctal_chars_in_buffer,
794 .get_icount = ipoctal_get_icount,
795 .hangup = ipoctal_hangup,
796};
797
798static int ipoctal_match(struct ipack_device *dev)
799{
800 int res;
801 unsigned char board_id;
802
ec440335
SIG
803 if ((!dev->bus->ops) || (!dev->bus->ops->map_space) ||
804 (!dev->bus->ops->unmap_space))
805 return 0;
806
807 res = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
ba4dc61f 808 if (res)
ec440335 809 return 0;
ba4dc61f
SIG
810
811 res = ipoctal_check_model(dev, &board_id);
ec440335
SIG
812 dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
813 if (!res)
814 return 1;
815
816 return 0;
ba4dc61f
SIG
817}
818
819static int ipoctal_probe(struct ipack_device *dev)
820{
821 int res;
822 struct ipoctal *ipoctal;
823
824 ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL);
825 if (ipoctal == NULL)
826 return -ENOMEM;
827
828 ipoctal->dev = dev;
829 res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot, dev->irq);
830 if (res)
831 goto out_uninst;
832
833 list_add_tail(&ipoctal->list, &ipoctal_list);
834 return 0;
835
836out_uninst:
837 kfree(ipoctal);
838 return res;
839}
840
841static void __ipoctal_remove(struct ipoctal *ipoctal)
842{
843 int i;
844
845 for (i = 0; i < NR_CHANNELS; i++) {
846 tty_unregister_device(ipoctal->tty_drv, i);
847 tty_port_free_xmit_buf(&ipoctal->tty_port[i]);
848 }
849
850 tty_unregister_driver(ipoctal->tty_drv);
851 put_tty_driver(ipoctal->tty_drv);
ba4dc61f
SIG
852 list_del(&ipoctal->list);
853 kfree(ipoctal);
854}
855
856static void ipoctal_remove(struct ipack_device *device)
857{
858 struct ipoctal *ipoctal, *next;
859
860 list_for_each_entry_safe(ipoctal, next, &ipoctal_list, list) {
861 if (ipoctal->dev == device)
862 __ipoctal_remove(ipoctal);
863 }
864}
865
866static struct ipack_driver_ops ipoctal_drv_ops = {
867 .match = ipoctal_match,
868 .probe = ipoctal_probe,
869 .remove = ipoctal_remove,
870};
871
872static int __init ipoctal_init(void)
873{
ba4dc61f 874 driver.ops = &ipoctal_drv_ops;
ec440335 875 return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME);
ba4dc61f
SIG
876}
877
878static void __exit ipoctal_exit(void)
879{
880 struct ipoctal *p, *next;
881
882 list_for_each_entry_safe(p, next, &ipoctal_list, list)
597d473f 883 p->dev->bus->ops->remove_device(p->dev);
ba4dc61f
SIG
884
885 ipack_driver_unregister(&driver);
886}
887
888MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver");
889MODULE_LICENSE("GPL");
890
891module_init(ipoctal_init);
892module_exit(ipoctal_exit);
This page took 0.093707 seconds and 5 git commands to generate.