aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreinelt <>2003-04-04 06:02:04 +0000
committerreinelt <>2003-04-04 06:02:04 +0000
commit43f6cfacf15926a6538fc8c8a7e46430851aaa67 (patch)
treedeb1bbf2bbb8fb7a9d610520b2d1453c91d0da20
parent898186678d7b2680f915cd1c3cca57bd27333f72 (diff)
downloadlcd4linux-43f6cfacf15926a6538fc8c8a7e46430851aaa67.tar.gz
[lcd4linux @ 2003-04-04 06:01:59 by reinelt]
new parallel port abstraction scheme
-rw-r--r--HD44780.c311
-rw-r--r--M50530.c149
-rw-r--r--USBLCD.c6
-rwxr-xr-xconfigure18
-rw-r--r--configure.in16
-rw-r--r--parport.c346
-rw-r--r--parport.h38
-rw-r--r--udelay.c7
8 files changed, 516 insertions, 375 deletions
diff --git a/HD44780.c b/HD44780.c
index e5e254e..ac17d8e 100644
--- a/HD44780.c
+++ b/HD44780.c
@@ -1,4 +1,4 @@
-/* $Id: HD44780.c,v 1.26 2003/02/22 07:53:09 reinelt Exp $
+/* $Id: HD44780.c,v 1.27 2003/04/04 06:01:59 reinelt Exp $
*
* driver for display modules based on the HD44780 chip
*
@@ -20,6 +20,9 @@
*
*
* $Log: HD44780.c,v $
+ * Revision 1.27 2003/04/04 06:01:59 reinelt
+ * new parallel port abstraction scheme
+ *
* Revision 1.26 2003/02/22 07:53:09 reinelt
* cfg_get(key,defval)
*
@@ -150,38 +153,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_SYS_IO_H
-#include <sys/io.h>
-#define WITH_OUTB
-#else
-#ifdef HAVE_ASM_IO_H
-#include <asm/io.h>
-#define WITH_OUTB
-#endif
-#endif
-
-#if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H)
-#define WITH_PPDEV
-#include <linux/parport.h>
-#include <linux/ppdev.h>
-#endif
-
-
-#if !defined(WITH_OUTB) && !defined(WITH_PPDEV)
-#error neither outb() nor ppdev() possible
-#error cannot compile HD44780 driver
-#endif
#include "debug.h"
#include "cfg.h"
#include "display.h"
#include "bar.h"
+#include "parport.h"
#include "udelay.h"
#define XRES 5
@@ -190,203 +167,75 @@
static LCD Lcd;
-
-static unsigned short Port=0;
-
-static char *PPdev=NULL;
-
-#ifdef WITH_PPDEV
-static int PPfd=-1;
-#endif
-
static char Txt[4][40];
static int GPO=0;
-#ifdef WITH_PPDEV
-static void HD_toggle (int bit, int inv, int delay)
-{
- struct ppdev_frob_struct frob;
- frob.mask=bit;
-
- // rise
- frob.val=inv?0:bit;
- ioctl (PPfd, PPFCONTROL, &frob);
-
- // pulse width
- ndelay(delay);
+static unsigned char SIGNAL_RS;
+static unsigned char SIGNAL_ENABLE;
+static unsigned char SIGNAL_ENABLE_GPO;
- // lower
- frob.val=inv?bit:0;
- ioctl (PPfd, PPFCONTROL, &frob);
-}
-#endif
static void HD_command (unsigned char cmd, int delay)
{
-#ifdef WITH_PPDEV
- if (PPdev) {
-
- struct ppdev_frob_struct frob;
-
- // put data on DB1..DB8
- ioctl(PPfd, PPWDATA, &cmd);
- // clear RS (inverted)
- frob.mask=PARPORT_CONTROL_AUTOFD;
- frob.val=PARPORT_CONTROL_AUTOFD;
- ioctl (PPfd, PPFCONTROL, &frob);
+ // put data on DB1..DB8
+ parport_data (cmd);
+
+ // clear RS
+ parport_control (SIGNAL_RS, 0);
- // Address set-up time
- ndelay(40);
+ // Address set-up time
+ ndelay(40);
- // send command
- // Enable cycle time = 230ns
- HD_toggle(PARPORT_CONTROL_STROBE, 1, 230);
+ // send command
+ // Enable cycle time = 230ns
+ parport_toggle (SIGNAL_ENABLE, 1, 230);
- // wait for command completion
- udelay(delay);
-
- } else
+ // wait for command completion
+ udelay(delay);
-#endif
-
- {
- outb (cmd, Port); // put data on DB1..DB8
- outb (0x03, Port+2); // clear RS = bit 2 invertet
- ndelay(40); // Address set-up time
- outb (0x02, Port+2); // set Enable = bit 0 invertet
- ndelay(230); // Enable cycle time
- outb (0x03, Port+2); // clear Enable
- udelay (delay); // wait for command completion
- }
}
+
static void HD_write (char *string, int len, int delay)
{
-#ifdef WITH_PPDEV
- if (PPdev) {
+ // set RS
+ parport_control (SIGNAL_RS, SIGNAL_RS);
- struct ppdev_frob_struct frob;
-
- // set RS (inverted)
- frob.mask=PARPORT_CONTROL_AUTOFD;
- frob.val=0;
- ioctl (PPfd, PPFCONTROL, &frob);
+ // Address set-up time
+ ndelay(40);
+
+ while (len--) {
- // Address set-up time
- ndelay(40);
+ // put data on DB1..DB8
+ parport_data (*(string++));
- while (len--) {
-
- // put data on DB1..DB8
- ioctl(PPfd, PPWDATA, string++);
-
- // send command
- HD_toggle(PARPORT_CONTROL_STROBE, 1, 230);
-
- // wait for command completion
- udelay(delay);
- }
+ // send command
+ // Enable cycle time = 230ns
+ parport_toggle (SIGNAL_ENABLE, 1, 230);
- } else
-
-#endif
-
- {
- outb (0x01, Port+2); // set RS = bit 2 invertet
- ndelay(40); // Address set-up time
- while (len--) {
- outb (*string++, Port); // put data on DB1..DB8
- outb (0x00, Port+2); // set Enable = bit 0 invertet
- ndelay(230); // Enable cycle time
- outb (0x01, Port+2); // clear Enable
- udelay (delay);
- }
- }
+ // wait for command completion
+ udelay(delay);
+ }
}
static void HD_setGPO (int bits)
{
if (Lcd.gpos>0) {
-
-#ifdef WITH_PPDEV
-
-
- if (PPdev) {
-
- // put data on DB1..DB8
- ioctl(PPfd, PPWDATA, &bits);
-
- // 74HCT573 set-up time
- ndelay(20);
-
- // toggle INIT
- // 74HCT573 enable pulse width = 24ns
- HD_toggle(PARPORT_CONTROL_INIT, 0, 24);
-
- } else
-
-#endif
-
- {
- outb (bits, Port); // put data on DB1..DB8
- ndelay(20); // 74HCT573 set-up time
- outb (0x05, Port+2); // set INIT = bit 2 invertet
- ndelay(24); // 74HCT573 enable pulse width
- outb (0x03, Port+2); // clear INIT
- }
+
+ // put data on DB1..DB8
+ parport_data (bits);
+
+ // 74HCT573 set-up time
+ ndelay(20);
+
+ // send data
+ // 74HCT573 enable pulse width = 24ns
+ parport_toggle (SIGNAL_ENABLE_GPO, 1, 230);
}
}
-static int HD_open (void)
-{
-#ifdef WITH_PPDEV
-
- if (PPdev) {
- debug ("using ppdev %s", PPdev);
- PPfd=open(PPdev, O_RDWR);
- if (PPfd==-1) {
- error ("HD44780: open(%s) failed: %s", PPdev, strerror(errno));
- return -1;
- }
-
-#if 0
- if (ioctl(PPfd, PPEXCL)) {
- debug ("ioctl(%s, PPEXCL) failed: %s", PPdev, strerror(errno));
- } else {
- debug ("ioctl(%s, PPEXCL) succeded.");
- }
-#endif
-
- if (ioctl(PPfd, PPCLAIM)) {
- error ("HD44780: ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno));
- return -1;
- }
- } else
-
-#endif
-
- {
- debug ("using raw port 0x%x", Port);
- if (ioperm(Port, 3, 1)!=0) {
- error ("HD44780: ioperm(0x%x) failed: %s", Port, strerror(errno));
- return -1;
- }
- }
-
- HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms
- HD_command (0x30, 100); // 8 Bit mode, wait 100 us
- HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms
- HD_command (0x38, 40); // 8 Bit mode, 1/16 duty cycle, 5x8 font
- HD_command (0x08, 40); // Display off, cursor off, blink off
- HD_command (0x0c, 1640); // Display on, cursor off, blink off, wait 1.64 ms
- HD_command (0x06, 40); // curser moves to right, no shift
-
- return 0;
-}
-
-
static void HD_define_char (int ascii, char *buffer)
{
HD_command (0x40|8*ascii, 40);
@@ -418,34 +267,6 @@ int HD_init (LCD *Self)
int rows=-1, cols=-1, gpos=-1;
char *s, *e;
- s=cfg_get ("Port",NULL);
- if (s==NULL || *s=='\0') {
- error ("HD44780: no 'Port' entry in %s", cfg_file());
- return -1;
- }
- PPdev=NULL;
- if ((Port=strtol(s, &e, 0))==0 || *e!='\0') {
-#ifdef WITH_PPDEV
- Port=0;
- PPdev=s;
-#else
- error ("HD44780: bad port '%s' in %s", s, cfg_file());
- return -1;
-#endif
- }
-
-#ifdef USE_OLD_UDELAY
- s=cfg_get ("Delay",NULL);
- if (s==NULL || *s=='\0') {
- error ("HD44780: no 'Delay' entry in %s", cfg_file());
- return -1;
- }
- if ((loops_per_usec=strtol(s, &e, 0))==0 || *e!='\0') {
- error ("HD44780: bad delay '%s' in %s", s, cfg_file());
- return -1;
- }
-#endif
-
s=cfg_get("Size",NULL);
if (s==NULL || *s=='\0') {
error ("HD44780: no 'Size' entry in %s", cfg_file());
@@ -470,13 +291,24 @@ int HD_init (LCD *Self)
Self->gpos=gpos;
Lcd=*Self;
-#ifndef USE_OLD_UDELAY
- udelay_init();
-#endif
+ SIGNAL_RS=parport_wire ("RS", "AUTOFD");
+ SIGNAL_ENABLE=parport_wire ("ENABLE", "STROBE");
+ SIGNAL_ENABLE_GPO=parport_wire ("ENABLE_GPO", "INIT");
- if (HD_open()!=0)
+ if (parport_open() != 0) {
+ error ("HD44780: could not initialize parallel port!");
return -1;
-
+ }
+
+ HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms
+ HD_command (0x30, 100); // 8 Bit mode, wait 100 us
+ HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms
+ HD_command (0x38, 40); // 8 Bit mode, 1/16 duty cycle, 5x8 font
+ HD_command (0x08, 40); // Display off, cursor off, blink off
+ HD_command (0x0c, 1640); // Display on, cursor off, blink off, wait 1.64 ms
+ HD_command (0x06, 40); // curser moves to right, no shift
+
+
bar_init(rows, cols, XRES, YRES, CHARS);
bar_add_segment( 0, 0,255, 32); // ASCII 32 = blank
bar_add_segment(255,255,255,255); // ASCII 255 = block
@@ -562,26 +394,7 @@ int HD_flush (void)
int HD_quit (void)
{
-#ifdef WITH_PPDEV
- if (PPdev) {
- debug ("closing ppdev %s", PPdev);
- if (ioctl(PPfd, PPRELEASE)) {
- error ("HD44780: ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno));
- }
- if (close(PPfd)==-1) {
- error ("HD44780: close(%s) failed: %s", PPdev, strerror(errno));
- return -1;
- }
- } else
-#endif
- {
- debug ("closing raw port 0x%x", Port);
- if (ioperm(Port, 3, 0)!=0) {
- error ("HD44780: ioperm(0x%x) failed: %s", Port, strerror(errno));
- return -1;
- }
- }
- return 0;
+ return parport_close();
}
diff --git a/M50530.c b/M50530.c
index ed64b32..afeb185 100644
--- a/M50530.c
+++ b/M50530.c
@@ -1,4 +1,4 @@
-/* $Id: M50530.c,v 1.6 2003/02/22 07:53:10 reinelt Exp $
+/* $Id: M50530.c,v 1.7 2003/04/04 06:01:59 reinelt Exp $
*
* driver for display modules based on the M50530 chip
*
@@ -20,6 +20,9 @@
*
*
* $Log: M50530.c,v $
+ * Revision 1.7 2003/04/04 06:01:59 reinelt
+ * new parallel port abstraction scheme
+ *
* Revision 1.6 2003/02/22 07:53:10 reinelt
* cfg_get(key,defval)
*
@@ -56,25 +59,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H)
-#define WITH_PPDEV
-#include <linux/parport.h>
-#include <linux/ppdev.h>
-#else
-#error The M50530 driver needs ppdev
-#error cannot compile M50530 driver
-#endif
#include "debug.h"
#include "cfg.h"
#include "display.h"
#include "bar.h"
+#include "parport.h"
#include "udelay.h"
#define XRES 5
@@ -83,52 +73,34 @@
static LCD Lcd;
-
-static char *PPdev=NULL;
-static int PPfd=-1;
-
static char Txt[8][40];
static int GPO=0;
+static unsigned char SIGNAL_EX;
+static unsigned char SIGNAL_IOC1;
+static unsigned char SIGNAL_IOC2;
+static unsigned char SIGNAL_ENABLE_GPO;
static void M5_command (unsigned int cmd, int delay)
{
- unsigned char data;
- struct ppdev_frob_struct frob;
// put data on DB1..DB8
- data=cmd&0xff;
- ioctl(PPfd, PPWDATA, &data);
+ parport_data (cmd&0xff);
// set I/OC1 (Select inverted)
// set I/OC2 (AutoFeed inverted)
- frob.mask=PARPORT_CONTROL_SELECT | PARPORT_CONTROL_AUTOFD;
- frob.val=0;
- if (!(cmd & 0x200)) {
- frob.val|=PARPORT_CONTROL_SELECT;
- }
- if (!(cmd & 0x100)) {
- frob.val|=PARPORT_CONTROL_AUTOFD;
- }
- ioctl (PPfd, PPFCONTROL, &frob);
+ parport_control (SIGNAL_IOC1|SIGNAL_IOC2,
+ (cmd&0x200?SIGNAL_IOC1:0) |
+ (cmd&0x100?SIGNAL_IOC2:0));
// Control data setup time
ndelay(200);
- // rise EX (Strobe, inverted)
- frob.mask=PARPORT_CONTROL_STROBE;
- frob.val=0;
- ioctl (PPfd, PPFCONTROL, &frob);
-
- // EX signal pulse width
+ // send command
+ // EX signal pulse width = 500ns
// Fixme: why 500 ns? Datasheet says 200ns
- ndelay(500);
+ parport_toggle (SIGNAL_EX, 1, 500);
- // lower EX (Strobe, inverted)
- frob.mask=PARPORT_CONTROL_STROBE;
- frob.val=PARPORT_CONTROL_STROBE;
- ioctl (PPfd, PPFCONTROL, &frob);
-
// wait
udelay(delay);
@@ -150,61 +122,19 @@ static void M5_setGPO (int bits)
{
if (Lcd.gpos>0) {
- struct ppdev_frob_struct frob;
-
// put data on DB1..DB8
- ioctl(PPfd, PPWDATA, &bits);
+ parport_data (bits);
// 74HCT573 set-up time
ndelay(20);
- // toggle INIT
- frob.mask=PARPORT_CONTROL_INIT;
- frob.val=PARPORT_CONTROL_INIT; // rise
- ioctl (PPfd, PPFCONTROL, &frob);
-
- // 74HCT573 enable pulse width
- ndelay(24);
-
- frob.val=0; // lower
- ioctl (PPfd, PPFCONTROL, &frob);
+ // send data
+ // 74HCT573 enable pulse width = 24ns
+ parport_toggle (SIGNAL_ENABLE_GPO, 1, 24);
}
}
-static int M5_open (void)
-{
-
- debug ("using ppdev %s", PPdev);
- PPfd=open(PPdev, O_RDWR);
- if (PPfd==-1) {
- error ("open(%s) failed: %s", PPdev, strerror(errno));
- return -1;
- }
-
-#if 0
- if (ioctl(PPfd, PPEXCL)) {
- debug ("ioctl(%s, PPEXCL) failed: %s", PPdev, strerror(errno));
- } else {
- debug ("ioctl(%s, PPEXCL) succeded.");
- }
-#endif
-
- if (ioctl(PPfd, PPCLAIM)) {
- error ("ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno));
- return -1;
- }
-
- M5_command (0x00FA, 20); // set function mode
- M5_command (0x0020, 20); // set display mode
- M5_command (0x0050, 20); // set entry mode
- M5_command (0x0030, 20); // set display mode
- M5_command (0x0001, 1250); // clear display
-
- return 0;
-}
-
-
static void M5_define_char (int ascii, char *buffer)
{
M5_command (0x300+192+8*ascii, 20);
@@ -237,18 +167,6 @@ int M5_init (LCD *Self)
int rows=-1, cols=-1, gpos=-1;
char *s, *e;
- if (PPdev) {
- free (PPdev);
- PPdev=NULL;
- }
-
- s=cfg_get ("Port",NULL);
- if (s==NULL || *s=='\0') {
- error ("M50530: no 'Port' entry in %s", cfg_file());
- return -1;
- }
- PPdev=strdup(s);
-
s=cfg_get("Size",NULL);
if (s==NULL || *s=='\0') {
error ("M50530: no 'Size' entry in %s", cfg_file());
@@ -275,14 +193,25 @@ int M5_init (LCD *Self)
Self->gpos=gpos;
Lcd=*Self;
- udelay_init();
+ SIGNAL_EX=parport_wire ("EX", "STROBE");
+ SIGNAL_EX=parport_wire ("IOC1", "SELECT");
+ SIGNAL_EX=parport_wire ("IOC2", "AUTOFD");
+ SIGNAL_EX=parport_wire ("ENABLE_GPO", "INIT");
- if (M5_open()!=0)
+ if (parport_open() != 0) {
+ error ("M50530: could not initialize parallel port!");
return -1;
+ }
+
+ M5_command (0x00FA, 20); // set function mode
+ M5_command (0x0020, 20); // set display mode
+ M5_command (0x0050, 20); // set entry mode
+ M5_command (0x0030, 20); // set display mode
+ M5_command (0x0001, 1250); // clear display
bar_init(rows, cols, XRES, YRES, CHARS);
bar_add_segment(0,0,255,32); // ASCII 32 = blank
-
+
M5_clear();
return 0;
@@ -366,15 +295,7 @@ int M5_flush (void)
int M5_quit (void)
{
- debug ("closing ppdev %s", PPdev);
- if (ioctl(PPfd, PPRELEASE)) {
- error ("ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno));
- }
- if (close(PPfd)==-1) {
- error ("close(%s) failed: %s", PPdev, strerror(errno));
- return -1;
- }
- return 0;
+ return parport_close();
}
diff --git a/USBLCD.c b/USBLCD.c
index 2cee0df..a2479e9 100644
--- a/USBLCD.c
+++ b/USBLCD.c
@@ -1,4 +1,4 @@
-/* $Id: USBLCD.c,v 1.8 2003/02/22 07:53:10 reinelt Exp $
+/* $Id: USBLCD.c,v 1.9 2003/04/04 06:01:59 reinelt Exp $
*
* Driver for USBLCD ( see http://www.usblcd.de )
* This Driver is based on HD44780.c
@@ -22,6 +22,9 @@
*
*
* $Log: USBLCD.c,v $
+ * Revision 1.9 2003/04/04 06:01:59 reinelt
+ * new parallel port abstraction scheme
+ *
* Revision 1.8 2003/02/22 07:53:10 reinelt
* cfg_get(key,defval)
*
@@ -79,7 +82,6 @@
#include "cfg.h"
#include "display.h"
#include "bar.h"
-#include "udelay.h"
#define GET_HARD_VERSION 1
#define GET_DRV_VERSION 2
diff --git a/configure b/configure
index 077ca9c..5a21ab8 100755
--- a/configure
+++ b/configure
@@ -4573,6 +4573,7 @@ echo "$as_me:$LINENO: result: done" >&5
echo "${ECHO_T}done" >&6
RASTER="no"
+PARPORT="no"
if test "$BECKMANNEGLE" = "yes"; then
DRIVERS="$DRIVERS BeckmannEgle.o"
@@ -4602,6 +4603,7 @@ _ACEOF
fi
if test "$HD44780" = "yes"; then
+ PARPORT="yes"
DRIVERS="$DRIVERS HD44780.o"
cat >>confdefs.h <<\_ACEOF
@@ -4611,6 +4613,7 @@ _ACEOF
fi
if test "$M50530" = "yes"; then
+ PARPORT="yes"
DRIVERS="$DRIVERS M50530.o"
cat >>confdefs.h <<\_ACEOF
@@ -4620,6 +4623,7 @@ _ACEOF
fi
if test "$T6963" = "yes"; then
+ PARPORT="yes"
DRIVERS="$DRIVERS T6963.o"
cat >>confdefs.h <<\_ACEOF
@@ -4724,16 +4728,20 @@ _ACEOF
fi
fi
+if test "$DRIVERS" = ""; then
+ { { echo "$as_me:$LINENO: error: You should include at least one driver..." >&5
+echo "$as_me: error: You should include at least one driver..." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
# Raster.o depends on PPM or PNG
if test "$RASTER" = "yes"; then
DRIVERS="$DRIVERS Raster.o"
fi
-
-if test "$DRIVERS" = ""; then
- { { echo "$as_me:$LINENO: error: You should include at least one driver..." >&5
-echo "$as_me: error: You should include at least one driver..." >&2;}
- { (exit 1); exit 1; }; }
+# parport driver
+if test "$PARPORT" = "yes"; then
+ DRIVERS="$DRIVERS parport.o"
fi
diff --git a/configure.in b/configure.in
index 3d052a4..8648538 100644
--- a/configure.in
+++ b/configure.in
@@ -121,6 +121,7 @@ done
AC_MSG_RESULT([done])
RASTER="no"
+PARPORT="no"
if test "$BECKMANNEGLE" = "yes"; then
DRIVERS="$DRIVERS BeckmannEgle.o"
@@ -138,16 +139,19 @@ if test "$CWLINUX" = "yes"; then
fi
if test "$HD44780" = "yes"; then
+ PARPORT="yes"
DRIVERS="$DRIVERS HD44780.o"
AC_DEFINE(WITH_HD44780,1,[junk])
fi
if test "$M50530" = "yes"; then
+ PARPORT="yes"
DRIVERS="$DRIVERS M50530.o"
AC_DEFINE(WITH_M50530,1,[junk])
fi
if test "$T6963" = "yes"; then
+ PARPORT="yes"
DRIVERS="$DRIVERS T6963.o"
AC_DEFINE(WITH_T6963,1,[junk])
fi
@@ -209,16 +213,20 @@ if test "$X11" = "yes"; then
fi
fi
+if test "$DRIVERS" = ""; then
+ AC_MSG_ERROR([You should include at least one driver...])
+fi
+
# Raster.o depends on PPM or PNG
if test "$RASTER" = "yes"; then
DRIVERS="$DRIVERS Raster.o"
fi
-
-if test "$DRIVERS" = ""; then
- AC_MSG_ERROR([You should include at least one driver...])
+# parport driver
+if test "$PARPORT" = "yes"; then
+ DRIVERS="$DRIVERS parport.o"
fi
-
+
AC_SUBST(DRIVERS)
AC_SUBST(DRVLIBS)
diff --git a/parport.c b/parport.c
new file mode 100644
index 0000000..6e7cbe4
--- /dev/null
+++ b/parport.c
@@ -0,0 +1,346 @@
+/* $Id: parport.c,v 1.1 2003/04/04 06:02:03 reinelt Exp $
+ *
+ * generic parallel port handling
+ *
+ * Copyright 2003 by Michael Reinelt (reinelt@eunet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: parport.c,v $
+ * Revision 1.1 2003/04/04 06:02:03 reinelt
+ * new parallel port abstraction scheme
+ *
+ */
+
+/*
+ * exported functions:
+ *
+ * int parport_open (void)
+ * reads 'Port' entry from config and opens
+ * the parallel port
+ * returns 0 if ok, -1 on failure
+ *
+ * int parport_close (void)
+ * closes parallel port
+ * returns 0 if ok, -1 on failure
+ *
+ * unsigned char parport_wire (char *name, char *deflt)
+ * reads wiring for one control signal from config
+ * returns PARPORT_CONTROL_* or 255 on error
+ *
+ * void parport_control (unsigned char mask, unsigned char value)
+ * frobs control line and takes care of inverted signals
+ *
+ * void parport_toggle (unsigned char bit, int level, int delay)
+ * toggles the line <bit> to <level> for <delay> nanoseconds
+ *
+ * void parport_data (unsigned char value)
+ * put data bits on DB1..DB8
+ *
+ */
+
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+
+#ifdef HAVE_SYS_IO_H
+#include <sys/io.h>
+#define WITH_OUTB
+#else
+#ifdef HAVE_ASM_IO_H
+#include <asm/io.h>
+#define WITH_OUTB
+#endif
+#endif
+
+#if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H)
+#define WITH_PPDEV
+#include <linux/parport.h>
+#include <linux/ppdev.h>
+#else
+#define PARPORT_CONTROL_STROBE 0x1
+#define PARPORT_CONTROL_AUTOFD 0x2
+#define PARPORT_CONTROL_INIT 0x4
+#define PARPORT_CONTROL_SELECT 0x8
+#endif
+
+#if !defined(WITH_OUTB) && !defined(WITH_PPDEV)
+#error neither outb() nor ppdev() possible
+#error cannot compile parallel port driver
+#endif
+
+
+#include "debug.h"
+#include "cfg.h"
+#include "udelay.h"
+#include "parport.h"
+
+
+static unsigned short Port=0;
+static char *PPdev=NULL;
+
+// initial value taken from linux/parport_pc.c
+static unsigned char ctr = 0xc;
+
+#ifdef WITH_PPDEV
+static int PPfd=-1;
+#endif
+
+int parport_open (void)
+{
+ char *s, *e;
+
+#ifdef USE_OLD_UDELAY
+ s=cfg_get ("Delay",NULL);
+ if (s==NULL || *s=='\0') {
+ error ("parport: no 'Delay' entry in %s", cfg_file());
+ return -1;
+ }
+ if ((loops_per_usec=strtol(s, &e, 0))==0 || *e!='\0') {
+ error ("parport: bad delay '%s' in %s", s, cfg_file());
+ return -1;
+ }
+#else
+ udelay_init();
+#endif
+
+ s=cfg_get ("Port",NULL);
+ if (s==NULL || *s=='\0') {
+ error ("parport: no 'Port' entry in %s", cfg_file());
+ return -1;
+ }
+ PPdev=NULL;
+ if ((Port=strtol(s, &e, 0))==0 || *e!='\0') {
+#ifdef WITH_PPDEV
+ Port=0;
+ PPdev=s;
+#else
+ error ("parport: bad Port '%s' in %s", s, cfg_file());
+ return -1;
+#endif
+ }
+
+
+#ifdef WITH_PPDEV
+
+ if (PPdev) {
+ debug ("using ppdev %s", PPdev);
+ PPfd=open(PPdev, O_RDWR);
+ if (PPfd==-1) {
+ error ("parport: open(%s) failed: %s", PPdev, strerror(errno));
+ return -1;
+ }
+
+#if 0
+ // Fixme
+ if (ioctl(PPfd, PPEXCL)) {
+ debug ("ioctl(%s, PPEXCL) failed: %s", PPdev, strerror(errno));
+ } else {
+ debug ("ioctl(%s, PPEXCL) succeded.");
+ }
+#endif
+
+ if (ioctl(PPfd, PPCLAIM)) {
+ error ("parport: ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno));
+ return -1;
+ }
+ } else
+
+#endif
+
+ {
+ debug ("using raw port 0x%x", Port);
+ if (ioperm(Port, 3, 1)!=0) {
+ error ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+int parport_close (void)
+{
+#ifdef WITH_PPDEV
+ if (PPdev) {
+ debug ("closing ppdev %s", PPdev);
+ if (ioctl(PPfd, PPRELEASE)) {
+ error ("parport: ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno));
+ }
+ if (close(PPfd)==-1) {
+ error ("parport: close(%s) failed: %s", PPdev, strerror(errno));
+ return -1;
+ }
+ } else
+#endif
+ {
+ debug ("closing raw port 0x%x", Port);
+ if (ioperm(Port, 3, 0)!=0) {
+ error ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+unsigned char parport_wire (char *name, unsigned char *deflt)
+{
+ unsigned char w;
+ char wire[256];
+ char *s;
+ int n;
+
+ snprintf (wire, sizeof(wire), "Wire.%s", name);
+ s=cfg_get (wire,deflt);
+ if (strcasecmp(s,"STROBE")==0) {
+ w=PARPORT_CONTROL_STROBE;
+ } else if(strcasecmp(s,"AUTOFD")==0) {
+ w=PARPORT_CONTROL_AUTOFD;
+ } else if(strcasecmp(s,"INIT")==0) {
+ w=PARPORT_CONTROL_INIT;
+ } else if(strcasecmp(s,"SELECT")==0) {
+ w=PARPORT_CONTROL_SELECT;
+ } else {
+ error ("parport: unknown signal <%s> for wire <%s>", s, name);
+ error (" should be STROBE, AUTOFD, INIT or SELECT");
+ return 255;
+ }
+
+ n=0;
+ if (w&PARPORT_CONTROL_STROBE) {
+ n++;
+ info ("wiring: [DISPLAY:%s]==[PARPORT:STROBE]", name);
+ }
+ if (w&PARPORT_CONTROL_AUTOFD) {
+ n++;
+ info ("wiring: [DISPLAY:%s]==[PARPORT:AUTOFD]", name);
+ }
+ if (w&PARPORT_CONTROL_INIT) {
+ n++;
+ info ("wiring: [DISPLAY:%s]==[PARPORT:INIT]", name);
+ }
+ if (w&PARPORT_CONTROL_SELECT) {
+ n++;
+ info ("wiring: [DISPLAY:%s]==[PARPORT:SELECT]", name);
+ }
+ if (n<1) {
+ error ("parport: no signal for wire <%s> found!", name);
+ return 255;
+ }
+ if (n>1) {
+ error ("parport: more than one signal for wire <%s> found!", name);
+ return 255;
+ }
+ return w;
+}
+
+
+void parport_control (unsigned char mask, unsigned char value)
+{
+
+ // sanity check
+ if (mask==0) {
+ error ("parport: internal error: control without signal called!");
+ return;
+ }
+
+ // Strobe, Select and AutoFeed are inverted!
+ value ^= PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD;
+
+#ifdef WITH_PPDEV
+ if (PPdev) {
+ struct ppdev_frob_struct frob;
+ frob.mask=mask;
+ frob.val=value;
+ ioctl (PPfd, PPFCONTROL, &frob);
+ } else
+#endif
+ {
+ // code stolen from linux/parport_pc.h
+ ctr = (ctr & ~mask) ^ value;
+ outb (ctr, Port+2);
+ }
+}
+
+
+void parport_toggle (unsigned char bit, int level, int delay)
+{
+
+ // sanity check
+ if (bit==0) {
+ error ("parport: internal error: toggle without signal called!");
+ return;
+ }
+
+ // Strobe, Select and AutoFeed are inverted!
+ if (bit & (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD)) {
+ level=!level;
+ }
+
+#ifdef WITH_PPDEV
+ if (PPdev) {
+ struct ppdev_frob_struct frob;
+ frob.mask=bit;
+
+ // rise
+ frob.val=level?bit:0;
+ ioctl (PPfd, PPFCONTROL, &frob);
+
+ // pulse width
+ ndelay(delay);
+
+ // lower
+ frob.val=level?0:bit;
+ ioctl (PPfd, PPFCONTROL, &frob);
+ } else
+#endif
+ {
+ // rise
+ ctr = (ctr & ~bit) ^ (level?bit:0);
+ outb (ctr, Port+2);
+
+ // pulse width
+ ndelay(delay);
+
+ // lower
+ ctr = (ctr & ~bit) ^ (level?0:bit);
+ outb (ctr, Port+2);
+ }
+}
+
+
+void parport_data (unsigned char data)
+{
+#ifdef WITH_PPDEV
+ if (PPdev) {
+ ioctl(PPfd, PPWDATA, &data);
+ } else
+#endif
+ {
+ outb (data, Port);
+ }
+}
+
diff --git a/parport.h b/parport.h
new file mode 100644
index 0000000..c8170b2
--- /dev/null
+++ b/parport.h
@@ -0,0 +1,38 @@
+/* $Id: parport.h,v 1.1 2003/04/04 06:02:03 reinelt Exp $
+ *
+ * generic parallel port handling
+ *
+ * Copyright 2003 by Michael Reinelt (reinelt@eunet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: parport.h,v $
+ * Revision 1.1 2003/04/04 06:02:03 reinelt
+ * new parallel port abstraction scheme
+ *
+ */
+
+#ifndef _PARPORT_H_
+#define _PARPORT_H_
+
+int parport_open (void);
+int parport_close (void);
+unsigned char parport_wire (char *name, char *deflt);
+void parport_control (unsigned char mask, unsigned char value);
+void parport_toggle (unsigned char bit, int level, int delay);
+void parport_data (unsigned char data);
+
+#endif
diff --git a/udelay.c b/udelay.c
index 2ba21f3..c33c683 100644
--- a/udelay.c
+++ b/udelay.c
@@ -1,4 +1,4 @@
-/* $Id: udelay.c,v 1.10 2003/02/27 07:43:11 reinelt Exp $
+/* $Id: udelay.c,v 1.11 2003/04/04 06:02:04 reinelt Exp $
*
* short delays
*
@@ -20,6 +20,9 @@
*
*
* $Log: udelay.c,v $
+ * Revision 1.11 2003/04/04 06:02:04 reinelt
+ * new parallel port abstraction scheme
+ *
* Revision 1.10 2003/02/27 07:43:11 reinelt
*
* asm/msr.h: included hard-coded definition of rdtscl() if msr.h cannot be found.
@@ -217,6 +220,7 @@ static void getCPUinfo (int *hasTSC, double *MHz)
}
+
void udelay_init (void)
{
int tsc;
@@ -233,6 +237,7 @@ void udelay_init (void)
}
}
+
void ndelay (unsigned long nsec)
{