diff -ubrN lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-bast.c lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-bast.c
--- lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-bast.c	1970-01-01 01:00:00.000000000 +0100
+++ lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-bast.c	2003-07-04 01:39:27.000000000 +0100
@@ -0,0 +1,335 @@
+/*
+ * 8-bit driver module for Hitachi HD44780 based LCD displays.
+ * The LCD is operated in it's 8 bit-mode and is attched to the onboard port
+ * of the bast board (http://www.simtec.co.uk/products/EB2410ITX/)
+ *
+ * Copyright (C) 2003, Vincent Sanders <vince@simtec.co.uk>
+ *
+ * The board allows for direct access to an 8bit LCD module using memory areas
+ * to select command and data ports, read and write, the areas are duplicated
+ * once for E1 and once for E2. The bast board also allows for backlight
+ * control both on and off but also using PWM for variable brightnes.
+ *
+ * Wiring on the board is intended so most HD44780 type display modules can be
+ * connected with a simple ribbon cable, refer to the web site for port pinouts
+ * and example wiring for several modules.
+ *
+ * Based on the code in the ext8bit driver
+ *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ */
+
+#include "hd44780-bast.h"
+#include "hd44780.h"
+#include "lpt-port.h"
+
+#include "port.h"
+#include "lcd_sem.h"
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+// Generally, any function that accesses the LCD control lines needs to be
+// implemented separately for each HW design. This is typically (but not
+// restricted to):
+// HD44780_senddata
+// HD44780_readkeypad
+
+void bast_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch);
+void bast_HD44780_backlight (unsigned char state);
+unsigned char bast_HD44780_readkeypad (unsigned int YData);
+void bast_HD44780_close();
+
+static char backlight_bit = 0;
+static int stuckinputs;
+
+static int semid;
+
+volatile unsigned char *bast_lcd_e1_wdata;
+volatile unsigned char *bast_lcd_e1_wcmd;
+volatile unsigned char *bast_lcd_e1_rcmd;
+
+volatile unsigned char *bast_lcd_e2_wdata;
+volatile unsigned char *bast_lcd_e2_wcmd;
+volatile unsigned char *bast_lcd_e2_rcmd;
+
+volatile unsigned char *bast_cpld4;
+
+volatile unsigned long *bast_cpu_gpio;
+
+int bastfd;
+
+#define MAPSIZE (4*1024)
+
+#define BAST_LCD_E1_WCMD  (0x08000000)
+#define BAST_LCD_E1_RCMD  (0x08800000)
+#define BAST_LCD_E1_WDATA (0x09000000)
+#define BAST_LCD_E1_RDATA (0x09800000)
+
+#define BAST_LCD_E2_WCMD  (0x0A000000)
+#define BAST_LCD_E2_RCMD  (0x0A800000)
+#define BAST_LCD_E2_WDATA (0x0B000000)
+#define BAST_LCD_E2_RDATA (0x0B800000)
+
+#define BAST_CS1 (0x8 << 24)
+#define BAST_LCD_CPLD4 (BAST_CS1 + (0xe << 23))
+
+#define BAST_CPU_GPIO (0x56000000)
+
+volatile unsigned char *
+bast_map_area(unsigned long area)
+{
+    void *data = mmap(NULL, MAPSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, bastfd, area);
+
+    if (data == (void *)-1)
+    {
+	perror("mmap");
+	return NULL;
+    }
+    return (volatile unsigned char *)data;
+}
+
+void
+bast_munmap()
+{
+    if(bast_lcd_e1_wdata)
+	munmap(bast_lcd_e1_wdata, MAPSIZE);
+    if(bast_lcd_e1_wcmd)
+	munmap(bast_lcd_e1_wcmd, MAPSIZE);
+    if(bast_lcd_e1_rcmd)
+	munmap(bast_lcd_e1_rcmd, MAPSIZE);
+    if(bast_lcd_e1_wdata)
+	munmap(bast_lcd_e2_wdata, MAPSIZE);
+    if(bast_lcd_e1_wcmd)
+	munmap(bast_lcd_e2_wcmd, MAPSIZE);
+    if(bast_lcd_e1_rcmd)
+	munmap(bast_lcd_e2_rcmd, MAPSIZE);
+    if(bast_cpld4)
+	munmap(bast_cpld4, MAPSIZE);
+    if(bast_cpu_gpio)
+	munmap(bast_cpu_gpio, MAPSIZE);
+}
+
+int
+bast_mmap()
+{
+    bast_lcd_e1_wdata = bast_map_area(BAST_LCD_E1_WDATA);
+    if( bast_lcd_e1_wdata == NULL)
+	return 1;
+
+    bast_lcd_e1_wcmd = bast_map_area(BAST_LCD_E1_WCMD);
+    if( bast_lcd_e1_wcmd == NULL)
+	return 2;
+
+    bast_lcd_e1_rcmd = bast_map_area(BAST_LCD_E1_RCMD);
+    if( bast_lcd_e1_rcmd == NULL)
+	return 3;
+
+    bast_lcd_e2_wdata = bast_map_area(BAST_LCD_E2_WDATA);
+    if( bast_lcd_e2_wdata == NULL)
+	return 4;
+
+    bast_lcd_e2_wcmd = bast_map_area(BAST_LCD_E2_WCMD);
+    if( bast_lcd_e2_wcmd == NULL)
+	return 5;
+
+    bast_lcd_e2_rcmd = bast_map_area(BAST_LCD_E2_RCMD);
+    if( bast_lcd_e2_rcmd == NULL)
+	return 6;
+
+    bast_cpld4 = bast_map_area(BAST_LCD_CPLD4);
+    if( bast_cpld4 == NULL )
+	return 7;
+
+    bast_cpu_gpio = bast_map_area(BAST_CPU_GPIO);
+    if( bast_cpu_gpio == NULL )
+	return 8;
+
+    return 0;
+}
+
+
+
+/* write byte to port, the double write is correct, the first starts the
+ * write cycle the second finishes it, this is so the onboard logic doesnt have
+ * to do extended wait states */
+void
+bast_lcd_write(volatile unsigned char * reg,unsigned char val)
+{
+    *reg=val;
+    hd44780_functions->uPause (1);
+    *reg=val;
+}
+
+unsigned char
+bast_lcd_read(volatile unsigned char * reg)
+{
+    unsigned char tmp;
+    tmp = *reg;
+    hd44780_functions->uPause (1);
+    return *reg;
+}
+
+
+/* check the lcd busy command register and wait until its cleared */
+static int
+bast_busy_wait(volatile unsigned char * reg)
+{
+    int count = 0x8000;
+    unsigned long tmp;
+
+    while (count-- > 0) {
+	hd44780_functions->uPause (10);
+
+	tmp=bast_lcd_read(reg);
+
+	if ((tmp & (1<<7)) == 0)
+	{
+	    return (tmp & 0x7f);
+	}
+    }
+    return -1;
+}
+
+void
+bast_backlight_init()
+{
+    bast_cpu_gpio[4] = ((bast_cpu_gpio[4] & (~3)) | 1);/* configure GPIOB0 as output */
+}
+
+
+// initialise the driver
+int
+hd_init_bast (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port)
+{
+    semid = sem_get ();
+
+    /* get fd for /dev/mem */
+    bastfd = open("/dev/mem", O_RDWR | O_SYNC);
+
+    if (bastfd < 0) {
+	perror("open(/dev/mem)");
+	return 1;
+    }
+
+    /* get mmaped areas */
+    if (bast_mmap())
+    {
+	bast_munmap();/* remove any mappings that suceeded */
+	return 2;
+    }
+
+    bast_backlight_init();
+
+
+    /* all areas sucessfuly mapped - setup functions */
+    hd44780_functions->senddata = bast_HD44780_senddata;
+    hd44780_functions->backlight = bast_HD44780_backlight;
+    hd44780_functions->readkeypad = bast_HD44780_readkeypad;
+    hd44780_functions->close = bast_HD44780_close;
+
+    // setup the lcd in 8 bit mode
+    hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
+    hd44780_functions->uPause (4100);
+    hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
+    hd44780_functions->uPause (100);
+    hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR);
+    hd44780_functions->uPause (40);
+
+    common_init ();
+
+    if (have_keypad) {
+	// Remember which input lines are stuck
+	stuckinputs = bast_HD44780_readkeypad (0);
+    }
+    return 0;
+}
+
+
+
+/* frees all resources claimed by driver */
+void
+bast_HD44780_close()
+{
+    bast_munmap();
+
+    close(bastfd);
+}
+
+// bast_HD44780_senddata
+void
+bast_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch)
+{
+    sem_wait (semid);
+
+    /* printf("bast_HD44780_senddata: displayID %d\n",displayID);*/
+
+    switch(displayID)
+    {
+
+    case 0:/*all enables */
+	bast_busy_wait(bast_lcd_e1_rcmd);/* wait for module to be ready */
+	bast_busy_wait(bast_lcd_e2_rcmd);/* wait for module to be ready */
+	if (flags == RS_DATA)
+	{
+	    bast_lcd_write(bast_lcd_e1_wdata,ch);
+	    bast_lcd_write(bast_lcd_e2_wdata,ch);
+	}
+	else
+	{
+	    bast_lcd_write(bast_lcd_e1_wcmd,ch);
+	    bast_lcd_write(bast_lcd_e2_wdata,ch);
+	}
+	break;
+
+    case 1:
+	bast_busy_wait(bast_lcd_e2_rcmd);/* wait for module to be ready */
+	if (flags == RS_DATA)
+	    bast_lcd_write(bast_lcd_e1_wdata,ch);
+	else
+	    bast_lcd_write(bast_lcd_e1_wcmd,ch);
+	break;
+
+    case 2:
+	bast_busy_wait(bast_lcd_e2_rcmd);/* wait for module to be ready */
+	if (flags == RS_DATA)
+	    bast_lcd_write(bast_lcd_e2_wdata,ch);
+	else
+	    bast_lcd_write(bast_lcd_e2_wcmd,ch);
+	break;
+
+    default:
+	/* this is an error as the bast port only supports e1 and e2 */
+	break;
+    }
+
+    sem_signal (semid);
+}
+
+void bast_HD44780_backlight (unsigned char state)
+{
+    if(state)
+	bast_cpu_gpio[5] = (bast_cpu_gpio[5] | 1); /* turn backlight on */
+    else
+	bast_cpu_gpio[5] = (bast_cpu_gpio[5] & (~1)); /* turn backlight off */
+}
+
+
+/* the keypad is on the GPIO registers */
+unsigned char bast_HD44780_readkeypad (unsigned int YData)
+{
+    unsigned char readval;
+
+    sem_wait (semid);
+    /* TODO: add gpio kb reading here */
+    /* GPIOF0-7 are rows GPIOE 5- 10 are colums */
+    sem_signal (semid);
+
+    return 0;
+}
diff -ubrN lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-bast.h lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-bast.h
--- lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-bast.h	1970-01-01 01:00:00.000000000 +0100
+++ lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-bast.h	2003-07-02 00:08:04.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef HD_BAST_H
+#define HD_BAST_H
+
+#include "lcd.h"					  /* for lcd_logical_driver */
+#include "hd44780-low.h"		  /* for HD44780_functions */
+
+// initialise this particular driver
+int hd_init_bast (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port);
+
+#endif
diff -ubrN lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-drivers.h lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-drivers.h
--- lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-drivers.h	2003-01-05 08:05:01.000000000 +0000
+++ lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-drivers.h	2003-07-02 00:11:05.000000000 +0100
@@ -20,9 +20,10 @@
 #include "hd44780-picanlcd.h"
 #include "hd44780-usblcd.h"
 #include "hd44780-anslcd.h"
+#include "hd44780-bast.h"
 // add new connection type header files here
 
-enum connectionType { HD_4bit, HD_8bit, HD_serialLpt, HD_winamp, HD_picanlcd,HD_usblcd,HD_anslcd,
+enum connectionType { HD_4bit, HD_8bit, HD_serialLpt, HD_winamp, HD_picanlcd,HD_usblcd,HD_anslcd,HD_bast,
 	// add new connection types here
 	HD_unknown
 };
@@ -49,6 +50,7 @@
 	{ HD_picanlcd, "picanlcd", hd_init_picanlcd, ""},
 	{ HD_usblcd, "usblcd", hd_init_usblcd, ""},
 	{ HD_anslcd, "anslcd", hd_init_anslcd, ""},
+	{ HD_bast, "bast", hd_init_bast, ""},
 		 // add new connection types and their string specifier here
 		 // default, end of structure element (do not delete)
 	{ HD_unknown, "", NULL, ""}
diff -ubrN lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-low.h lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-low.h
--- lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780-low.h	2002-12-28 08:05:08.000000000 +0000
+++ lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780-low.h	2003-07-03 16:15:25.000000000 +0100
@@ -39,6 +39,8 @@
 	// - override scankeypad.
 	unsigned char (*scankeypad) ();
 
+	//A subdriver may need to free resources on close
+	void (*close) ();
 
 } HD44780_functions;				  /* for want of a better name :-) */
 
diff -ubrN lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780.c lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780.c
--- lcdproc-CVS-stable-0-4-4-20030701/server/drivers/hd44780.c	2003-01-05 08:05:01.000000000 +0000
+++ lcdproc-CVS-stable-0-4-4-20030701-bast/server/drivers/hd44780.c	2003-07-03 16:21:34.000000000 +0100
@@ -153,6 +153,7 @@
 void HD44780_draw_frame (char *dat);
 char HD44780_getkey ();
 
+void HD44780_close_driver ();
 void HD44780_position (int x, int y);
 unsigned char HD44780_scankeypad();
 static int parse_span_list (int *spanListArray[], int *spLsize, int *dispOffsets[], int *dOffsize, int *dispSizeArray[], char *spanlist);
@@ -303,6 +304,7 @@
 
 	hd44780_functions->scankeypad = HD44780_scankeypad;
 	
+	hd44780_functions->close = HD44780_close_driver;
 	
 	if (connectionMapping[connectiontype_index].init_fn (hd44780_functions, driver, args, port) < 0)
 		return -1;
@@ -357,10 +359,17 @@
 //
 void HD44780_close()
 {
+	hd44780_functions->close();
+
 	free( HD44780->framebuf );
 	free( lcd_contents );
 }
 
+void HD44780_close_driver()
+{
+	/* dummy close for sub drivers */
+}
+
 /////////////////////////////////////////////////////////////////
 // Set position (not part of API)
 //

