--- linux-2.6.17-vanilla/arch/arm/mach-sa1100/jornada720.c 2006-06-18 01:49:35.000000000 +0000 +++ linux-2.6.17/arch/arm/mach-sa1100/jornada720.c 2006-07-10 17:06:11.000000000 +0000 @@ -22,11 +22,170 @@ #include <asm/mach/map.h> #include <asm/mach/serial_sa1100.h> +#include <asm/arch/jornada720.h> + +#include <linux/lcd.h> +#include <linux/backlight.h> +#include <linux/fb.h> #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; }