aboutsummaryrefslogtreecommitdiffstats
path: root/T6963.c
diff options
context:
space:
mode:
authorreinelt <>2003-04-07 06:03:10 +0000
committerreinelt <>2003-04-07 06:03:10 +0000
commit72fd720c2d1a819d454771f99e86d852416e568e (patch)
tree4a8c738b835534804a9789bdc1998313fa5b669d /T6963.c
parent43f6cfacf15926a6538fc8c8a7e46430851aaa67 (diff)
downloadlcd4linux-72fd720c2d1a819d454771f99e86d852416e568e.tar.gz
[lcd4linux @ 2003-04-07 06:02:58 by reinelt]
further parallel port abstraction
Diffstat (limited to 'T6963.c')
-rw-r--r--T6963.c259
1 files changed, 98 insertions, 161 deletions
diff --git a/T6963.c b/T6963.c
index 85aedbc..e7b7263 100644
--- a/T6963.c
+++ b/T6963.c
@@ -1,4 +1,4 @@
-/* $Id: T6963.c,v 1.5 2003/02/22 07:53:10 reinelt Exp $
+/* $Id: T6963.c,v 1.6 2003/04/07 06:03:00 reinelt Exp $
*
* driver for display modules based on the Toshiba T6963 chip
*
@@ -20,6 +20,9 @@
*
*
* $Log: T6963.c,v $
+ * Revision 1.6 2003/04/07 06:03:00 reinelt
+ * further parallel port abstraction
+ *
* Revision 1.5 2003/02/22 07:53:10 reinelt
* cfg_get(key,defval)
*
@@ -53,116 +56,82 @@
#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 T6963 driver needs ppdev
-#error cannot compile T6963 driver
-#endif
#include "debug.h"
#include "cfg.h"
#include "display.h"
#include "bar.h"
+#include "parport.h"
#include "udelay.h"
#include "pixmap.h"
-/*
- * /CE (Chip Enable) <==> /Strobe
- * C/D (Command/Data) <==> /Select
- * /RD (Read) <==> /AutoFeed
- * /WR (Write) <==> Init
- *
- */
-
-#define CE_L PARPORT_CONTROL_STROBE
-#define CE_H 0
-
-#define CD_L PARPORT_CONTROL_SELECT
-#define CD_H 0
-
-#define RD_L PARPORT_CONTROL_AUTOFD
-#define RD_H 0
-
-#define WR_L 0
-#define WR_H PARPORT_CONTROL_INIT
-
-
#define XRES 6
#define YRES 8
static LCD Lcd;
-static char *PPdev=NULL;
-static int PPfd=-1;
-
unsigned char *Buffer1, *Buffer2;
+static unsigned char SIGNAL_CE;
+static unsigned char SIGNAL_CD;
+static unsigned char SIGNAL_RD;
+static unsigned char SIGNAL_WR;
+
+
+// Fixme:
+static int bug=0;
+
// perform normal status check
void T6_status1 (void)
{
- int direction;
int n;
- unsigned char ctrl, data;
-
- // turn off data line drivers
- direction=1;
- ioctl (PPfd, PPDATADIR, &direction);
- // lower RD and CE
- ctrl = RD_L | WR_H | CE_L | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ // turn off data line drivers
+ parport_direction (1);
- ndelay(150); // Access Time: 150 ns
+ // lower CE and RD
+ parport_control (SIGNAL_CE | SIGNAL_RD, 0);
+ // Access Time: 150 ns
+ ndelay(150);
+
// wait for STA0=1 and STA1=1
n=0;
do {
rep_nop();
if (++n>1000) {
debug("hang in status1");
+ bug=1;
break;
}
- ioctl (PPfd, PPRDATA, &data);
- } while ((data & 0x03) != 0x03);
+ } while ((parport_read() & 0x03) != 0x03);
// rise RD and CE
- ctrl = RD_H | WR_H | CE_H | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_RD | SIGNAL_CE, SIGNAL_RD | SIGNAL_CE);
- // turn on data line drivers
- direction=0;
- ioctl (PPfd, PPDATADIR, &direction);
+ // Output Hold Time: 50 ns
+ ndelay(50);
+ // turn on data line drivers
+ parport_direction (0);
}
-// Fixme:
-static int bug=0;
+
// perform status check in "auto mode"
void T6_status2 (void)
{
- int direction;
int n;
- unsigned char ctrl, data;
// turn off data line drivers
- direction=1;
- ioctl (PPfd, PPDATADIR, &direction);
-
+ parport_direction (1);
+
// lower RD and CE
- ctrl = RD_L | WR_H | CE_L | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_RD | SIGNAL_CE, 0);
- ndelay(150); // Access Time: 150 ns
+ // Access Time: 150 ns
+ ndelay(150);
// wait for STA3=1
n=0;
@@ -173,114 +142,110 @@ void T6_status2 (void)
bug=1;
break;
}
- ioctl (PPfd, PPRDATA, &data);
- } while ((data & 0x08) != 0x08);
+ } while ((parport_read() & 0x08) != 0x08);
// rise RD and CE
- ctrl = RD_H | WR_H | CE_H | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_RD | SIGNAL_CE, SIGNAL_RD | SIGNAL_CE);
+
+ // Output Hold Time: 50 ns
+ ndelay(50);
// turn on data line drivers
- direction=0;
- ioctl (PPfd, PPDATADIR, &direction);
+ parport_direction (0);
}
static void T6_write_cmd (unsigned char cmd)
{
- unsigned char ctrl;
-
// wait until the T6963 is idle
T6_status1();
// put data on DB1..DB8
- ioctl(PPfd, PPWDATA, &cmd);
-
+ parport_data (cmd);
+
// lower WR and CE
- ctrl = RD_H | WR_L | CE_L | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_WR | SIGNAL_CE, 0);
- ndelay(80); // Pulse width
+ // Pulse width
+ ndelay(80);
// rise WR and CE
- ctrl = RD_H | WR_H | CE_H | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE);
- ndelay(40); // Data Hold Time
+ // Data Hold Time
+ ndelay(40);
}
+
static void T6_write_data (unsigned char data)
{
- unsigned char ctrl;
-
// wait until the T6963 is idle
T6_status1();
// put data on DB1..DB8
- ioctl(PPfd, PPWDATA, &data);
+ parport_data (data);
// lower C/D
- ctrl = RD_H | WR_H | CE_H | CD_L;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_CD, 0);
- ndelay(20); // C/D Setup Time
+ // C/D Setup Time
+ ndelay(20);
// lower WR and CE
- ctrl = RD_H | WR_L | CE_L | CD_L;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_WR | SIGNAL_CE, 0);
- ndelay(80); // Pulse Width
+ // Pulse Width
+ ndelay(80);
// rise WR and CE
- ctrl = RD_H | WR_H | CE_H | CD_L;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE);
- ndelay(40); // Data Hold Time
+ // Data Hold Time
+ ndelay(40);
// rise CD
- ctrl = RD_H | WR_H | CE_H | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_CD, SIGNAL_CD);
}
+
static void T6_write_auto (unsigned char data)
{
- unsigned char ctrl;
-
// wait until the T6963 is idle
T6_status2();
// put data on DB1..DB8
- ioctl(PPfd, PPWDATA, &data);
+ parport_data (data);
// lower C/D
- ctrl = RD_H | WR_H | CE_H | CD_L;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_CD, 0);
- ndelay(20); // C/D Setup Time
+ // C/D Setup Time
+ ndelay(20);
// lower WR and CE
- ctrl = RD_H | WR_L | CE_L | CD_L;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_WR | SIGNAL_CE, 0);
- ndelay(80); // Pulse Width
+ // Pulse Width
+ ndelay(80);
// rise WR and CE
- ctrl = RD_H | WR_H | CE_H | CD_L;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE);
- ndelay(40); // Data Hold Time
+ // Data Hold Time
+ ndelay(40);
// rise CD
- ctrl = RD_H | WR_H | CE_H | CD_H;
- ioctl (PPfd, PPWCONTROL, &ctrl);
+ parport_control (SIGNAL_CD, SIGNAL_CD);
}
+
static void T6_send_byte (unsigned char cmd, unsigned char data)
{
T6_write_data(data);
T6_write_cmd(cmd);
}
+
static void T6_send_word (unsigned char cmd, unsigned short data)
{
T6_write_data(data&0xff);
@@ -288,6 +253,7 @@ static void T6_send_word (unsigned char cmd, unsigned short data)
T6_write_cmd(cmd);
}
+
static void T6_memset(unsigned short addr, unsigned char data, int len)
{
int i;
@@ -324,40 +290,15 @@ static void T6_memcpy(unsigned short addr, unsigned char *data, int len)
}
-static int T6_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;
- }
-
- return 0;
-}
-
int T6_clear (void)
{
int rows;
rows=(Lcd.rows>8 ? 8 : Lcd.rows);
-
+
T6_memset(0x0000, 0, Lcd.cols*rows); // clear text area
T6_memset(0x0200, 0, Lcd.cols*rows*8); // clear graphic area
-
+
if (Lcd.rows>8) {
T6_memset(0x8000, 0, Lcd.cols*(Lcd.rows-rows)); // clear text area #2
T6_memset(0x8200, 0, Lcd.cols*(Lcd.rows-rows)*8); // clear graphic area #2
@@ -369,23 +310,10 @@ int T6_clear (void)
return pix_clear();
}
+
int T6_init (LCD *Self)
{
- char *port;
-
Lcd=*Self;
-
- if (PPdev) {
- free (PPdev);
- PPdev=NULL;
- }
-
- port=cfg_get ("Port",NULL);
- if (port==NULL || *port=='\0') {
- error ("T6963: no 'Port' entry in %s", cfg_file());
- return -1;
- }
- PPdev=strdup(port);
if (pix_init (Lcd.rows, Lcd.cols, Lcd.xres, Lcd.yres)!=0) {
error ("T6963: pix_init(%d, %d, %d, %d) failed", Lcd.rows, Lcd.cols, Lcd.xres, Lcd.yres);
@@ -404,11 +332,23 @@ int T6_init (LCD *Self)
return -1;
}
- udelay_init();
+ if ((SIGNAL_CE=parport_wire ("CE", "STROBE"))==0xff) return -1;
+ if ((SIGNAL_CD=parport_wire ("CD", "SELECT"))==0xff) return -1;
+ if ((SIGNAL_RD=parport_wire ("RD", "AUTOFD"))==0xff) return -1;
+ if ((SIGNAL_WR=parport_wire ("WR", "INIT"))==0xff) return -1;
- if (T6_open()!=0)
+ if (parport_open() != 0) {
+ error ("HD44780: could not initialize parallel port!");
return -1;
+ }
+
+ // rise CE, CD, RD and WR
+ parport_control (SIGNAL_CE | SIGNAL_CD | SIGNAL_RD | SIGNAL_WR,
+ SIGNAL_CE | SIGNAL_CD | SIGNAL_RD | SIGNAL_WR);
+ // set direction: write
+ parport_direction (0);
+
debug ("setting %d columns", Lcd.cols);
T6_send_word (0x40, 0x0000); // Set Text Home Address
@@ -428,16 +368,19 @@ int T6_init (LCD *Self)
return 0;
}
+
int T6_put (int row, int col, char *text)
{
return pix_put(row,col,text);
}
+
int T6_bar (int type, int row, int col, int max, int len1, int len2)
{
return pix_bar(type,row,col,max,len1,len2);
}
+
int T6_flush (void)
{
int i, j, e;
@@ -470,19 +413,13 @@ int T6_flush (void)
return 0;
}
+
int T6_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();
}
+
LCD T6963[] = {
{ name: "TLC1091",
rows: 16,