2 * Parallel Port Pin driver for Linux 2.6: ppin
4 * This kernel module will register the /dev/ppin (10, 151)
5 * device which controls up to eight pins through the first
8 * Controlling the pins is as easy as 'echo Num State >/dev/ppin',
9 * where Num is 0 to 7 and State is one of 'on', 'off'.
10 * For example: "echo 3 on >/dev/ppin" switches the 3rd pin on.
12 * You can read the status of the pins with 'cat /dev/ppin'.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
19 * Authors: Alexander Barton, <alex@barton.de> (for Linux 2.6, 2009)
21 * This work is heavily(!) based on the "devled" driver written by
22 * Konstantinos Natsakis, <cyfex@mail.com> (for Linux 2.2/2.4).
25 #include <linux/module.h>
26 #include <linux/miscdevice.h>
27 #include <linux/parport.h>
28 #include <asm/uaccess.h>
30 #define PPIN_NAME "ppin"
31 #define PPIN_VERSION "0.1"
33 #define PPIN_DEV "ppin"
34 #define PPIN_MAJOR MISC_MAJOR
35 #define PPIN_MINOR 151
37 #define ON_COMMAND "on"
38 #define OFF_COMMAND "off"
40 static char pin_state = 0;
41 static int buffer_empty = 0;
42 static int ppin_open_cnt = 0;
43 static int available_ports = 0;
44 static struct pardevice *parport_pins = 0;
46 MODULE_AUTHOR("Alexander Barton, alex@barton.de");
47 MODULE_DESCRIPTION("Driver for controlling the state of parallel port PINs");
48 MODULE_LICENSE("GPL");
51 ppin_attach(struct parport *port)
53 if (available_ports == 0) {
55 parport_register_device(port, PPIN_DEV, NULL, NULL,
58 if (parport_pins == 0)
60 "Could not associate " PPIN_DEV " device with parallel port #%d\n",
64 "Associated " PPIN_DEV " device with parallel port #%d\n",
72 ppin_detach(struct parport *port)
74 if (available_ports == 1)
80 static struct parport_driver ppin_driver = {
88 ppin_read(struct file *file, char *buf, size_t count, loff_t * ppos)
98 "PIN #: 0 1 2 3 4 5 6 7\n"
99 "State: %s %s %s %s %s %s %s %s\n",
100 pin_state & (1 << 0) ? " on" : "off",
101 pin_state & (1 << 1) ? " on" : "off",
102 pin_state & (1 << 2) ? " on" : "off",
103 pin_state & (1 << 3) ? " on" : "off",
104 pin_state & (1 << 4) ? " on" : "off",
105 pin_state & (1 << 5) ? " on" : "off",
106 pin_state & (1 << 6) ? " on" : "off",
107 pin_state & (1 << 7) ? " on" : "off");
109 for (i = 0; count-- > 0 && i < 78; ++i, ++tmp)
110 put_user(status[i], tmp);
119 ppin_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
124 i = simple_strtol(buf, &tmp_2, 0);
126 if (i < 0 || i > 7) {
127 printk(KERN_WARNING "" PPIN_DEV ": No such PIN: %d\n", i);
132 tmp_1 = strstr(tmp_2, OFF_COMMAND);
134 pin_state &= ~(1 << i);
136 tmp_1 = strstr(tmp_2, ON_COMMAND);
138 pin_state |= (1 << i);
142 printk(KERN_WARNING "" PPIN_DEV": No such state\n");
146 if (parport_claim_or_block(parport_pins) < 0) {
148 "Could not claim the " PPIN_DEV " parallel port device\n");
152 parport_write_data(parport_pins->port, pin_state);
154 parport_release(parport_pins);
159 ppin_open(struct inode *inode, struct file *file)
171 ppin_release(struct inode *inode, struct file *file)
177 static struct file_operations ppin_fops = {
182 release:ppin_release,
185 static struct miscdevice ppin_dev = {
194 if (parport_register_driver(&ppin_driver) != 0) {
195 printk(KERN_ERR "Could not register the " PPIN_DEV " driver.\n");
199 if (misc_register(&ppin_dev) != 0) {
201 "Could not register the misc device " PPIN_DEV " (%d, %d)\n",
202 PPIN_MAJOR, PPIN_MINOR);
206 printk(KERN_INFO "" PPIN_NAME " driver v%s loaded\n", PPIN_VERSION);
213 if (misc_deregister(&ppin_dev) != 0)
215 "Cound not deregister the misc device " PPIN_DEV " (%d, %d)\n",
216 PPIN_MAJOR, PPIN_MINOR);
218 parport_unregister_device(parport_pins);
219 parport_unregister_driver(&ppin_driver);
221 printk(KERN_INFO "" PPIN_NAME " driver v%s unloaded\n", PPIN_VERSION);
224 module_init(ppin_init);
225 module_exit(ppin_cleanup);