Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight

* 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight:
backlight: Add driver for Tabletkiosk Sahara TouchIT-213 Tablet PC
backlight: da903x: Add backlight driver for DA9030/DA9034
tosa: add support for bl/lcd driver
backlight: add support for Sharp SL-6000 LCD and backlight drivers

+942 -1
+3
arch/arm/mach-pxa/include/mach/tosa.h
··· 193 193 #define TOSA_KEY_MAIL KEY_MAIL 194 194 #endif 195 195 196 + struct spi_device; 197 + extern int tosa_bl_enable(struct spi_device *spi, int enable); 198 + 196 199 #endif /* _ASM_ARCH_TOSA_H_ */
+20 -1
arch/arm/mach-pxa/tosa.c
··· 31 31 #include <linux/gpio.h> 32 32 #include <linux/pda_power.h> 33 33 #include <linux/rfkill.h> 34 + #include <linux/spi/spi.h> 34 35 35 36 #include <asm/setup.h> 36 37 #include <asm/mach-types.h> ··· 43 42 #include <mach/mmc.h> 44 43 #include <mach/udc.h> 45 44 #include <mach/tosa_bt.h> 45 + #include <mach/pxa2xx_spi.h> 46 46 47 47 #include <asm/mach/arch.h> 48 48 #include <mach/tosa.h> ··· 614 612 rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); 615 613 if (rc) 616 614 goto err_req_suspend; 617 - rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); 615 + rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v"); 618 616 if (rc) 619 617 goto err_req_l3v; 620 618 rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); ··· 774 772 .dev.platform_data = &tosa_bt_data, 775 773 }; 776 774 775 + static struct pxa2xx_spi_master pxa_ssp_master_info = { 776 + .num_chipselect = 1, 777 + }; 778 + 779 + static struct spi_board_info spi_board_info[] __initdata = { 780 + { 781 + .modalias = "tosa-lcd", 782 + // .platform_data 783 + .max_speed_hz = 28750, 784 + .bus_num = 2, 785 + .chip_select = 0, 786 + .mode = SPI_MODE_0, 787 + }, 788 + }; 777 789 778 790 static struct platform_device *devices[] __initdata = { 779 791 &tosascoop_device, ··· 841 825 pxa_set_ficp_info(&tosa_ficp_platform_data); 842 826 pxa_set_i2c_info(NULL); 843 827 platform_scoop_config = &tosa_pcmcia_config; 828 + 829 + pxa2xx_set_spi_info(2, &pxa_ssp_master_info); 830 + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); 844 831 845 832 clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL); 846 833
+32
drivers/video/backlight/Kconfig
··· 75 75 This driver provides a platform-device registered LCD power 76 76 control interface. 77 77 78 + config LCD_TOSA 79 + tristate "Sharp SL-6000 LCD Driver" 80 + depends on LCD_CLASS_DEVICE && SPI 81 + depends on MACH_TOSA 82 + default n 83 + help 84 + If you have an Sharp SL-6000 Zaurus say Y to enable a driver 85 + for its LCD. 86 + 78 87 # 79 88 # Backlight 80 89 # ··· 180 171 If you have a LCD backlight adjustable by PWM, say Y to enable 181 172 this driver. 182 173 174 + config BACKLIGHT_DA903X 175 + tristate "Backlight Driver for DA9030/DA9034 using WLED" 176 + depends on BACKLIGHT_CLASS_DEVICE && PMIC_DA903X 177 + help 178 + If you have a LCD backlight connected to the WLED output of DA9030 179 + or DA9034 WLED output, say Y here to enable this driver. 180 + 183 181 config BACKLIGHT_MBP_NVIDIA 184 182 tristate "MacBook Pro Nvidia Backlight Driver" 185 183 depends on BACKLIGHT_CLASS_DEVICE && X86 ··· 195 179 If you have an Apple Macbook Pro with Nvidia graphics hardware say Y 196 180 to enable a driver for its backlight 197 181 182 + config BACKLIGHT_TOSA 183 + tristate "Sharp SL-6000 Backlight Driver" 184 + depends on BACKLIGHT_CLASS_DEVICE && I2C 185 + depends on MACH_TOSA && LCD_TOSA 186 + default n 187 + help 188 + If you have an Sharp SL-6000 Zaurus say Y to enable a driver 189 + for its backlight 190 + 191 + config BACKLIGHT_SAHARA 192 + tristate "Tabletkiosk Sahara Touch-iT Backlight Driver" 193 + depends on BACKLIGHT_CLASS_DEVICE && X86 194 + default n 195 + help 196 + If you have a Tabletkiosk Sahara Touch-iT, say y to enable the 197 + backlight driver.
+4
drivers/video/backlight/Makefile
··· 7 7 obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o 8 8 obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o 9 9 obj-$(CONFIG_LCD_TDO24M) += tdo24m.o 10 + obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o 10 11 11 12 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 12 13 obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o ··· 18 17 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o 19 18 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 20 19 obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 20 + obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o 21 21 obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 22 + obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 23 + obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 22 24
+201
drivers/video/backlight/da903x.c
··· 1 + /* 2 + * Backlight driver for Dialog Semiconductor DA9030/DA9034 3 + * 4 + * Copyright (C) 2008 Compulab, Ltd. 5 + * Mike Rapoport <mike@compulab.co.il> 6 + * 7 + * Copyright (C) 2006-2008 Marvell International Ltd. 8 + * Eric Miao <eric.miao@marvell.com> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + */ 14 + 15 + #include <linux/kernel.h> 16 + #include <linux/init.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/fb.h> 19 + #include <linux/backlight.h> 20 + #include <linux/mfd/da903x.h> 21 + 22 + #define DA9030_WLED_CONTROL 0x25 23 + #define DA9030_WLED_CP_EN (1 << 6) 24 + #define DA9030_WLED_TRIM(x) ((x) & 0x7) 25 + 26 + #define DA9034_WLED_CONTROL1 0x3C 27 + #define DA9034_WLED_CONTROL2 0x3D 28 + 29 + #define DA9034_WLED_BOOST_EN (1 << 5) 30 + 31 + #define DA9030_MAX_BRIGHTNESS 7 32 + #define DA9034_MAX_BRIGHTNESS 0x7f 33 + 34 + struct da903x_backlight_data { 35 + struct device *da903x_dev; 36 + int id; 37 + int current_brightness; 38 + }; 39 + 40 + static int da903x_backlight_set(struct backlight_device *bl, int brightness) 41 + { 42 + struct da903x_backlight_data *data = bl_get_data(bl); 43 + struct device *dev = data->da903x_dev; 44 + uint8_t val; 45 + int ret = 0; 46 + 47 + switch (data->id) { 48 + case DA9034_ID_WLED: 49 + ret = da903x_update(dev, DA9034_WLED_CONTROL1, 50 + brightness, 0x7f); 51 + if (ret) 52 + return ret; 53 + 54 + if (data->current_brightness && brightness == 0) 55 + ret = da903x_clr_bits(dev, 56 + DA9034_WLED_CONTROL2, 57 + DA9034_WLED_BOOST_EN); 58 + 59 + if (data->current_brightness == 0 && brightness) 60 + ret = da903x_set_bits(dev, 61 + DA9034_WLED_CONTROL2, 62 + DA9034_WLED_BOOST_EN); 63 + break; 64 + case DA9030_ID_WLED: 65 + val = DA9030_WLED_TRIM(brightness); 66 + val |= brightness ? DA9030_WLED_CP_EN : 0; 67 + ret = da903x_write(dev, DA9030_WLED_CONTROL, val); 68 + break; 69 + } 70 + 71 + if (ret) 72 + return ret; 73 + 74 + data->current_brightness = brightness; 75 + return 0; 76 + } 77 + 78 + static int da903x_backlight_update_status(struct backlight_device *bl) 79 + { 80 + int brightness = bl->props.brightness; 81 + 82 + if (bl->props.power != FB_BLANK_UNBLANK) 83 + brightness = 0; 84 + 85 + if (bl->props.fb_blank != FB_BLANK_UNBLANK) 86 + brightness = 0; 87 + 88 + return da903x_backlight_set(bl, brightness); 89 + } 90 + 91 + static int da903x_backlight_get_brightness(struct backlight_device *bl) 92 + { 93 + struct da903x_backlight_data *data = bl_get_data(bl); 94 + return data->current_brightness; 95 + } 96 + 97 + static struct backlight_ops da903x_backlight_ops = { 98 + .update_status = da903x_backlight_update_status, 99 + .get_brightness = da903x_backlight_get_brightness, 100 + }; 101 + 102 + static int da903x_backlight_probe(struct platform_device *pdev) 103 + { 104 + struct da903x_backlight_data *data; 105 + struct backlight_device *bl; 106 + int max_brightness; 107 + 108 + data = kzalloc(sizeof(*data), GFP_KERNEL); 109 + if (data == NULL) 110 + return -ENOMEM; 111 + 112 + switch (pdev->id) { 113 + case DA9030_ID_WLED: 114 + max_brightness = DA9030_MAX_BRIGHTNESS; 115 + break; 116 + case DA9034_ID_WLED: 117 + max_brightness = DA9034_MAX_BRIGHTNESS; 118 + break; 119 + default: 120 + dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", 121 + pdev->id); 122 + return -EINVAL; 123 + } 124 + 125 + data->id = pdev->id; 126 + data->da903x_dev = pdev->dev.parent; 127 + data->current_brightness = 0; 128 + 129 + bl = backlight_device_register(pdev->name, data->da903x_dev, 130 + data, &da903x_backlight_ops); 131 + if (IS_ERR(bl)) { 132 + dev_err(&pdev->dev, "failed to register backlight\n"); 133 + return PTR_ERR(bl); 134 + } 135 + 136 + bl->props.max_brightness = max_brightness; 137 + bl->props.brightness = max_brightness; 138 + 139 + platform_set_drvdata(pdev, bl); 140 + backlight_update_status(bl); 141 + return 0; 142 + } 143 + 144 + static int da903x_backlight_remove(struct platform_device *pdev) 145 + { 146 + struct backlight_device *bl = platform_get_drvdata(pdev); 147 + struct da903x_backlight_data *data = bl_get_data(bl); 148 + 149 + backlight_device_unregister(bl); 150 + kfree(data); 151 + return 0; 152 + } 153 + 154 + #ifdef CONFIG_PM 155 + static int da903x_backlight_suspend(struct platform_device *pdev, 156 + pm_message_t state) 157 + { 158 + struct backlight_device *bl = platform_get_drvdata(pdev); 159 + return da903x_backlight_set(bl, 0); 160 + } 161 + 162 + static int da903x_backlight_resume(struct platform_device *pdev) 163 + { 164 + struct backlight_device *bl = platform_get_drvdata(pdev); 165 + 166 + backlight_update_status(bl); 167 + return 0; 168 + } 169 + #else 170 + #define da903x_backlight_suspend NULL 171 + #define da903x_backlight_resume NULL 172 + #endif 173 + 174 + static struct platform_driver da903x_backlight_driver = { 175 + .driver = { 176 + .name = "da903x-backlight", 177 + .owner = THIS_MODULE, 178 + }, 179 + .probe = da903x_backlight_probe, 180 + .remove = da903x_backlight_remove, 181 + .suspend = da903x_backlight_suspend, 182 + .resume = da903x_backlight_resume, 183 + }; 184 + 185 + static int __init da903x_backlight_init(void) 186 + { 187 + return platform_driver_register(&da903x_backlight_driver); 188 + } 189 + module_init(da903x_backlight_init); 190 + 191 + static void __exit da903x_backlight_exit(void) 192 + { 193 + platform_driver_unregister(&da903x_backlight_driver); 194 + } 195 + module_exit(da903x_backlight_exit); 196 + 197 + MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034"); 198 + MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" 199 + "Mike Rapoport <mike@compulab.co.il>"); 200 + MODULE_LICENSE("GPL"); 201 + MODULE_ALIAS("platform:da903x-backlight");
+204
drivers/video/backlight/kb3886_bl.c
··· 1 + /* 2 + * Backlight Driver for the KB3886 Backlight 3 + * 4 + * Copyright (c) 2007-2008 Claudio Nieder 5 + * 6 + * Based on corgi_bl.c by Richard Purdie and kb3886 driver by Robert Woerle 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + */ 13 + 14 + #include <linux/module.h> 15 + #include <linux/kernel.h> 16 + #include <linux/init.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/mutex.h> 19 + #include <linux/fb.h> 20 + #include <linux/backlight.h> 21 + #include <linux/delay.h> 22 + #include <linux/dmi.h> 23 + 24 + #define KB3886_PARENT 0x64 25 + #define KB3886_IO 0x60 26 + #define KB3886_ADC_DAC_PWM 0xC4 27 + #define KB3886_PWM0_WRITE 0x81 28 + #define KB3886_PWM0_READ 0x41 29 + 30 + static DEFINE_MUTEX(bl_mutex); 31 + 32 + static void kb3886_bl_set_intensity(int intensity) 33 + { 34 + mutex_lock(&bl_mutex); 35 + intensity = intensity&0xff; 36 + outb(KB3886_ADC_DAC_PWM, KB3886_PARENT); 37 + msleep(10); 38 + outb(KB3886_PWM0_WRITE, KB3886_IO); 39 + msleep(10); 40 + outb(intensity, KB3886_IO); 41 + mutex_unlock(&bl_mutex); 42 + } 43 + 44 + struct kb3886bl_machinfo { 45 + int max_intensity; 46 + int default_intensity; 47 + int limit_mask; 48 + void (*set_bl_intensity)(int intensity); 49 + }; 50 + 51 + static struct kb3886bl_machinfo kb3886_bl_machinfo = { 52 + .max_intensity = 0xff, 53 + .default_intensity = 0xa0, 54 + .limit_mask = 0x7f, 55 + .set_bl_intensity = kb3886_bl_set_intensity, 56 + }; 57 + 58 + static struct platform_device kb3886bl_device = { 59 + .name = "kb3886-bl", 60 + .dev = { 61 + .platform_data = &kb3886_bl_machinfo, 62 + }, 63 + .id = -1, 64 + }; 65 + 66 + static struct platform_device *devices[] __initdata = { 67 + &kb3886bl_device, 68 + }; 69 + 70 + /* 71 + * Back to driver 72 + */ 73 + 74 + static int kb3886bl_intensity; 75 + static struct backlight_device *kb3886_backlight_device; 76 + static struct kb3886bl_machinfo *bl_machinfo; 77 + 78 + static unsigned long kb3886bl_flags; 79 + #define KB3886BL_SUSPENDED 0x01 80 + 81 + static struct dmi_system_id __initdata kb3886bl_device_table[] = { 82 + { 83 + .ident = "Sahara Touch-iT", 84 + .matches = { 85 + DMI_MATCH(DMI_SYS_VENDOR, "SDV"), 86 + DMI_MATCH(DMI_PRODUCT_NAME, "iTouch T201"), 87 + }, 88 + }, 89 + { } 90 + }; 91 + 92 + static int kb3886bl_send_intensity(struct backlight_device *bd) 93 + { 94 + int intensity = bd->props.brightness; 95 + 96 + if (bd->props.power != FB_BLANK_UNBLANK) 97 + intensity = 0; 98 + if (bd->props.fb_blank != FB_BLANK_UNBLANK) 99 + intensity = 0; 100 + if (kb3886bl_flags & KB3886BL_SUSPENDED) 101 + intensity = 0; 102 + 103 + bl_machinfo->set_bl_intensity(intensity); 104 + 105 + kb3886bl_intensity = intensity; 106 + return 0; 107 + } 108 + 109 + #ifdef CONFIG_PM 110 + static int kb3886bl_suspend(struct platform_device *pdev, pm_message_t state) 111 + { 112 + struct backlight_device *bd = platform_get_drvdata(pdev); 113 + 114 + kb3886bl_flags |= KB3886BL_SUSPENDED; 115 + backlight_update_status(bd); 116 + return 0; 117 + } 118 + 119 + static int kb3886bl_resume(struct platform_device *pdev) 120 + { 121 + struct backlight_device *bd = platform_get_drvdata(pdev); 122 + 123 + kb3886bl_flags &= ~KB3886BL_SUSPENDED; 124 + backlight_update_status(bd); 125 + return 0; 126 + } 127 + #else 128 + #define kb3886bl_suspend NULL 129 + #define kb3886bl_resume NULL 130 + #endif 131 + 132 + static int kb3886bl_get_intensity(struct backlight_device *bd) 133 + { 134 + return kb3886bl_intensity; 135 + } 136 + 137 + static struct backlight_ops kb3886bl_ops = { 138 + .get_brightness = kb3886bl_get_intensity, 139 + .update_status = kb3886bl_send_intensity, 140 + }; 141 + 142 + static int kb3886bl_probe(struct platform_device *pdev) 143 + { 144 + struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; 145 + 146 + bl_machinfo = machinfo; 147 + if (!machinfo->limit_mask) 148 + machinfo->limit_mask = -1; 149 + 150 + kb3886_backlight_device = backlight_device_register("kb3886-bl", 151 + &pdev->dev, NULL, &kb3886bl_ops); 152 + if (IS_ERR(kb3886_backlight_device)) 153 + return PTR_ERR(kb3886_backlight_device); 154 + 155 + platform_set_drvdata(pdev, kb3886_backlight_device); 156 + 157 + kb3886_backlight_device->props.max_brightness = machinfo->max_intensity; 158 + kb3886_backlight_device->props.power = FB_BLANK_UNBLANK; 159 + kb3886_backlight_device->props.brightness = machinfo->default_intensity; 160 + backlight_update_status(kb3886_backlight_device); 161 + 162 + return 0; 163 + } 164 + 165 + static int kb3886bl_remove(struct platform_device *pdev) 166 + { 167 + struct backlight_device *bd = platform_get_drvdata(pdev); 168 + 169 + backlight_device_unregister(bd); 170 + 171 + return 0; 172 + } 173 + 174 + static struct platform_driver kb3886bl_driver = { 175 + .probe = kb3886bl_probe, 176 + .remove = kb3886bl_remove, 177 + .suspend = kb3886bl_suspend, 178 + .resume = kb3886bl_resume, 179 + .driver = { 180 + .name = "kb3886-bl", 181 + }, 182 + }; 183 + 184 + static int __init kb3886_init(void) 185 + { 186 + if (!dmi_check_system(kb3886bl_device_table)) 187 + return -ENODEV; 188 + 189 + platform_add_devices(devices, ARRAY_SIZE(devices)); 190 + return platform_driver_register(&kb3886bl_driver); 191 + } 192 + 193 + static void __exit kb3886_exit(void) 194 + { 195 + platform_driver_unregister(&kb3886bl_driver); 196 + } 197 + 198 + module_init(kb3886_init); 199 + module_exit(kb3886_exit); 200 + 201 + MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>"); 202 + MODULE_DESCRIPTION("Tabletkiosk Sahara Touch-iT Backlight Driver"); 203 + MODULE_LICENSE("GPL"); 204 + MODULE_ALIAS("dmi:*:svnSDV:pniTouchT201:*");
+198
drivers/video/backlight/tosa_bl.c
··· 1 + /* 2 + * LCD / Backlight control code for Sharp SL-6000x (tosa) 3 + * 4 + * Copyright (c) 2005 Dirk Opfer 5 + * Copyright (c) 2007,2008 Dmitry Baryshkov 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/device.h> 16 + #include <linux/spi/spi.h> 17 + #include <linux/i2c.h> 18 + #include <linux/gpio.h> 19 + #include <linux/fb.h> 20 + #include <linux/backlight.h> 21 + 22 + #include <asm/mach/sharpsl_param.h> 23 + 24 + #include <mach/tosa.h> 25 + 26 + #define COMADJ_DEFAULT 97 27 + 28 + #define DAC_CH1 0 29 + #define DAC_CH2 1 30 + 31 + struct tosa_bl_data { 32 + struct i2c_client *i2c; 33 + struct backlight_device *bl; 34 + 35 + int comadj; 36 + }; 37 + 38 + static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness) 39 + { 40 + struct spi_device *spi = data->i2c->dev.platform_data; 41 + 42 + i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj); 43 + 44 + /* SetBacklightDuty */ 45 + i2c_smbus_write_byte_data(data->i2c, DAC_CH2, (u8)(brightness & 0xff)); 46 + 47 + /* SetBacklightVR */ 48 + gpio_set_value(TOSA_GPIO_BL_C20MA, brightness & 0x100); 49 + 50 + tosa_bl_enable(spi, brightness); 51 + } 52 + 53 + static int tosa_bl_update_status(struct backlight_device *dev) 54 + { 55 + struct backlight_properties *props = &dev->props; 56 + struct tosa_bl_data *data = dev_get_drvdata(&dev->dev); 57 + int power = max(props->power, props->fb_blank); 58 + int brightness = props->brightness; 59 + 60 + if (power) 61 + brightness = 0; 62 + 63 + tosa_bl_set_backlight(data, brightness); 64 + 65 + return 0; 66 + } 67 + 68 + static int tosa_bl_get_brightness(struct backlight_device *dev) 69 + { 70 + struct backlight_properties *props = &dev->props; 71 + 72 + return props->brightness; 73 + } 74 + 75 + static struct backlight_ops bl_ops = { 76 + .get_brightness = tosa_bl_get_brightness, 77 + .update_status = tosa_bl_update_status, 78 + }; 79 + 80 + static int __devinit tosa_bl_probe(struct i2c_client *client, 81 + const struct i2c_device_id *id) 82 + { 83 + struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL); 84 + int ret = 0; 85 + if (!data) 86 + return -ENOMEM; 87 + 88 + data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; 89 + 90 + ret = gpio_request(TOSA_GPIO_BL_C20MA, "backlight"); 91 + if (ret) { 92 + dev_dbg(&data->bl->dev, "Unable to request gpio!\n"); 93 + goto err_gpio_bl; 94 + } 95 + ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0); 96 + if (ret) 97 + goto err_gpio_dir; 98 + 99 + i2c_set_clientdata(client, data); 100 + data->i2c = client; 101 + 102 + data->bl = backlight_device_register("tosa-bl", &client->dev, 103 + data, &bl_ops); 104 + if (IS_ERR(data->bl)) { 105 + ret = PTR_ERR(data->bl); 106 + goto err_reg; 107 + } 108 + 109 + data->bl->props.brightness = 69; 110 + data->bl->props.max_brightness = 512 - 1; 111 + data->bl->props.power = FB_BLANK_UNBLANK; 112 + 113 + backlight_update_status(data->bl); 114 + 115 + return 0; 116 + 117 + err_reg: 118 + data->bl = NULL; 119 + i2c_set_clientdata(client, NULL); 120 + err_gpio_dir: 121 + gpio_free(TOSA_GPIO_BL_C20MA); 122 + err_gpio_bl: 123 + kfree(data); 124 + return ret; 125 + } 126 + 127 + static int __devexit tosa_bl_remove(struct i2c_client *client) 128 + { 129 + struct tosa_bl_data *data = i2c_get_clientdata(client); 130 + 131 + backlight_device_unregister(data->bl); 132 + data->bl = NULL; 133 + i2c_set_clientdata(client, NULL); 134 + 135 + gpio_free(TOSA_GPIO_BL_C20MA); 136 + 137 + kfree(data); 138 + 139 + return 0; 140 + } 141 + 142 + #ifdef CONFIG_PM 143 + static int tosa_bl_suspend(struct i2c_client *client, pm_message_t pm) 144 + { 145 + struct tosa_bl_data *data = i2c_get_clientdata(client); 146 + 147 + tosa_bl_set_backlight(data, 0); 148 + 149 + return 0; 150 + } 151 + 152 + static int tosa_bl_resume(struct i2c_client *client) 153 + { 154 + struct tosa_bl_data *data = i2c_get_clientdata(client); 155 + 156 + backlight_update_status(data->bl); 157 + return 0; 158 + } 159 + #else 160 + #define tosa_bl_suspend NULL 161 + #define tosa_bl_resume NULL 162 + #endif 163 + 164 + static const struct i2c_device_id tosa_bl_id[] = { 165 + { "tosa-bl", 0 }, 166 + { }, 167 + }; 168 + 169 + 170 + static struct i2c_driver tosa_bl_driver = { 171 + .driver = { 172 + .name = "tosa-bl", 173 + .owner = THIS_MODULE, 174 + }, 175 + .probe = tosa_bl_probe, 176 + .remove = __devexit_p(tosa_bl_remove), 177 + .suspend = tosa_bl_suspend, 178 + .resume = tosa_bl_resume, 179 + .id_table = tosa_bl_id, 180 + }; 181 + 182 + static int __init tosa_bl_init(void) 183 + { 184 + return i2c_add_driver(&tosa_bl_driver); 185 + } 186 + 187 + static void __exit tosa_bl_exit(void) 188 + { 189 + i2c_del_driver(&tosa_bl_driver); 190 + } 191 + 192 + module_init(tosa_bl_init); 193 + module_exit(tosa_bl_exit); 194 + 195 + MODULE_AUTHOR("Dmitry Baryshkov"); 196 + MODULE_LICENSE("GPL v2"); 197 + MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); 198 +
+280
drivers/video/backlight/tosa_lcd.c
··· 1 + /* 2 + * LCD / Backlight control code for Sharp SL-6000x (tosa) 3 + * 4 + * Copyright (c) 2005 Dirk Opfer 5 + * Copyright (c) 2007,2008 Dmitry Baryshkov 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/device.h> 16 + #include <linux/spi/spi.h> 17 + #include <linux/i2c.h> 18 + #include <linux/gpio.h> 19 + #include <linux/delay.h> 20 + #include <linux/lcd.h> 21 + #include <linux/fb.h> 22 + 23 + #include <asm/mach/sharpsl_param.h> 24 + 25 + #include <mach/tosa.h> 26 + 27 + #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) 28 + 29 + #define TG_REG0_VQV 0x0001 30 + #define TG_REG0_COLOR 0x0002 31 + #define TG_REG0_UD 0x0004 32 + #define TG_REG0_LR 0x0008 33 + 34 + #define DAC_BASE 0x4e 35 + 36 + struct tosa_lcd_data { 37 + struct spi_device *spi; 38 + struct lcd_device *lcd; 39 + struct i2c_client *i2c; 40 + 41 + int lcd_power; 42 + }; 43 + 44 + static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data) 45 + { 46 + u8 buf[1]; 47 + struct spi_message msg; 48 + struct spi_transfer xfer = { 49 + .len = 1, 50 + .cs_change = 1, 51 + .tx_buf = buf, 52 + }; 53 + 54 + buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f); 55 + spi_message_init(&msg); 56 + spi_message_add_tail(&xfer, &msg); 57 + 58 + return spi_sync(spi, &msg); 59 + } 60 + 61 + int tosa_bl_enable(struct spi_device *spi, int enable) 62 + { 63 + /* bl_enable GP04=1 otherwise GP04=0*/ 64 + return tosa_tg_send(spi, TG_GPODR2, enable? 0x01 : 0x00); 65 + } 66 + EXPORT_SYMBOL(tosa_bl_enable); 67 + 68 + static void tosa_lcd_tg_init(struct tosa_lcd_data *data) 69 + { 70 + /* TG on */ 71 + gpio_set_value(TOSA_GPIO_TG_ON, 0); 72 + 73 + mdelay(60); 74 + 75 + /* delayed 0clk TCTL signal for VGA */ 76 + tosa_tg_send(data->spi, TG_TPOSCTL, 0x00); 77 + /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */ 78 + tosa_tg_send(data->spi, TG_GPOSR, 0x02); 79 + } 80 + 81 + static void tosa_lcd_tg_on(struct tosa_lcd_data *data) 82 + { 83 + struct spi_device *spi = data->spi; 84 + const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; 85 + tosa_tg_send(spi, TG_PNLCTL, value | TG_REG0_VQV); /* this depends on mode */ 86 + 87 + /* TG LCD pannel power up */ 88 + tosa_tg_send(spi, TG_PINICTL,0x4); 89 + mdelay(50); 90 + 91 + /* TG LCD GVSS */ 92 + tosa_tg_send(spi, TG_PINICTL,0x0); 93 + 94 + if (!data->i2c) { 95 + /* after the pannel is powered up the first time, we can access the i2c bus */ 96 + /* so probe for the DAC */ 97 + struct i2c_adapter *adap = i2c_get_adapter(0); 98 + struct i2c_board_info info = { 99 + .type = "tosa-bl", 100 + .addr = DAC_BASE, 101 + .platform_data = data->spi, 102 + }; 103 + data->i2c = i2c_new_device(adap, &info); 104 + } 105 + } 106 + 107 + static void tosa_lcd_tg_off(struct tosa_lcd_data *data) 108 + { 109 + struct spi_device *spi = data->spi; 110 + 111 + /* TG LCD VHSA off */ 112 + tosa_tg_send(spi, TG_PINICTL,0x4); 113 + mdelay(50); 114 + 115 + /* TG LCD signal off */ 116 + tosa_tg_send(spi, TG_PINICTL,0x6); 117 + mdelay(50); 118 + 119 + /* TG Off */ 120 + gpio_set_value(TOSA_GPIO_TG_ON, 1); 121 + mdelay(100); 122 + } 123 + 124 + int tosa_lcd_set_power(struct lcd_device *lcd, int power) 125 + { 126 + struct tosa_lcd_data *data = lcd_get_data(lcd); 127 + 128 + if (POWER_IS_ON(power) && !POWER_IS_ON(data->lcd_power)) 129 + tosa_lcd_tg_on(data); 130 + 131 + if (!POWER_IS_ON(power) && POWER_IS_ON(data->lcd_power)) 132 + tosa_lcd_tg_off(data); 133 + 134 + data->lcd_power = power; 135 + return 0; 136 + } 137 + 138 + static int tosa_lcd_get_power(struct lcd_device *lcd) 139 + { 140 + struct tosa_lcd_data *data = lcd_get_data(lcd); 141 + 142 + return data->lcd_power; 143 + } 144 + 145 + static struct lcd_ops tosa_lcd_ops = { 146 + .set_power = tosa_lcd_set_power, 147 + .get_power = tosa_lcd_get_power, 148 + }; 149 + 150 + static int __devinit tosa_lcd_probe(struct spi_device *spi) 151 + { 152 + int ret; 153 + struct tosa_lcd_data *data; 154 + 155 + data = kzalloc(sizeof(struct tosa_lcd_data), GFP_KERNEL); 156 + if (!data) 157 + return -ENOMEM; 158 + 159 + /* 160 + * bits_per_word cannot be configured in platform data 161 + */ 162 + spi->bits_per_word = 8; 163 + 164 + ret = spi_setup(spi); 165 + if (ret < 0) 166 + goto err_spi; 167 + 168 + data->spi = spi; 169 + dev_set_drvdata(&spi->dev, data); 170 + 171 + ret = gpio_request(TOSA_GPIO_TG_ON, "tg #pwr"); 172 + if (ret < 0) 173 + goto err_gpio_tg; 174 + 175 + mdelay(60); 176 + 177 + ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0); 178 + if (ret < 0) 179 + goto err_gpio_dir; 180 + 181 + mdelay(60); 182 + tosa_lcd_tg_init(data); 183 + 184 + tosa_lcd_tg_on(data); 185 + 186 + data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data, 187 + &tosa_lcd_ops); 188 + 189 + if (IS_ERR(data->lcd)) { 190 + ret = PTR_ERR(data->lcd); 191 + data->lcd = NULL; 192 + goto err_register; 193 + } 194 + 195 + return 0; 196 + 197 + err_register: 198 + tosa_lcd_tg_off(data); 199 + err_gpio_dir: 200 + gpio_free(TOSA_GPIO_TG_ON); 201 + err_gpio_tg: 202 + dev_set_drvdata(&spi->dev, NULL); 203 + err_spi: 204 + kfree(data); 205 + return ret; 206 + } 207 + 208 + static int __devexit tosa_lcd_remove(struct spi_device *spi) 209 + { 210 + struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); 211 + 212 + lcd_device_unregister(data->lcd); 213 + 214 + if (data->i2c) 215 + i2c_unregister_device(data->i2c); 216 + 217 + tosa_lcd_tg_off(data); 218 + 219 + gpio_free(TOSA_GPIO_TG_ON); 220 + dev_set_drvdata(&spi->dev, NULL); 221 + kfree(data); 222 + 223 + return 0; 224 + } 225 + 226 + #ifdef CONFIG_PM 227 + static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state) 228 + { 229 + struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); 230 + 231 + tosa_lcd_tg_off(data); 232 + 233 + return 0; 234 + } 235 + 236 + static int tosa_lcd_resume(struct spi_device *spi) 237 + { 238 + struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev); 239 + 240 + tosa_lcd_tg_init(data); 241 + if (POWER_IS_ON(data->lcd_power)) 242 + tosa_lcd_tg_on(data); 243 + else 244 + tosa_lcd_tg_off(data); 245 + 246 + return 0; 247 + } 248 + #else 249 + #define tosa_lcd_suspend NULL 250 + #define tosa_lcd_reume NULL 251 + #endif 252 + 253 + static struct spi_driver tosa_lcd_driver = { 254 + .driver = { 255 + .name = "tosa-lcd", 256 + .owner = THIS_MODULE, 257 + }, 258 + .probe = tosa_lcd_probe, 259 + .remove = __devexit_p(tosa_lcd_remove), 260 + .suspend = tosa_lcd_suspend, 261 + .resume = tosa_lcd_resume, 262 + }; 263 + 264 + static int __init tosa_lcd_init(void) 265 + { 266 + return spi_register_driver(&tosa_lcd_driver); 267 + } 268 + 269 + static void __exit tosa_lcd_exit(void) 270 + { 271 + spi_unregister_driver(&tosa_lcd_driver); 272 + } 273 + 274 + module_init(tosa_lcd_init); 275 + module_exit(tosa_lcd_exit); 276 + 277 + MODULE_AUTHOR("Dmitry Baryshkov"); 278 + MODULE_LICENSE("GPL v2"); 279 + MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); 280 +