summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app-misc/lcdproc/files/us2066.patch')
-rw-r--r--app-misc/lcdproc/files/us2066.patch430
1 files changed, 430 insertions, 0 deletions
diff --git a/app-misc/lcdproc/files/us2066.patch b/app-misc/lcdproc/files/us2066.patch
new file mode 100644
index 0000000..426cc33
--- /dev/null
+++ b/app-misc/lcdproc/files/us2066.patch
@@ -0,0 +1,430 @@
+--- lcdproc-0.5.6/server/drivers/hd44780-i2c.c 2010-12-27 06:32:57.000000000 -0700
++++ RPi-OLED-Display-SSD1311/hd44780-i2c.c 2015-07-09 22:52:19.193298735 -0600
+@@ -12,40 +12,6 @@
+ * 1998 Richard Rognlie <rrognlie@gamerz.net>
+ * 1997 Matthias Prinke <m.prinke@trashcan.mcnet.de>
+ *
+- * The connections are:
+- * PCF8574AP LCD
+- * P0 (4) D4 (11)
+- * P1 (5) D5 (12)
+- * P2 (6) D6 (13)
+- * P3 (7) D7 (14)
+- * P4 (9) RS (4)
+- * P5 (10) RW (5)
+- * P6 (11) EN (6)
+- *
+- * Backlight
+- * P7 (12) /backlight (optional, active-low)
+- *
+- * Configuration:
+- * device=/dev/i2c-0 # the device file of the i2c bus
+- * port=0x20 # the i2c address of the i2c port expander
+- *
+- * Attention: Bit 8 of the address given in port is special:
+- * It tells the driver to treat the device as PCA9554 or similar,
+- * a device that needs a 2-byte command, and it will be stripped
+- * off the address.
+- * So we have:
+- * port=0x20..0x27 PCF8574 with A[012]=0..7
+- * port=0x38..0x3f PCF8574A with A[012]=0..7
+- * port=0xa0..0xa7 PCA9554 with A[012]=0..7
+- * port=0xa0..0xa7 PCA9554A with A[012]=0..7
+- *
+- * When using this driver, DON'T load the i2c chip module (e.g. pcf8574),
+- * you only need the i2c bus driver module!
+- *
+- *
+- * Based mostly on the hd44780-4bit module, see there for a complete history.
+- * Suggestions for PCA9554 support from Tonu Samuel <tonu@jes.ee>.
+- *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ */
+@@ -54,17 +20,26 @@
+ #include "hd44780-low.h"
+
+ #include "report.h"
++#ifdef HAVE_CONFIG_H
++# include "config.h"
++#endif
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
++
++#ifdef HAVE_DEV_IICBUS_IIC_H
++#include <dev/iicbus/iic.h>
++#else /* HAVE_LINUX_I2C_DEV_H */
+ #include <linux/i2c-dev.h>
+ /* I2C_SLAVE is missing in linux/i2c-dev.h from kernel headers of 2.4.x kernels */
+ #ifndef I2C_SLAVE
+ #define I2C_SLAVE 0x0703 /* Change slave address */
+ #endif
++#endif
++
+
+ // Generally, any function that accesses the LCD control lines needs to be
+ // implemented separately for each HW design. This is typically (but not
+@@ -76,9 +51,9 @@
+ void i2c_HD44780_backlight(PrivateData *p, unsigned char state);
+ void i2c_HD44780_close(PrivateData *p);
+
+-#define RS 0x10
+-#define RW 0x20
+-#define EN 0x40
++//#define RS 0x10
++//#define RW 0x20
++//#define EN 0x40
+ #define BL 0x80
+ // note that the above bits are all meant for the data port of PCF8574
+
+@@ -86,21 +61,36 @@
+ #define I2C_PCAX_MASK 0x80
+
+ static void
+-i2c_out(PrivateData *p, unsigned char val)
++i2c_out(PrivateData *p, unsigned char val[2])
+ {
+- __u8 data[2];
++// char data[2];
+ int datalen;
+ static int no_more_errormsgs=0;
+- if (p->port & I2C_PCAX_MASK) { // we have a PCA9554 or similar, that needs a 2-byte command
+- data[0]=1; // command: read/write output port register
+- data[1]=val;
+- datalen=2;
+- } else { // we have a PCF8574 or similar, that needs a 1-byte command
+- data[0]=val;
+- datalen=1;
+- }
+- if (write(p->fd,data,datalen) != datalen) {
+- p->hd44780_functions->drv_report(no_more_errormsgs?RPT_DEBUG:RPT_ERR, "HD44780: I2C: i2c write data %u to address %u failed: %s",
++#ifdef HAVE_DEV_IICBUS_IIC_H
++ struct iiccmd cmd;
++ bzero(&cmd, sizeof(cmd));
++#endif
++
++// if (p->port & I2C_PCAX_MASK) { // we have a PCA9554 or similar, that needs a 2-byte command
++// data[0]=1; // command: read/write output port register
++// data[1]=val;
++ datalen=2;
++// } else { // we have a PCF8574 or similar, that needs a 1-byte command
++// data[0]=val;
++// datalen=1;
++// }
++
++#ifdef HAVE_DEV_IICBUS_IIC_H
++ cmd.slave = (p->port & I2C_ADDR_MASK) << 1;
++ cmd.last = 1;
++ cmd.count = datalen;
++ cmd.buf = val;
++
++ if (ioctl(p->fd, I2CWRITE, &cmd) < 0) {
++#else /* HAVE_LINUX_I2C_DEV_H */
++ if (write(p->fd,val,datalen) != datalen) {
++#endif
++ p->hd44780_functions->drv_report(no_more_errormsgs?RPT_DEBUG:RPT_ERR, "HD44780: I2C: i2c write data %u to address 0x%02X failed: %s",
+ val, p->port & I2C_ADDR_MASK, strerror(errno));
+ no_more_errormsgs=1;
+ }
+@@ -121,8 +111,14 @@
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+ HD44780_functions *hd44780_functions = p->hd44780_functions;
+
+- int enableLines = EN;
++// int enableLines = EN;
+ char device[256] = DEFAULT_DEVICE;
++#ifdef HAVE_DEV_IICBUS_IIC_H
++ struct iiccmd cmd;
++ bzero(&cmd, sizeof(cmd));
++#endif
++
++//###?? p->backlight_bit = BL;
+ p->backlight_bit = BL;
+
+ /* READ CONFIG FILE */
+@@ -130,7 +126,7 @@
+ /* Get serial device to use */
+ strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device));
+ device[sizeof(device)-1] = '\0';
+- report(RPT_INFO,"HD44780: I2C: Using device '%s' and address %u for a %s",
++ report(RPT_INFO,"HD44780: I2C: Using device '%s' and address 0x%02X for a %s",
+ device, p->port & I2C_ADDR_MASK, (p->port & I2C_PCAX_MASK) ? "PCA9554(A)" : "PCF8574(A)");
+
+ // Open the I2C device
+@@ -141,89 +137,125 @@
+ }
+
+ // Set I2C address
++#ifdef HAVE_DEV_IICBUS_IIC_H
++ cmd.slave = (p->port & I2C_ADDR_MASK) << 1;
++ cmd.last = 0;
++ cmd.count = 0;
++ if (ioctl(p->fd, I2CRSTCARD, &cmd) < 0) {
++ report(RPT_ERR, "HD44780: I2C: reset bus failed: %s", strerror(errno));
++ return -1;
++ }
++ if (ioctl(p->fd, I2CSTART, &cmd) < 0) {
++ report(RPT_ERR, "HD44780: I2C: set address to 0x%02X: %s", p->port & I2C_ADDR_MASK, strerror(errno));
++ return -1;
++ }
++#else /* HAVE_LINUX_I2C_DEV_H */
+ if (ioctl(p->fd,I2C_SLAVE, p->port & I2C_ADDR_MASK) < 0) {
+ report(RPT_ERR, "HD44780: I2C: set address to '%i': %s", p->port & I2C_ADDR_MASK, strerror(errno));
+ return(-1);
+ }
+-
+-
+- if (p->port & I2C_PCAX_MASK) { // we have a PCA9554 or similar, that needs special config
+- __u8 data[2];
+- data[0] = 2; // command: set polarity inversion
+- data[1] = 0; // -> no polarity inversion
+- if (write(p->fd,data,2) != 2) {
+- report(RPT_ERR, "HD44780: I2C: i2c set polarity inversion failed: %s", strerror(errno));
+- }
+- data[0] = 3; // command: set output direction
+- data[1] = 0; // -> all pins are outputs
+- if (write(p->fd,data,2) != 2) {
+- report(RPT_ERR, "HD44780: I2C: i2c set output direction failed: %s", strerror(errno));
+- }
+- }
+-
++#endif
+ hd44780_functions->senddata = i2c_HD44780_senddata;
+ hd44780_functions->backlight = i2c_HD44780_backlight;
+ hd44780_functions->close = i2c_HD44780_close;
++ /* Display init */
+
+- // powerup the lcd now
+- /* We'll now send 0x03 a couple of times,
+- * which is in fact (FUNCSET | IF_8BIT) >> 4 */
+- i2c_out(p, 0x03);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+-
+- i2c_out(p, enableLines | 0x03);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+- i2c_out(p, 0x03);
+- hd44780_functions->uPause(p, 15000);
+-
+- i2c_out(p, enableLines | 0x03);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+- i2c_out(p, 0x03);
+- hd44780_functions->uPause(p, 5000);
+-
+- i2c_out(p, enableLines | 0x03);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+- i2c_out(p, 0x03);
+- hd44780_functions->uPause(p, 100);
+-
+- i2c_out(p, enableLines | 0x03);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+- i2c_out(p, 0x03);
+- hd44780_functions->uPause(p, 100);
+-
+- // now in 8-bit mode... set 4-bit mode
+- i2c_out(p, 0x02);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+-
+- i2c_out(p, enableLines | 0x02);
+- if (p->delayBus)
+- hd44780_functions->uPause(p, 1);
+- i2c_out(p, 0x02);
+- hd44780_functions->uPause(p, 100);
+-
+- // Set up two-line, small character (5x8) mode
+- hd44780_functions->senddata(p, 0, RS_INSTR, FUNCSET | IF_4BIT | TWOLINE | SMALLCHAR);
+- hd44780_functions->uPause(p, 40);
+-
+- common_init(p, IF_4BIT);
++ unsigned char data[2];
++ data[0] = 0x80;
++ i2c_out(p, data);
++
++ data[1] = 0x2A; // **** Set "RE"=1<--->00101010B
++ i2c_out(p, data);
++ data[1] = 0x71; //# Function Selection A [71h] (IS = X, RE = 1, SD=0;, 2bajty
++ i2c_out(p, data);
++ data[1] = 0x5C; // 0x5C set Vdd
++ i2c_out(p, data);
++ data[1] = 0x28;
++ i2c_out(p, data);
++
++ data[1] = 0x08; // **** Set Sleep Mode On
++ i2c_out(p, data);
++ data[1] = 0x2A; // **** Set "RE"=1 00101010B
++ i2c_out(p, data);
++ data[1] = 0x79; // **** Set "SD"=1 01111001B
++ i2c_out(p, data);
++
++ data[1] = 0xD5; //# Set Display Clock Divide Ratio/ Oscillator Frequency (D5h
++ i2c_out(p, data);
++ data[1] = 0x70;
++ i2c_out(p, data);
++ data[1] = 0x78; // **** Set "SD"=0
++ i2c_out(p, data);
++
++ data[1] = 0x08; // **** Set 5-dot, 3 or 4 line(0x09;, 1 or 2 line(0x08;
++ i2c_out(p, data);
++
++ data[1] = 0x06; // **** Set Com31-->Com0 Seg0-->Seg99
++ i2c_out(p, data);
++
++ //**** Set OLED Characterization
++ data[1] = 0x2A; // **** Set "RE"=1
++ i2c_out(p, data);
++ data[1] = 0x79; // **** Set "SD"=1
++ i2c_out(p, data);
++
++ // **** CGROM/CGRAM Management *** //
++ data[1] = 0x72; // **** Set ROM
++ i2c_out(p, data);
++ data[1] = 0x00; // **** Set ROM A and 8 CGRAM
++ i2c_out(p, data);
++
++ data[1] = 0xDA; // **** Set Seg Pins HW Config
++ i2c_out(p, data);
++ data[1] = 0x10;
++ i2c_out(p, data);
++
++ //data[1] = 0x81; // **** Set Contrast
++ //i2c_out(p, data);
++ //data[1] = 0x50;
++ //i2c_out(p, data);
++
++ data[1] = 0xDB; // **** Set VCOM deselect level
++ i2c_out(p, data);
++ data[1] = 0x30; // **** VCC x 0.83
++ i2c_out(p, data);
++
++ data[1] = 0xDC; // **** Set gpio - turn EN for 15V generator on.
++ i2c_out(p, data);
++ data[1] = 0x03;
++ i2c_out(p, data);
++
++ data[1] = 0x78; // **** Exiting Set OLED Characterization
++ i2c_out(p, data);
++ data[1] = 0x28;
++ i2c_out(p, data);
++ data[1] = 0x2A;
++ i2c_out(p, data);
++ data[1] = 0x6; // **** Set Entry Mode
++ i2c_out(p, data);
++ data[1] = 0x08;
++ i2c_out(p, data);
++ data[1] = 0x28; // **** Set "IS"=0 , "RE" =0 //28
++ i2c_out(p, data);
++ i2c_out(p, data);
++ data[1] = 0x01;
++ i2c_out(p, data);
++ data[1] = 0x80; // **** Set DDRAM Address to 0x80 (line 1 start;
++ i2c_out(p, data);
++
++ //sleep 0.1s;
++ data[1] = 0x0C; // **** Turn on Display
++ i2c_out(p, data);
+
+ return 0;
+ }
+
+-
+-/**
+- * Close the device.
+- * \param p Pointer to driver's private data structure.
+- */
+ void
+ i2c_HD44780_close(PrivateData *p) {
+ if (p->fd >= 0) {
++#ifdef HAVE_DEV_IICBUS_IIC_H
++ ioctl(p->fd, I2CSTOP);
++#endif
+ close(p->fd);
+ }
+ }
+@@ -239,34 +271,13 @@
+ void
+ i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
+ {
+- unsigned char enableLines = 0, portControl = 0;
+- unsigned char h = (ch >> 4) & 0x0f; // high and low nibbles
+- unsigned char l = ch & 0x0f;
+-
++ unsigned char data[2];
+ if (flags == RS_INSTR)
+- portControl = 0;
+- else //if (flags == RS_DATA)
+- portControl = RS;
+-
+- portControl |= p->backlight_bit;
+-
+- enableLines = EN;
+-
+- i2c_out(p, portControl | h);
+- if (p->delayBus)
+- p->hd44780_functions->uPause(p, 1);
+- i2c_out(p, enableLines | portControl | h);
+- if (p->delayBus)
+- p->hd44780_functions->uPause(p, 1);
+- i2c_out(p, portControl | h);
+-
+- i2c_out(p, portControl | l);
+- if (p->delayBus)
+- p->hd44780_functions->uPause(p, 1);
+- i2c_out(p, enableLines | portControl | l);
+- if (p->delayBus)
+- p->hd44780_functions->uPause(p, 1);
+- i2c_out(p, portControl | l);
++ data[0] = 0x80;
++ else
++ data[0] = 0x40;
++ data[1] = ch;
++ i2c_out(p, data);
+ }
+
+
+@@ -277,7 +288,35 @@
+ */
+ void i2c_HD44780_backlight(PrivateData *p, unsigned char state)
+ {
+- p->backlight_bit = ((!p->have_backlight||state) ? 0 : BL);
+
+- i2c_out(p, p->backlight_bit);
++// printf("Backlight %d",state);
++ unsigned char data[2];
++
++ data[0] = 0x80;
++ data[1] = 0x2A;
++ i2c_out(p, data);
++
++// data[0] = 0x80;
++ data[1] = 0x79;
++ i2c_out(p, data);
++
++// data[0] = 0x80;
++ data[1] = 0x81;
++ i2c_out(p, data);
++
++// data[0] = 0x80;
++ if (state)
++ data[1] = 240;
++ else
++ data[1] = 50;
++ i2c_out(p, data);
++
++// data[0] = 0x80;
++ data[1] = 0x78;
++ i2c_out(p, data);
++
++// data[0] = 0x80;
++ data[1] = 0x28;
++ i2c_out(p, data);
++
+ }