1 /* 2 * Backlight control code for Sharp Zaurus SL-5500 3 * 4 * Copyright 2005 John Lenz <lenz@cs.wisc.edu> 5 * Maintainer: Pavel Machek <pavel@suse.cz> (unless John wants to :-) 6 * GPL v2 7 * 8 * This driver assumes single CPU. That's okay, because collie is 9 * slightly old hardware, and noone is going to retrofit second CPU to 10 * old PDA. 11 */ 12 13 /* LCD power functions */ 14 #include <linux/config.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/delay.h> 18 #include <linux/device.h> 19 #include <linux/interrupt.h> 20 21 #include <asm/hardware/locomo.h> 22 #include <asm/irq.h> 23 #include <asm/mach/sharpsl_param.h> 24 #include <asm/mach-types.h> 25 26 #include "../../../arch/arm/mach-sa1100/generic.h" 27 28 static struct locomo_dev *locomolcd_dev; 29 30 static void locomolcd_on(int comadj) 31 { 32 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0); 33 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 1); 34 mdelay(2); 35 36 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0); 37 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 1); 38 mdelay(2); 39 40 locomo_m62332_senddata(locomolcd_dev, comadj, 0); 41 mdelay(5); 42 43 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0); 44 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 1); 45 mdelay(10); 46 47 /* TFTCRST | CPSOUT=0 | CPSEN */ 48 locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC); 49 50 /* Set CPSD */ 51 locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD); 52 53 /* TFTCRST | CPSOUT=0 | CPSEN */ 54 locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC); 55 mdelay(10); 56 57 locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0); 58 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 1); 59 } 60 61 static void locomolcd_off(int comadj) 62 { 63 /* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */ 64 locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC); 65 mdelay(1); 66 67 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0); 68 mdelay(110); 69 70 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0); 71 mdelay(700); 72 73 /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */ 74 locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC); 75 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0); 76 locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0); 77 } 78 79 void locomolcd_power(int on) 80 { 81 int comadj = sharpsl_param.comadj; 82 unsigned long flags; 83 84 local_irq_save(flags); 85 86 if (!locomolcd_dev) { 87 local_irq_restore(flags); 88 return; 89 } 90 91 /* read comadj */ 92 if (comadj == -1) { 93 if (machine_is_poodle()) 94 comadj = 118; 95 if (machine_is_collie()) 96 comadj = 128; 97 } 98 99 if (on) 100 locomolcd_on(comadj); 101 else 102 locomolcd_off(comadj); 103 104 local_irq_restore(flags); 105 } 106 EXPORT_SYMBOL(locomolcd_power); 107 108 static int poodle_lcd_probe(struct locomo_dev *dev) 109 { 110 unsigned long flags; 111 112 local_irq_save(flags); 113 locomolcd_dev = dev; 114 115 /* the poodle_lcd_power function is called for the first time 116 * from fs_initcall, which is before locomo is activated. 117 * We need to recall poodle_lcd_power here*/ 118 #ifdef CONFIG_MACH_POODLE 119 locomolcd_power(1); 120 #endif 121 local_irq_restore(flags); 122 return 0; 123 } 124 125 static int poodle_lcd_remove(struct locomo_dev *dev) 126 { 127 unsigned long flags; 128 local_irq_save(flags); 129 locomolcd_dev = NULL; 130 local_irq_restore(flags); 131 return 0; 132 } 133 134 static struct locomo_driver poodle_lcd_driver = { 135 .drv = { 136 .name = "locomo-backlight", 137 }, 138 .devid = LOCOMO_DEVID_BACKLIGHT, 139 .probe = poodle_lcd_probe, 140 .remove = poodle_lcd_remove, 141 }; 142 143 static int __init poodle_lcd_init(void) 144 { 145 int ret = locomo_driver_register(&poodle_lcd_driver); 146 if (ret) return ret; 147 148 #ifdef CONFIG_SA1100_COLLIE 149 sa1100fb_lcd_power = locomolcd_power; 150 #endif 151 return 0; 152 } 153 device_initcall(poodle_lcd_init); 154 155