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");
53 if (parport_claim_or_block(parport_pins) < 0) {
55 "Could not claim the " PPIN_DEV " parallel port device\n");
58 parport_write_data(parport_pins->port, pin_state);
59 parport_release(parport_pins);
63 ppin_attach(struct parport *port)
65 if (available_ports == 0) {
67 parport_register_device(port, PPIN_DEV, NULL, NULL,
70 if (parport_pins == 0)
72 "Could not associate " PPIN_DEV " device with parallel port #%d\n",
76 "Associated " PPIN_DEV " device with parallel port #%d\n",
84 ppin_detach(struct parport *port)
86 if (available_ports == 1)
92 static struct parport_driver ppin_driver = {
100 ppin_read(struct file *file, char *buf, size_t count, loff_t * ppos)
110 "PIN #: 0 1 2 3 4 5 6 7\n"
111 "State: %s %s %s %s %s %s %s %s\n",
112 pin_state & (1 << 0) ? " on" : "off",
113 pin_state & (1 << 1) ? " on" : "off",
114 pin_state & (1 << 2) ? " on" : "off",
115 pin_state & (1 << 3) ? " on" : "off",
116 pin_state & (1 << 4) ? " on" : "off",
117 pin_state & (1 << 5) ? " on" : "off",
118 pin_state & (1 << 6) ? " on" : "off",
119 pin_state & (1 << 7) ? " on" : "off");
121 for (i = 0; count-- > 0 && i < 78; ++i, ++tmp)
122 put_user(status[i], tmp);
131 ppin_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
136 i = simple_strtol(buf, &tmp_2, 0);
138 if (i < 0 || i > 7) {
139 printk(KERN_WARNING "" PPIN_DEV ": No such PIN: %d\n", i);
144 tmp_1 = strstr(tmp_2, OFF_COMMAND);
146 pin_state &= ~(1 << i);
148 tmp_1 = strstr(tmp_2, ON_COMMAND);
150 pin_state |= (1 << i);
154 printk(KERN_WARNING "" PPIN_DEV": No such state\n");
163 ppin_open(struct inode *inode, struct file *file)
175 ppin_release(struct inode *inode, struct file *file)
181 static struct file_operations ppin_fops = {
186 release:ppin_release,
189 static struct miscdevice ppin_dev = {
198 if (parport_register_driver(&ppin_driver) != 0) {
199 printk(KERN_ERR "Could not register the " PPIN_DEV " driver.\n");
203 if (misc_register(&ppin_dev) != 0) {
205 "Could not register the misc device " PPIN_DEV " (%d, %d)\n",
206 PPIN_MAJOR, PPIN_MINOR);
210 printk(KERN_INFO "" PPIN_NAME " driver v%s loaded\n", PPIN_VERSION);
219 if (misc_deregister(&ppin_dev) != 0)
221 "Cound not deregister the misc device " PPIN_DEV " (%d, %d)\n",
222 PPIN_MAJOR, PPIN_MINOR);
224 parport_unregister_device(parport_pins);
225 parport_unregister_driver(&ppin_driver);
227 printk(KERN_INFO "" PPIN_NAME " driver v%s unloaded\n", PPIN_VERSION);
230 module_init(ppin_init);
231 module_exit(ppin_cleanup);