diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/comedi_parport.c')
-rw-r--r-- | drivers/staging/comedi/drivers/comedi_parport.c | 306 |
1 files changed, 0 insertions, 306 deletions
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c deleted file mode 100644 index 5338b5eea440..000000000000 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ /dev/null @@ -1,306 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * comedi_parport.c - * Comedi driver for standard parallel port - * - * For more information see: - * http://retired.beyondlogic.org/spp/parallel.htm - * - * COMEDI - Linux Control and Measurement Device Interface - * Copyright (C) 1998,2001 David A. Schleef <ds@schleef.org> - */ - -/* - * Driver: comedi_parport - * Description: Standard PC parallel port - * Author: ds - * Status: works in immediate mode - * Devices: [standard] parallel port (comedi_parport) - * Updated: Tue, 30 Apr 2002 21:11:45 -0700 - * - * A cheap and easy way to get a few more digital I/O lines. Steal - * additional parallel ports from old computers or your neighbors' - * computers. - * - * Option list: - * 0: I/O port base for the parallel port. - * 1: IRQ (optional) - * - * Parallel Port Lines: - * - * pin subdev chan type name - * ----- ------ ---- ---- -------------- - * 1 2 0 DO strobe - * 2 0 0 DIO data 0 - * 3 0 1 DIO data 1 - * 4 0 2 DIO data 2 - * 5 0 3 DIO data 3 - * 6 0 4 DIO data 4 - * 7 0 5 DIO data 5 - * 8 0 6 DIO data 6 - * 9 0 7 DIO data 7 - * 10 1 3 DI ack - * 11 1 4 DI busy - * 12 1 2 DI paper out - * 13 1 1 DI select in - * 14 2 1 DO auto LF - * 15 1 0 DI error - * 16 2 2 DO init - * 17 2 3 DO select printer - * 18-25 ground - * - * When an IRQ is configured subdevice 3 pretends to be a digital - * input subdevice, but it always returns 0 when read. However, if - * you run a command with scan_begin_src=TRIG_EXT, it uses pin 10 - * as a external trigger, which can be used to wake up tasks. - */ - -#include <linux/module.h> -#include <linux/interrupt.h> - -#include "../comedidev.h" - -/* - * Register map - */ -#define PARPORT_DATA_REG 0x00 -#define PARPORT_STATUS_REG 0x01 -#define PARPORT_CTRL_REG 0x02 -#define PARPORT_CTRL_IRQ_ENA BIT(4) -#define PARPORT_CTRL_BIDIR_ENA BIT(5) - -static int parport_data_reg_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (comedi_dio_update_state(s, data)) - outb(s->state, dev->iobase + PARPORT_DATA_REG); - - data[1] = inb(dev->iobase + PARPORT_DATA_REG); - - return insn->n; -} - -static int parport_data_reg_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int ctrl; - int ret; - - ret = comedi_dio_insn_config(dev, s, insn, data, 0xff); - if (ret) - return ret; - - ctrl = inb(dev->iobase + PARPORT_CTRL_REG); - if (s->io_bits) - ctrl &= ~PARPORT_CTRL_BIDIR_ENA; - else - ctrl |= PARPORT_CTRL_BIDIR_ENA; - outb(ctrl, dev->iobase + PARPORT_CTRL_REG); - - return insn->n; -} - -static int parport_status_reg_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inb(dev->iobase + PARPORT_STATUS_REG) >> 3; - - return insn->n; -} - -static int parport_ctrl_reg_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int ctrl; - - if (comedi_dio_update_state(s, data)) { - ctrl = inb(dev->iobase + PARPORT_CTRL_REG); - ctrl &= (PARPORT_CTRL_IRQ_ENA | PARPORT_CTRL_BIDIR_ENA); - ctrl |= s->state; - outb(ctrl, dev->iobase + PARPORT_CTRL_REG); - } - - data[1] = s->state; - - return insn->n; -} - -static int parport_intr_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = 0; - return insn->n; -} - -static int parport_intr_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - - /* Step 1 : check if triggers are trivially valid */ - - err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); - err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); - err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); - err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE); - - if (err) - return 1; - - /* Step 2a : make sure trigger sources are unique */ - /* Step 2b : and mutually compatible */ - - /* Step 3: check if arguments are trivially valid */ - - err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); - err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); - err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, - cmd->chanlist_len); - err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); - - if (err) - return 3; - - /* Step 4: fix up any arguments */ - - /* Step 5: check channel list if it exists */ - - return 0; -} - -static int parport_intr_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - unsigned int ctrl; - - ctrl = inb(dev->iobase + PARPORT_CTRL_REG); - ctrl |= PARPORT_CTRL_IRQ_ENA; - outb(ctrl, dev->iobase + PARPORT_CTRL_REG); - - return 0; -} - -static int parport_intr_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - unsigned int ctrl; - - ctrl = inb(dev->iobase + PARPORT_CTRL_REG); - ctrl &= ~PARPORT_CTRL_IRQ_ENA; - outb(ctrl, dev->iobase + PARPORT_CTRL_REG); - - return 0; -} - -static irqreturn_t parport_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->read_subdev; - unsigned int ctrl; - unsigned short val = 0; - - ctrl = inb(dev->iobase + PARPORT_CTRL_REG); - if (!(ctrl & PARPORT_CTRL_IRQ_ENA)) - return IRQ_NONE; - - comedi_buf_write_samples(s, &val, 1); - comedi_handle_events(dev, s); - - return IRQ_HANDLED; -} - -static int parport_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int ret; - - ret = comedi_request_region(dev, it->options[0], 0x03); - if (ret) - return ret; - - if (it->options[1]) { - ret = request_irq(it->options[1], parport_interrupt, 0, - dev->board_name, dev); - if (ret == 0) - dev->irq = it->options[1]; - } - - ret = comedi_alloc_subdevices(dev, dev->irq ? 4 : 3); - if (ret) - return ret; - - /* Digial I/O subdevice - Parallel port DATA register */ - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = parport_data_reg_insn_bits; - s->insn_config = parport_data_reg_insn_config; - - /* Digial Input subdevice - Parallel port STATUS register */ - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 5; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = parport_status_reg_insn_bits; - - /* Digial Output subdevice - Parallel port CONTROL register */ - s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = parport_ctrl_reg_insn_bits; - - if (dev->irq) { - /* Digial Input subdevice - Interrupt support */ - s = &dev->subdevices[3]; - dev->read_subdev = s; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; - s->n_chan = 1; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = parport_intr_insn_bits; - s->len_chanlist = 1; - s->do_cmdtest = parport_intr_cmdtest; - s->do_cmd = parport_intr_cmd; - s->cancel = parport_intr_cancel; - } - - outb(0, dev->iobase + PARPORT_DATA_REG); - outb(0, dev->iobase + PARPORT_CTRL_REG); - - return 0; -} - -static struct comedi_driver parport_driver = { - .driver_name = "comedi_parport", - .module = THIS_MODULE, - .attach = parport_attach, - .detach = comedi_legacy_detach, -}; -module_comedi_driver(parport_driver); - -MODULE_AUTHOR("Comedi https://www.comedi.org"); -MODULE_DESCRIPTION("Comedi: Standard parallel port driver"); -MODULE_LICENSE("GPL"); |