13124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef/* 23124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef comedi/drivers/mpc8260.c 33124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef driver for digital I/O pins on the MPC 8260 CPM module 43124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 53124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef COMEDI - Linux Control and Measurement Device Interface 63124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org> 73124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 83124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef This program is free software; you can redistribute it and/or modify 93124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef it under the terms of the GNU General Public License as published by 103124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef the Free Software Foundation; either version 2 of the License, or 113124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef (at your option) any later version. 123124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 133124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef This program is distributed in the hope that it will be useful, 143124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef but WITHOUT ANY WARRANTY; without even the implied warranty of 153124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 163124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef GNU General Public License for more details. 173124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 183124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef You should have received a copy of the GNU General Public License 193124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef along with this program; if not, write to the Free Software 203124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 213124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 223124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef*/ 233124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef/* 243124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefDriver: mpc8260cpm 253124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefDescription: MPC8260 CPM module generic digital I/O lines 263124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefDevices: [Motorola] MPC8260 CPM (mpc8260cpm) 273124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefAuthor: ds 283124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefStatus: experimental 293124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefUpdated: Sat, 16 Mar 2002 17:34:48 -0800 303124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 313124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefThis driver is specific to the Motorola MPC8260 processor, allowing 323124dd1cba314da1482540bc805d2054b449ce4bDavid Schleefyou to access the processor's generic digital I/O lines. 333124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 343124dd1cba314da1482540bc805d2054b449ce4bDavid SchleefIt is apparently missing some code. 353124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef*/ 363124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 373124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef#include "../comedidev.h" 383124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 393124dd1cba314da1482540bc805d2054b449ce4bDavid Schleefextern unsigned long mpc8260_dio_reserved[4]; 403124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 416555be0a1c25576be6270bb43f1bd444df7d86f8Bill Pembertonstruct mpc8260cpm_private { 426555be0a1c25576be6270bb43f1bd444df7d86f8Bill Pemberton 433124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef int data; 443124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 456555be0a1c25576be6270bb43f1bd444df7d86f8Bill Pemberton}; 466555be0a1c25576be6270bb43f1bd444df7d86f8Bill Pemberton 476555be0a1c25576be6270bb43f1bd444df7d86f8Bill Pemberton#define devpriv ((struct mpc8260cpm_private *)dev->private) 483124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc8260cpm_attach(struct comedi_device *dev, 500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 51da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int mpc8260cpm_detach(struct comedi_device *dev); 52139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_mpc8260cpm = { 5368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "mpc8260cpm", 5468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 5568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = mpc8260cpm_attach, 5668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = mpc8260cpm_detach, 573124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef}; 583124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 597114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_mpc8260cpm_init_module(void) 607114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 617114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas return comedi_driver_register(&driver_mpc8260cpm); 627114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 637114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 647114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_mpc8260cpm_cleanup_module(void) 657114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 667114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas comedi_driver_unregister(&driver_mpc8260cpm); 677114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 687114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 697114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_mpc8260cpm_init_module); 707114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_mpc8260cpm_cleanup_module); 713124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc8260cpm_dio_config(struct comedi_device *dev, 730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc8260cpm_dio_bits(struct comedi_device *dev, 760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 783124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc8260cpm_attach(struct comedi_device *dev, 800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 813124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef{ 8234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 833124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef int i; 843124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 853124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef printk("comedi%d: mpc8260cpm: ", dev->minor); 863124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 873124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef dev->board_ptr = mpc8260cpm_boards + dev->board; 883124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 893124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef dev->board_name = thisboard->name; 903124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 916555be0a1c25576be6270bb43f1bd444df7d86f8Bill Pemberton if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) 923124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return -ENOMEM; 933124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 943124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef if (alloc_subdevices(dev, 4) < 0) 953124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return -ENOMEM; 963124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 973124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef for (i = 0; i < 4; i++) { 983124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s = dev->subdevices + i; 993124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->type = COMEDI_SUBD_DIO; 1003124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1013124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->n_chan = 32; 1023124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->maxdata = 1; 1033124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->range_table = &range_digital; 1043124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->insn_config = mpc8260cpm_dio_config; 1053124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->insn_bits = mpc8260cpm_dio_bits; 1063124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef } 1073124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1083124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return 1; 1093124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef} 1103124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 111da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int mpc8260cpm_detach(struct comedi_device *dev) 1123124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef{ 1133124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef printk("comedi%d: mpc8260cpm: remove\n", dev->minor); 1143124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1153124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return 0; 1163124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef} 1173124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1183124dd1cba314da1482540bc805d2054b449ce4bDavid Schleefstatic unsigned long *cpm_pdat(int port) 1193124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef{ 1203124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef switch (port) { 1213124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 0: 1223124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdata; 1233124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 1: 1243124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdatb; 1253124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 2: 1263124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdatc; 1273124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 3: 1283124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdatd; 1293124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef } 1303124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef} 1313124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc8260cpm_dio_config(struct comedi_device *dev, 1330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1353124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef{ 1363124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef int n; 1373124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef unsigned int d; 1383124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef unsigned int mask; 1393124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef int port; 1403124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1413124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef port = (int)s->private; 1423124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef mask = 1 << CR_CHAN(insn->chanspec); 1433124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef if (mask & cpm_reserved_bits[port]) { 1443124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return -EINVAL; 1453124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef } 1463124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1473124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef switch (data[0]) { 1483124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case INSN_CONFIG_DIO_OUTPUT: 1493124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->io_bits |= mask; 1503124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef break; 1513124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case INSN_CONFIG_DIO_INPUT: 1523124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef s->io_bits &= ~mask; 1533124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef break; 1543124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case INSN_CONFIG_DIO_QUERY: 1553124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; 1563124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return insn->n; 1573124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef break; 1583124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef default: 1593124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return -EINVAL; 1603124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef } 1613124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1623124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef switch (port) { 1633124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 0: 1643124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdira; 1653124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 1: 1663124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdirb; 1673124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 2: 1683124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdirc; 1693124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef case 3: 1703124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return &io->iop_pdird; 1713124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef } 1723124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1733124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return 1; 1743124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef} 1753124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc8260cpm_dio_bits(struct comedi_device *dev, 1770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1793124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef{ 1803124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef int port; 1813124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef unsigned long *p; 1823124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1833124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef p = cpm_pdat((int)s->private); 1843124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef 1853124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef return 2; 1863124dd1cba314da1482540bc805d2054b449ce4bDavid Schleef} 187