diff -ruN linux-2.6.18-vanilla/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.6.18/arch/arm/mach-sa1100/cpu-sa1110.c --- linux-2.6.18-vanilla/arch/arm/mach-sa1100/cpu-sa1110.c 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/arch/arm/mach-sa1100/cpu-sa1110.c 2006-10-03 22:58:39.000000000 +0000 @@ -82,6 +82,14 @@ .twr = 9, .refresh = 64000, .cas_latency = 3, + }, { /* Samsung K4s281632b-1h */ + .name = "K4S281632B-1H", + .rows = 12, + .tck = 10, + .trp = 20, + .twr = 10, + .refresh = 64000, + .cas_latency = 3, }, { /* Samsung KM416S4030CT */ .name = "KM416S4030CT", .rows = 13, @@ -366,6 +374,9 @@ if (machine_is_h3100()) name = "KM416S4030CT"; + + if (machine_is_jornada720()) + name = "K4S281632B-1H"; } sdram = sa1110_find_sdram(name); diff -ruN linux-2.6.18-vanilla/arch/arm/mach-sa1100/jornada720.c linux-2.6.18/arch/arm/mach-sa1100/jornada720.c --- linux-2.6.18-vanilla/arch/arm/mach-sa1100/jornada720.c 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/arch/arm/mach-sa1100/jornada720.c 2006-10-03 22:58:39.000000000 +0000 @@ -22,11 +22,170 @@ #include #include +#include + +#include +#include +#include #include "generic.h" #define JORTUCR_VAL 0x20000400 +/* Jornada 720 MCU functions */ +#define MCU_REVERSE(i) ((unsigned char)(((0x80 & i) >> 7) | ((0x40 & i) >> 5) \ + | ((0x20 & i) >> 3) | ((0x10 & i) >> 1) | ((0x08 & i) << 1) \ + | ((0x04 & i) << 3) | ((0x02 & i) << 5) | ((0x01 & i) << 7))) + +void jornada720_init_ser(void) +{ + int i; + + GPSR = GPIO_GPIO25; + Ser4SSCR0 = 0x0307; + Ser4MCCR0 = 0; + Ser4SSCR1 = 0x18; + Ser4SSCR0 = 0x0387; + while (Ser4SSSR & SSSR_RNE) + i = Ser4SSDR; +} + +int jornada720_mcu_byte(int arg_data) +{ + int i; + + while ((Ser4SSSR & SSSR_TNF) == 0); + i = 0; + while ((GPLR & 0x400) && i++ < 400000); + /* wait for MCU */ + + if (i >= 400000) { + printk("jornada 720_mcu_byte: timed out\n"); + return -1; + } + Ser4SSDR = MCU_REVERSE(arg_data) << 8; + udelay(100); + while ((Ser4SSSR & SSSR_RNE) == 0); + i = Ser4SSDR; + if (i > 0xff) + printk("jornada720 mcu_byte: read %x\n", i); + return MCU_REVERSE(i & 0xff) & 0xff; +} + + +int jornada720_mcu_start(int arg_data) +{ + int i; + + GPCR = GPIO_GPIO25; /* clear -> enable */ + udelay(100); + i = jornada720_mcu_byte(arg_data); + if (i != MCU_TxDummy) + { + printk("jornada720_mcu_start: sent %x got %x\n", arg_data, i); + for (i = 0; i < 256; i++) + if (jornada720_mcu_read() == -1) + break; + + jornada720_init_ser(); + return -1; + } + + return 0; +} + + +void jornada720_mcu_end(void) +{ + udelay(100); + GPSR = GPIO_GPIO25; /* set */ +} + +void jornada720_mcu_init(void) +{ + + /*int i; + + if (state) { + PPSR &= ~PPC_LDD1; + PPDR &= PPC_LDD1; + } + else { */ + PPSR |= PPC_LDD1; + /*} + return 0;*/ +} + +/*static int jornada720_backlight_get_power(struct backlight_device *bd) +{ + + return ~(PPSR&PPC_LDD1); +}*/ + +static int jornada720_backlight_get_brightness(struct backlight_device *bd) +{ + int brightness; + jornada720_mcu_start(MCU_GetBrightness); + brightness = jornada720_mcu_read(); + jornada720_mcu_end(); + return brightness; +} + +static int jornada720_backlight_set_brightness(struct backlight_device *bd) +{ + /* TODO: should it be substracted? */ + int brightness = 255 - bd->props->brightness; + jornada720_mcu_start(MCU_SetBrightness); + jornada720_mcu_byte(brightness); + jornada720_mcu_end(); + return 0; +} + +static struct backlight_properties jornada720_backlight_properties = { + .owner = THIS_MODULE, + .get_brightness = jornada720_backlight_get_brightness, + .update_status = jornada720_backlight_set_brightness, + .max_brightness = 255, +}; + +static int jornada720_lcd_set_power(struct lcd_device *ld, int power) +{ + return 0; +} + +static int jornada720_lcd_get_power(struct lcd_device *ld) +{ + return 1; +} + +static int jornada720_lcd_get_contrast(struct lcd_device *ld) +{ + int contrast; + + jornada720_mcu_start(MCU_GetContrast); + contrast = jornada720_mcu_read(); + jornada720_mcu_end(); + + return contrast; +} + +static int jornada720_lcd_set_contrast(struct lcd_device *ld, int contrast) +{ + jornada720_mcu_start(MCU_SetContrast); + jornada720_mcu_byte(contrast); + jornada720_mcu_end(); + return 0; +} + +static struct lcd_properties jornada720_lcd_properties = { + .owner = THIS_MODULE, + .set_power = jornada720_lcd_set_power, + .get_power = jornada720_lcd_get_power, + .set_contrast = jornada720_lcd_set_contrast, + .get_contrast = jornada720_lcd_get_contrast, + .max_contrast = 255, +}; + static struct resource sa1111_resources[] = { [0] = { .start = 0x40000000, @@ -77,6 +236,10 @@ PPDR |= PPC_LDD3 | PPC_LDD4; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + + jornada720_mcu_init(); + backlight_device_register("e1356fb", 0, &jornada720_backlight_properties); + lcd_device_register("e1356fb", 0, &jornada720_lcd_properties); } return ret; } diff -ruN linux-2.6.18-vanilla/drivers/input/keyboard/Kconfig linux-2.6.18/drivers/input/keyboard/Kconfig --- linux-2.6.18-vanilla/drivers/input/keyboard/Kconfig 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/drivers/input/keyboard/Kconfig 2006-10-03 22:58:39.000000000 +0000 @@ -183,4 +183,11 @@ This driver implements support for HIL-keyboards attached to your machine, so normally you should say Y here. +config KEYBOARD_JORNADA720 + tristate "HP Jornada 720 Keyboard Support" + depends on SA1100_JORNADA720 + default y + help + Say Y to enable keyboard on the Hewlett Packard Jornada + 7xx(710/720/728) series of PDAs. endif diff -ruN linux-2.6.18-vanilla/drivers/input/keyboard/Makefile linux-2.6.18/drivers/input/keyboard/Makefile --- linux-2.6.18-vanilla/drivers/input/keyboard/Makefile 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/drivers/input/keyboard/Makefile 2006-10-03 22:58:39.000000000 +0000 @@ -15,4 +15,4 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o - +obj-$(CONFIG_KEYBOARD_JORNADA720) += jornada720_kbd.o diff -ruN linux-2.6.18-vanilla/drivers/input/keyboard/jornada720_kbd.c linux-2.6.18/drivers/input/keyboard/jornada720_kbd.c --- linux-2.6.18-vanilla/drivers/input/keyboard/jornada720_kbd.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.18/drivers/input/keyboard/jornada720_kbd.c 2006-10-03 23:05:54.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * Jornada 720 keyboard interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Alex Lange "); +MODULE_DESCRIPTION("Jornada 720 keyboard driver"); +MODULE_LICENSE("GPL"); + +static char jornada720_kbd_name[] = "Jornada 720 keyboard"; + +static struct input_dev *dev; + +static unsigned char jornada720_normal_keymap[128] = { + 0, 1, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 87, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE, + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, + 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 43, 14, 0, 0, 0, + 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, KEY_LEFTBRACE, KEY_RIGHTBRACE, 0, 0, 0, + 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, KEY_KPMINUS, 40, 28, 0, 0, 0, + 0, 15, 0, 42, 0, 40, 0, 0, 0, 0, 103, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 56, KEY_GRAVE, 0, 0, 105, 108, 106, 0, 0, 0, 0, + 0, 55, 29, 0, 57, 0, 0, 0, 53, 111, 0, 0, 0, 0, 0, 116, +}; + +static irqreturn_t jornada720_keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int key, keycode; + int count, mcu_data=0; + + jornada720_mcu_start(MCU_GetScanKeyCode); + count = jornada720_mcu_read(); + + while (count-- > 0) { + key = mcu_data = jornada720_mcu_read(); + + if (key > 128) + key = key - 128; + + keycode = jornada720_normal_keymap[key]; + + if (mcu_data < 128) { + input_report_key(dev, keycode, 1); + input_sync(dev); + } + else { + input_report_key(dev, keycode, 0); + input_sync(dev); + } + } + + jornada720_mcu_end(); + + return IRQ_HANDLED; +} + +static int __init jornada720_kbd_init(void) +{ + int i,ret; + printk("jorada720_kbd: Jornada 720 keyboard\n"); + + /*init_input_dev(&dev);*/ + dev = input_allocate_device(); + dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + dev->keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND); + + for ( i=0 ; i<=128 ; i++ ) { + if (!(jornada720_normal_keymap[i])) { + } + else + set_bit(jornada720_normal_keymap[i], dev->keybit); + } + + dev->name = jornada720_kbd_name; + + ret = request_irq(GPIO_JORNADA720_KEYBOARD_IRQ, + jornada720_keyboard_interrupt, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "Jornada720 Keyboard",NULL); + if (ret) { + printk("Unable to grab Jornada 720 keyboard IRQ: %d\n", ret); + input_free_device(dev); + return ret; + } + + input_register_device(dev); + + return 0; +} + +module_init(jornada720_kbd_init); diff -ruN linux-2.6.18-vanilla/drivers/input/touchscreen/Kconfig linux-2.6.18/drivers/input/touchscreen/Kconfig --- linux-2.6.18-vanilla/drivers/input/touchscreen/Kconfig 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/drivers/input/touchscreen/Kconfig 2006-10-03 22:58:39.000000000 +0000 @@ -108,4 +108,11 @@ To compile this driver as a module, choose M here: the module will be called hp680_ts_input. +config TOUCHSCREEN_JORNADA720 + tristate "HP Jornada 720 touchscreen support" + depends on SA1100_JORNADA720 + help + Say Y here if you are using a HP Jornada 710/720/728 handheld + and want to use the touchscreen. + endif diff -ruN linux-2.6.18-vanilla/drivers/input/touchscreen/Makefile linux-2.6.18/drivers/input/touchscreen/Makefile --- linux-2.6.18-vanilla/drivers/input/touchscreen/Makefile 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/drivers/input/touchscreen/Makefile 2006-10-03 22:58:39.000000000 +0000 @@ -12,3 +12,4 @@ obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o +obj-$(CONFIG_TOUCHSCREEN_JORNADA720) += jornada720_ts.o diff -ruN linux-2.6.18-vanilla/drivers/input/touchscreen/jornada720_ts.c linux-2.6.18/drivers/input/touchscreen/jornada720_ts.c --- linux-2.6.18-vanilla/drivers/input/touchscreen/jornada720_ts.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.18/drivers/input/touchscreen/jornada720_ts.c 2006-10-03 23:07:32.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * Jornada 720 touchscreen interface based on Jornada 56x interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Alex Lange "); +MODULE_DESCRIPTION("Jornada 720 touchscreen driver"); +MODULE_LICENSE("GPL"); + +static char jornada720_ts_name[] = "Jornada 720 touchscreen"; + +static struct input_dev *dev; + +static irqreturn_t jornada720_mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int down; + int X[3], Y[3], high_x, high_y, x, y; + + udelay(1); + + down = ( (GPLR & GPIO_JORNADA720_MOUSE) == 0); + + if(!down) { + input_report_key(dev, BTN_TOUCH, down); /* report a pen up */ + input_report_abs(dev, ABS_PRESSURE, 0); + input_sync(dev); + return IRQ_HANDLED; + } + + /* read x & y data from mcu interface and pass it on */ + + jornada720_mcu_start(MCU_GetTouchSamples); + X[0] = jornada720_mcu_read(); + X[1] = jornada720_mcu_read(); + X[2] = jornada720_mcu_read(); + Y[0] = jornada720_mcu_read(); + Y[1] = jornada720_mcu_read(); + Y[2] = jornada720_mcu_read(); + high_x = jornada720_mcu_read(); /* msbs of samples */ + high_y = jornada720_mcu_read(); + jornada720_mcu_end(); + + X[0] |= (high_x & 3) << 8; + X[1] |= (high_x & 0xc) << 6; + X[2] |= (high_x & 0x30) << 4; + + Y[0] |= (high_y & 3) << 8; + Y[1] |= (high_y & 0xc) << 6; + Y[2] |= (high_y & 0x30) << 4; + + /* simple averaging filter */ + x = (X[0] + X[1] + X[2])/3; + y = (Y[0] + Y[1] + Y[2])/3; + + input_report_key(dev, BTN_TOUCH, down); + input_report_abs(dev, ABS_X, x); + input_report_abs(dev, ABS_Y, y); + input_report_abs(dev, ABS_PRESSURE, 1); + input_sync(dev); + + return IRQ_HANDLED; + +} + +static int __init jornada720_ts_init(void) +{ + int ret; + printk("jornada720_ts: Jornada 720 touchscreen\n"); + + dev = input_allocate_device(); + dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + + dev->absmin[ABS_X] = 270; dev->absmin[ABS_Y] = 180; + dev->absmax[ABS_X] = 3900; dev->absmax[ABS_Y] = 3700; + + dev->name = jornada720_ts_name; + + ret = request_irq(GPIO_JORNADA720_MOUSE_IRQ, + jornada720_mouse_interrupt, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "Jornada720 Mouse",NULL); + if (ret) { + printk("Unable to grab Jornada 720 Mouse/Touchscreen IRQ: %d\n", ret); + input_free_device(dev); + return ret; + } + + input_register_device(dev); + + return 0; +} + +module_init(jornada720_ts_init); + diff -ruN linux-2.6.18-vanilla/drivers/video/Kconfig linux-2.6.18/drivers/video/Kconfig --- linux-2.6.18-vanilla/drivers/video/Kconfig 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/drivers/video/Kconfig 2006-10-03 22:58:39.000000000 +0000 @@ -680,6 +680,16 @@ framebuffer. Product specs at . +config FB_EPSON1356 + bool "Epson 1356 framebuffer support" + depends on FB && ARM && SA1100_JORNADA720 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the 1356 framebuffer device on the HP Jornada + 710/720/728 hanheld pc. + config FB_S1D13XXX tristate "Epson S1D13XXX framebuffer support" depends on FB diff -ruN linux-2.6.18-vanilla/drivers/video/Makefile linux-2.6.18/drivers/video/Makefile --- linux-2.6.18-vanilla/drivers/video/Makefile 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/drivers/video/Makefile 2006-10-03 22:58:39.000000000 +0000 @@ -77,6 +77,7 @@ obj-$(CONFIG_FB_SUN3) += sun3fb.o obj-$(CONFIG_FB_HIT) += hitfb.o obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o +obj-$(CONFIG_FB_EPSON1356) += epson1356fb.o obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o diff -ruN linux-2.6.18-vanilla/drivers/video/epson1356fb.c linux-2.6.18/drivers/video/epson1356fb.c --- linux-2.6.18-vanilla/drivers/video/epson1356fb.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.18/drivers/video/epson1356fb.c 2006-10-03 22:58:39.000000000 +0000 @@ -0,0 +1,345 @@ +/* + * linux/drivers/video/epson1356fb.c -- Epson 1356 LCD Controller Frame Buffer Device + * + * Copyright (C) 2001 MIT + * + * Edited from sa1100fb.c + * Copyright (C) 1999 Eric A. Thomas + * Based on acornfb.c Copyright (C) Russell King. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * 20050203: Ported to kernel 2.6. Very basic interface for the Jornada 720 (C) Alex Lange (chicken@handhelds.org) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "console/fbcon.h" + +u32 pseudo_pal[16]; + +struct fb_info fb_info; + +static int e1356fb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *fb_info) +{ + int bpp, m = 0; + + bpp = fb_info->var.bits_per_pixel; + m = (bpp <= 8) ? (1 << bpp) : 256; + if (regno >= m) { + printk("regno %d out of range (max %d)\n", regno, m); + return -EINVAL; + } + switch (bpp) { + case 8: + break; + case 16: + /* RGB 565 */ + pseudo_pal[regno] = ((red & 0xF800) | + ((green & 0xFC00) >> 5) | + ((blue & 0xF800) >> 11)); + break; + } + + return 0; +} + +static int e1356fb_blank(int blank, struct fb_info *info) +{ + switch (blank) { + case FB_BLANK_POWERDOWN: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + PPSR &= ~PPC_LDD1; + PPDR |= PPC_LDD1; + break; + + case FB_BLANK_UNBLANK: + PPSR |= PPC_LDD1; + mdelay(100); + } + return 0; +} + +static struct fb_var_screeninfo e1356fb_screeninfo = { + .xres = 640, + .yres = 240, + .xres_virtual = 640, + .yres_virtual = 240, + .bits_per_pixel = 16, + .red.length = 5, + .green.length = 6, + .blue.length = 5, + .transp.length = 0, + .red.offset = 11, + .green.offset = 5, + .blue.offset = 0, + .transp.offset = 0, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, + .accel_flags = 0, + .nonstd = 0, +}; + +static struct fb_ops e1356fb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = e1356fb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = soft_cursor, + .fb_blank = e1356fb_blank, +}; + +static struct fb_fix_screeninfo e1356fb_fix = { + .id = "e1356fb", + .smem_len = (MAX_XRES * MAX_YRES * MAX_BPP)/8, + .smem_start = (unsigned long)DISP_MEM_OFFSET_PHYS, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = (640 * 16) / 8, + .accel = FB_ACCEL_NONE, + .type_aux = 0, + .ypanstep = 0, + .ywrapstep = 0, +}; + +unsigned char LUT8[256*3] = { + /* Primary and secondary colors */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x00, 0xA0, 0xA0, + 0xA0, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0, 0xA0, + 0x50, 0x50, 0x50, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0xF0, + 0xF0, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xF0, 0xF0, 0xF0 +}; + +static char lut_base[] = { + /*red green blue rinc ginc binc */ + 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, /* Gray shades */ + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, /* Black to red */ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, /* Black to green */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* Black to blue */ + 0x00, 0x00, 0xF0, 0x00, 0x10, 0x00, /* Blue to cyan (blue and green) */ + 0x00, 0xf0, 0xf0, 0x00, 0x00, -0x10, /* Cyan (blue and green) to green */ + 0x00, 0xf0, 0x00, 0x10, 0x00, 0x00, /* Green to yellow (red and green)*/ + 0xf0, 0xf0, 0x00, 0x00, -0x10, 0x00, /* Yellow (red and green) to red */ + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x10, /* Red to magenta (blue and red) */ + 0xf0, 0x00, 0xf0, -0x10, 0x00, 0x00, /* Magenta (blue and red) to blue */ + 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, /* Black to magenta (blue and red)*/ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, /* Black to cyan (blue and green) */ + 0xf0, 0x00, 0x00, 0x00, 0x10, 0x10, /* Red to white */ + 0x00, 0xf0, 0x00, 0x10, 0x00, 0x10, /* Green to white */ + 0x00, 0x00, 0xf0, 0x10, 0x10, 0x00, /* Blue to white */ +}; + +void e1356fb_init_hardware(void) +{ + unsigned char *pRegs = REGISTER_OFFSET; + unsigned char *pLUT = LUT8; + unsigned char *pseed = lut_base; + unsigned char plast[3]; + int i, j, rgb; + + /* Enable access to SED1356 by setting memory/register select bit to 0. */ + pRegs[0x001] = 0; + udelay(2); + /* Disable display outputs during initialization) */ + pRegs[0x1FC] = 0; + + /* Set the GPIOs to input. Should GPIO bits in register [004] get switched + then the GPIO outputs, according to register [008], are driven low. */ + pRegs[0x004] = 0; + pRegs[0x008] = 0; + + /* Program the LCD panel type and panel timing registers. + * The horizontal and vertical non-display times have been + * calculated for a 78 Hz frame rate. + * LCD PCLK + * FrameRate = ----------------------------- + * (HDP + HNDP) * (VDP/2 + VNDP) + * + * 20,000,000 + * = ---------------------------- = 78 Hz + * (640 + 256) * (480 / 2 + 45) + */ + + pRegs[0x10] = 0x1; /* Memory Clock Configuration Register */ + pRegs[0x14] = 0x11; /* LCD Pixel Clock Configuration Register */ + pRegs[0x18] = 0x1; /* CRT/TV Pixel Clock Configuration Register */ + pRegs[0x1c] = 0x1; /* MediaPlug Clock Configuration Register */ + pRegs[0x1e] = 0x1; /* CPU To Memory Wait State Select Register */ + pRegs[0x20] = 0; /* Memory Configuration Register */ + pRegs[0x21] = 0x45; /* DRAM Refresh Rate Register */ + pRegs[0x2a] = 0x1; /* DRAM Timings Control Register 0 */ + pRegs[0x2b] = 0x1; /* DRAM Timings Control Register 1 */ + pRegs[0x30] = 0x1c; /* Panel Type Register */ + pRegs[0x31] = 0; /* MOD Rate Register */ + pRegs[0x32] = 0x4f; /* LCD Horizontal Display Width Register */ + pRegs[0x34] = 0x7; /* LCD Horizontal Non-Display Period Register */ + pRegs[0x35] = 0x1; /* TFT FPLINE Start Position Register */ + pRegs[0x36] = 0xb; /* TFT FPLINE Pulse Width Register */ + pRegs[0x38] = 0xef; /* LCD Vertical Display Height Register 0 */ + pRegs[0x39] = 0; /* LCD Vertical Display Height Register 1 */ + pRegs[0x3a] = 0x13; /* LCD Vertical Non-Display Period Register */ + pRegs[0x3b] = 0xb; /* TFT FPFRAME Start Position Register */ + pRegs[0x3c] = 0x1; /* TFT FPFRAME Pulse Width Register */ + pRegs[0x40] = 0x5; /* LCD Display Mode Register */ + pRegs[0x41] = 0; /* LCD Miscellaneous Register */ + pRegs[0x42] = 0; /* LCD Display Start Address Register 0 */ + pRegs[0x43] = 0; /* LCD Display Start Address Register 1 */ + pRegs[0x44] = 0; /* LCD Display Start Address Register 2 */ + pRegs[0x46] = 0x80; /* LCD Memory Address Offset Register 0 */ + pRegs[0x47] = 0x2; /* LCD Memory Address Offset Register 1 */ + pRegs[0x48] = 0; /* LCD Pixel Panning Register */ + pRegs[0x4a] = 0; /* LCD Display FIFO High Threshold Control Register */ + pRegs[0x4b] = 0; /* LCD Display FIFO Low Threshold Control Register */ + pRegs[0x50] = 0x4f; /* CRT/TV Horizontal Display Width Register */ + pRegs[0x52] = 0x13; /* CRT/TV Horizontal Non-Display Period Register */ + pRegs[0x53] = 0x1; /* CRT/TV HRTC Start Position Register */ + pRegs[0x54] = 0xb; /* CRT/TV HRTC Pulse Width Register */ + pRegs[0x56] = 0xdf; /* CRT/TV Vertical Display Height Register 0 */ + pRegs[0x57] = 0x1; /* CRT/TV Vertical Display Height Register 1 */ + pRegs[0x58] = 0x2b; /* CRT/TV Vertical Non-Display Period Register */ + pRegs[0x59] = 0x9; /* CRT/TV VRTC Start Position Register */ + pRegs[0x5a] = 0x1; /* CRT/TV VRTC Pulse Width Register */ + pRegs[0x5b] = 0x10; /* TV Output Control Register */ + pRegs[0x60] = 0x3; /* CRT/TV Display Mode Register */ + pRegs[0x62] = 0; /* CRT/TV Display Start Address Register 0 */ + pRegs[0x63] = 0; /* CRT/TV Display Start Address Register 1 */ + pRegs[0x64] = 0; /* CRT/TV Display Start Address Register 2 */ + pRegs[0x66] = 0x40; /* CRT/TV Memory Address Offset Register 0 */ + pRegs[0x67] = 0x1; /* CRT/TV Memory Address Offset Register 1 */ + pRegs[0x68] = 0; /* CRT/TV Pixel Panning Register */ + pRegs[0x6a] = 0; /* CRT/TV Display FIFO High Threshold Control Register */ + pRegs[0x6b] = 0; /* CRT/TV Display FIFO Low Threshold Control Register */ + pRegs[0x70] = 0; /* LCD Ink/Cursor Control Register */ + pRegs[0x71] = 0x1; /* LCD Ink/Cursor Start Address Register */ + pRegs[0x72] = 0; /* LCD Cursor X Position Register 0 */ + pRegs[0x73] = 0; /* LCD Cursor X Position Register 1 */ + pRegs[0x74] = 0; /* LCD Cursor Y Position Register 0 */ + pRegs[0x75] = 0; /* LCD Cursor Y Position Register 1 */ + pRegs[0x76] = 0; /* LCD Ink/Cursor Blue Color 0 Register */ + pRegs[0x77] = 0; /* LCD Ink/Cursor Green Color 0 Register */ + pRegs[0x78] = 0; /* LCD Ink/Cursor Red Color 0 Register */ + pRegs[0x7a] = 0x1f; /* LCD Ink/Cursor Blue Color 1 Register */ + pRegs[0x7b] = 0x3f; /* LCD Ink/Cursor Green Color 1 Register */ + pRegs[0x7c] = 0x1f; /* LCD Ink/Cursor Red Color 1 Register */ + pRegs[0x7e] = 0; /* LCD Ink/Cursor FIFO Threshold Register */ + pRegs[0x80] = 0; /* CRT/TV Ink/Cursor Control Register */ + pRegs[0x81] = 0x1; /* CRT/TV Ink/Cursor Start Address Register */ + pRegs[0x82] = 0; /* CRT/TV Cursor X Position Register 0 */ + pRegs[0x83] = 0; /* CRT/TV Cursor X Position Register 1 */ + pRegs[0x84] = 0; /* CRT/TV Cursor Y Position Register 0 */ + pRegs[0x85] = 0; /* CRT/TV Cursor Y Position Register 1 */ + pRegs[0x86] = 0; /* CRT/TV Ink/Cursor Blue Color 0 Register */ + pRegs[0x87] = 0; /* CRT/TV Ink/Cursor Green Color 0 Register */ + pRegs[0x88] = 0; /* CRT/TV Ink/Cursor Red Color 0 Register */ + pRegs[0x8a] = 0x1f; /* CRT/TV Ink/Cursor Blue Color 1 Register */ + pRegs[0x8b] = 0x3f; /* CRT/TV Ink/Cursor Green Color 1 Register */ + pRegs[0x8c] = 0x1f; /* CRT/TV Ink/Cursor Red Color 1 Register */ + pRegs[0x8e] = 0; /* CRT/TV Ink/Cursor FIFO Threshold Register */ + + /* Set the 2D acceleration (BitBLT) registers to a known state */ + for (i = 0x100; i <= 0x119; i++) + if (i != 0x107 && i != 0x10b && i != 0x10e && i != 0x10f && i != 0x117) + pRegs[i] = 0x00; + + /* Program the look-up table to a known state. */ + pRegs[0x1E0] = 0x01; /* Enable the LCD LUT for read/write. */ + pRegs[0x1E2] = 0; /* Reset the LUT address. */ + for (i = 0; i < 16 * 3; i++) + pRegs[0x1E4] = *pLUT++; /* non-regular color template */ + + for (i = 0; i < 15; i++) { + for (rgb = 0; rgb < 3; rgb++) { + plast[rgb] = *pseed++; /* base color value */ + pRegs[0x1E4] = plast[rgb]; + } + for (j = 0; j < 15; j++) + for (rgb = 0; rgb < 3; rgb++) { + plast[rgb] += pseed[rgb]; /* increment through color values*/ + pRegs[0x1E4] = plast[rgb]; + } + pseed += 3; + } + + pRegs[0x1e4] = 0; /* Look-Up Table Data Register */ + pRegs[0x1f0] = 0; /* Power Save Configuration Register */ + pRegs[0x1f1] = 0; /* Power Save Status Register */ + pRegs[0x1f4] = 0; /* CPU-to-Memory Access Watchdog Timer Register */ + + PPSR |= PPC_LDD0; + + mdelay(100); /* Wait for 100ms */ + pRegs[0x1F0] = 0; /* Turn off power save mode */ + pRegs[0x1F4] = 0; /* Disable the watchdog timer */ + pRegs[0x1FC] = 0x01; /* Disable power save mode, enable display */ +} + +int __init e1356fb_init(void) +{ + if (fb_get_options("e1356fb", NULL)) + return -ENODEV; + + printk("Configuring the Jornada 720 screen...\n"); + + fb_info.screen_base = (u_char *) DISP_MEM_OFFSET; + fb_info.screen_size = ALLOCATED_FB_MEM_SIZE; + memset(&fb_info.var, 0, sizeof(fb_info.var)); + + PPSR &= ~(PPC_LDD0 | PPC_LDD1 | PPC_LDD2); + PPDR |= PPC_LDD0 | PPC_LDD1 | PPC_LDD2; + LCCR3 = 0; + LCCR2 = 0; + LCCR1 = 0; + LCCR0 = 0; + DBAR1 = 0; + DBAR2 = 0; + + e1356fb_init_hardware(); + memset ((unsigned char *)DISP_MEM_OFFSET, 0, ALLOCATED_FB_MEM_SIZE); + + PPSR |= PPC_LDD1; + mdelay(100); /* delay again */ + PPSR |= PPC_LDD2; + + fb_info.fbops = &e1356fb_ops; + fb_info.var = e1356fb_screeninfo; + fb_info.fix = e1356fb_fix; + fb_info.flags = FBINFO_DEFAULT; + + fb_info.pseudo_palette = &pseudo_pal; + + if (register_framebuffer(&fb_info) < 0) + return 1; + + return 0; +} + +module_init(e1356fb_init); + diff -ruN linux-2.6.18-vanilla/include/asm-arm/arch-sa1100/jornada720.h linux-2.6.18/include/asm-arm/arch-sa1100/jornada720.h --- linux-2.6.18-vanilla/include/asm-arm/arch-sa1100/jornada720.h 2006-09-20 03:42:06.000000000 +0000 +++ linux-2.6.18/include/asm-arm/arch-sa1100/jornada720.h 2006-10-03 22:58:39.000000000 +0000 @@ -11,6 +11,8 @@ #error "include instead" #endif +#define jornada720_mcu_read() jornada720_mcu_byte(MCU_TxDummy) + #define SA1111_BASE (0x40000000) #define GPIO_JORNADA720_KEYBOARD GPIO_GPIO(0) @@ -19,9 +21,38 @@ #define GPIO_JORNADA720_KEYBOARD_IRQ IRQ_GPIO0 #define GPIO_JORNADA720_MOUSE_IRQ IRQ_GPIO9 +/* Epson 1356 LCD controll parameters */ +#define REGISTER_OFFSET ((unsigned char *) 0xf0000000/* 0 */) +#define DISP_MEM_OFFSET ((unsigned char *) 0xf1000000/* 0 */) +#define DISP_MEM_OFFSET_PHYS ((unsigned char *) 0x48200000/* 0 filip wtf? */) +#define ALLOCATED_FB_MEM_SIZE 0x80000 /* display memory size (512kb) */ + +#define MAX_BPP 16 +#define MAX_XRES 640 +#define MAX_YRES 240 +#define MIN_XRES 64 +#define MIN_YRES 64 + +/* MCU COMMANDS */ +#define MCU_GetBatteryData 0xc0 +#define MCU_GetScanKeyCode 0x90 +#define MCU_GetTouchSamples 0xa0 +#define MCU_GetContrast 0xD0 +#define MCU_SetContrast 0xD1 +#define MCU_GetBrightness 0xD2 +#define MCU_SetBrightness 0xD3 +#define MCU_ContrastOff 0xD8 +#define MCU_BrightnessOff 0xD9 +#define MCU_PWMOFF 0xDF +#define MCU_TxDummy 0x11 +#define MCU_ErrorCode 0x00 + #ifndef __ASSEMBLY__ void jornada720_mcu_init(void); +int jornada720_mcu_byte(int arg_data); +int jornada720_mcu_start(int arg_data); +void jornada720_mcu_end(void); void jornada_contrast(int arg_contrast); void jornada720_battery(void); int jornada720_getkey(unsigned char *data, int size);