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