diff options
Diffstat (limited to 'drivers/video')
| -rw-r--r-- | drivers/video/backlight/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/video/backlight/Makefile | 2 | ||||
| -rw-r--r-- | drivers/video/backlight/jornada720_bl.c | 161 | ||||
| -rw-r--r-- | drivers/video/backlight/jornada720_lcd.c | 153 | ||||
| -rw-r--r-- | drivers/video/backlight/mbp_nvidia_bl.c | 191 | ||||
| -rw-r--r-- | drivers/video/backlight/pwm_bl.c | 4 | 
6 files changed, 491 insertions, 38 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 72facb9eb7db..f9d19be05540 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -84,6 +84,15 @@ config LCD_TOSA  	  If you have an Sharp SL-6000 Zaurus say Y to enable a driver  	  for its LCD. +config LCD_HP700 +	tristate "HP Jornada 700 series LCD Driver" +	depends on LCD_CLASS_DEVICE +	depends on SA1100_JORNADA720_SSP && !PREEMPT +	default y +	help +	  If you have an HP Jornada 700 series handheld (710/720/728) +	  say Y to enable LCD control driver. +  #  # Backlight  # @@ -157,6 +166,15 @@ config BACKLIGHT_HP680  	  If you have a HP Jornada 680, say y to enable the  	  backlight driver. +config BACKLIGHT_HP700 +	tristate "HP Jornada 700 series Backlight Driver" +	depends on BACKLIGHT_CLASS_DEVICE +	depends on SA1100_JORNADA720_SSP && !PREEMPT +	default y +	help +	  If you have an HP Jornada 700 series, +	  say Y to include backlight control driver. +  config BACKLIGHT_PROGEAR  	tristate "Frontpath ProGear Backlight Driver"  	depends on BACKLIGHT_CLASS_DEVICE && PCI && X86 diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 63d759498165..4eb178c1d684 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -2,6 +2,7 @@  obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o  obj-$(CONFIG_LCD_CORGI)		   += corgi_lcd.o +obj-$(CONFIG_LCD_HP700)		   += jornada720_lcd.o  obj-$(CONFIG_LCD_LTV350QV)	   += ltv350qv.o  obj-$(CONFIG_LCD_ILI9320)	   += ili9320.o  obj-$(CONFIG_LCD_PLATFORM)	   += platform_lcd.o @@ -12,6 +13,7 @@ obj-$(CONFIG_LCD_TOSA)		   += tosa_lcd.o  obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o  obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o  obj-$(CONFIG_BACKLIGHT_GENERIC)	+= generic_bl.o +obj-$(CONFIG_BACKLIGHT_HP700)	+= jornada720_bl.o  obj-$(CONFIG_BACKLIGHT_HP680)	+= hp680_bl.o  obj-$(CONFIG_BACKLIGHT_LOCOMO)	+= locomolcd.o  obj-$(CONFIG_BACKLIGHT_OMAP1)	+= omap1_bl.o diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c new file mode 100644 index 000000000000..c3ebb6b41ce1 --- /dev/null +++ b/drivers/video/backlight/jornada720_bl.c @@ -0,0 +1,161 @@ +/* + * + * Backlight driver for HP Jornada 700 series (710/720/728) + * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 or any later version as published by the Free Software Foundation. + * + */ + +#include <linux/backlight.h> +#include <linux/device.h> +#include <linux/fb.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <mach/jornada720.h> +#include <mach/hardware.h> + +#include <video/s1d13xxxfb.h> + +#define BL_MAX_BRIGHT	255 +#define BL_DEF_BRIGHT	25 + +static int jornada_bl_get_brightness(struct backlight_device *bd) +{ +	int ret; + +	/* check if backlight is on */ +	if (!(PPSR & PPC_LDD1)) +		return 0; + +	jornada_ssp_start(); + +	/* cmd should return txdummy */ +	ret = jornada_ssp_byte(GETBRIGHTNESS); + +	if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) { +		printk(KERN_ERR "bl : get brightness timeout\n"); +		jornada_ssp_end(); +		return -ETIMEDOUT; +	} else /* exchange txdummy for value */ +		ret = jornada_ssp_byte(TXDUMMY); + +	jornada_ssp_end(); + +	return (BL_MAX_BRIGHT - ret); +} + +static int jornada_bl_update_status(struct backlight_device *bd) +{ +	int ret = 0; + +	jornada_ssp_start(); + +	/* If backlight is off then really turn it off */ +	if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) { +		ret = jornada_ssp_byte(BRIGHTNESSOFF); +		if (ret != TXDUMMY) { +			printk(KERN_INFO "bl : brightness off timeout\n"); +			/* turn off backlight */ +			PPSR &= ~PPC_LDD1; +			PPDR |= PPC_LDD1; +			ret = -ETIMEDOUT; +		} +	} else  /* turn on backlight */ +		PPSR |= PPC_LDD1; + +		/* send command to our mcu */ +		if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) { +			printk(KERN_INFO "bl : failed to set brightness\n"); +			ret = -ETIMEDOUT; +			goto out +		} + +		/* at this point we expect that the mcu has accepted +		   our command and is waiting for our new value +		   please note that maximum brightness is 255, +		   but due to physical layout it is equal to 0, so we simply +		   invert the value (MAX VALUE - NEW VALUE). */ +		if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) { +			printk(KERN_ERR "bl : set brightness failed\n"); +			ret = -ETIMEDOUT; +		} + +		/* If infact we get an TXDUMMY as output we are happy and dont +		   make any further comments about it */ +out: +	jornada_ssp_end(); + +	return ret; +} + +static struct backlight_ops jornada_bl_ops = { +	.get_brightness = jornada_bl_get_brightness, +	.update_status = jornada_bl_update_status, +	.options = BL_CORE_SUSPENDRESUME, +}; + +static int jornada_bl_probe(struct platform_device *pdev) +{ +	int ret; +	struct backlight_device *bd; + +	bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops); + +	if (IS_ERR(bd)) { +		ret = PTR_ERR(bd); +		printk(KERN_ERR "bl : failed to register device, err=%x\n", ret); +		return ret; +	} + +	bd->props.power = FB_BLANK_UNBLANK; +	bd->props.brightness = BL_DEF_BRIGHT; +	/* note. make sure max brightness is set otherwise +	   you will get seemingly non-related errors when +	   trying to change brightness */ +	bd->props.max_brightness = BL_MAX_BRIGHT; +	jornada_bl_update_status(bd); + +	platform_set_drvdata(pdev, bd); +	printk(KERN_INFO "HP Jornada 700 series backlight driver\n"); + +	return 0; +} + +static int jornada_bl_remove(struct platform_device *pdev) +{ +	struct backlight_device *bd = platform_get_drvdata(pdev); + +	backlight_device_unregister(bd); + +	return 0; +} + +static struct platform_driver jornada_bl_driver = { +	.probe		= jornada_bl_probe, +	.remove		= jornada_bl_remove, +	.driver	= { +		.name	= "jornada_bl", +	}, +}; + +int __init jornada_bl_init(void) +{ +	return platform_driver_register(&jornada_bl_driver); +} + +void __exit jornada_bl_exit(void) +{ +	platform_driver_unregister(&jornada_bl_driver); +} + +MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>"); +MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver"); +MODULE_LICENSE("GPL"); + +module_init(jornada_bl_init); +module_exit(jornada_bl_exit); diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c new file mode 100644 index 000000000000..cbbb167fd268 --- /dev/null +++ b/drivers/video/backlight/jornada720_lcd.c @@ -0,0 +1,153 @@ +/* + * + * LCD driver for HP Jornada 700 series (710/720/728) + * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 or any later version as published by the Free Software Foundation. + * + */ + +#include <linux/device.h> +#include <linux/fb.h> +#include <linux/kernel.h> +#include <linux/lcd.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#include <mach/jornada720.h> +#include <mach/hardware.h> + +#include <video/s1d13xxxfb.h> + +#define LCD_MAX_CONTRAST	0xff +#define LCD_DEF_CONTRAST	0x80 + +static int jornada_lcd_get_power(struct lcd_device *dev) +{ +	/* LDD2 in PPC = LCD POWER */ +	if (PPSR & PPC_LDD2) +		return FB_BLANK_UNBLANK;	/* PW ON */ +	else +		return FB_BLANK_POWERDOWN;	/* PW OFF */ +} + +static int jornada_lcd_get_contrast(struct lcd_device *dev) +{ +	int ret; + +	if (jornada_lcd_get_power(dev) != FB_BLANK_UNBLANK) +		return 0; + +	jornada_ssp_start(); + +	if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) { +		printk(KERN_ERR "lcd: get contrast failed\n"); +		jornada_ssp_end(); +		return -ETIMEDOUT; +	} else { +		ret = jornada_ssp_byte(TXDUMMY); +		jornada_ssp_end(); +		return ret; +	} +} + +static int jornada_lcd_set_contrast(struct lcd_device *dev, int value) +{ +	int ret; + +	jornada_ssp_start(); + +	/* start by sending our set contrast cmd to mcu */ +	ret = jornada_ssp_byte(SETCONTRAST); + +	/* push the new value */ +	if (jornada_ssp_byte(value) != TXDUMMY) { +		printk(KERN_ERR "lcd : set contrast failed\n"); +		jornada_ssp_end(); +		return -ETIMEDOUT; +	} + +	/* if we get here we can assume everything went well */ +	jornada_ssp_end(); + +	return 0; +} + +static int jornada_lcd_set_power(struct lcd_device *dev, int power) +{ +	if (power != FB_BLANK_UNBLANK) { +		PPSR &= ~PPC_LDD2; +		PPDR |= PPC_LDD2; +	} else +		PPSR |= PPC_LDD2; + +	return 0; +} + +static struct lcd_ops jornada_lcd_props = { +	.get_contrast = jornada_lcd_get_contrast, +	.set_contrast = jornada_lcd_set_contrast, +	.get_power = jornada_lcd_get_power, +	.set_power = jornada_lcd_set_power, +}; + +static int jornada_lcd_probe(struct platform_device *pdev) +{ +	struct lcd_device *lcd_device; +	int ret; + +	lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props); + +	if (IS_ERR(lcd_device)) { +		ret = PTR_ERR(lcd_device); +		printk(KERN_ERR "lcd : failed to register device\n"); +		return ret; +	} + +	platform_set_drvdata(pdev, lcd_device); + +	/* lets set our default values */ +	jornada_lcd_set_contrast(lcd_device, LCD_DEF_CONTRAST); +	jornada_lcd_set_power(lcd_device, FB_BLANK_UNBLANK); +	/* give it some time to startup */ +	msleep(100); + +	return 0; +} + +static int jornada_lcd_remove(struct platform_device *pdev) +{ +	struct lcd_device *lcd_device = platform_get_drvdata(pdev); + +	lcd_device_unregister(lcd_device); + +	return 0; +} + +static struct platform_driver jornada_lcd_driver = { +	.probe	= jornada_lcd_probe, +	.remove	= jornada_lcd_remove, +	.driver	= { +		.name	= "jornada_lcd", +	}, +}; + +int __init jornada_lcd_init(void) +{ +	return platform_driver_register(&jornada_lcd_driver); +} + +void __exit jornada_lcd_exit(void) +{ +	platform_driver_unregister(&jornada_lcd_driver); +} + +MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); +MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver"); +MODULE_LICENSE("GPL"); + +module_init(jornada_lcd_init); +module_exit(jornada_lcd_exit); diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 65864c500455..3bb4c0a50c62 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -27,73 +27,192 @@  static struct backlight_device *mbp_backlight_device; -static struct dmi_system_id __initdata mbp_device_table[] = { +/* Structure to be passed to the DMI_MATCH function. */ +struct dmi_match_data { +	/* I/O resource to allocate. */ +	unsigned long iostart; +	unsigned long iolen; +	/* Backlight operations structure. */ +	struct backlight_ops backlight_ops; +}; + +/* Module parameters. */ +static int debug; +module_param_named(debug, debug, int, 0644); +MODULE_PARM_DESC(debug, "Set to one to enable debugging messages."); + +/* + * Implementation for MacBooks with Intel chipset. + */ +static int intel_chipset_send_intensity(struct backlight_device *bd) +{ +	int intensity = bd->props.brightness; + +	if (debug) +		printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n", +		       intensity); + +	outb(0x04 | (intensity << 4), 0xb3); +	outb(0xbf, 0xb2); +	return 0; +} + +static int intel_chipset_get_intensity(struct backlight_device *bd) +{ +	int intensity; + +	outb(0x03, 0xb3); +	outb(0xbf, 0xb2); +	intensity = inb(0xb3) >> 4; + +	if (debug) +		printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n", +		       intensity); + +	return intensity; +} + +static const struct dmi_match_data intel_chipset_data = { +	.iostart = 0xb2, +	.iolen = 2, +	.backlight_ops	= { +		.options	= BL_CORE_SUSPENDRESUME, +		.get_brightness	= intel_chipset_get_intensity, +		.update_status	= intel_chipset_send_intensity, +	} +}; + +/* + * Implementation for MacBooks with Nvidia chipset. + */ +static int nvidia_chipset_send_intensity(struct backlight_device *bd) +{ +	int intensity = bd->props.brightness; + +	if (debug) +		printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n", +		       intensity); + +	outb(0x04 | (intensity << 4), 0x52f); +	outb(0xbf, 0x52e); +	return 0; +} + +static int nvidia_chipset_get_intensity(struct backlight_device *bd) +{ +	int intensity; + +	outb(0x03, 0x52f); +	outb(0xbf, 0x52e); +	intensity = inb(0x52f) >> 4; + +	if (debug) +		printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n", +		       intensity); + +	return intensity; +} + +static const struct dmi_match_data nvidia_chipset_data = { +	.iostart = 0x52e, +	.iolen = 2, +	.backlight_ops		= { +		.options	= BL_CORE_SUSPENDRESUME, +		.get_brightness	= nvidia_chipset_get_intensity, +		.update_status	= nvidia_chipset_send_intensity +	} +}; + +/* + * DMI matching. + */ +static /* const */ struct dmi_match_data *driver_data; + +static int mbp_dmi_match(const struct dmi_system_id *id) +{ +	driver_data = id->driver_data; + +	printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident); +	return 1; +} + +static const struct dmi_system_id __initdata mbp_device_table[] = {  	{ -		.ident = "3,1", -		.matches = { +		.callback	= mbp_dmi_match, +		.ident		= "MacBookPro 3,1", +		.matches	= {  			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),  			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),  		}, +		.driver_data	= (void *)&intel_chipset_data,  	},  	{ -		.ident = "3,2", -		.matches = { +		.callback	= mbp_dmi_match, +		.ident		= "MacBookPro 3,2", +		.matches	= {  			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),  			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),  		}, +		.driver_data	= (void *)&intel_chipset_data,  	},  	{ -		.ident = "4,1", -		.matches = { +		.callback	= mbp_dmi_match, +		.ident		= "MacBookPro 4,1", +		.matches	= {  			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),  			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),  		}, +		.driver_data	= (void *)&intel_chipset_data, +	}, +	{ +		.callback	= mbp_dmi_match, +		.ident		= "MacBook 5,1", +		.matches	= { +			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), +			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"), +		}, +		.driver_data	= (void *)&nvidia_chipset_data, +	}, +	{ +		.callback	= mbp_dmi_match, +		.ident		= "MacBookAir 2,1", +		.matches	= { +			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), +			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"), +		}, +		.driver_data	= (void *)&nvidia_chipset_data, +	}, +	{ +		.callback	= mbp_dmi_match, +		.ident		= "MacBookPro 5,1", +		.matches	= { +			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), +			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"), +		}, +		.driver_data	= (void *)&nvidia_chipset_data,  	},  	{ }  }; -static int mbp_send_intensity(struct backlight_device *bd) -{ -	int intensity = bd->props.brightness; - -	outb(0x04 | (intensity << 4), 0xb3); -	outb(0xbf, 0xb2); - -	return 0; -} - -static int mbp_get_intensity(struct backlight_device *bd) -{ -	outb(0x03, 0xb3); -	outb(0xbf, 0xb2); -	return inb(0xb3) >> 4; -} - -static struct backlight_ops mbp_ops = { -	.options = BL_CORE_SUSPENDRESUME, -	.get_brightness = mbp_get_intensity, -	.update_status  = mbp_send_intensity, -}; -  static int __init mbp_init(void)  {  	if (!dmi_check_system(mbp_device_table))  		return -ENODEV; -	if (!request_region(0xb2, 2, "Macbook Pro backlight")) +	if (!request_region(driver_data->iostart, driver_data->iolen,  +						"Macbook Pro backlight"))  		return -ENXIO;  	mbp_backlight_device = backlight_device_register("mbp_backlight", -							 NULL, NULL, -							 &mbp_ops); +					NULL, NULL, &driver_data->backlight_ops);  	if (IS_ERR(mbp_backlight_device)) { -		release_region(0xb2, 2); +		release_region(driver_data->iostart, driver_data->iolen);  		return PTR_ERR(mbp_backlight_device);  	}  	mbp_backlight_device->props.max_brightness = 15;  	mbp_backlight_device->props.brightness = -		mbp_get_intensity(mbp_backlight_device); +		driver_data->backlight_ops.get_brightness(mbp_backlight_device);  	backlight_update_status(mbp_backlight_device);  	return 0; @@ -103,7 +222,7 @@ static void __exit mbp_exit(void)  {  	backlight_device_unregister(mbp_backlight_device); -	release_region(0xb2, 2); +	release_region(driver_data->iostart, driver_data->iolen);  }  module_init(mbp_init); diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index ea07258565f0..e641584e212e 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -3,7 +3,7 @@   *   * simple PWM based backlight control, board code has to setup   * 1) pin configuration so PWM waveforms can output - * 2) platform_data casts to the PWM id (0/1/2/3 on PXA) + * 2) platform_data being correctly configured   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 as @@ -97,7 +97,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)  	} else  		dev_dbg(&pdev->dev, "got pwm for backlight\n"); -	bl = backlight_device_register(pdev->name, &pdev->dev, +	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,  			pb, &pwm_backlight_ops);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  | 
