mpc8260cpm.c revision 68c3dbff9fc9f25872408d0e95980d41733d48d0
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, struct comedi_devconfig *it); 50static int mpc8260cpm_detach(struct comedi_device *dev); 51static struct comedi_driver driver_mpc8260cpm = { 52 .driver_name = "mpc8260cpm", 53 .module = THIS_MODULE, 54 .attach = mpc8260cpm_attach, 55 .detach = mpc8260cpm_detach, 56}; 57 58COMEDI_INITCLEANUP(driver_mpc8260cpm); 59 60static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdevice *s, 61 struct comedi_insn *insn, unsigned int *data); 62static int mpc8260cpm_dio_bits(struct comedi_device *dev, struct comedi_subdevice *s, 63 struct comedi_insn *insn, unsigned int *data); 64 65static int mpc8260cpm_attach(struct comedi_device *dev, struct comedi_devconfig *it) 66{ 67 struct comedi_subdevice *s; 68 int i; 69 70 printk("comedi%d: mpc8260cpm: ", dev->minor); 71 72 dev->board_ptr = mpc8260cpm_boards + dev->board; 73 74 dev->board_name = thisboard->name; 75 76 if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) 77 return -ENOMEM; 78 79 if (alloc_subdevices(dev, 4) < 0) 80 return -ENOMEM; 81 82 for (i = 0; i < 4; i++) { 83 s = dev->subdevices + i; 84 s->type = COMEDI_SUBD_DIO; 85 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 86 s->n_chan = 32; 87 s->maxdata = 1; 88 s->range_table = &range_digital; 89 s->insn_config = mpc8260cpm_dio_config; 90 s->insn_bits = mpc8260cpm_dio_bits; 91 } 92 93 return 1; 94} 95 96static int mpc8260cpm_detach(struct comedi_device *dev) 97{ 98 printk("comedi%d: mpc8260cpm: remove\n", dev->minor); 99 100 return 0; 101} 102 103static unsigned long *cpm_pdat(int port) 104{ 105 switch (port) { 106 case 0: 107 return &io->iop_pdata; 108 case 1: 109 return &io->iop_pdatb; 110 case 2: 111 return &io->iop_pdatc; 112 case 3: 113 return &io->iop_pdatd; 114 } 115} 116 117static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdevice *s, 118 struct comedi_insn *insn, unsigned int *data) 119{ 120 int n; 121 unsigned int d; 122 unsigned int mask; 123 int port; 124 125 port = (int)s->private; 126 mask = 1 << CR_CHAN(insn->chanspec); 127 if (mask & cpm_reserved_bits[port]) { 128 return -EINVAL; 129 } 130 131 switch (data[0]) { 132 case INSN_CONFIG_DIO_OUTPUT: 133 s->io_bits |= mask; 134 break; 135 case INSN_CONFIG_DIO_INPUT: 136 s->io_bits &= ~mask; 137 break; 138 case INSN_CONFIG_DIO_QUERY: 139 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; 140 return insn->n; 141 break; 142 default: 143 return -EINVAL; 144 } 145 146 switch (port) { 147 case 0: 148 return &io->iop_pdira; 149 case 1: 150 return &io->iop_pdirb; 151 case 2: 152 return &io->iop_pdirc; 153 case 3: 154 return &io->iop_pdird; 155 } 156 157 return 1; 158} 159 160static int mpc8260cpm_dio_bits(struct comedi_device *dev, struct comedi_subdevice *s, 161 struct comedi_insn *insn, unsigned int *data) 162{ 163 int port; 164 unsigned long *p; 165 166 p = cpm_pdat((int)s->private); 167 168 return 2; 169} 170