/* $Id$
* $URL$
*
* LUIse lcd4linux driver
*
* Copyright (C) 2005 Theo Schneider <theo@schneider-berlin.net>
* Copyright (C) 2005 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
*
* This file is part of LCD4Linux.
*
* LCD4Linux 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.
*
* LCD4Linux 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.
*
*/
/*
*
* exported fuctions:
*
* struct DRIVER drv_LUIse
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <usb.h>
#include <luise.h>
#include "debug.h"
#include "cfg.h"
#include "qprintf.h"
#include "udelay.h"
#include "plugin.h"
#include "drv.h"
#include "drv_generic_graphic.h"
static char Name[] = "LUIse";
/* default Wert */
static int devNum = 0;
/****************************************/
/*** hardware dependant functions ***/
/****************************************/
static void drv_LUIse_clear(void)
{
unsigned char buf[9600];
int x;
// clear text
LUI_Text(devNum, 0, 0, 320, 240, 0, 0, 1, 1, "");
// clear picture
for (x = 0; x < 9600; x++)
buf[x] = 0x00;
LUI_Bitmap(devNum, 0, 0, 0, 0, 0, DCOLS, DROWS, DCOLS, DROWS, buf);
LUI_Bitmap(devNum, 1, 0, 0, 0, 0, DCOLS, DROWS, DCOLS, DROWS, buf);
}
static void drv_LUIse_blit(const int row, const int/* $Id$
* $URL$
*
* driver for the "Router Board LCD port"
* see port details at http://www.routerboard.com
*
* Copyright (C) 2004 Roman Jozsef <rjoco77@freemail.hu>
* Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
*
* based on the HD44780 parallel port driver and RB SDK example
*
* This file is part of LCD4Linux.
*
* LCD4Linux 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.
*
* LCD4Linux 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.
*
*/
/* This particulary board not have paralell port but have a special LCD header
* where can connect an HD44780 display.
* This port called IOSC0 port, and is write only, this port control the
* 4 leds on board too.
* Because its a write only port you can't control leds outside lcd driver
* or inverse, for this added the socket controlled leds. To send led status
* simply open an UDP socket and send to localhost 127.0.0.1 port 3333 one
* byte or more anyway only the first byte 4 low bits used the others is
* cleared and ignored bit0 = Led1 ,bit1 = Led2 ...
* This socket polled via timer callback, for detail see at drv_RB_start()
* I add at to end of this file an example!
* If you don't want coment #define RB_WITH LEDS and this part will be ignored
*
* The connection details:
* The IOCS0 port lower 16 bits connected as follows:
* bit LCD LEDS
* 0..7 data
* 8 INITX
* 9 SLINX
* 10 AFDX
* 11 backlit
* 12 LED1
* 13 LED2
* 14 LED3
* 15 LED4
*
* LCD male header:
* 1 Vcc +5V
* 2 GND
* 3 RS (Register Select,AFDX)
* 4 Contrast adjust (controlled) but how? if you know tell me not mentioned on User Manual
* 5 E (enable signal, INITX)
* 6 R/W (Data read/write or SLINX) not used connect LCD pin to ground
* 7 Data 1
* 8 Data 0
* 9 Data 3
* 10 Data 2
* 11 Data 5
* 12 Data 4
* 13 Data 7
* 14 Data 6
* 15 Backlit GND (controlled) (IOSC0 bit 11)
* 16 Backlit Vcc +5V
*
* If you using this driver and board and you have any fun device connected,
* program or story :-) ,please share for me. Thanks.
*
* Literature
* [GEODE] Geode SC1100 Information Appliance On a Chip
* (http://www.national.com/ds/SC/SC1100.pdf)
* [RB User Manual]
* (http://www.routerboard.com)
*
*
* Revision 1.2
* Added backlight control
*/
/*
*
* exported fuctions:
*
* struct DRIVER drv_RouterBoard
*
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/io.h>
#include "debug.h"
#include "cfg.h"
#include "udelay.h"
#include "qprintf.h"
#include "plugin.h"
#include "widget.h"
#include "widget_text.h"
#include "widget_icon.h"
#include "widget_bar.h"
#include "drv.h"
#include "drv_generic_text.h"
#include "drv_generic_gpio.h"
/* #define RB_WITH_LEDS 1 */
#ifdef RB_WITH_LEDS /* Build without socket&led support */
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/poll.h>
#define POLL_TIMEOUT 10 /* Socket poll timeout */
#define MAXMSG_SIZE 100 /* Max messagge we can receive */
static int sock_c; /* Socket handler */
static struct sockaddr_in *sacl;
char sock_msg[MAXMSG_SIZE];
#endif
static char Name[] = "RouterBoard";
static int Model;
static int Capabilities;
/* RouterBoard control signals */
#define LCD_INITX 0x0100
#define LCD_SLINX 0x0200
#define LCD_AFDX 0x0400
#define LCD_BACKLIGHT 0x0800
#define RB_LEDS 0xF000
#define CAR 0x0CF8
#define CDR 0x0CFC
/* HD44780 execution timings [microseconds]
* as these values differ from spec to spec,
* we use the worst-case values.
*/
#define T_INIT1 4100 /* first init sequence: 4.1 msec */
#define T_INIT2 100 /* second init sequence: 100 usec */
#define T_EXEC 80 /* normal execution time */
#define T_WRCG 120 /* CG RAM Write */
#define T_CLEAR 1680 /* Clear Display */
#define T_AS 60 /* Address setup time */
/* buffer holding the GPO state */
static unsigned char GPO = 0;
/* buffor holding backlight and LED states */
static unsigned int RB_Leds = 0;
typedef struct {
int type;
char *name;
int capabilities;
} MODEL;
#define CAP_HD66712 (1<<0)
static MODEL Models[] = {
{0x01, "HD44780", 0},
{0x02, "HD66712", CAP_HD66712},
{0xff, "Unknown", 0}
};
/****************************************/
/*** hardware dependant functions ***/
/****************************************/
#ifdef RB_WITH_LEDS
static int drv_RB_sock_init()
{
if ((sacl = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in))) == NULL) {
return -1;
}
memset(sacl, 0, sizeof(struct sockaddr_in));
sacl->sin_family = AF_INET;
sacl->sin_port = htons(3333); /* Listen Port */
sacl->sin_addr.s_addr = inet_addr("127.0.0.1"); /* Listen Address */
if ((sock_c = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
error("Socket open failed");
free(sacl);
return -1;
}
if (bind(sock_c, (struct sockaddr *) sacl, sizeof(struct sockaddr_in)) < 0) {
error("Socket bind open failed");
free(sacl);
return -1;
}
return 0;
}
static void drv_RB_poll_data(void __attribute__ ((unused)) * notused)
{
int len, size;
struct pollfd usfd;
usfd.fd = sock_c;
usfd.events = POLLIN | POLLPRI;
while (poll(&usfd, 1, POLL_TIMEOUT) > 0) {
len = sizeof(struct sockaddr_in);
if ((size = recvfrom(sock_c, sock_msg, MAXMSG_SIZE, 0, (struct sockaddr *) sacl, (socklen_t *) & len)) < 0);
else {
RB_Leds &= 0x0fff;
RB_Leds |= (sock_msg[0] & 0x0F) << 12;
/* fprintf(stderr, "Received data %s\n",sock_msg); */
}
}
}
#endif
static void drv_RB_outw(const unsigned int data)
{
static unsigned int port = 0;
/* IOCS0 port number can read from PCI Configuration Space Function 0 (F0) */
/* at index 74h as 16 bit value (see [GEODE] 5.3.1 pg.151 and pg.176 Table 5-29 */
if (port == 0) {
/* get IO permission, here you can't use ioperm command */
iopl(3);
outl(0x80009074, CAR);
port = inw(CDR);
}
outw(data | RB_Leds, port);
}
static int drv_RB_backlight(int backlight)
{
/* -1 is used to query the current Backlight */
if (backlight == -1) {
return (RB_Leds & LCD_BACKLIGHT) ? 1 : 0;
}
if (backlight > 0) {
/* set bit */
RB_Leds |= LCD_BACKLIGHT;
backlight = 1;
} else {
backlight = 0;
/* clear bit */
RB_Leds &= ~LCD_BACKLIGHT;
}
/* Set backlight output */
drv_RB_outw(0);
return backlight;
}
static void drv_RB_command(const unsigned char cmd, const int delay)
{
drv_RB_outw(LCD_INITX | cmd);
ndelay(T_AS);
drv_RB_outw(cmd);
/* wait for command completion */
udelay(delay);
}
static void drv_RB_data(const char *string, const int len, const int delay)
{
int l = len;
unsigned char ch;
/* sanity check */
if (len <= 0)
return;
while (l--) {
ch = *(string++);
drv_RB_outw(ch | LCD_AFDX | LCD_INITX);
ndelay