mpc8260cpm.c revision 0a85b6f0ab0d2edb0d41b32697111ce0e4f43496
1/* 2 comedi/drivers/mpc8260.c 3 driver for digital I/O pins on the MPC 8260 CPM module 4 5 COMEDI - Linux Control and Measurement Device Interface 6 Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org> 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 22*/ 23/* 24Driver: mpc8260cpm 25Description: MPC8260 CPM module generic digital I/O lines 26Devices: [Motorola] MPC8260 CPM (mpc8260cpm) 27Author: ds 28Status: experimental 29Updated: Sat, 16 Mar 2002 17:34:48 -0800 30 31This driver is specific to the Motorola MPC8260 processor, allowing 32you to access the processor's generic digital I/O lines. 33 34It is apparently missing some code. 35*/ 36 37#include "../comedidev.h" 38 39extern unsigned long mpc8260_dio_reserved[4]; 40 41struct mpc8260cpm_private { 42 43 int data; 44 45}; 46 47#define devpriv ((struct mpc8260cpm_private *)dev->private) 48 49static int mpc8260cpm_attach(struct comedi_device *dev, 50 struct comedi_devconfig *it); 51static int mpc8260cpm_detach(struct comedi_device *dev); 52static struct comedi_driver driver_mpc8260cpm = { 53 .driver_name = "mpc8260cpm", 54 .module = THIS_MODULE, 55 .attach = mpc8260cpm_attach, 56 .detach = mpc8260cpm_detach, 57}; 58 59COMEDI_INITCLEANUP(driver_mpc8260cpm); 60 61static int mpc8260cpm_dio_config(struct comedi_device *dev, 62 struct comedi_subdevice *s, 63 struct comedi_insn *insn, unsigned int *data); 64static int mpc8260cpm_dio_bits(struct comedi_device *dev, 65 struct comedi_subdevice *s, 66 struct comedi_insn *insn, unsigned int *data); 67 68static int mpc8260cpm_attach(struct comedi_device *dev, 69 struct comedi_devconfig *it) 70{ 71 struct comedi_subdevice *s; 72 int i; 73 74 printk("comedi%d: mpc8260cpm: ", dev->minor); 75 76 dev->board_ptr = mpc8260cpm_boards + dev->board; 77 78 dev->board_name = thisboard->name; 79 80 if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) 81 return -ENOMEM; 82 83 if (alloc_subdevices(dev, 4) < 0) 84 return -ENOMEM; 85 86 for (i = 0; i < 4; i++) { 87 s = dev->subdevices + i; 88 s->type = COMEDI_SUBD_DIO; 89 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 90 s->n_chan = 32; 91 s->maxdata = 1; 92 s->range_table = &range_digital; 93 s->insn_config = mpc8260cpm_dio_config; 94 s->insn_bits = mpc8260cpm_dio_bits; 95 } 96 97 return 1; 98} 99 100static int mpc8260cpm_detach(struct comedi_device *dev) 101{ 102 printk("comedi%d: mpc8260cpm: remove\n", dev->minor); 103 104 return 0; 105} 106 107static unsigned long *cpm_pdat(int port) 108{ 109 switch (port) { 110 case 0: 111 return &io->iop_pdata; 112 case 1: 113 return &io->iop_pdatb; 114 case 2: 115 return &io->iop_pdatc; 116 case 3: 117 return &io->iop_pdatd; 118 } 119} 120 121static int mpc8260cpm_dio_config(struct comedi_device *dev, 122 struct comedi_subdevice *s, 123 struct comedi_insn *insn, unsigned int *data) 124{ 125 int n; 126 unsigned int d; 127 unsigned int mask; 128 int port; 129 130 port = (int)s->private; 131 mask = 1 << CR_CHAN(insn->chanspec); 132 if (mask & cpm_reserved_bits[port]) { 133 return -EINVAL; 134 } 135 136 switch (data[0]) { 137 case INSN_CONFIG_DIO_OUTPUT: 138 s->io_bits |= mask; 139 break; 140 case INSN_CONFIG_DIO_INPUT: 141 s->io_bits &= ~mask; 142 break; 143 case INSN_CONFIG_DIO_QUERY: 144 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; 145 return insn->n; 146 break; 147 default: 148 return -EINVAL; 149 } 150 151 switch (port) { 152 case 0: 153 return &io->iop_pdira; 154 case 1: 155 return &io->iop_pdirb; 156 case 2: 157 return &io->iop_pdirc; 158 case 3: 159 return &io->iop_pdird; 160 } 161 162 return 1; 163} 164 165static int mpc8260cpm_dio_bits(struct comedi_device *dev, 166 struct comedi_subdevice *s, 167 struct comedi_insn *insn, unsigned int *data) 168{ 169 int port; 170 unsigned long *p; 171 172 p = cpm_pdat((int)s->private); 173 174 return 2; 175} 176