Re: Controlling par port

Paul Schulz (pauls@caemrad.com.au)
Thu, 28 Oct 1999 09:09:26 +0930 (CST)


This was my attempt at a parallel port module after reading
Rubini's book (Linux Device Drivers), it documents the parallel port
adequately for you purposes.

This worked for 2.0.x kernels, but I don't know what in the kernbel
interface changed for 2.2.x.. any doco out there?

You'll need to also do..
mknod /dev/pmod0 c 63 0

See the attached perl script for an application..
with an led (and resistor) attached to each of the 8 output lines I
had a fairly spiffy load monitor.

--8<--(cut)-------------------------------------------------------------
/* Paul's Parallel Port Module : pmodule */
/* GLP'ed */
/* pmin.c */
/* April, 1999 */
/* pauls@caemrad.com.au */

To compile:
gcc -D__KERNEL__ -DMODULE -O -Wall -I/usr/include -c -o pmin pmin.c

Needs:
mknod /dev/pmod0 c 63 0

Need to fix:
make code re-entrant

Bugs:
records state of port on every open, regardless
of whether this is a read or write.
*/

#define __NO_VERSION__
#include <linux/module.h> /* needed for 'printk' */
#include <linux/sched.h> /* needed for 'current' */
#include <linux/version.h>
#include <linux/ioport.h> /* needed for allocating io ports */
#include <linux/interrupt.h> /* needed for probe_irq_ */
#include <linux/errno.h> /* needed for error numbers */
#include <linux/fs.h> /* needed for registering devices */
#include <asm/segment.h> /* needed for memcpy_ */
#include <asm/io.h> /* needed for port access */

#define MAX_STRING 200

char kernel_version[] = UTS_RELEASE;
#define VERSION_CODE(vars,rel,seq) (((vers)<<16) | ((rel)<<8) | (seq))

#define PMOD_MAJOR 63
#define PMOD_BASE 0x378

int pmod_major = PMOD_MAJOR;
int pmod_base = PMOD_BASE;
int pmod_irq = -1;

int pmod_open(struct inode *inode, struct file *filp);
void pmod_release(struct inode *inode, struct file *filp);
int pmod_write(struct inode *inode, struct file *filp, const char *buf, int i);

struct file_operations pmod_fops = {
NULL, /* lseek */
NULL, /* read */
&pmod_write, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
&pmod_open, /* open */
&pmod_release /* release */
};

int init_module(void){
int result;

/* pmod_detect(???); */
result = register_chrdev(pmod_major, "pmod", &pmod_fops);
if(result < 0 ){
printk(KERN_WARNING "pmodule: can't get major %d\n", pmod_major);
return result;
}
if(pmod_major == 0) pmod_major = result;

printk("<1>pmodule: Using port: %x\n",pmod_base);
printk("<1>pmodule: Registering MAJOR device number: %i\n",
pmod_major);
printk("<1>pmodule: The process is \"%s\" (pid %i)\n",
current->comm, current->pid);
return 0;
}

void cleanup_module(void){
int result;
outb(0x00, pmod_base);

result = unregister_chrdev(pmod_major, "pmod");
printk("<1>pmodule: Unregistered char device.\n");
}

int pmod_open(struct inode *inode, struct file *filp){
filp->f_op = &pmod_fops;
MOD_INC_USE_COUNT;
/* printk("<1>pmodule: node opened\n"); */
return 0;
}

void pmod_release(struct inode *inode, struct file *filp){
MOD_DEC_USE_COUNT;
/* printk("<1>pmodule: node closed\n"); */
}

int pmod_write(struct inode *inode, struct file *filp, const char *buf, int i){
unsigned char value;

memcpy_fromfs(&value, (void *)buf, 1);
/* printk("<1>pmodule: byte value received : %i\n",value); */
outb(value, pmod_base);
/* printk("<1>pmodule: wrote byte value : %i\n",value); */
return 1;
}

--8<-(cut)---------------------------------------------------------------

#!/usr/bin/perl
#load2.pl
$fullscale=2.0;

while(1){
open(IFILE,"uptime |");
$line=<IFILE>;
close IFILE;

chop $line;

($time1,$time2,$users,$load)=split(',',$line,4);
$load=~ s/^.*:([^,]*),.*$/$1/;
# linear
# $load=int($load*8/$fullscale);

# logarithmic
# $load=int($load*4);
if($load != 0){
$load=int(2*log($load*4)/log(2));
if($load < 0){$load=0;}
}

$out = (1 << $load) - 1;
$out = $out & 0xff;
# print "$load - $out\n$line\n";
$char = chr $out;

open(OFILE,">/dev/pmod0");
print OFILE $char;
close(OFILE);

sleep 1;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/