zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/88pm860x_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/88pm860x_bl.c
new file mode 100644
index 0000000..f49181c
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/88pm860x_bl.c
@@ -0,0 +1,281 @@
+/*
+ * Backlight driver for Marvell Semiconductor 88PM8606
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/module.h>
+
+#define MAX_BRIGHTNESS		(0xFF)
+#define MIN_BRIGHTNESS		(0)
+
+#define CURRENT_BITMASK		(0x1F << 1)
+
+struct pm860x_backlight_data {
+	struct pm860x_chip *chip;
+	struct i2c_client *i2c;
+	int	current_brightness;
+	int	port;
+	int	pwm;
+	int	iset;
+};
+
+static inline int wled_a(int port)
+{
+	int ret;
+
+	ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
+	return ret;
+}
+
+static inline int wled_b(int port)
+{
+	int ret;
+
+	ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
+	return ret;
+}
+
+/* WLED2 & WLED3 share the same IDC */
+static inline int wled_idc(int port)
+{
+	int ret;
+
+	switch (port) {
+	case PM8606_BACKLIGHT1:
+	case PM8606_BACKLIGHT2:
+		ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
+		break;
+	case PM8606_BACKLIGHT3:
+	default:
+		ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
+		break;
+	}
+	return ret;
+}
+
+static int backlight_power_set(struct pm860x_chip *chip, int port,
+		int on)
+{
+	int ret = -EINVAL;
+
+	switch (port) {
+	case PM8606_BACKLIGHT1:
+		ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
+			pm8606_osc_disable(chip, WLED1_DUTY);
+		break;
+	case PM8606_BACKLIGHT2:
+		ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
+			pm8606_osc_disable(chip, WLED2_DUTY);
+		break;
+	case PM8606_BACKLIGHT3:
+		ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
+			pm8606_osc_disable(chip, WLED3_DUTY);
+		break;
+	}
+	return ret;
+}
+
+static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
+{
+	struct pm860x_backlight_data *data = bl_get_data(bl);
+	struct pm860x_chip *chip = data->chip;
+	unsigned char value;
+	int ret;
+
+	if (brightness > MAX_BRIGHTNESS)
+		value = MAX_BRIGHTNESS;
+	else
+		value = brightness;
+
+	if (brightness)
+		backlight_power_set(chip, data->port, 1);
+
+	ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+	if (ret < 0)
+		goto out;
+
+	if ((data->current_brightness == 0) && brightness) {
+		if (data->iset) {
+			ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+					      CURRENT_BITMASK, data->iset);
+			if (ret < 0)
+				goto out;
+		}
+		if (data->pwm) {
+			ret = pm860x_set_bits(data->i2c, PM8606_PWM,
+					      PM8606_PWM_FREQ_MASK, data->pwm);
+			if (ret < 0)
+				goto out;
+		}
+		if (brightness == MAX_BRIGHTNESS) {
+			/* set WLED_ON bit as 100% */
+			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+					      PM8606_WLED_ON, PM8606_WLED_ON);
+		}
+	} else {
+		if (brightness == MAX_BRIGHTNESS) {
+			/* set WLED_ON bit as 100% */
+			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+					      PM8606_WLED_ON, PM8606_WLED_ON);
+		} else {
+			/* clear WLED_ON bit since it's not 100% */
+			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+					      PM8606_WLED_ON, 0);
+		}
+	}
+	if (ret < 0)
+		goto out;
+
+	if (brightness == 0)
+		backlight_power_set(chip, data->port, 0);
+
+	dev_dbg(chip->dev, "set brightness %d\n", value);
+	data->current_brightness = value;
+	return 0;
+out:
+	dev_dbg(chip->dev, "set brightness %d failure with return "
+		"value:%d\n", value, ret);
+	return ret;
+}
+
+static int pm860x_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	return pm860x_backlight_set(bl, brightness);
+}
+
+static int pm860x_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct pm860x_backlight_data *data = bl_get_data(bl);
+	struct pm860x_chip *chip = data->chip;
+	int ret;
+
+	ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+	if (ret < 0)
+		goto out;
+	data->current_brightness = ret;
+	dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
+	return data->current_brightness;
+out:
+	return -EINVAL;
+}
+
+static const struct backlight_ops pm860x_backlight_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= pm860x_backlight_update_status,
+	.get_brightness	= pm860x_backlight_get_brightness,
+};
+
+static int pm860x_backlight_probe(struct platform_device *pdev)
+{
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_backlight_pdata *pdata = NULL;
+	struct pm860x_backlight_data *data;
+	struct backlight_device *bl;
+	struct resource *res;
+	struct backlight_properties props;
+	char name[MFD_NAME_SIZE];
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource!\n");
+		return -EINVAL;
+	}
+
+	pdata = pdev->dev.platform_data;
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "platform data isn't assigned to "
+			"backlight\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
+			    GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	strncpy(name, res->name, MFD_NAME_SIZE);
+	data->chip = chip;
+	data->i2c = (chip->id == CHIP_PM8606) ? chip->client	\
+			: chip->companion;
+	data->current_brightness = MAX_BRIGHTNESS;
+	data->pwm = pdata->pwm;
+	data->iset = pdata->iset;
+	data->port = pdata->flags;
+	if (data->port < 0) {
+		dev_err(&pdev->dev, "wrong platform data is assigned");
+		return -EINVAL;
+	}
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = MAX_BRIGHTNESS;
+	bl = backlight_device_register(name, &pdev->dev, data,
+					&pm860x_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+	bl->props.brightness = MAX_BRIGHTNESS;
+
+	platform_set_drvdata(pdev, bl);
+
+	/* read current backlight */
+	ret = pm860x_backlight_get_brightness(bl);
+	if (ret < 0)
+		goto out;
+
+	backlight_update_status(bl);
+	return 0;
+out:
+	backlight_device_unregister(bl);
+	return ret;
+}
+
+static int pm860x_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(bl);
+	return 0;
+}
+
+static struct platform_driver pm860x_backlight_driver = {
+	.driver		= {
+		.name	= "88pm860x-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pm860x_backlight_probe,
+	.remove		= pm860x_backlight_remove,
+};
+
+module_platform_driver(pm860x_backlight_driver);
+
+MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/Kconfig b/ap/os/linux/linux-3.4.x/drivers/video/backlight/Kconfig
new file mode 100644
index 0000000..af16884
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/Kconfig
@@ -0,0 +1,366 @@
+#
+# Backlight & LCD drivers configuration
+#
+
+menuconfig BACKLIGHT_LCD_SUPPORT
+	bool "Backlight & LCD device support"
+	help
+	  Enable this to be able to choose the drivers for controlling the
+	  backlight and the LCD panel on some platforms, for example on PDAs.
+
+if BACKLIGHT_LCD_SUPPORT
+
+#
+# LCD
+#
+config LCD_CLASS_DEVICE
+        tristate "Lowlevel LCD controls"
+	default m
+	help
+	  This framework adds support for low-level control of LCD.
+	  Some framebuffer devices connect to platform-specific LCD modules
+	  in order to have a platform-specific way to control the flat panel
+	  (contrast and applying power to the LCD (not to the backlight!)).
+
+	  To have support for your specific LCD panel you will have to
+	  select the proper drivers which depend on this option.
+
+if LCD_CLASS_DEVICE
+
+config LCD_CORGI
+	tristate "LCD Panel support for SHARP corgi/spitz model"
+	depends on SPI_MASTER && PXA_SHARPSL
+	help
+	  Say y here to support the LCD panels usually found on SHARP
+	  corgi (C7x0) and spitz (Cxx00) models.
+
+config LCD_L4F00242T03
+	tristate "Epson L4F00242T03 LCD"
+	depends on SPI_MASTER && GENERIC_GPIO
+	help
+	  SPI driver for Epson L4F00242T03. This provides basic support
+	  for init and powering the LCD up/down through a sysfs interface.
+
+config LCD_LMS283GF05
+	tristate "Samsung LMS283GF05 LCD"
+	depends on SPI_MASTER && GENERIC_GPIO
+	help
+	  SPI driver for Samsung LMS283GF05. This provides basic support
+	  for powering the LCD up/down through a sysfs interface.
+
+config LCD_LTV350QV
+	tristate "Samsung LTV350QV LCD Panel"
+	depends on SPI_MASTER
+	help
+	  If you have a Samsung LTV350QV LCD panel, say y to include a
+	  power control driver for it.  The panel starts up in power
+	  off state, so you need this driver in order to see any
+	  output.
+
+	  The LTV350QV panel is present on all ATSTK1000 boards.
+
+config LCD_ILI9320
+	tristate
+	help
+	  If you have a panel based on the ILI9320 controller chip
+	  then say y to include a power driver for it.
+
+config LCD_TDO24M
+	tristate "Toppoly TDO24M  and TDO35S LCD Panels support"
+	depends on SPI_MASTER
+	help
+	  If you have a Toppoly TDO24M/TDO35S series LCD panel, say y here to
+	  include the support for it.
+
+config LCD_VGG2432A4
+	tristate "VGG2432A4 LCM device support"
+	depends on SPI_MASTER
+	select LCD_ILI9320
+	help
+	  If you have a VGG2432A4 panel based on the ILI9320 controller chip
+	  then say y to include a power driver for it.
+
+config LCD_PLATFORM
+	tristate "Platform LCD controls"
+	help
+	  This driver provides a platform-device registered LCD power
+	  control interface.
+
+config LCD_TOSA
+	tristate "Sharp SL-6000 LCD Driver"
+	depends on SPI && MACH_TOSA
+	help
+	  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 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.
+
+config LCD_S6E63M0
+	tristate "S6E63M0 AMOLED LCD Driver"
+	depends on SPI && BACKLIGHT_CLASS_DEVICE
+	default n
+	help
+	  If you have an S6E63M0 LCD Panel, say Y to enable its
+	  LCD control driver.
+
+config LCD_LD9040
+	tristate "LD9040 AMOLED LCD Driver"
+	depends on SPI && BACKLIGHT_CLASS_DEVICE
+	default n
+	help
+	  If you have an LD9040 Panel, say Y to enable its
+	  control driver.
+
+config LCD_AMS369FG06
+	tristate "AMS369FG06 AMOLED LCD Driver"
+	depends on SPI && BACKLIGHT_CLASS_DEVICE
+	default n
+	help
+	  If you have an AMS369FG06 AMOLED Panel, say Y to enable its
+	  LCD control driver.
+
+endif # LCD_CLASS_DEVICE
+
+#
+# Backlight
+#
+config BACKLIGHT_CLASS_DEVICE
+        tristate "Lowlevel Backlight controls"
+	default m
+	help
+	  This framework adds support for low-level control of the LCD
+          backlight. This includes support for brightness and power.
+
+	  To have support for your specific LCD panel you will have to
+	  select the proper drivers which depend on this option.
+
+if BACKLIGHT_CLASS_DEVICE
+
+config BACKLIGHT_ATMEL_LCDC
+	bool "Atmel LCDC Contrast-as-Backlight control"
+	depends on FB_ATMEL
+	default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK
+	help
+	  This provides a backlight control internal to the Atmel LCDC
+	  driver.  If the LCD "contrast control" on your board is wired
+	  so it controls the backlight brightness, select this option to
+	  export this as a PWM-based backlight control.
+
+	  If in doubt, it's safe to enable this option; it doesn't kick
+	  in unless the board's description says it's wired that way.
+
+config BACKLIGHT_ATMEL_PWM
+	tristate "Atmel PWM backlight control"
+	depends on ATMEL_PWM
+	help
+	  Say Y here if you want to use the PWM peripheral in Atmel AT91 and
+	  AVR32 devices. This driver will need additional platform data to know
+	  which PWM instance to use and how to configure it.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called atmel-pwm-bl.
+
+config BACKLIGHT_EP93XX
+	tristate "Cirrus EP93xx Backlight Driver"
+	depends on FB_EP93XX
+	help
+	  If you have a LCD backlight connected to the BRIGHT output of
+	  the EP93xx, say Y here to enable this driver.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called ep93xx_bl.
+
+config BACKLIGHT_GENERIC
+	tristate "Generic (aka Sharp Corgi) Backlight Driver"
+	default y
+	help
+	  Say y to enable the generic platform backlight driver previously
+	  known as the Corgi backlight driver. If you have a Sharp Zaurus
+	  SL-C7xx, SL-Cxx00 or SL-6000x say y.
+
+config BACKLIGHT_LOCOMO
+	tristate "Sharp LOCOMO LCD/Backlight Driver"
+	depends on SHARP_LOCOMO
+	default y
+	help
+	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
+	  enable the LCD/backlight driver.
+
+config BACKLIGHT_OMAP1
+	tristate "OMAP1 PWL-based LCD Backlight"
+	depends on ARCH_OMAP1
+	default y
+	help
+	  This driver controls the LCD backlight level and power for
+	  the PWL module of OMAP1 processors.  Say Y if your board
+	  uses this hardware.
+
+config BACKLIGHT_HP680
+	tristate "HP Jornada 680 Backlight Driver"
+	depends on SH_HP6XX
+	default y
+	help
+	  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 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 PCI && X86
+	help
+	  If you have a Frontpath ProGear say Y to enable the
+	  backlight driver.
+
+config BACKLIGHT_CARILLO_RANCH
+	tristate "Intel Carillo Ranch Backlight Driver"
+	depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
+	help
+	  If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
+	  backlight driver.
+
+config BACKLIGHT_PWM
+	tristate "Generic PWM based Backlight Driver"
+	depends on HAVE_PWM
+	help
+	  If you have a LCD backlight adjustable by PWM, say Y to enable
+	  this driver.
+
+config BACKLIGHT_DA903X
+	tristate "Backlight Driver for DA9030/DA9034 using WLED"
+	depends on PMIC_DA903X
+	help
+	  If you have a LCD backlight connected to the WLED output of DA9030
+	  or DA9034 WLED output, say Y here to enable this driver.
+
+config BACKLIGHT_DA9052
+	tristate "Dialog DA9052/DA9053 WLED"
+	depends on PMIC_DA9052
+	help
+	  Enable the Backlight Driver for DA9052-BC and DA9053-AA/Bx PMICs.
+
+config BACKLIGHT_MAX8925
+	tristate "Backlight driver for MAX8925"
+	depends on MFD_MAX8925
+	help
+	  If you have a LCD backlight connected to the WLED output of MAX8925
+	  WLED output, say Y here to enable this driver.
+
+config BACKLIGHT_APPLE
+       tristate "Apple Backlight Driver"
+       depends on X86 && ACPI
+       help
+         If you have an Intel-based Apple say Y to enable a driver for its
+	 backlight.
+
+config BACKLIGHT_TOSA
+	tristate "Sharp SL-6000 Backlight Driver"
+	depends on I2C && MACH_TOSA && LCD_TOSA
+	help
+	  If you have an Sharp SL-6000 Zaurus say Y to enable a driver
+	  for its backlight
+
+config BACKLIGHT_SAHARA
+	tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
+	depends on X86
+	help
+	  If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
+	  backlight driver.
+
+config BACKLIGHT_WM831X
+	tristate "WM831x PMIC Backlight Driver"
+	depends on MFD_WM831X
+	help
+	  If you have a backlight driven by the ISINK and DCDC of a
+	  WM831x PMIC say y to enable the backlight driver for it.
+
+config BACKLIGHT_ADP5520
+	tristate "Backlight Driver for ADP5520/ADP5501 using WLED"
+	depends on PMIC_ADP5520
+	help
+	  If you have a LCD backlight connected to the BST/BL_SNK output of
+	  ADP5520 or ADP5501, say Y here to enable this driver.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called adp5520_bl.
+
+config BACKLIGHT_ADP8860
+	tristate "Backlight Driver for ADP8860/ADP8861/ADP8863 using WLED"
+	depends on BACKLIGHT_CLASS_DEVICE && I2C
+	select NEW_LEDS
+	select LEDS_CLASS
+	help
+	  If you have a LCD backlight connected to the ADP8860, ADP8861 or
+	  ADP8863 say Y here to enable this driver.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called adp8860_bl.
+
+config BACKLIGHT_ADP8870
+	tristate "Backlight Driver for ADP8870 using WLED"
+	depends on BACKLIGHT_CLASS_DEVICE && I2C
+	select NEW_LEDS
+	select LEDS_CLASS
+	help
+	  If you have a LCD backlight connected to the ADP8870,
+	  say Y here to enable this driver.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called adp8870_bl.
+
+config BACKLIGHT_88PM860X
+	tristate "Backlight Driver for 88PM8606 using WLED"
+	depends on MFD_88PM860X
+	help
+	  Say Y to enable the backlight driver for Marvell 88PM8606.
+
+config BACKLIGHT_PCF50633
+	tristate "Backlight driver for NXP PCF50633 MFD"
+	depends on BACKLIGHT_CLASS_DEVICE && MFD_PCF50633
+	help
+	  If you have a backlight driven by a NXP PCF50633 MFD, say Y here to
+	  enable its driver.
+
+config BACKLIGHT_AAT2870
+	tristate "AnalogicTech AAT2870 Backlight"
+	depends on BACKLIGHT_CLASS_DEVICE && MFD_AAT2870_CORE
+	help
+	  If you have a AnalogicTech AAT2870 say Y to enable the
+	  backlight driver.
+
+config BACKLIGHT_LP855X
+	tristate "Backlight driver for TI LP855X"
+	depends on BACKLIGHT_CLASS_DEVICE && I2C
+	help
+	  This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556
+	  backlight driver.
+
+config BACKLIGHT_OT200
+	tristate "Backlight driver for ot200 visualisation device"
+	depends on BACKLIGHT_CLASS_DEVICE && CS5535_MFGPT && GPIO_CS5535
+	help
+	  To compile this driver as a module, choose M here: the module will be
+	  called ot200_bl.
+
+config BACKLIGHT_PANDORA
+	tristate "Backlight driver for Pandora console"
+	depends on TWL4030_CORE
+	help
+	  If you have a Pandora console, say Y to enable the
+	  backlight driver.
+
+endif # BACKLIGHT_CLASS_DEVICE
+
+endif # BACKLIGHT_LCD_SUPPORT
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/Makefile b/ap/os/linux/linux-3.4.x/drivers/video/backlight/Makefile
new file mode 100644
index 0000000..36855ae
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/Makefile
@@ -0,0 +1,44 @@
+# Backlight & LCD drivers
+
+obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
+obj-$(CONFIG_LCD_CORGI)		   += corgi_lcd.o
+obj-$(CONFIG_LCD_HP700)		   += jornada720_lcd.o
+obj-$(CONFIG_LCD_L4F00242T03)	   += l4f00242t03.o
+obj-$(CONFIG_LCD_LMS283GF05)	   += lms283gf05.o
+obj-$(CONFIG_LCD_LTV350QV)	   += ltv350qv.o
+obj-$(CONFIG_LCD_ILI9320)	   += ili9320.o
+obj-$(CONFIG_LCD_PLATFORM)	   += platform_lcd.o
+obj-$(CONFIG_LCD_VGG2432A4)	   += vgg2432a4.o
+obj-$(CONFIG_LCD_TDO24M)	   += tdo24m.o
+obj-$(CONFIG_LCD_TOSA)		   += tosa_lcd.o
+obj-$(CONFIG_LCD_S6E63M0)	+= s6e63m0.o
+obj-$(CONFIG_LCD_LD9040)	+= ld9040.o
+obj-$(CONFIG_LCD_AMS369FG06)	+= ams369fg06.o
+
+obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
+obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o
+obj-$(CONFIG_BACKLIGHT_EP93XX)	+= ep93xx_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_LP855X)	+= lp855x_bl.o
+obj-$(CONFIG_BACKLIGHT_OMAP1)	+= omap1_bl.o
+obj-$(CONFIG_BACKLIGHT_PANDORA)	+= pandora_bl.o
+obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
+obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
+obj-$(CONFIG_BACKLIGHT_PWM)	+= pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_DA903X)	+= da903x_bl.o
+obj-$(CONFIG_BACKLIGHT_DA9052)	+= da9052_bl.o
+obj-$(CONFIG_BACKLIGHT_MAX8925)	+= max8925_bl.o
+obj-$(CONFIG_BACKLIGHT_APPLE)	+= apple_bl.o
+obj-$(CONFIG_BACKLIGHT_TOSA)	+= tosa_bl.o
+obj-$(CONFIG_BACKLIGHT_SAHARA)	+= kb3886_bl.o
+obj-$(CONFIG_BACKLIGHT_WM831X)	+= wm831x_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP5520)	+= adp5520_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP8860)	+= adp8860_bl.o
+obj-$(CONFIG_BACKLIGHT_ADP8870)	+= adp8870_bl.o
+obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
+obj-$(CONFIG_BACKLIGHT_PCF50633)	+= pcf50633-backlight.o
+obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
+obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/aat2870_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/aat2870_bl.c
new file mode 100644
index 0000000..7ff7522
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/aat2870_bl.c
@@ -0,0 +1,245 @@
+/*
+ * linux/drivers/video/backlight/aat2870_bl.c
+ *
+ * Copyright (c) 2011, NVIDIA Corporation.
+ * Author: Jin Park <jinyoungp@nvidia.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 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/mfd/aat2870.h>
+
+struct aat2870_bl_driver_data {
+	struct platform_device *pdev;
+	struct backlight_device *bd;
+
+	int channels;
+	int max_current;
+	int brightness; /* current brightness */
+};
+
+static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl,
+				     int brightness)
+{
+	struct backlight_device *bd = aat2870_bl->bd;
+	int val;
+
+	val = brightness * (aat2870_bl->max_current - 1);
+	val /= bd->props.max_brightness;
+
+	return val;
+}
+
+static inline int aat2870_bl_enable(struct aat2870_bl_driver_data *aat2870_bl)
+{
+	struct aat2870_data *aat2870
+			= dev_get_drvdata(aat2870_bl->pdev->dev.parent);
+
+	return aat2870->write(aat2870, AAT2870_BL_CH_EN,
+			      (u8)aat2870_bl->channels);
+}
+
+static inline int aat2870_bl_disable(struct aat2870_bl_driver_data *aat2870_bl)
+{
+	struct aat2870_data *aat2870
+			= dev_get_drvdata(aat2870_bl->pdev->dev.parent);
+
+	return aat2870->write(aat2870, AAT2870_BL_CH_EN, 0x0);
+}
+
+static int aat2870_bl_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+static int aat2870_bl_update_status(struct backlight_device *bd)
+{
+	struct aat2870_bl_driver_data *aat2870_bl = dev_get_drvdata(&bd->dev);
+	struct aat2870_data *aat2870 =
+			dev_get_drvdata(aat2870_bl->pdev->dev.parent);
+	int brightness = bd->props.brightness;
+	int ret;
+
+	if ((brightness < 0) || (bd->props.max_brightness < brightness)) {
+		dev_err(&bd->dev, "invalid brightness, %d\n", brightness);
+		return -EINVAL;
+	}
+
+	dev_dbg(&bd->dev, "brightness=%d, power=%d, state=%d\n",
+		 bd->props.brightness, bd->props.power, bd->props.state);
+
+	if ((bd->props.power != FB_BLANK_UNBLANK) ||
+			(bd->props.state & BL_CORE_FBBLANK) ||
+			(bd->props.state & BL_CORE_SUSPENDED))
+		brightness = 0;
+
+	ret = aat2870->write(aat2870, AAT2870_BLM,
+			     (u8)aat2870_brightness(aat2870_bl, brightness));
+	if (ret < 0)
+		return ret;
+
+	if (brightness == 0) {
+		ret = aat2870_bl_disable(aat2870_bl);
+		if (ret < 0)
+			return ret;
+	} else if (aat2870_bl->brightness == 0) {
+		ret = aat2870_bl_enable(aat2870_bl);
+		if (ret < 0)
+			return ret;
+	}
+
+	aat2870_bl->brightness = brightness;
+
+	return 0;
+}
+
+static int aat2870_bl_check_fb(struct backlight_device *bd, struct fb_info *fi)
+{
+	return 1;
+}
+
+static const struct backlight_ops aat2870_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = aat2870_bl_get_brightness,
+	.update_status = aat2870_bl_update_status,
+	.check_fb = aat2870_bl_check_fb,
+};
+
+static int aat2870_bl_probe(struct platform_device *pdev)
+{
+	struct aat2870_bl_platform_data *pdata = pdev->dev.platform_data;
+	struct aat2870_bl_driver_data *aat2870_bl;
+	struct backlight_device *bd;
+	struct backlight_properties props;
+	int ret = 0;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "No platform data\n");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	if (pdev->id != AAT2870_ID_BL) {
+		dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	aat2870_bl = devm_kzalloc(&pdev->dev,
+				  sizeof(struct aat2870_bl_driver_data),
+				  GFP_KERNEL);
+	if (!aat2870_bl) {
+		dev_err(&pdev->dev,
+			"Failed to allocate memory for aat2870 backlight\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+
+	props.type = BACKLIGHT_RAW;
+	bd = backlight_device_register("aat2870-backlight", &pdev->dev,
+				       aat2870_bl, &aat2870_bl_ops, &props);
+	if (IS_ERR(bd)) {
+		dev_err(&pdev->dev,
+			"Failed allocate memory for backlight device\n");
+		ret = PTR_ERR(bd);
+		goto out;
+	}
+
+	aat2870_bl->pdev = pdev;
+	platform_set_drvdata(pdev, aat2870_bl);
+
+	aat2870_bl->bd = bd;
+
+	if (pdata->channels > 0)
+		aat2870_bl->channels = pdata->channels;
+	else
+		aat2870_bl->channels = AAT2870_BL_CH_ALL;
+
+	if (pdata->max_current > 0)
+		aat2870_bl->max_current = pdata->max_current;
+	else
+		aat2870_bl->max_current = AAT2870_CURRENT_27_9;
+
+	if (pdata->max_brightness > 0)
+		bd->props.max_brightness = pdata->max_brightness;
+	else
+		bd->props.max_brightness = 255;
+
+	aat2870_bl->brightness = 0;
+	bd->props.power = FB_BLANK_UNBLANK;
+	bd->props.brightness = bd->props.max_brightness;
+
+	ret = aat2870_bl_update_status(bd);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to initialize\n");
+		goto out_bl_dev_unregister;
+	}
+
+	return 0;
+
+out_bl_dev_unregister:
+	backlight_device_unregister(bd);
+out:
+	return ret;
+}
+
+static int aat2870_bl_remove(struct platform_device *pdev)
+{
+	struct aat2870_bl_driver_data *aat2870_bl = platform_get_drvdata(pdev);
+	struct backlight_device *bd = aat2870_bl->bd;
+
+	bd->props.power = FB_BLANK_POWERDOWN;
+	bd->props.brightness = 0;
+	backlight_update_status(bd);
+
+	backlight_device_unregister(bd);
+
+	return 0;
+}
+
+static struct platform_driver aat2870_bl_driver = {
+	.driver = {
+		.name	= "aat2870-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= aat2870_bl_probe,
+	.remove		= aat2870_bl_remove,
+};
+
+static int __init aat2870_bl_init(void)
+{
+	return platform_driver_register(&aat2870_bl_driver);
+}
+subsys_initcall(aat2870_bl_init);
+
+static void __exit aat2870_bl_exit(void)
+{
+	platform_driver_unregister(&aat2870_bl_driver);
+}
+module_exit(aat2870_bl_exit);
+
+MODULE_DESCRIPTION("AnalogicTech AAT2870 Backlight");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp5520_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp5520_bl.c
new file mode 100644
index 0000000..4911ea7
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp5520_bl.c
@@ -0,0 +1,388 @@
+/*
+ * Backlight driver for Analog Devices ADP5520/ADP5501 MFD PMICs
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+struct adp5520_bl {
+	struct device *master;
+	struct adp5520_backlight_platform_data *pdata;
+	struct mutex lock;
+	unsigned long cached_daylight_max;
+	int id;
+	int current_brightness;
+};
+
+static int adp5520_bl_set(struct backlight_device *bl, int brightness)
+{
+	struct adp5520_bl *data = bl_get_data(bl);
+	struct device *master = data->master;
+	int ret = 0;
+
+	if (data->pdata->en_ambl_sens) {
+		if ((brightness > 0) && (brightness < ADP5020_MAX_BRIGHTNESS)) {
+			/* Disable Ambient Light auto adjust */
+			ret |= adp5520_clr_bits(master, ADP5520_BL_CONTROL,
+					ADP5520_BL_AUTO_ADJ);
+			ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX,
+					brightness);
+		} else {
+			/*
+			 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
+			 * restore daylight l3 sysfs brightness
+			 */
+			ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX,
+					 data->cached_daylight_max);
+			ret |= adp5520_set_bits(master, ADP5520_BL_CONTROL,
+					 ADP5520_BL_AUTO_ADJ);
+		}
+	} else {
+		ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX, brightness);
+	}
+
+	if (data->current_brightness && brightness == 0)
+		ret |= adp5520_set_bits(master,
+				ADP5520_MODE_STATUS, ADP5520_DIM_EN);
+	else if (data->current_brightness == 0 && brightness)
+		ret |= adp5520_clr_bits(master,
+				ADP5520_MODE_STATUS, ADP5520_DIM_EN);
+
+	if (!ret)
+		data->current_brightness = brightness;
+
+	return ret;
+}
+
+static int adp5520_bl_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	return adp5520_bl_set(bl, brightness);
+}
+
+static int adp5520_bl_get_brightness(struct backlight_device *bl)
+{
+	struct adp5520_bl *data = bl_get_data(bl);
+	int error;
+	uint8_t reg_val;
+
+	error = adp5520_read(data->master, ADP5520_BL_VALUE, &reg_val);
+
+	return error ? data->current_brightness : reg_val;
+}
+
+static const struct backlight_ops adp5520_bl_ops = {
+	.update_status	= adp5520_bl_update_status,
+	.get_brightness	= adp5520_bl_get_brightness,
+};
+
+static int adp5520_bl_setup(struct backlight_device *bl)
+{
+	struct adp5520_bl *data = bl_get_data(bl);
+	struct device *master = data->master;
+	struct adp5520_backlight_platform_data *pdata = data->pdata;
+	int ret = 0;
+
+	ret |= adp5520_write(master, ADP5520_DAYLIGHT_MAX,
+				pdata->l1_daylight_max);
+	ret |= adp5520_write(master, ADP5520_DAYLIGHT_DIM,
+				pdata->l1_daylight_dim);
+
+	if (pdata->en_ambl_sens) {
+		data->cached_daylight_max = pdata->l1_daylight_max;
+		ret |= adp5520_write(master, ADP5520_OFFICE_MAX,
+				pdata->l2_office_max);
+		ret |= adp5520_write(master, ADP5520_OFFICE_DIM,
+				pdata->l2_office_dim);
+		ret |= adp5520_write(master, ADP5520_DARK_MAX,
+				pdata->l3_dark_max);
+		ret |= adp5520_write(master, ADP5520_DARK_DIM,
+				pdata->l3_dark_dim);
+		ret |= adp5520_write(master, ADP5520_L2_TRIP,
+				pdata->l2_trip);
+		ret |= adp5520_write(master, ADP5520_L2_HYS,
+				pdata->l2_hyst);
+		ret |= adp5520_write(master, ADP5520_L3_TRIP,
+				 pdata->l3_trip);
+		ret |= adp5520_write(master, ADP5520_L3_HYS,
+				pdata->l3_hyst);
+		ret |= adp5520_write(master, ADP5520_ALS_CMPR_CFG,
+				ALS_CMPR_CFG_VAL(pdata->abml_filt,
+				ADP5520_L3_EN));
+	}
+
+	ret |= adp5520_write(master, ADP5520_BL_CONTROL,
+			BL_CTRL_VAL(pdata->fade_led_law,
+					pdata->en_ambl_sens));
+
+	ret |= adp5520_write(master, ADP5520_BL_FADE, FADE_VAL(pdata->fade_in,
+			pdata->fade_out));
+
+	ret |= adp5520_set_bits(master, ADP5520_MODE_STATUS,
+			ADP5520_BL_EN | ADP5520_DIM_EN);
+
+	return ret;
+}
+
+static ssize_t adp5520_show(struct device *dev, char *buf, int reg)
+{
+	struct adp5520_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+
+	mutex_lock(&data->lock);
+	error = adp5520_read(data->master, reg, &reg_val);
+	mutex_unlock(&data->lock);
+
+	return sprintf(buf, "%u\n", reg_val);
+}
+
+static ssize_t adp5520_store(struct device *dev, const char *buf,
+			 size_t count, int reg)
+{
+	struct adp5520_bl *data = dev_get_drvdata(dev);
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&data->lock);
+	adp5520_write(data->master, reg, val);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static ssize_t adp5520_bl_dark_max_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp5520_show(dev, buf, ADP5520_DARK_MAX);
+}
+
+static ssize_t adp5520_bl_dark_max_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	return adp5520_store(dev, buf, count, ADP5520_DARK_MAX);
+}
+static DEVICE_ATTR(dark_max, 0664, adp5520_bl_dark_max_show,
+			adp5520_bl_dark_max_store);
+
+static ssize_t adp5520_bl_office_max_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp5520_show(dev, buf, ADP5520_OFFICE_MAX);
+}
+
+static ssize_t adp5520_bl_office_max_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	return adp5520_store(dev, buf, count, ADP5520_OFFICE_MAX);
+}
+static DEVICE_ATTR(office_max, 0664, adp5520_bl_office_max_show,
+			adp5520_bl_office_max_store);
+
+static ssize_t adp5520_bl_daylight_max_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp5520_show(dev, buf, ADP5520_DAYLIGHT_MAX);
+}
+
+static ssize_t adp5520_bl_daylight_max_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct adp5520_bl *data = dev_get_drvdata(dev);
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data->cached_daylight_max);
+	if (ret < 0)
+		return ret;
+
+	return adp5520_store(dev, buf, count, ADP5520_DAYLIGHT_MAX);
+}
+static DEVICE_ATTR(daylight_max, 0664, adp5520_bl_daylight_max_show,
+			adp5520_bl_daylight_max_store);
+
+static ssize_t adp5520_bl_dark_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp5520_show(dev, buf, ADP5520_DARK_DIM);
+}
+
+static ssize_t adp5520_bl_dark_dim_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	return adp5520_store(dev, buf, count, ADP5520_DARK_DIM);
+}
+static DEVICE_ATTR(dark_dim, 0664, adp5520_bl_dark_dim_show,
+			adp5520_bl_dark_dim_store);
+
+static ssize_t adp5520_bl_office_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp5520_show(dev, buf, ADP5520_OFFICE_DIM);
+}
+
+static ssize_t adp5520_bl_office_dim_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	return adp5520_store(dev, buf, count, ADP5520_OFFICE_DIM);
+}
+static DEVICE_ATTR(office_dim, 0664, adp5520_bl_office_dim_show,
+			adp5520_bl_office_dim_store);
+
+static ssize_t adp5520_bl_daylight_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp5520_show(dev, buf, ADP5520_DAYLIGHT_DIM);
+}
+
+static ssize_t adp5520_bl_daylight_dim_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	return adp5520_store(dev, buf, count, ADP5520_DAYLIGHT_DIM);
+}
+static DEVICE_ATTR(daylight_dim, 0664, adp5520_bl_daylight_dim_show,
+			adp5520_bl_daylight_dim_store);
+
+static struct attribute *adp5520_bl_attributes[] = {
+	&dev_attr_dark_max.attr,
+	&dev_attr_dark_dim.attr,
+	&dev_attr_office_max.attr,
+	&dev_attr_office_dim.attr,
+	&dev_attr_daylight_max.attr,
+	&dev_attr_daylight_dim.attr,
+	NULL
+};
+
+static const struct attribute_group adp5520_bl_attr_group = {
+	.attrs = adp5520_bl_attributes,
+};
+
+static int __devinit adp5520_bl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct backlight_device *bl;
+	struct adp5520_bl *data;
+	int ret = 0;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	data->master = pdev->dev.parent;
+	data->pdata = pdev->dev.platform_data;
+
+	if (data->pdata  == NULL) {
+		dev_err(&pdev->dev, "missing platform data\n");
+		return -ENODEV;
+	}
+
+	data->id = pdev->id;
+	data->current_brightness = 0;
+
+	mutex_init(&data->lock);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = ADP5020_MAX_BRIGHTNESS;
+	bl = backlight_device_register(pdev->name, data->master, data,
+				       &adp5520_bl_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+
+	bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
+	if (data->pdata->en_ambl_sens)
+		ret = sysfs_create_group(&bl->dev.kobj,
+			&adp5520_bl_attr_group);
+
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register sysfs\n");
+		backlight_device_unregister(bl);
+	}
+
+	platform_set_drvdata(pdev, bl);
+	ret |= adp5520_bl_setup(bl);
+	backlight_update_status(bl);
+
+	return ret;
+}
+
+static int __devexit adp5520_bl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct adp5520_bl *data = bl_get_data(bl);
+
+	adp5520_clr_bits(data->master, ADP5520_MODE_STATUS, ADP5520_BL_EN);
+
+	if (data->pdata->en_ambl_sens)
+		sysfs_remove_group(&bl->dev.kobj,
+				&adp5520_bl_attr_group);
+
+	backlight_device_unregister(bl);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int adp5520_bl_suspend(struct platform_device *pdev,
+				 pm_message_t state)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	return adp5520_bl_set(bl, 0);
+}
+
+static int adp5520_bl_resume(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+
+	backlight_update_status(bl);
+	return 0;
+}
+#else
+#define adp5520_bl_suspend	NULL
+#define adp5520_bl_resume	NULL
+#endif
+
+static struct platform_driver adp5520_bl_driver = {
+	.driver		= {
+		.name	= "adp5520-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= adp5520_bl_probe,
+	.remove		= __devexit_p(adp5520_bl_remove),
+	.suspend	= adp5520_bl_suspend,
+	.resume		= adp5520_bl_resume,
+};
+
+module_platform_driver(adp5520_bl_driver);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("ADP5520(01) Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:adp5520-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp8860_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp8860_bl.c
new file mode 100644
index 0000000..feda482
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp8860_bl.c
@@ -0,0 +1,827 @@
+/*
+ * Backlight driver for Analog Devices ADP8860 Backlight Devices
+ *
+ * Copyright 2009-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+
+#include <linux/i2c/adp8860.h>
+#define ADP8860_EXT_FEATURES
+#define ADP8860_USE_LEDS
+
+#define ADP8860_MFDVID 0x00 /* Manufacturer and device ID */
+#define ADP8860_MDCR 0x01 /* Device mode and status */
+#define ADP8860_MDCR2 0x02 /* Device mode and Status Register 2 */
+#define ADP8860_INTR_EN 0x03 /* Interrupts enable */
+#define ADP8860_CFGR 0x04 /* Configuration register */
+#define ADP8860_BLSEN 0x05 /* Sink enable backlight or independent */
+#define ADP8860_BLOFF 0x06 /* Backlight off timeout */
+#define ADP8860_BLDIM 0x07 /* Backlight dim timeout */
+#define ADP8860_BLFR 0x08 /* Backlight fade in and out rates */
+#define ADP8860_BLMX1 0x09 /* Backlight (Brightness Level 1-daylight) maximum current */
+#define ADP8860_BLDM1 0x0A /* Backlight (Brightness Level 1-daylight) dim current */
+#define ADP8860_BLMX2 0x0B /* Backlight (Brightness Level 2-office) maximum current */
+#define ADP8860_BLDM2 0x0C /* Backlight (Brightness Level 2-office) dim current */
+#define ADP8860_BLMX3 0x0D /* Backlight (Brightness Level 3-dark) maximum current */
+#define ADP8860_BLDM3 0x0E /* Backlight (Brightness Level 3-dark) dim current */
+#define ADP8860_ISCFR 0x0F /* Independent sink current fade control register */
+#define ADP8860_ISCC 0x10 /* Independent sink current control register */
+#define ADP8860_ISCT1 0x11 /* Independent Sink Current Timer Register LED[7:5] */
+#define ADP8860_ISCT2 0x12 /* Independent Sink Current Timer Register LED[4:1] */
+#define ADP8860_ISCF 0x13 /* Independent sink current fade register */
+#define ADP8860_ISC7 0x14 /* Independent Sink Current LED7 */
+#define ADP8860_ISC6 0x15 /* Independent Sink Current LED6 */
+#define ADP8860_ISC5 0x16 /* Independent Sink Current LED5 */
+#define ADP8860_ISC4 0x17 /* Independent Sink Current LED4 */
+#define ADP8860_ISC3 0x18 /* Independent Sink Current LED3 */
+#define ADP8860_ISC2 0x19 /* Independent Sink Current LED2 */
+#define ADP8860_ISC1 0x1A /* Independent Sink Current LED1 */
+#define ADP8860_CCFG 0x1B /* Comparator configuration */
+#define ADP8860_CCFG2 0x1C /* Second comparator configuration */
+#define ADP8860_L2_TRP 0x1D /* L2 comparator reference */
+#define ADP8860_L2_HYS 0x1E /* L2 hysteresis */
+#define ADP8860_L3_TRP 0x1F /* L3 comparator reference */
+#define ADP8860_L3_HYS 0x20 /* L3 hysteresis */
+#define ADP8860_PH1LEVL 0x21 /* First phototransistor ambient light level-low byte register */
+#define ADP8860_PH1LEVH 0x22 /* First phototransistor ambient light level-high byte register */
+#define ADP8860_PH2LEVL 0x23 /* Second phototransistor ambient light level-low byte register */
+#define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */
+
+#define ADP8860_MANUFID		0x0  /* Analog Devices ADP8860 Manufacturer ID */
+#define ADP8861_MANUFID		0x4  /* Analog Devices ADP8861 Manufacturer ID */
+#define ADP8863_MANUFID		0x2  /* Analog Devices ADP8863 Manufacturer ID */
+
+#define ADP8860_DEVID(x)	((x) & 0xF)
+#define ADP8860_MANID(x)	((x) >> 4)
+
+/* MDCR Device mode and status */
+#define INT_CFG			(1 << 6)
+#define NSTBY			(1 << 5)
+#define DIM_EN			(1 << 4)
+#define GDWN_DIS		(1 << 3)
+#define SIS_EN			(1 << 2)
+#define CMP_AUTOEN		(1 << 1)
+#define BLEN			(1 << 0)
+
+/* ADP8860_CCFG Main ALS comparator level enable */
+#define L3_EN			(1 << 1)
+#define L2_EN			(1 << 0)
+
+#define CFGR_BLV_SHIFT		3
+#define CFGR_BLV_MASK		0x3
+#define ADP8860_FLAG_LED_MASK	0xFF
+
+#define FADE_VAL(in, out)	((0xF & (in)) | ((0xF & (out)) << 4))
+#define BL_CFGR_VAL(law, blv)	((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1))
+#define ALS_CCFG_VAL(filt)	((0x7 & filt) << 5)
+
+enum {
+	adp8860,
+	adp8861,
+	adp8863
+};
+
+struct adp8860_led {
+	struct led_classdev	cdev;
+	struct work_struct	work;
+	struct i2c_client	*client;
+	enum led_brightness	new_brightness;
+	int			id;
+	int			flags;
+};
+
+struct adp8860_bl {
+	struct i2c_client *client;
+	struct backlight_device *bl;
+	struct adp8860_led *led;
+	struct adp8860_backlight_platform_data *pdata;
+	struct mutex lock;
+	unsigned long cached_daylight_max;
+	int id;
+	int revid;
+	int current_brightness;
+	unsigned en_ambl_sens:1;
+	unsigned gdwn_dis:1;
+};
+
+static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
+		return ret;
+	}
+
+	*val = (uint8_t)ret;
+	return 0;
+}
+
+static int adp8860_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int adp8860_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
+{
+	struct adp8860_bl *data = i2c_get_clientdata(client);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	ret = adp8860_read(client, reg, &reg_val);
+
+	if (!ret && ((reg_val & bit_mask) != bit_mask)) {
+		reg_val |= bit_mask;
+		ret = adp8860_write(client, reg, reg_val);
+	}
+
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+static int adp8860_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
+{
+	struct adp8860_bl *data = i2c_get_clientdata(client);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	ret = adp8860_read(client, reg, &reg_val);
+
+	if (!ret && (reg_val & bit_mask)) {
+		reg_val &= ~bit_mask;
+		ret = adp8860_write(client, reg, reg_val);
+	}
+
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+/*
+ * Independent sink / LED
+ */
+#if defined(ADP8860_USE_LEDS)
+static void adp8860_led_work(struct work_struct *work)
+{
+	struct adp8860_led *led = container_of(work, struct adp8860_led, work);
+	adp8860_write(led->client, ADP8860_ISC1 - led->id + 1,
+			 led->new_brightness >> 1);
+}
+
+static void adp8860_led_set(struct led_classdev *led_cdev,
+			   enum led_brightness value)
+{
+	struct adp8860_led *led;
+
+	led = container_of(led_cdev, struct adp8860_led, cdev);
+	led->new_brightness = value;
+	schedule_work(&led->work);
+}
+
+static int adp8860_led_setup(struct adp8860_led *led)
+{
+	struct i2c_client *client = led->client;
+	int ret = 0;
+
+	ret = adp8860_write(client, ADP8860_ISC1 - led->id + 1, 0);
+	ret |= adp8860_set_bits(client, ADP8860_ISCC, 1 << (led->id - 1));
+
+	if (led->id > 4)
+		ret |= adp8860_set_bits(client, ADP8860_ISCT1,
+				(led->flags & 0x3) << ((led->id - 5) * 2));
+	else
+		ret |= adp8860_set_bits(client, ADP8860_ISCT2,
+				(led->flags & 0x3) << ((led->id - 1) * 2));
+
+	return ret;
+}
+
+static int __devinit adp8860_led_probe(struct i2c_client *client)
+{
+	struct adp8860_backlight_platform_data *pdata =
+		client->dev.platform_data;
+	struct adp8860_bl *data = i2c_get_clientdata(client);
+	struct adp8860_led *led, *led_dat;
+	struct led_info *cur_led;
+	int ret, i;
+
+	led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
+	if (led == NULL) {
+		dev_err(&client->dev, "failed to alloc memory\n");
+		return -ENOMEM;
+	}
+
+	ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law);
+	ret = adp8860_write(client, ADP8860_ISCT1,
+			(pdata->led_on_time & 0x3) << 6);
+	ret |= adp8860_write(client, ADP8860_ISCF,
+			FADE_VAL(pdata->led_fade_in, pdata->led_fade_out));
+
+	if (ret) {
+		dev_err(&client->dev, "failed to write\n");
+		goto err_free;
+	}
+
+	for (i = 0; i < pdata->num_leds; ++i) {
+		cur_led = &pdata->leds[i];
+		led_dat = &led[i];
+
+		led_dat->id = cur_led->flags & ADP8860_FLAG_LED_MASK;
+
+		if (led_dat->id > 7 || led_dat->id < 1) {
+			dev_err(&client->dev, "Invalid LED ID %d\n",
+				led_dat->id);
+			goto err;
+		}
+
+		if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
+			dev_err(&client->dev, "LED %d used by Backlight\n",
+				led_dat->id);
+			goto err;
+		}
+
+		led_dat->cdev.name = cur_led->name;
+		led_dat->cdev.default_trigger = cur_led->default_trigger;
+		led_dat->cdev.brightness_set = adp8860_led_set;
+		led_dat->cdev.brightness = LED_OFF;
+		led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT;
+		led_dat->client = client;
+		led_dat->new_brightness = LED_OFF;
+		INIT_WORK(&led_dat->work, adp8860_led_work);
+
+		ret = led_classdev_register(&client->dev, &led_dat->cdev);
+		if (ret) {
+			dev_err(&client->dev, "failed to register LED %d\n",
+				led_dat->id);
+			goto err;
+		}
+
+		ret = adp8860_led_setup(led_dat);
+		if (ret) {
+			dev_err(&client->dev, "failed to write\n");
+			i++;
+			goto err;
+		}
+	}
+
+	data->led = led;
+
+	return 0;
+
+ err:
+	for (i = i - 1; i >= 0; --i) {
+		led_classdev_unregister(&led[i].cdev);
+		cancel_work_sync(&led[i].work);
+	}
+
+ err_free:
+	kfree(led);
+
+	return ret;
+}
+
+static int __devexit adp8860_led_remove(struct i2c_client *client)
+{
+	struct adp8860_backlight_platform_data *pdata =
+		client->dev.platform_data;
+	struct adp8860_bl *data = i2c_get_clientdata(client);
+	int i;
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		led_classdev_unregister(&data->led[i].cdev);
+		cancel_work_sync(&data->led[i].work);
+	}
+
+	kfree(data->led);
+	return 0;
+}
+#else
+static int __devinit adp8860_led_probe(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int __devexit adp8860_led_remove(struct i2c_client *client)
+{
+	return 0;
+}
+#endif
+
+static int adp8860_bl_set(struct backlight_device *bl, int brightness)
+{
+	struct adp8860_bl *data = bl_get_data(bl);
+	struct i2c_client *client = data->client;
+	int ret = 0;
+
+	if (data->en_ambl_sens) {
+		if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) {
+			/* Disable Ambient Light auto adjust */
+			ret |= adp8860_clr_bits(client, ADP8860_MDCR,
+					CMP_AUTOEN);
+			ret |= adp8860_write(client, ADP8860_BLMX1, brightness);
+		} else {
+			/*
+			 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
+			 * restore daylight l1 sysfs brightness
+			 */
+			ret |= adp8860_write(client, ADP8860_BLMX1,
+					 data->cached_daylight_max);
+			ret |= adp8860_set_bits(client, ADP8860_MDCR,
+					 CMP_AUTOEN);
+		}
+	} else
+		ret |= adp8860_write(client, ADP8860_BLMX1, brightness);
+
+	if (data->current_brightness && brightness == 0)
+		ret |= adp8860_set_bits(client,
+				ADP8860_MDCR, DIM_EN);
+	else if (data->current_brightness == 0 && brightness)
+		ret |= adp8860_clr_bits(client,
+				ADP8860_MDCR, DIM_EN);
+
+	if (!ret)
+		data->current_brightness = brightness;
+
+	return ret;
+}
+
+static int adp8860_bl_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	return adp8860_bl_set(bl, brightness);
+}
+
+static int adp8860_bl_get_brightness(struct backlight_device *bl)
+{
+	struct adp8860_bl *data = bl_get_data(bl);
+
+	return data->current_brightness;
+}
+
+static const struct backlight_ops adp8860_bl_ops = {
+	.update_status	= adp8860_bl_update_status,
+	.get_brightness	= adp8860_bl_get_brightness,
+};
+
+static int adp8860_bl_setup(struct backlight_device *bl)
+{
+	struct adp8860_bl *data = bl_get_data(bl);
+	struct i2c_client *client = data->client;
+	struct adp8860_backlight_platform_data *pdata = data->pdata;
+	int ret = 0;
+
+	ret |= adp8860_write(client, ADP8860_BLSEN, ~pdata->bl_led_assign);
+	ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max);
+	ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim);
+
+	if (data->en_ambl_sens) {
+		data->cached_daylight_max = pdata->l1_daylight_max;
+		ret |= adp8860_write(client, ADP8860_BLMX2,
+						pdata->l2_office_max);
+		ret |= adp8860_write(client, ADP8860_BLDM2,
+						pdata->l2_office_dim);
+		ret |= adp8860_write(client, ADP8860_BLMX3,
+						pdata->l3_dark_max);
+		ret |= adp8860_write(client, ADP8860_BLDM3,
+						pdata->l3_dark_dim);
+
+		ret |= adp8860_write(client, ADP8860_L2_TRP, pdata->l2_trip);
+		ret |= adp8860_write(client, ADP8860_L2_HYS, pdata->l2_hyst);
+		ret |= adp8860_write(client, ADP8860_L3_TRP, pdata->l3_trip);
+		ret |= adp8860_write(client, ADP8860_L3_HYS, pdata->l3_hyst);
+		ret |= adp8860_write(client, ADP8860_CCFG, L2_EN | L3_EN |
+						ALS_CCFG_VAL(pdata->abml_filt));
+	}
+
+	ret |= adp8860_write(client, ADP8860_CFGR,
+			BL_CFGR_VAL(pdata->bl_fade_law, 0));
+
+	ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in,
+			pdata->bl_fade_out));
+
+	ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY |
+			(data->gdwn_dis ? GDWN_DIS : 0));
+
+	return ret;
+}
+
+static ssize_t adp8860_show(struct device *dev, char *buf, int reg)
+{
+	struct adp8860_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+
+	mutex_lock(&data->lock);
+	error = adp8860_read(data->client, reg, &reg_val);
+	mutex_unlock(&data->lock);
+
+	if (error < 0)
+		return error;
+
+	return sprintf(buf, "%u\n", reg_val);
+}
+
+static ssize_t adp8860_store(struct device *dev, const char *buf,
+			 size_t count, int reg)
+{
+	struct adp8860_bl *data = dev_get_drvdata(dev);
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&data->lock);
+	adp8860_write(data->client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static ssize_t adp8860_bl_l3_dark_max_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	return adp8860_show(dev, buf, ADP8860_BLMX3);
+}
+
+static ssize_t adp8860_bl_l3_dark_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return adp8860_store(dev, buf, count, ADP8860_BLMX3);
+}
+
+static DEVICE_ATTR(l3_dark_max, 0664, adp8860_bl_l3_dark_max_show,
+			adp8860_bl_l3_dark_max_store);
+
+static ssize_t adp8860_bl_l2_office_max_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return adp8860_show(dev, buf, ADP8860_BLMX2);
+}
+
+static ssize_t adp8860_bl_l2_office_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return adp8860_store(dev, buf, count, ADP8860_BLMX2);
+}
+static DEVICE_ATTR(l2_office_max, 0664, adp8860_bl_l2_office_max_show,
+			adp8860_bl_l2_office_max_store);
+
+static ssize_t adp8860_bl_l1_daylight_max_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8860_show(dev, buf, ADP8860_BLMX1);
+}
+
+static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct adp8860_bl *data = dev_get_drvdata(dev);
+	int ret = strict_strtoul(buf, 10, &data->cached_daylight_max);
+	if (ret)
+		return ret;
+
+	return adp8860_store(dev, buf, count, ADP8860_BLMX1);
+}
+static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show,
+			adp8860_bl_l1_daylight_max_store);
+
+static ssize_t adp8860_bl_l3_dark_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8860_show(dev, buf, ADP8860_BLDM3);
+}
+
+static ssize_t adp8860_bl_l3_dark_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8860_store(dev, buf, count, ADP8860_BLDM3);
+}
+static DEVICE_ATTR(l3_dark_dim, 0664, adp8860_bl_l3_dark_dim_show,
+			adp8860_bl_l3_dark_dim_store);
+
+static ssize_t adp8860_bl_l2_office_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8860_show(dev, buf, ADP8860_BLDM2);
+}
+
+static ssize_t adp8860_bl_l2_office_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8860_store(dev, buf, count, ADP8860_BLDM2);
+}
+static DEVICE_ATTR(l2_office_dim, 0664, adp8860_bl_l2_office_dim_show,
+			adp8860_bl_l2_office_dim_store);
+
+static ssize_t adp8860_bl_l1_daylight_dim_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	return adp8860_show(dev, buf, ADP8860_BLDM1);
+}
+
+static ssize_t adp8860_bl_l1_daylight_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8860_store(dev, buf, count, ADP8860_BLDM1);
+}
+static DEVICE_ATTR(l1_daylight_dim, 0664, adp8860_bl_l1_daylight_dim_show,
+			adp8860_bl_l1_daylight_dim_store);
+
+#ifdef ADP8860_EXT_FEATURES
+static ssize_t adp8860_bl_ambient_light_level_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct adp8860_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+	uint16_t ret_val;
+
+	mutex_lock(&data->lock);
+	error = adp8860_read(data->client, ADP8860_PH1LEVL, &reg_val);
+	ret_val = reg_val;
+	error |= adp8860_read(data->client, ADP8860_PH1LEVH, &reg_val);
+	mutex_unlock(&data->lock);
+
+	if (error < 0)
+		return error;
+
+	/* Return 13-bit conversion value for the first light sensor */
+	ret_val += (reg_val & 0x1F) << 8;
+
+	return sprintf(buf, "%u\n", ret_val);
+}
+static DEVICE_ATTR(ambient_light_level, 0444,
+		adp8860_bl_ambient_light_level_show, NULL);
+
+static ssize_t adp8860_bl_ambient_light_zone_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct adp8860_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+
+	mutex_lock(&data->lock);
+	error = adp8860_read(data->client, ADP8860_CFGR, &reg_val);
+	mutex_unlock(&data->lock);
+
+	if (error < 0)
+		return error;
+
+	return sprintf(buf, "%u\n",
+		((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1);
+}
+
+static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct adp8860_bl *data = dev_get_drvdata(dev);
+	unsigned long val;
+	uint8_t reg_val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val == 0) {
+		/* Enable automatic ambient light sensing */
+		adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN);
+	} else if ((val > 0) && (val <= 3)) {
+		/* Disable automatic ambient light sensing */
+		adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN);
+
+		/* Set user supplied ambient light zone */
+		mutex_lock(&data->lock);
+		adp8860_read(data->client, ADP8860_CFGR, &reg_val);
+		reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT);
+		reg_val |= (val - 1) << CFGR_BLV_SHIFT;
+		adp8860_write(data->client, ADP8860_CFGR, reg_val);
+		mutex_unlock(&data->lock);
+	}
+
+	return count;
+}
+static DEVICE_ATTR(ambient_light_zone, 0664,
+		adp8860_bl_ambient_light_zone_show,
+		adp8860_bl_ambient_light_zone_store);
+#endif
+
+static struct attribute *adp8860_bl_attributes[] = {
+	&dev_attr_l3_dark_max.attr,
+	&dev_attr_l3_dark_dim.attr,
+	&dev_attr_l2_office_max.attr,
+	&dev_attr_l2_office_dim.attr,
+	&dev_attr_l1_daylight_max.attr,
+	&dev_attr_l1_daylight_dim.attr,
+#ifdef ADP8860_EXT_FEATURES
+	&dev_attr_ambient_light_level.attr,
+	&dev_attr_ambient_light_zone.attr,
+#endif
+	NULL
+};
+
+static const struct attribute_group adp8860_bl_attr_group = {
+	.attrs = adp8860_bl_attributes,
+};
+
+static int __devinit adp8860_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct backlight_device *bl;
+	struct adp8860_bl *data;
+	struct adp8860_backlight_platform_data *pdata =
+		client->dev.platform_data;
+	struct backlight_properties props;
+	uint8_t reg_val;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
+		return -EIO;
+	}
+
+	if (!pdata) {
+		dev_err(&client->dev, "no platform data?\n");
+		return -EINVAL;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = adp8860_read(client, ADP8860_MFDVID, &reg_val);
+	if (ret < 0)
+		goto out2;
+
+	switch (ADP8860_MANID(reg_val)) {
+	case ADP8863_MANUFID:
+		data->gdwn_dis = !!pdata->gdwn_dis;
+	case ADP8860_MANUFID:
+		data->en_ambl_sens = !!pdata->en_ambl_sens;
+		break;
+	case ADP8861_MANUFID:
+		data->gdwn_dis = !!pdata->gdwn_dis;
+		break;
+	default:
+		dev_err(&client->dev, "failed to probe\n");
+		ret = -ENODEV;
+		goto out2;
+	}
+
+	/* It's confirmed that the DEVID field is actually a REVID */
+
+	data->revid = ADP8860_DEVID(reg_val);
+	data->client = client;
+	data->pdata = pdata;
+	data->id = id->driver_data;
+	data->current_brightness = 0;
+	i2c_set_clientdata(client, data);
+
+	memset(&props, 0, sizeof(props));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = ADP8860_MAX_BRIGHTNESS;
+
+	mutex_init(&data->lock);
+
+	bl = backlight_device_register(dev_driver_string(&client->dev),
+			&client->dev, data, &adp8860_bl_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&client->dev, "failed to register backlight\n");
+		ret = PTR_ERR(bl);
+		goto out2;
+	}
+
+	bl->props.brightness = ADP8860_MAX_BRIGHTNESS;
+
+	data->bl = bl;
+
+	if (data->en_ambl_sens)
+		ret = sysfs_create_group(&bl->dev.kobj,
+			&adp8860_bl_attr_group);
+
+	if (ret) {
+		dev_err(&client->dev, "failed to register sysfs\n");
+		goto out1;
+	}
+
+	ret = adp8860_bl_setup(bl);
+	if (ret) {
+		ret = -EIO;
+		goto out;
+	}
+
+	backlight_update_status(bl);
+
+	dev_info(&client->dev, "%s Rev.%d Backlight\n",
+		client->name, data->revid);
+
+	if (pdata->num_leds)
+		adp8860_led_probe(client);
+
+	return 0;
+
+out:
+	if (data->en_ambl_sens)
+		sysfs_remove_group(&data->bl->dev.kobj,
+			&adp8860_bl_attr_group);
+out1:
+	backlight_device_unregister(bl);
+out2:
+	kfree(data);
+
+	return ret;
+}
+
+static int __devexit adp8860_remove(struct i2c_client *client)
+{
+	struct adp8860_bl *data = i2c_get_clientdata(client);
+
+	adp8860_clr_bits(client, ADP8860_MDCR, NSTBY);
+
+	if (data->led)
+		adp8860_led_remove(client);
+
+	if (data->en_ambl_sens)
+		sysfs_remove_group(&data->bl->dev.kobj,
+			&adp8860_bl_attr_group);
+
+	backlight_device_unregister(data->bl);
+	kfree(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message)
+{
+	adp8860_clr_bits(client, ADP8860_MDCR, NSTBY);
+
+	return 0;
+}
+
+static int adp8860_i2c_resume(struct i2c_client *client)
+{
+	adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN);
+
+	return 0;
+}
+#else
+#define adp8860_i2c_suspend NULL
+#define adp8860_i2c_resume NULL
+#endif
+
+static const struct i2c_device_id adp8860_id[] = {
+	{ "adp8860", adp8860 },
+	{ "adp8861", adp8861 },
+	{ "adp8863", adp8863 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adp8860_id);
+
+static struct i2c_driver adp8860_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+	},
+	.probe    = adp8860_probe,
+	.remove   = __devexit_p(adp8860_remove),
+	.suspend = adp8860_i2c_suspend,
+	.resume  = adp8860_i2c_resume,
+	.id_table = adp8860_id,
+};
+
+module_i2c_driver(adp8860_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("ADP8860 Backlight driver");
+MODULE_ALIAS("i2c:adp8860-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp8870_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp8870_bl.c
new file mode 100644
index 0000000..c7a2c35
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/adp8870_bl.c
@@ -0,0 +1,999 @@
+/*
+ * Backlight driver for Analog Devices ADP8870 Backlight Devices
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/leds.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+
+#include <linux/i2c/adp8870.h>
+#define ADP8870_EXT_FEATURES
+#define ADP8870_USE_LEDS
+
+
+#define ADP8870_MFDVID	0x00  /* Manufacturer and device ID */
+#define ADP8870_MDCR	0x01  /* Device mode and status */
+#define ADP8870_INT_STAT 0x02  /* Interrupts status */
+#define ADP8870_INT_EN	0x03  /* Interrupts enable */
+#define ADP8870_CFGR	0x04  /* Configuration register */
+#define ADP8870_BLSEL	0x05  /* Sink enable backlight or independent */
+#define ADP8870_PWMLED	0x06  /* PWM Enable Selection Register */
+#define ADP8870_BLOFF	0x07  /* Backlight off timeout */
+#define ADP8870_BLDIM	0x08  /* Backlight dim timeout */
+#define ADP8870_BLFR	0x09  /* Backlight fade in and out rates */
+#define ADP8870_BLMX1	0x0A  /* Backlight (Brightness Level 1-daylight) maximum current */
+#define ADP8870_BLDM1	0x0B  /* Backlight (Brightness Level 1-daylight) dim current */
+#define ADP8870_BLMX2	0x0C  /* Backlight (Brightness Level 2-bright) maximum current */
+#define ADP8870_BLDM2	0x0D  /* Backlight (Brightness Level 2-bright) dim current */
+#define ADP8870_BLMX3	0x0E  /* Backlight (Brightness Level 3-office) maximum current */
+#define ADP8870_BLDM3	0x0F  /* Backlight (Brightness Level 3-office) dim current */
+#define ADP8870_BLMX4	0x10  /* Backlight (Brightness Level 4-indoor) maximum current */
+#define ADP8870_BLDM4	0x11  /* Backlight (Brightness Level 4-indoor) dim current */
+#define ADP8870_BLMX5	0x12  /* Backlight (Brightness Level 5-dark) maximum current */
+#define ADP8870_BLDM5	0x13  /* Backlight (Brightness Level 5-dark) dim current */
+#define ADP8870_ISCLAW	0x1A  /* Independent sink current fade law register */
+#define ADP8870_ISCC	0x1B  /* Independent sink current control register */
+#define ADP8870_ISCT1	0x1C  /* Independent Sink Current Timer Register LED[7:5] */
+#define ADP8870_ISCT2	0x1D  /* Independent Sink Current Timer Register LED[4:1] */
+#define ADP8870_ISCF	0x1E  /* Independent sink current fade register */
+#define ADP8870_ISC1	0x1F  /* Independent Sink Current LED1 */
+#define ADP8870_ISC2	0x20  /* Independent Sink Current LED2 */
+#define ADP8870_ISC3	0x21  /* Independent Sink Current LED3 */
+#define ADP8870_ISC4	0x22  /* Independent Sink Current LED4 */
+#define ADP8870_ISC5	0x23  /* Independent Sink Current LED5 */
+#define ADP8870_ISC6	0x24  /* Independent Sink Current LED6 */
+#define ADP8870_ISC7	0x25  /* Independent Sink Current LED7 (Brightness Level 1-daylight) */
+#define ADP8870_ISC7_L2	0x26  /* Independent Sink Current LED7 (Brightness Level 2-bright) */
+#define ADP8870_ISC7_L3	0x27  /* Independent Sink Current LED7 (Brightness Level 3-office) */
+#define ADP8870_ISC7_L4	0x28  /* Independent Sink Current LED7 (Brightness Level 4-indoor) */
+#define ADP8870_ISC7_L5	0x29  /* Independent Sink Current LED7 (Brightness Level 5-dark) */
+#define ADP8870_CMP_CTL	0x2D  /* ALS Comparator Control Register */
+#define ADP8870_ALS1_EN	0x2E  /* Main ALS comparator level enable */
+#define ADP8870_ALS2_EN	0x2F  /* Second ALS comparator level enable */
+#define ADP8870_ALS1_STAT 0x30  /* Main ALS Comparator Status Register */
+#define ADP8870_ALS2_STAT 0x31  /* Second ALS Comparator Status Register */
+#define ADP8870_L2TRP	0x32  /* L2 comparator reference */
+#define ADP8870_L2HYS	0x33  /* L2 hysteresis */
+#define ADP8870_L3TRP	0x34  /* L3 comparator reference */
+#define ADP8870_L3HYS	0x35  /* L3 hysteresis */
+#define ADP8870_L4TRP	0x36  /* L4 comparator reference */
+#define ADP8870_L4HYS	0x37  /* L4 hysteresis */
+#define ADP8870_L5TRP	0x38  /* L5 comparator reference */
+#define ADP8870_L5HYS	0x39  /* L5 hysteresis */
+#define ADP8870_PH1LEVL	0x40  /* First phototransistor ambient light level-low byte register */
+#define ADP8870_PH1LEVH	0x41  /* First phototransistor ambient light level-high byte register */
+#define ADP8870_PH2LEVL	0x42  /* Second phototransistor ambient light level-low byte register */
+#define ADP8870_PH2LEVH	0x43  /* Second phototransistor ambient light level-high byte register */
+
+#define ADP8870_MANUFID		0x3  /* Analog Devices AD8870 Manufacturer and device ID */
+#define ADP8870_DEVID(x)	((x) & 0xF)
+#define ADP8870_MANID(x)	((x) >> 4)
+
+/* MDCR Device mode and status */
+#define D7ALSEN			(1 << 7)
+#define INT_CFG			(1 << 6)
+#define NSTBY			(1 << 5)
+#define DIM_EN			(1 << 4)
+#define GDWN_DIS		(1 << 3)
+#define SIS_EN			(1 << 2)
+#define CMP_AUTOEN		(1 << 1)
+#define BLEN			(1 << 0)
+
+/* ADP8870_ALS1_EN Main ALS comparator level enable */
+#define L5_EN			(1 << 3)
+#define L4_EN			(1 << 2)
+#define L3_EN			(1 << 1)
+#define L2_EN			(1 << 0)
+
+#define CFGR_BLV_SHIFT		3
+#define CFGR_BLV_MASK		0x7
+#define ADP8870_FLAG_LED_MASK	0xFF
+
+#define FADE_VAL(in, out)	((0xF & (in)) | ((0xF & (out)) << 4))
+#define BL_CFGR_VAL(law, blv)	((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1))
+#define ALS_CMPR_CFG_VAL(filt)	((0x7 & (filt)) << 1)
+
+struct adp8870_bl {
+	struct i2c_client *client;
+	struct backlight_device *bl;
+	struct adp8870_led *led;
+	struct adp8870_backlight_platform_data *pdata;
+	struct mutex lock;
+	unsigned long cached_daylight_max;
+	int id;
+	int revid;
+	int current_brightness;
+};
+
+struct adp8870_led {
+	struct led_classdev	cdev;
+	struct work_struct	work;
+	struct i2c_client	*client;
+	enum led_brightness	new_brightness;
+	int			id;
+	int			flags;
+};
+
+static int adp8870_read(struct i2c_client *client, int reg, uint8_t *val)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
+		return ret;
+	}
+
+	*val = ret;
+	return 0;
+}
+
+
+static int adp8870_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret = i2c_smbus_write_byte_data(client, reg, val);
+	if (ret)
+		dev_err(&client->dev, "failed to write\n");
+
+	return ret;
+}
+
+static int adp8870_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
+{
+	struct adp8870_bl *data = i2c_get_clientdata(client);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	ret = adp8870_read(client, reg, &reg_val);
+
+	if (!ret && ((reg_val & bit_mask) != bit_mask)) {
+		reg_val |= bit_mask;
+		ret = adp8870_write(client, reg, reg_val);
+	}
+
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+static int adp8870_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
+{
+	struct adp8870_bl *data = i2c_get_clientdata(client);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	ret = adp8870_read(client, reg, &reg_val);
+
+	if (!ret && (reg_val & bit_mask)) {
+		reg_val &= ~bit_mask;
+		ret = adp8870_write(client, reg, reg_val);
+	}
+
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+/*
+ * Independent sink / LED
+ */
+#if defined(ADP8870_USE_LEDS)
+static void adp8870_led_work(struct work_struct *work)
+{
+	struct adp8870_led *led = container_of(work, struct adp8870_led, work);
+	adp8870_write(led->client, ADP8870_ISC1 + led->id - 1,
+			 led->new_brightness >> 1);
+}
+
+static void adp8870_led_set(struct led_classdev *led_cdev,
+			   enum led_brightness value)
+{
+	struct adp8870_led *led;
+
+	led = container_of(led_cdev, struct adp8870_led, cdev);
+	led->new_brightness = value;
+	/*
+	 * Use workqueue for IO since I2C operations can sleep.
+	 */
+	schedule_work(&led->work);
+}
+
+static int adp8870_led_setup(struct adp8870_led *led)
+{
+	struct i2c_client *client = led->client;
+	int ret = 0;
+
+	ret = adp8870_write(client, ADP8870_ISC1 + led->id - 1, 0);
+	if (ret)
+		return ret;
+
+	ret = adp8870_set_bits(client, ADP8870_ISCC, 1 << (led->id - 1));
+	if (ret)
+		return ret;
+
+	if (led->id > 4)
+		ret = adp8870_set_bits(client, ADP8870_ISCT1,
+				(led->flags & 0x3) << ((led->id - 5) * 2));
+	else
+		ret = adp8870_set_bits(client, ADP8870_ISCT2,
+				(led->flags & 0x3) << ((led->id - 1) * 2));
+
+	return ret;
+}
+
+static int __devinit adp8870_led_probe(struct i2c_client *client)
+{
+	struct adp8870_backlight_platform_data *pdata =
+		client->dev.platform_data;
+	struct adp8870_bl *data = i2c_get_clientdata(client);
+	struct adp8870_led *led, *led_dat;
+	struct led_info *cur_led;
+	int ret, i;
+
+
+	led = kcalloc(pdata->num_leds, sizeof(*led), GFP_KERNEL);
+	if (led == NULL) {
+		dev_err(&client->dev, "failed to alloc memory\n");
+		return -ENOMEM;
+	}
+
+	ret = adp8870_write(client, ADP8870_ISCLAW, pdata->led_fade_law);
+	if (ret)
+		goto err_free;
+
+	ret = adp8870_write(client, ADP8870_ISCT1,
+			(pdata->led_on_time & 0x3) << 6);
+	if (ret)
+		goto err_free;
+
+	ret = adp8870_write(client, ADP8870_ISCF,
+			FADE_VAL(pdata->led_fade_in, pdata->led_fade_out));
+	if (ret)
+		goto err_free;
+
+	for (i = 0; i < pdata->num_leds; ++i) {
+		cur_led = &pdata->leds[i];
+		led_dat = &led[i];
+
+		led_dat->id = cur_led->flags & ADP8870_FLAG_LED_MASK;
+
+		if (led_dat->id > 7 || led_dat->id < 1) {
+			dev_err(&client->dev, "Invalid LED ID %d\n",
+				led_dat->id);
+			goto err;
+		}
+
+		if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
+			dev_err(&client->dev, "LED %d used by Backlight\n",
+				led_dat->id);
+			goto err;
+		}
+
+		led_dat->cdev.name = cur_led->name;
+		led_dat->cdev.default_trigger = cur_led->default_trigger;
+		led_dat->cdev.brightness_set = adp8870_led_set;
+		led_dat->cdev.brightness = LED_OFF;
+		led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT;
+		led_dat->client = client;
+		led_dat->new_brightness = LED_OFF;
+		INIT_WORK(&led_dat->work, adp8870_led_work);
+
+		ret = led_classdev_register(&client->dev, &led_dat->cdev);
+		if (ret) {
+			dev_err(&client->dev, "failed to register LED %d\n",
+				led_dat->id);
+			goto err;
+		}
+
+		ret = adp8870_led_setup(led_dat);
+		if (ret) {
+			dev_err(&client->dev, "failed to write\n");
+			i++;
+			goto err;
+		}
+	}
+
+	data->led = led;
+
+	return 0;
+
+ err:
+	for (i = i - 1; i >= 0; --i) {
+		led_classdev_unregister(&led[i].cdev);
+		cancel_work_sync(&led[i].work);
+	}
+
+ err_free:
+	kfree(led);
+
+	return ret;
+}
+
+static int __devexit adp8870_led_remove(struct i2c_client *client)
+{
+	struct adp8870_backlight_platform_data *pdata =
+		client->dev.platform_data;
+	struct adp8870_bl *data = i2c_get_clientdata(client);
+	int i;
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		led_classdev_unregister(&data->led[i].cdev);
+		cancel_work_sync(&data->led[i].work);
+	}
+
+	kfree(data->led);
+	return 0;
+}
+#else
+static int __devinit adp8870_led_probe(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int __devexit adp8870_led_remove(struct i2c_client *client)
+{
+	return 0;
+}
+#endif
+
+static int adp8870_bl_set(struct backlight_device *bl, int brightness)
+{
+	struct adp8870_bl *data = bl_get_data(bl);
+	struct i2c_client *client = data->client;
+	int ret = 0;
+
+	if (data->pdata->en_ambl_sens) {
+		if ((brightness > 0) && (brightness < ADP8870_MAX_BRIGHTNESS)) {
+			/* Disable Ambient Light auto adjust */
+			ret = adp8870_clr_bits(client, ADP8870_MDCR,
+					CMP_AUTOEN);
+			if (ret)
+				return ret;
+			ret = adp8870_write(client, ADP8870_BLMX1, brightness);
+			if (ret)
+				return ret;
+		} else {
+			/*
+			 * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust
+			 * restore daylight l1 sysfs brightness
+			 */
+			ret = adp8870_write(client, ADP8870_BLMX1,
+					 data->cached_daylight_max);
+			if (ret)
+				return ret;
+
+			ret = adp8870_set_bits(client, ADP8870_MDCR,
+					 CMP_AUTOEN);
+			if (ret)
+				return ret;
+		}
+	} else {
+		ret = adp8870_write(client, ADP8870_BLMX1, brightness);
+		if (ret)
+			return ret;
+	}
+
+	if (data->current_brightness && brightness == 0)
+		ret = adp8870_set_bits(client,
+				ADP8870_MDCR, DIM_EN);
+	else if (data->current_brightness == 0 && brightness)
+		ret = adp8870_clr_bits(client,
+				ADP8870_MDCR, DIM_EN);
+
+	if (!ret)
+		data->current_brightness = brightness;
+
+	return ret;
+}
+
+static int adp8870_bl_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	return adp8870_bl_set(bl, brightness);
+}
+
+static int adp8870_bl_get_brightness(struct backlight_device *bl)
+{
+	struct adp8870_bl *data = bl_get_data(bl);
+
+	return data->current_brightness;
+}
+
+static const struct backlight_ops adp8870_bl_ops = {
+	.update_status	= adp8870_bl_update_status,
+	.get_brightness	= adp8870_bl_get_brightness,
+};
+
+static int adp8870_bl_setup(struct backlight_device *bl)
+{
+	struct adp8870_bl *data = bl_get_data(bl);
+	struct i2c_client *client = data->client;
+	struct adp8870_backlight_platform_data *pdata = data->pdata;
+	int ret = 0;
+
+	ret = adp8870_write(client, ADP8870_BLSEL, ~pdata->bl_led_assign);
+	if (ret)
+		return ret;
+
+	ret = adp8870_write(client, ADP8870_PWMLED, pdata->pwm_assign);
+	if (ret)
+		return ret;
+
+	ret = adp8870_write(client, ADP8870_BLMX1, pdata->l1_daylight_max);
+	if (ret)
+		return ret;
+
+	ret = adp8870_write(client, ADP8870_BLDM1, pdata->l1_daylight_dim);
+	if (ret)
+		return ret;
+
+	if (pdata->en_ambl_sens) {
+		data->cached_daylight_max = pdata->l1_daylight_max;
+		ret = adp8870_write(client, ADP8870_BLMX2,
+						pdata->l2_bright_max);
+		if (ret)
+			return ret;
+		ret = adp8870_write(client, ADP8870_BLDM2,
+						pdata->l2_bright_dim);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_BLMX3,
+						pdata->l3_office_max);
+		if (ret)
+			return ret;
+		ret = adp8870_write(client, ADP8870_BLDM3,
+						pdata->l3_office_dim);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_BLMX4,
+						pdata->l4_indoor_max);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_BLDM4,
+						pdata->l4_indor_dim);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_BLMX5,
+						pdata->l5_dark_max);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_BLDM5,
+						pdata->l5_dark_dim);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L2TRP, pdata->l2_trip);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L2HYS, pdata->l2_hyst);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L3TRP, pdata->l3_trip);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L3HYS, pdata->l3_hyst);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L4TRP, pdata->l4_trip);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L4HYS, pdata->l4_hyst);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L5TRP, pdata->l5_trip);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_L5HYS, pdata->l5_hyst);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_ALS1_EN, L5_EN | L4_EN |
+						L3_EN | L2_EN);
+		if (ret)
+			return ret;
+
+		ret = adp8870_write(client, ADP8870_CMP_CTL,
+			ALS_CMPR_CFG_VAL(pdata->abml_filt));
+		if (ret)
+			return ret;
+	}
+
+	ret = adp8870_write(client, ADP8870_CFGR,
+			BL_CFGR_VAL(pdata->bl_fade_law, 0));
+	if (ret)
+		return ret;
+
+	ret = adp8870_write(client, ADP8870_BLFR, FADE_VAL(pdata->bl_fade_in,
+			pdata->bl_fade_out));
+	if (ret)
+		return ret;
+	/*
+	 * ADP8870 Rev0 requires GDWN_DIS bit set
+	 */
+
+	ret = adp8870_set_bits(client, ADP8870_MDCR, BLEN | DIM_EN | NSTBY |
+			(data->revid == 0 ? GDWN_DIS : 0));
+
+	return ret;
+}
+
+static ssize_t adp8870_show(struct device *dev, char *buf, int reg)
+{
+	struct adp8870_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+
+	mutex_lock(&data->lock);
+	error = adp8870_read(data->client, reg, &reg_val);
+	mutex_unlock(&data->lock);
+
+	if (error < 0)
+		return error;
+
+	return sprintf(buf, "%u\n", reg_val);
+}
+
+static ssize_t adp8870_store(struct device *dev, const char *buf,
+			 size_t count, int reg)
+{
+	struct adp8870_bl *data = dev_get_drvdata(dev);
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&data->lock);
+	adp8870_write(data->client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static ssize_t adp8870_bl_l5_dark_max_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLMX5);
+}
+
+static ssize_t adp8870_bl_l5_dark_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLMX5);
+}
+static DEVICE_ATTR(l5_dark_max, 0664, adp8870_bl_l5_dark_max_show,
+			adp8870_bl_l5_dark_max_store);
+
+
+static ssize_t adp8870_bl_l4_indoor_max_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLMX4);
+}
+
+static ssize_t adp8870_bl_l4_indoor_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLMX4);
+}
+static DEVICE_ATTR(l4_indoor_max, 0664, adp8870_bl_l4_indoor_max_show,
+			adp8870_bl_l4_indoor_max_store);
+
+
+static ssize_t adp8870_bl_l3_office_max_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLMX3);
+}
+
+static ssize_t adp8870_bl_l3_office_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLMX3);
+}
+
+static DEVICE_ATTR(l3_office_max, 0664, adp8870_bl_l3_office_max_show,
+			adp8870_bl_l3_office_max_store);
+
+static ssize_t adp8870_bl_l2_bright_max_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLMX2);
+}
+
+static ssize_t adp8870_bl_l2_bright_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLMX2);
+}
+static DEVICE_ATTR(l2_bright_max, 0664, adp8870_bl_l2_bright_max_show,
+			adp8870_bl_l2_bright_max_store);
+
+static ssize_t adp8870_bl_l1_daylight_max_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLMX1);
+}
+
+static ssize_t adp8870_bl_l1_daylight_max_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct adp8870_bl *data = dev_get_drvdata(dev);
+	int ret = strict_strtoul(buf, 10, &data->cached_daylight_max);
+	if (ret)
+		return ret;
+
+	return adp8870_store(dev, buf, count, ADP8870_BLMX1);
+}
+static DEVICE_ATTR(l1_daylight_max, 0664, adp8870_bl_l1_daylight_max_show,
+			adp8870_bl_l1_daylight_max_store);
+
+static ssize_t adp8870_bl_l5_dark_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLDM5);
+}
+
+static ssize_t adp8870_bl_l5_dark_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLDM5);
+}
+static DEVICE_ATTR(l5_dark_dim, 0664, adp8870_bl_l5_dark_dim_show,
+			adp8870_bl_l5_dark_dim_store);
+
+static ssize_t adp8870_bl_l4_indoor_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLDM4);
+}
+
+static ssize_t adp8870_bl_l4_indoor_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLDM4);
+}
+static DEVICE_ATTR(l4_indoor_dim, 0664, adp8870_bl_l4_indoor_dim_show,
+			adp8870_bl_l4_indoor_dim_store);
+
+
+static ssize_t adp8870_bl_l3_office_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLDM3);
+}
+
+static ssize_t adp8870_bl_l3_office_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLDM3);
+}
+static DEVICE_ATTR(l3_office_dim, 0664, adp8870_bl_l3_office_dim_show,
+			adp8870_bl_l3_office_dim_store);
+
+static ssize_t adp8870_bl_l2_bright_dim_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLDM2);
+}
+
+static ssize_t adp8870_bl_l2_bright_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLDM2);
+}
+static DEVICE_ATTR(l2_bright_dim, 0664, adp8870_bl_l2_bright_dim_show,
+			adp8870_bl_l2_bright_dim_store);
+
+static ssize_t adp8870_bl_l1_daylight_dim_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	return adp8870_show(dev, buf, ADP8870_BLDM1);
+}
+
+static ssize_t adp8870_bl_l1_daylight_dim_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return adp8870_store(dev, buf, count, ADP8870_BLDM1);
+}
+static DEVICE_ATTR(l1_daylight_dim, 0664, adp8870_bl_l1_daylight_dim_show,
+			adp8870_bl_l1_daylight_dim_store);
+
+#ifdef ADP8870_EXT_FEATURES
+static ssize_t adp8870_bl_ambient_light_level_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct adp8870_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+	uint16_t ret_val;
+
+	mutex_lock(&data->lock);
+	error = adp8870_read(data->client, ADP8870_PH1LEVL, &reg_val);
+	if (error < 0) {
+		mutex_unlock(&data->lock);
+		return error;
+	}
+	ret_val = reg_val;
+	error = adp8870_read(data->client, ADP8870_PH1LEVH, &reg_val);
+	mutex_unlock(&data->lock);
+
+	if (error < 0)
+		return error;
+
+	/* Return 13-bit conversion value for the first light sensor */
+	ret_val += (reg_val & 0x1F) << 8;
+
+	return sprintf(buf, "%u\n", ret_val);
+}
+static DEVICE_ATTR(ambient_light_level, 0444,
+		adp8870_bl_ambient_light_level_show, NULL);
+
+static ssize_t adp8870_bl_ambient_light_zone_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct adp8870_bl *data = dev_get_drvdata(dev);
+	int error;
+	uint8_t reg_val;
+
+	mutex_lock(&data->lock);
+	error = adp8870_read(data->client, ADP8870_CFGR, &reg_val);
+	mutex_unlock(&data->lock);
+
+	if (error < 0)
+		return error;
+
+	return sprintf(buf, "%u\n",
+		((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1);
+}
+
+static ssize_t adp8870_bl_ambient_light_zone_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct adp8870_bl *data = dev_get_drvdata(dev);
+	unsigned long val;
+	uint8_t reg_val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val == 0) {
+		/* Enable automatic ambient light sensing */
+		adp8870_set_bits(data->client, ADP8870_MDCR, CMP_AUTOEN);
+	} else if ((val > 0) && (val < 6)) {
+		/* Disable automatic ambient light sensing */
+		adp8870_clr_bits(data->client, ADP8870_MDCR, CMP_AUTOEN);
+
+		/* Set user supplied ambient light zone */
+		mutex_lock(&data->lock);
+		adp8870_read(data->client, ADP8870_CFGR, &reg_val);
+		reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT);
+		reg_val |= (val - 1) << CFGR_BLV_SHIFT;
+		adp8870_write(data->client, ADP8870_CFGR, reg_val);
+		mutex_unlock(&data->lock);
+	}
+
+	return count;
+}
+static DEVICE_ATTR(ambient_light_zone, 0664,
+		adp8870_bl_ambient_light_zone_show,
+		adp8870_bl_ambient_light_zone_store);
+#endif
+
+static struct attribute *adp8870_bl_attributes[] = {
+	&dev_attr_l5_dark_max.attr,
+	&dev_attr_l5_dark_dim.attr,
+	&dev_attr_l4_indoor_max.attr,
+	&dev_attr_l4_indoor_dim.attr,
+	&dev_attr_l3_office_max.attr,
+	&dev_attr_l3_office_dim.attr,
+	&dev_attr_l2_bright_max.attr,
+	&dev_attr_l2_bright_dim.attr,
+	&dev_attr_l1_daylight_max.attr,
+	&dev_attr_l1_daylight_dim.attr,
+#ifdef ADP8870_EXT_FEATURES
+	&dev_attr_ambient_light_level.attr,
+	&dev_attr_ambient_light_zone.attr,
+#endif
+	NULL
+};
+
+static const struct attribute_group adp8870_bl_attr_group = {
+	.attrs = adp8870_bl_attributes,
+};
+
+static int __devinit adp8870_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct backlight_properties props;
+	struct backlight_device *bl;
+	struct adp8870_bl *data;
+	struct adp8870_backlight_platform_data *pdata =
+		client->dev.platform_data;
+	uint8_t reg_val;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
+		return -EIO;
+	}
+
+	if (!pdata) {
+		dev_err(&client->dev, "no platform data?\n");
+		return -EINVAL;
+	}
+
+	ret = adp8870_read(client, ADP8870_MFDVID, &reg_val);
+	if (ret < 0)
+		return -EIO;
+
+	if (ADP8870_MANID(reg_val) != ADP8870_MANUFID) {
+		dev_err(&client->dev, "failed to probe\n");
+		return -ENODEV;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	data->revid = ADP8870_DEVID(reg_val);
+	data->client = client;
+	data->pdata = pdata;
+	data->id = id->driver_data;
+	data->current_brightness = 0;
+	i2c_set_clientdata(client, data);
+
+	mutex_init(&data->lock);
+
+	memset(&props, 0, sizeof(props));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = props.brightness = ADP8870_MAX_BRIGHTNESS;
+	bl = backlight_device_register(dev_driver_string(&client->dev),
+			&client->dev, data, &adp8870_bl_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&client->dev, "failed to register backlight\n");
+		ret = PTR_ERR(bl);
+		goto out2;
+	}
+
+	data->bl = bl;
+
+	if (pdata->en_ambl_sens)
+		ret = sysfs_create_group(&bl->dev.kobj,
+			&adp8870_bl_attr_group);
+
+	if (ret) {
+		dev_err(&client->dev, "failed to register sysfs\n");
+		goto out1;
+	}
+
+	ret = adp8870_bl_setup(bl);
+	if (ret) {
+		ret = -EIO;
+		goto out;
+	}
+
+	backlight_update_status(bl);
+
+	dev_info(&client->dev, "Rev.%d Backlight\n", data->revid);
+
+	if (pdata->num_leds)
+		adp8870_led_probe(client);
+
+	return 0;
+
+out:
+	if (data->pdata->en_ambl_sens)
+		sysfs_remove_group(&data->bl->dev.kobj,
+			&adp8870_bl_attr_group);
+out1:
+	backlight_device_unregister(bl);
+out2:
+	kfree(data);
+
+	return ret;
+}
+
+static int __devexit adp8870_remove(struct i2c_client *client)
+{
+	struct adp8870_bl *data = i2c_get_clientdata(client);
+
+	adp8870_clr_bits(client, ADP8870_MDCR, NSTBY);
+
+	if (data->led)
+		adp8870_led_remove(client);
+
+	if (data->pdata->en_ambl_sens)
+		sysfs_remove_group(&data->bl->dev.kobj,
+			&adp8870_bl_attr_group);
+
+	backlight_device_unregister(data->bl);
+	kfree(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message)
+{
+	adp8870_clr_bits(client, ADP8870_MDCR, NSTBY);
+
+	return 0;
+}
+
+static int adp8870_i2c_resume(struct i2c_client *client)
+{
+	adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN);
+
+	return 0;
+}
+#else
+#define adp8870_i2c_suspend NULL
+#define adp8870_i2c_resume NULL
+#endif
+
+static const struct i2c_device_id adp8870_id[] = {
+	{ "adp8870", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adp8870_id);
+
+static struct i2c_driver adp8870_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+	},
+	.probe    = adp8870_probe,
+	.remove   = __devexit_p(adp8870_remove),
+	.suspend = adp8870_i2c_suspend,
+	.resume  = adp8870_i2c_resume,
+	.id_table = adp8870_id,
+};
+
+module_i2c_driver(adp8870_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("ADP8870 Backlight driver");
+MODULE_ALIAS("i2c:adp8870-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ams369fg06.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ams369fg06.c
new file mode 100644
index 0000000..7bdadc7
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ams369fg06.c
@@ -0,0 +1,636 @@
+/*
+ * ams369fg06 AMOLED LCD panel driver.
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han  <jg1.han@samsung.com>
+ *
+ * Derived from drivers/video/s6e63m0.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/wait.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+
+#define SLEEPMSEC		0x1000
+#define ENDDEF			0x2000
+#define	DEFMASK			0xFF00
+#define COMMAND_ONLY		0xFE
+#define DATA_ONLY		0xFF
+
+#define MAX_GAMMA_LEVEL		5
+#define GAMMA_TABLE_COUNT	21
+
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		255
+#define DEFAULT_BRIGHTNESS	150
+
+struct ams369fg06 {
+	struct device			*dev;
+	struct spi_device		*spi;
+	unsigned int			power;
+	struct lcd_device		*ld;
+	struct backlight_device		*bd;
+	struct lcd_platform_data	*lcd_pd;
+};
+
+static const unsigned short seq_display_on[] = {
+	0x14, 0x03,
+	ENDDEF, 0x0000
+};
+
+static const unsigned short seq_display_off[] = {
+	0x14, 0x00,
+	ENDDEF, 0x0000
+};
+
+static const unsigned short seq_stand_by_on[] = {
+	0x1D, 0xA1,
+	SLEEPMSEC, 200,
+	ENDDEF, 0x0000
+};
+
+static const unsigned short seq_stand_by_off[] = {
+	0x1D, 0xA0,
+	SLEEPMSEC, 250,
+	ENDDEF, 0x0000
+};
+
+static const unsigned short seq_setting[] = {
+	0x31, 0x08,
+	0x32, 0x14,
+	0x30, 0x02,
+	0x27, 0x01,
+	0x12, 0x08,
+	0x13, 0x08,
+	0x15, 0x00,
+	0x16, 0x00,
+
+	0xef, 0xd0,
+	DATA_ONLY, 0xe8,
+
+	0x39, 0x44,
+	0x40, 0x00,
+	0x41, 0x3f,
+	0x42, 0x2a,
+	0x43, 0x27,
+	0x44, 0x27,
+	0x45, 0x1f,
+	0x46, 0x44,
+	0x50, 0x00,
+	0x51, 0x00,
+	0x52, 0x17,
+	0x53, 0x24,
+	0x54, 0x26,
+	0x55, 0x1f,
+	0x56, 0x43,
+	0x60, 0x00,
+	0x61, 0x3f,
+	0x62, 0x2a,
+	0x63, 0x25,
+	0x64, 0x24,
+	0x65, 0x1b,
+	0x66, 0x5c,
+
+	0x17, 0x22,
+	0x18, 0x33,
+	0x19, 0x03,
+	0x1a, 0x01,
+	0x22, 0xa4,
+	0x23, 0x00,
+	0x26, 0xa0,
+
+	0x1d, 0xa0,
+	SLEEPMSEC, 300,
+
+	0x14, 0x03,
+
+	ENDDEF, 0x0000
+};
+
+/* gamma value: 2.2 */
+static const unsigned int ams369fg06_22_250[] = {
+	0x00, 0x3f, 0x2a, 0x27, 0x27, 0x1f, 0x44,
+	0x00, 0x00, 0x17, 0x24, 0x26, 0x1f, 0x43,
+	0x00, 0x3f, 0x2a, 0x25, 0x24, 0x1b, 0x5c,
+};
+
+static const unsigned int ams369fg06_22_200[] = {
+	0x00, 0x3f, 0x28, 0x29, 0x27, 0x21, 0x3e,
+	0x00, 0x00, 0x10, 0x25, 0x27, 0x20, 0x3d,
+	0x00, 0x3f, 0x28, 0x27, 0x25, 0x1d, 0x53,
+};
+
+static const unsigned int ams369fg06_22_150[] = {
+	0x00, 0x3f, 0x2d, 0x29, 0x28, 0x23, 0x37,
+	0x00, 0x00, 0x0b, 0x25, 0x28, 0x22, 0x36,
+	0x00, 0x3f, 0x2b, 0x28, 0x26, 0x1f, 0x4a,
+};
+
+static const unsigned int ams369fg06_22_100[] = {
+	0x00, 0x3f, 0x30, 0x2a, 0x2b, 0x24, 0x2f,
+	0x00, 0x00, 0x00, 0x25, 0x29, 0x24, 0x2e,
+	0x00, 0x3f, 0x2f, 0x29, 0x29, 0x21, 0x3f,
+};
+
+static const unsigned int ams369fg06_22_50[] = {
+	0x00, 0x3f, 0x3c, 0x2c, 0x2d, 0x27, 0x24,
+	0x00, 0x00, 0x00, 0x22, 0x2a, 0x27, 0x23,
+	0x00, 0x3f, 0x3b, 0x2c, 0x2b, 0x24, 0x31,
+};
+
+struct ams369fg06_gamma {
+	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
+};
+
+static struct ams369fg06_gamma gamma_table = {
+	.gamma_22_table[0] = (unsigned int *)&ams369fg06_22_50,
+	.gamma_22_table[1] = (unsigned int *)&ams369fg06_22_100,
+	.gamma_22_table[2] = (unsigned int *)&ams369fg06_22_150,
+	.gamma_22_table[3] = (unsigned int *)&ams369fg06_22_200,
+	.gamma_22_table[4] = (unsigned int *)&ams369fg06_22_250,
+};
+
+static int ams369fg06_spi_write_byte(struct ams369fg06 *lcd, int addr, int data)
+{
+	u16 buf[1];
+	struct spi_message msg;
+
+	struct spi_transfer xfer = {
+		.len		= 2,
+		.tx_buf		= buf,
+	};
+
+	buf[0] = (addr << 8) | data;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(lcd->spi, &msg);
+}
+
+static int ams369fg06_spi_write(struct ams369fg06 *lcd, unsigned char address,
+	unsigned char command)
+{
+	int ret = 0;
+
+	if (address != DATA_ONLY)
+		ret = ams369fg06_spi_write_byte(lcd, 0x70, address);
+	if (command != COMMAND_ONLY)
+		ret = ams369fg06_spi_write_byte(lcd, 0x72, command);
+
+	return ret;
+}
+
+static int ams369fg06_panel_send_sequence(struct ams369fg06 *lcd,
+	const unsigned short *wbuf)
+{
+	int ret = 0, i = 0;
+
+	while ((wbuf[i] & DEFMASK) != ENDDEF) {
+		if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
+			ret = ams369fg06_spi_write(lcd, wbuf[i], wbuf[i+1]);
+			if (ret)
+				break;
+		} else
+			mdelay(wbuf[i+1]);
+		i += 2;
+	}
+
+	return ret;
+}
+
+static int _ams369fg06_gamma_ctl(struct ams369fg06 *lcd,
+	const unsigned int *gamma)
+{
+	unsigned int i = 0;
+	int ret = 0;
+
+	for (i = 0 ; i < GAMMA_TABLE_COUNT / 3; i++) {
+		ret = ams369fg06_spi_write(lcd, 0x40 + i, gamma[i]);
+		ret = ams369fg06_spi_write(lcd, 0x50 + i, gamma[i+7*1]);
+		ret = ams369fg06_spi_write(lcd, 0x60 + i, gamma[i+7*2]);
+		if (ret) {
+			dev_err(lcd->dev, "failed to set gamma table.\n");
+			goto gamma_err;
+		}
+	}
+
+gamma_err:
+	return ret;
+}
+
+static int ams369fg06_gamma_ctl(struct ams369fg06 *lcd, int brightness)
+{
+	int ret = 0;
+	int gamma = 0;
+
+	if ((brightness >= 0) && (brightness <= 50))
+		gamma = 0;
+	else if ((brightness > 50) && (brightness <= 100))
+		gamma = 1;
+	else if ((brightness > 100) && (brightness <= 150))
+		gamma = 2;
+	else if ((brightness > 150) && (brightness <= 200))
+		gamma = 3;
+	else if ((brightness > 200) && (brightness <= 255))
+		gamma = 4;
+
+	ret = _ams369fg06_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
+
+	return ret;
+}
+
+static int ams369fg06_ldi_init(struct ams369fg06 *lcd)
+{
+	int ret, i;
+	static const unsigned short *init_seq[] = {
+		seq_setting,
+		seq_stand_by_off,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
+		ret = ams369fg06_panel_send_sequence(lcd, init_seq[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int ams369fg06_ldi_enable(struct ams369fg06 *lcd)
+{
+	int ret, i;
+	static const unsigned short *init_seq[] = {
+		seq_stand_by_off,
+		seq_display_on,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
+		ret = ams369fg06_panel_send_sequence(lcd, init_seq[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int ams369fg06_ldi_disable(struct ams369fg06 *lcd)
+{
+	int ret, i;
+
+	static const unsigned short *init_seq[] = {
+		seq_display_off,
+		seq_stand_by_on,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
+		ret = ams369fg06_panel_send_sequence(lcd, init_seq[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int ams369fg06_power_is_on(int power)
+{
+	return ((power) <= FB_BLANK_NORMAL);
+}
+
+static int ams369fg06_power_on(struct ams369fg06 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+	struct backlight_device *bd = NULL;
+
+	pd = lcd->lcd_pd;
+	if (!pd) {
+		dev_err(lcd->dev, "platform data is NULL.\n");
+		return -EFAULT;
+	}
+
+	bd = lcd->bd;
+	if (!bd) {
+		dev_err(lcd->dev, "backlight device is NULL.\n");
+		return -EFAULT;
+	}
+
+	if (!pd->power_on) {
+		dev_err(lcd->dev, "power_on is NULL.\n");
+		return -EFAULT;
+	} else {
+		pd->power_on(lcd->ld, 1);
+		mdelay(pd->power_on_delay);
+	}
+
+	if (!pd->reset) {
+		dev_err(lcd->dev, "reset is NULL.\n");
+		return -EFAULT;
+	} else {
+		pd->reset(lcd->ld);
+		mdelay(pd->reset_delay);
+	}
+
+	ret = ams369fg06_ldi_init(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "failed to initialize ldi.\n");
+		return ret;
+	}
+
+	ret = ams369fg06_ldi_enable(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "failed to enable ldi.\n");
+		return ret;
+	}
+
+	/* set brightness to current value after power on or resume. */
+	ret = ams369fg06_gamma_ctl(lcd, bd->props.brightness);
+	if (ret) {
+		dev_err(lcd->dev, "lcd gamma setting failed.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ams369fg06_power_off(struct ams369fg06 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+
+	pd = lcd->lcd_pd;
+	if (!pd) {
+		dev_err(lcd->dev, "platform data is NULL\n");
+		return -EFAULT;
+	}
+
+	ret = ams369fg06_ldi_disable(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "lcd setting failed.\n");
+		return -EIO;
+	}
+
+	mdelay(pd->power_off_delay);
+
+	if (!pd->power_on) {
+		dev_err(lcd->dev, "power_on is NULL.\n");
+		return -EFAULT;
+	} else
+		pd->power_on(lcd->ld, 0);
+
+	return 0;
+}
+
+static int ams369fg06_power(struct ams369fg06 *lcd, int power)
+{
+	int ret = 0;
+
+	if (ams369fg06_power_is_on(power) &&
+		!ams369fg06_power_is_on(lcd->power))
+		ret = ams369fg06_power_on(lcd);
+	else if (!ams369fg06_power_is_on(power) &&
+		ams369fg06_power_is_on(lcd->power))
+		ret = ams369fg06_power_off(lcd);
+
+	if (!ret)
+		lcd->power = power;
+
+	return ret;
+}
+
+static int ams369fg06_get_power(struct lcd_device *ld)
+{
+	struct ams369fg06 *lcd = lcd_get_data(ld);
+
+	return lcd->power;
+}
+
+static int ams369fg06_set_power(struct lcd_device *ld, int power)
+{
+	struct ams369fg06 *lcd = lcd_get_data(ld);
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+		power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	return ams369fg06_power(lcd, power);
+}
+
+static int ams369fg06_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+static int ams369fg06_set_brightness(struct backlight_device *bd)
+{
+	int ret = 0;
+	int brightness = bd->props.brightness;
+	struct ams369fg06 *lcd = dev_get_drvdata(&bd->dev);
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bd->props.max_brightness) {
+		dev_err(&bd->dev, "lcd brightness should be %d to %d.\n",
+			MIN_BRIGHTNESS, MAX_BRIGHTNESS);
+		return -EINVAL;
+	}
+
+	ret = ams369fg06_gamma_ctl(lcd, bd->props.brightness);
+	if (ret) {
+		dev_err(&bd->dev, "lcd brightness setting failed.\n");
+		return -EIO;
+	}
+
+	return ret;
+}
+
+static struct lcd_ops ams369fg06_lcd_ops = {
+	.get_power = ams369fg06_get_power,
+	.set_power = ams369fg06_set_power,
+};
+
+static const struct backlight_ops ams369fg06_backlight_ops = {
+	.get_brightness = ams369fg06_get_brightness,
+	.update_status = ams369fg06_set_brightness,
+};
+
+static int __devinit ams369fg06_probe(struct spi_device *spi)
+{
+	int ret = 0;
+	struct ams369fg06 *lcd = NULL;
+	struct lcd_device *ld = NULL;
+	struct backlight_device *bd = NULL;
+	struct backlight_properties props;
+
+	lcd = kzalloc(sizeof(struct ams369fg06), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	/* ams369fg06 lcd panel uses 3-wire 16bits SPI Mode. */
+	spi->bits_per_word = 16;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&spi->dev, "spi setup failed.\n");
+		goto out_free_lcd;
+	}
+
+	lcd->spi = spi;
+	lcd->dev = &spi->dev;
+
+	lcd->lcd_pd = spi->dev.platform_data;
+	if (!lcd->lcd_pd) {
+		dev_err(&spi->dev, "platform data is NULL\n");
+		goto out_free_lcd;
+	}
+
+	ld = lcd_device_register("ams369fg06", &spi->dev, lcd,
+		&ams369fg06_lcd_ops);
+	if (IS_ERR(ld)) {
+		ret = PTR_ERR(ld);
+		goto out_free_lcd;
+	}
+
+	lcd->ld = ld;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = MAX_BRIGHTNESS;
+
+	bd = backlight_device_register("ams369fg06-bl", &spi->dev, lcd,
+		&ams369fg06_backlight_ops, &props);
+	if (IS_ERR(bd)) {
+		ret =  PTR_ERR(bd);
+		goto out_lcd_unregister;
+	}
+
+	bd->props.brightness = DEFAULT_BRIGHTNESS;
+	lcd->bd = bd;
+
+	if (!lcd->lcd_pd->lcd_enabled) {
+		/*
+		 * if lcd panel was off from bootloader then
+		 * current lcd status is powerdown and then
+		 * it enables lcd panel.
+		 */
+		lcd->power = FB_BLANK_POWERDOWN;
+
+		ams369fg06_power(lcd, FB_BLANK_UNBLANK);
+	} else
+		lcd->power = FB_BLANK_UNBLANK;
+
+	dev_set_drvdata(&spi->dev, lcd);
+
+	dev_info(&spi->dev, "ams369fg06 panel driver has been probed.\n");
+
+	return 0;
+
+out_lcd_unregister:
+	lcd_device_unregister(ld);
+out_free_lcd:
+	kfree(lcd);
+	return ret;
+}
+
+static int __devexit ams369fg06_remove(struct spi_device *spi)
+{
+	struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+
+	ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
+	backlight_device_unregister(lcd->bd);
+	lcd_device_unregister(lcd->ld);
+	kfree(lcd);
+
+	return 0;
+}
+
+#if defined(CONFIG_PM)
+static unsigned int before_power;
+
+static int ams369fg06_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+	int ret = 0;
+	struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+
+	dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+
+	before_power = lcd->power;
+
+	/*
+	 * when lcd panel is suspend, lcd panel becomes off
+	 * regardless of status.
+	 */
+	ret = ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
+
+	return ret;
+}
+
+static int ams369fg06_resume(struct spi_device *spi)
+{
+	int ret = 0;
+	struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+
+	/*
+	 * after suspended, if lcd panel status is FB_BLANK_UNBLANK
+	 * (at that time, before_power is FB_BLANK_UNBLANK) then
+	 * it changes that status to FB_BLANK_POWERDOWN to get lcd on.
+	 */
+	if (before_power == FB_BLANK_UNBLANK)
+		lcd->power = FB_BLANK_POWERDOWN;
+
+	dev_dbg(&spi->dev, "before_power = %d\n", before_power);
+
+	ret = ams369fg06_power(lcd, before_power);
+
+	return ret;
+}
+#else
+#define ams369fg06_suspend	NULL
+#define ams369fg06_resume	NULL
+#endif
+
+static void ams369fg06_shutdown(struct spi_device *spi)
+{
+	struct ams369fg06 *lcd = dev_get_drvdata(&spi->dev);
+
+	ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver ams369fg06_driver = {
+	.driver = {
+		.name	= "ams369fg06",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ams369fg06_probe,
+	.remove		= __devexit_p(ams369fg06_remove),
+	.shutdown	= ams369fg06_shutdown,
+	.suspend	= ams369fg06_suspend,
+	.resume		= ams369fg06_resume,
+};
+
+module_spi_driver(ams369fg06_driver);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("ams369fg06 LCD Driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/apple_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/apple_bl.c
new file mode 100644
index 0000000..a523b25
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/apple_bl.c
@@ -0,0 +1,260 @@
+/*
+ *  Backlight Driver for Intel-based Apples
+ *
+ *  Copyright (c) Red Hat <mjg@redhat.com>
+ *  Based on code from Pommed:
+ *  Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
+ *  Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
+ *  Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
+ *
+ *  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
+ *  published by the Free Software Foundation.
+ *
+ *  This driver triggers SMIs which cause the firmware to change the
+ *  backlight brightness. This is icky in many ways, but it's impractical to
+ *  get at the firmware code in order to figure out what it's actually doing.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/atomic.h>
+
+static struct backlight_device *apple_backlight_device;
+
+struct hw_data {
+	/* I/O resource to allocate. */
+	unsigned long iostart;
+	unsigned long iolen;
+	/* Backlight operations structure. */
+	const struct backlight_ops backlight_ops;
+	void (*set_brightness)(int);
+};
+
+static const struct hw_data *hw_data;
+
+#define DRIVER "apple_backlight: "
+
+/* 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 machines with Intel chipset.
+ */
+static void intel_chipset_set_brightness(int intensity)
+{
+	outb(0x04 | (intensity << 4), 0xb3);
+	outb(0xbf, 0xb2);
+}
+
+static int intel_chipset_send_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (debug)
+		printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
+		       intensity);
+
+	intel_chipset_set_brightness(intensity);
+	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 DRIVER "read brightness of %d\n",
+		       intensity);
+
+	return intensity;
+}
+
+static const struct hw_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,
+	},
+	.set_brightness = intel_chipset_set_brightness,
+};
+
+/*
+ * Implementation for machines with Nvidia chipset.
+ */
+static void nvidia_chipset_set_brightness(int intensity)
+{
+	outb(0x04 | (intensity << 4), 0x52f);
+	outb(0xbf, 0x52e);
+}
+
+static int nvidia_chipset_send_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (debug)
+		printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
+		       intensity);
+
+	nvidia_chipset_set_brightness(intensity);
+	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 DRIVER "read brightness of %d\n",
+		       intensity);
+
+	return intensity;
+}
+
+static const struct hw_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
+	},
+	.set_brightness = nvidia_chipset_set_brightness,
+};
+
+static int __devinit apple_bl_add(struct acpi_device *dev)
+{
+	struct backlight_properties props;
+	struct pci_dev *host;
+	int intensity;
+
+	host = pci_get_bus_and_slot(0, 0);
+
+	if (!host) {
+		printk(KERN_ERR DRIVER "unable to find PCI host\n");
+		return -ENODEV;
+	}
+
+	if (host->vendor == PCI_VENDOR_ID_INTEL)
+		hw_data = &intel_chipset_data;
+	else if (host->vendor == PCI_VENDOR_ID_NVIDIA)
+		hw_data = &nvidia_chipset_data;
+
+	pci_dev_put(host);
+
+	if (!hw_data) {
+		printk(KERN_ERR DRIVER "unknown hardware\n");
+		return -ENODEV;
+	}
+
+	/* Check that the hardware responds - this may not work under EFI */
+
+	intensity = hw_data->backlight_ops.get_brightness(NULL);
+
+	if (!intensity) {
+		hw_data->set_brightness(1);
+		if (!hw_data->backlight_ops.get_brightness(NULL))
+			return -ENODEV;
+
+		hw_data->set_brightness(0);
+	}
+
+	if (!request_region(hw_data->iostart, hw_data->iolen,
+			    "Apple backlight"))
+		return -ENXIO;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_PLATFORM;
+	props.max_brightness = 15;
+	apple_backlight_device = backlight_device_register("apple_backlight",
+				  NULL, NULL, &hw_data->backlight_ops, &props);
+
+	if (IS_ERR(apple_backlight_device)) {
+		release_region(hw_data->iostart, hw_data->iolen);
+		return PTR_ERR(apple_backlight_device);
+	}
+
+	apple_backlight_device->props.brightness =
+		hw_data->backlight_ops.get_brightness(apple_backlight_device);
+	backlight_update_status(apple_backlight_device);
+
+	return 0;
+}
+
+static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
+{
+	backlight_device_unregister(apple_backlight_device);
+
+	release_region(hw_data->iostart, hw_data->iolen);
+	hw_data = NULL;
+	return 0;
+}
+
+static const struct acpi_device_id apple_bl_ids[] = {
+	{"APP0002", 0},
+	{"", 0},
+};
+
+static struct acpi_driver apple_bl_driver = {
+	.name = "Apple backlight",
+	.ids = apple_bl_ids,
+	.ops = {
+		.add = apple_bl_add,
+		.remove = apple_bl_remove,
+	},
+};
+
+static atomic_t apple_bl_registered = ATOMIC_INIT(0);
+
+int apple_bl_register(void)
+{
+	if (atomic_xchg(&apple_bl_registered, 1) == 0)
+		return acpi_bus_register_driver(&apple_bl_driver);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(apple_bl_register);
+
+void apple_bl_unregister(void)
+{
+	if (atomic_xchg(&apple_bl_registered, 0) == 1)
+		acpi_bus_unregister_driver(&apple_bl_driver);
+}
+EXPORT_SYMBOL_GPL(apple_bl_unregister);
+
+static int __init apple_bl_init(void)
+{
+	return apple_bl_register();
+}
+
+static void __exit apple_bl_exit(void)
+{
+	apple_bl_unregister();
+}
+
+module_init(apple_bl_init);
+module_exit(apple_bl_exit);
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_DESCRIPTION("Apple Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(acpi, apple_bl_ids);
+MODULE_ALIAS("mbp_nvidia_bl");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/atmel-pwm-bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/atmel-pwm-bl.c
new file mode 100644
index 0000000..dab3a0c
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/atmel-pwm-bl.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * Backlight driver using Atmel PWM peripheral.
+ *
+ * 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 published by
+ * the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/backlight.h>
+#include <linux/atmel_pwm.h>
+#include <linux/atmel-pwm-bl.h>
+#include <linux/slab.h>
+
+struct atmel_pwm_bl {
+	const struct atmel_pwm_bl_platform_data	*pdata;
+	struct backlight_device			*bldev;
+	struct platform_device			*pdev;
+	struct pwm_channel			pwmc;
+	int					gpio_on;
+};
+
+static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
+{
+	struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
+	int intensity = bd->props.brightness;
+	int pwm_duty;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	if (pwmbl->pdata->pwm_active_low)
+		pwm_duty = pwmbl->pdata->pwm_duty_min + intensity;
+	else
+		pwm_duty = pwmbl->pdata->pwm_duty_max - intensity;
+
+	if (pwm_duty > pwmbl->pdata->pwm_duty_max)
+		pwm_duty = pwmbl->pdata->pwm_duty_max;
+	if (pwm_duty < pwmbl->pdata->pwm_duty_min)
+		pwm_duty = pwmbl->pdata->pwm_duty_min;
+
+	if (!intensity) {
+		if (pwmbl->gpio_on != -1) {
+			gpio_set_value(pwmbl->gpio_on,
+					0 ^ pwmbl->pdata->on_active_low);
+		}
+		pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
+		pwm_channel_disable(&pwmbl->pwmc);
+	} else {
+		pwm_channel_enable(&pwmbl->pwmc);
+		pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
+		if (pwmbl->gpio_on != -1) {
+			gpio_set_value(pwmbl->gpio_on,
+					1 ^ pwmbl->pdata->on_active_low);
+		}
+	}
+
+	return 0;
+}
+
+static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
+{
+	struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
+	u32 intensity;
+
+	if (pwmbl->pdata->pwm_active_low) {
+		intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) -
+			pwmbl->pdata->pwm_duty_min;
+	} else {
+		intensity = pwmbl->pdata->pwm_duty_max -
+			pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
+	}
+
+	return intensity & 0xffff;
+}
+
+static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
+{
+	unsigned long pwm_rate = pwmbl->pwmc.mck;
+	unsigned long prescale = DIV_ROUND_UP(pwm_rate,
+			(pwmbl->pdata->pwm_frequency *
+			 pwmbl->pdata->pwm_compare_max)) - 1;
+
+	/*
+	 * Prescale must be power of two and maximum 0xf in size because of
+	 * hardware limit. PWM speed will be:
+	 *	PWM module clock speed / (2 ^ prescale).
+	 */
+	prescale = fls(prescale);
+	if (prescale > 0xf)
+		prescale = 0xf;
+
+	pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale);
+	pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY,
+			pwmbl->pdata->pwm_duty_min +
+			pwmbl->bldev->props.brightness);
+	pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
+			pwmbl->pdata->pwm_compare_max);
+
+	dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver "
+			"(%lu Hz)\n", pwmbl->pwmc.mck /
+			pwmbl->pdata->pwm_compare_max /
+			(1 << prescale));
+
+	return pwm_channel_enable(&pwmbl->pwmc);
+}
+
+static const struct backlight_ops atmel_pwm_bl_ops = {
+	.get_brightness = atmel_pwm_bl_get_intensity,
+	.update_status  = atmel_pwm_bl_set_intensity,
+};
+
+static int atmel_pwm_bl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	const struct atmel_pwm_bl_platform_data *pdata;
+	struct backlight_device *bldev;
+	struct atmel_pwm_bl *pwmbl;
+	int retval;
+
+	pwmbl = kzalloc(sizeof(struct atmel_pwm_bl), GFP_KERNEL);
+	if (!pwmbl)
+		return -ENOMEM;
+
+	pwmbl->pdev = pdev;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		retval = -ENODEV;
+		goto err_free_mem;
+	}
+
+	if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
+			pdata->pwm_duty_min > pdata->pwm_duty_max ||
+			pdata->pwm_frequency == 0) {
+		retval = -EINVAL;
+		goto err_free_mem;
+	}
+
+	pwmbl->pdata = pdata;
+	pwmbl->gpio_on = pdata->gpio_on;
+
+	retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
+	if (retval)
+		goto err_free_mem;
+
+	if (pwmbl->gpio_on != -1) {
+		retval = gpio_request(pwmbl->gpio_on, "gpio_atmel_pwm_bl");
+		if (retval) {
+			pwmbl->gpio_on = -1;
+			goto err_free_pwm;
+		}
+
+		/* Turn display off by default. */
+		retval = gpio_direction_output(pwmbl->gpio_on,
+				0 ^ pdata->on_active_low);
+		if (retval)
+			goto err_free_gpio;
+	}
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
+	bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
+					  &atmel_pwm_bl_ops, &props);
+	if (IS_ERR(bldev)) {
+		retval = PTR_ERR(bldev);
+		goto err_free_gpio;
+	}
+
+	pwmbl->bldev = bldev;
+
+	platform_set_drvdata(pdev, pwmbl);
+
+	/* Power up the backlight by default at middle intesity. */
+	bldev->props.power = FB_BLANK_UNBLANK;
+	bldev->props.brightness = bldev->props.max_brightness / 2;
+
+	retval = atmel_pwm_bl_init_pwm(pwmbl);
+	if (retval)
+		goto err_free_bl_dev;
+
+	atmel_pwm_bl_set_intensity(bldev);
+
+	return 0;
+
+err_free_bl_dev:
+	platform_set_drvdata(pdev, NULL);
+	backlight_device_unregister(bldev);
+err_free_gpio:
+	if (pwmbl->gpio_on != -1)
+		gpio_free(pwmbl->gpio_on);
+err_free_pwm:
+	pwm_channel_free(&pwmbl->pwmc);
+err_free_mem:
+	kfree(pwmbl);
+	return retval;
+}
+
+static int __exit atmel_pwm_bl_remove(struct platform_device *pdev)
+{
+	struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
+
+	if (pwmbl->gpio_on != -1) {
+		gpio_set_value(pwmbl->gpio_on,
+					0 ^ pwmbl->pdata->on_active_low);
+		gpio_free(pwmbl->gpio_on);
+	}
+	pwm_channel_disable(&pwmbl->pwmc);
+	pwm_channel_free(&pwmbl->pwmc);
+	backlight_device_unregister(pwmbl->bldev);
+	platform_set_drvdata(pdev, NULL);
+	kfree(pwmbl);
+
+	return 0;
+}
+
+static struct platform_driver atmel_pwm_bl_driver = {
+	.driver = {
+		.name = "atmel-pwm-bl",
+	},
+	/* REVISIT add suspend() and resume() */
+	.remove = __exit_p(atmel_pwm_bl_remove),
+};
+
+static int __init atmel_pwm_bl_init(void)
+{
+	return platform_driver_probe(&atmel_pwm_bl_driver, atmel_pwm_bl_probe);
+}
+module_init(atmel_pwm_bl_init);
+
+static void __exit atmel_pwm_bl_exit(void)
+{
+	platform_driver_unregister(&atmel_pwm_bl_driver);
+}
+module_exit(atmel_pwm_bl_exit);
+
+MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
+MODULE_DESCRIPTION("Atmel PWM backlight driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/backlight.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/backlight.c
new file mode 100644
index 0000000..bf5b1ec
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/backlight.c
@@ -0,0 +1,401 @@
+/*
+ * Backlight Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/backlight.h>
+#include <linux/notifier.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
+static const char *const backlight_types[] = {
+	[BACKLIGHT_RAW] = "raw",
+	[BACKLIGHT_PLATFORM] = "platform",
+	[BACKLIGHT_FIRMWARE] = "firmware",
+};
+
+#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
+			   defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching backlight power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				unsigned long event, void *data)
+{
+	struct backlight_device *bd;
+	struct fb_event *evdata = data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
+		return 0;
+
+	bd = container_of(self, struct backlight_device, fb_notif);
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops)
+		if (!bd->ops->check_fb ||
+		    bd->ops->check_fb(bd, evdata->info)) {
+			bd->props.fb_blank = *(int *)evdata->data;
+			if (bd->props.fb_blank == FB_BLANK_UNBLANK)
+				bd->props.state &= ~BL_CORE_FBBLANK;
+			else
+				bd->props.state |= BL_CORE_FBBLANK;
+			backlight_update_status(bd);
+		}
+	mutex_unlock(&bd->ops_lock);
+	return 0;
+}
+
+static int backlight_register_fb(struct backlight_device *bd)
+{
+	memset(&bd->fb_notif, 0, sizeof(bd->fb_notif));
+	bd->fb_notif.notifier_call = fb_notifier_callback;
+
+	return fb_register_client(&bd->fb_notif);
+}
+
+static void backlight_unregister_fb(struct backlight_device *bd)
+{
+	fb_unregister_client(&bd->fb_notif);
+}
+#else
+static inline int backlight_register_fb(struct backlight_device *bd)
+{
+	return 0;
+}
+
+static inline void backlight_unregister_fb(struct backlight_device *bd)
+{
+}
+#endif /* CONFIG_FB */
+
+static void backlight_generate_event(struct backlight_device *bd,
+				     enum backlight_update_reason reason)
+{
+	char *envp[2];
+
+	switch (reason) {
+	case BACKLIGHT_UPDATE_SYSFS:
+		envp[0] = "SOURCE=sysfs";
+		break;
+	case BACKLIGHT_UPDATE_HOTKEY:
+		envp[0] = "SOURCE=hotkey";
+		break;
+	default:
+		envp[0] = "SOURCE=unknown";
+		break;
+	}
+	envp[1] = NULL;
+	kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp);
+	sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness");
+}
+
+static ssize_t backlight_show_power(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	return sprintf(buf, "%d\n", bd->props.power);
+}
+
+static ssize_t backlight_store_power(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(dev);
+	unsigned long power;
+
+	rc = kstrtoul(buf, 0, &power);
+	if (rc)
+		return rc;
+
+	rc = -ENXIO;
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops) {
+		pr_debug("backlight: set power to %lu\n", power);
+		if (bd->props.power != power) {
+			bd->props.power = power;
+			backlight_update_status(bd);
+		}
+		rc = count;
+	}
+	mutex_unlock(&bd->ops_lock);
+
+	return rc;
+}
+
+static ssize_t backlight_show_brightness(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	return sprintf(buf, "%d\n", bd->props.brightness);
+}
+
+static ssize_t backlight_store_brightness(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(dev);
+	unsigned long brightness;
+
+	rc = kstrtoul(buf, 0, &brightness);
+	if (rc)
+		return rc;
+
+	rc = -ENXIO;
+
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops) {
+		if (brightness > bd->props.max_brightness)
+			rc = -EINVAL;
+		else {
+			pr_debug("backlight: set brightness to %lu\n",
+				 brightness);
+			bd->props.brightness = brightness;
+			backlight_update_status(bd);
+			rc = count;
+		}
+	}
+	mutex_unlock(&bd->ops_lock);
+
+	backlight_generate_event(bd, BACKLIGHT_UPDATE_SYSFS);
+
+	return rc;
+}
+
+static ssize_t backlight_show_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	return sprintf(buf, "%s\n", backlight_types[bd->props.type]);
+}
+
+static ssize_t backlight_show_max_brightness(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	return sprintf(buf, "%d\n", bd->props.max_brightness);
+}
+
+static ssize_t backlight_show_actual_brightness(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int rc = -ENXIO;
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops && bd->ops->get_brightness)
+		rc = sprintf(buf, "%d\n", bd->ops->get_brightness(bd));
+	mutex_unlock(&bd->ops_lock);
+
+	return rc;
+}
+
+static struct class *backlight_class;
+
+static int backlight_suspend(struct device *dev, pm_message_t state)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
+		bd->props.state |= BL_CORE_SUSPENDED;
+		backlight_update_status(bd);
+	}
+	mutex_unlock(&bd->ops_lock);
+
+	return 0;
+}
+
+static int backlight_resume(struct device *dev)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
+		bd->props.state &= ~BL_CORE_SUSPENDED;
+		backlight_update_status(bd);
+	}
+	mutex_unlock(&bd->ops_lock);
+
+	return 0;
+}
+
+static void bl_device_release(struct device *dev)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+	kfree(bd);
+}
+
+static struct device_attribute bl_device_attributes[] = {
+	__ATTR(bl_power, 0644, backlight_show_power, backlight_store_power),
+	__ATTR(brightness, 0644, backlight_show_brightness,
+		     backlight_store_brightness),
+	__ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
+		     NULL),
+	__ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+	__ATTR(type, 0444, backlight_show_type, NULL),
+	__ATTR_NULL,
+};
+
+/**
+ * backlight_force_update - tell the backlight subsystem that hardware state
+ *   has changed
+ * @bd: the backlight device to update
+ *
+ * Updates the internal state of the backlight in response to a hardware event,
+ * and generate a uevent to notify userspace
+ */
+void backlight_force_update(struct backlight_device *bd,
+			    enum backlight_update_reason reason)
+{
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops && bd->ops->get_brightness)
+		bd->props.brightness = bd->ops->get_brightness(bd);
+	mutex_unlock(&bd->ops_lock);
+	backlight_generate_event(bd, reason);
+}
+EXPORT_SYMBOL(backlight_force_update);
+
+/**
+ * backlight_device_register - create and register a new object of
+ *   backlight_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @parent: a pointer to the parent device
+ * @devdata: an optional pointer to be stored for private driver use. The
+ *   methods may retrieve it by using bl_get_data(bd).
+ * @ops: the backlight operations structure.
+ *
+ * Creates and registers new backlight device. Returns either an
+ * ERR_PTR() or a pointer to the newly allocated device.
+ */
+struct backlight_device *backlight_device_register(const char *name,
+	struct device *parent, void *devdata, const struct backlight_ops *ops,
+	const struct backlight_properties *props)
+{
+	struct backlight_device *new_bd;
+	int rc;
+
+	pr_debug("backlight_device_register: name=%s\n", name);
+
+	new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL);
+	if (!new_bd)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&new_bd->update_lock);
+	mutex_init(&new_bd->ops_lock);
+
+	new_bd->dev.class = backlight_class;
+	new_bd->dev.parent = parent;
+	new_bd->dev.release = bl_device_release;
+	dev_set_name(&new_bd->dev, name);
+	dev_set_drvdata(&new_bd->dev, devdata);
+
+	/* Set default properties */
+	if (props) {
+		memcpy(&new_bd->props, props,
+		       sizeof(struct backlight_properties));
+		if (props->type <= 0 || props->type >= BACKLIGHT_TYPE_MAX) {
+			WARN(1, "%s: invalid backlight type", name);
+			new_bd->props.type = BACKLIGHT_RAW;
+		}
+	} else {
+		new_bd->props.type = BACKLIGHT_RAW;
+	}
+
+	rc = device_register(&new_bd->dev);
+	if (rc) {
+		kfree(new_bd);
+		return ERR_PTR(rc);
+	}
+
+	rc = backlight_register_fb(new_bd);
+	if (rc) {
+		device_unregister(&new_bd->dev);
+		return ERR_PTR(rc);
+	}
+
+	new_bd->ops = ops;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_lock(&pmac_backlight_mutex);
+	if (!pmac_backlight)
+		pmac_backlight = new_bd;
+	mutex_unlock(&pmac_backlight_mutex);
+#endif
+
+	return new_bd;
+}
+EXPORT_SYMBOL(backlight_device_register);
+
+/**
+ * backlight_device_unregister - unregisters a backlight device object.
+ * @bd: the backlight device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via backlight_device_register object.
+ */
+void backlight_device_unregister(struct backlight_device *bd)
+{
+	if (!bd)
+		return;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_lock(&pmac_backlight_mutex);
+	if (pmac_backlight == bd)
+		pmac_backlight = NULL;
+	mutex_unlock(&pmac_backlight_mutex);
+#endif
+	mutex_lock(&bd->ops_lock);
+	bd->ops = NULL;
+	mutex_unlock(&bd->ops_lock);
+
+	backlight_unregister_fb(bd);
+	device_unregister(&bd->dev);
+}
+EXPORT_SYMBOL(backlight_device_unregister);
+
+static void __exit backlight_class_exit(void)
+{
+	class_destroy(backlight_class);
+}
+
+static int __init backlight_class_init(void)
+{
+	backlight_class = class_create(THIS_MODULE, "backlight");
+	if (IS_ERR(backlight_class)) {
+		printk(KERN_WARNING "Unable to create backlight class; errno = %ld\n",
+				PTR_ERR(backlight_class));
+		return PTR_ERR(backlight_class);
+	}
+
+	backlight_class->dev_attrs = bl_device_attributes;
+	backlight_class->suspend = backlight_suspend;
+	backlight_class->resume = backlight_resume;
+	return 0;
+}
+
+/*
+ * if this is compiled into the kernel, we need to ensure that the
+ * class is registered before users of the class try to register lcd's
+ */
+postcore_initcall(backlight_class_init);
+module_exit(backlight_class_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
+MODULE_DESCRIPTION("Backlight Lowlevel Control Abstraction");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/corgi_lcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/corgi_lcd.c
new file mode 100644
index 0000000..6dab13f
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/corgi_lcd.c
@@ -0,0 +1,637 @@
+/*
+ *  LCD/Backlight Driver for Sharp Zaurus Handhelds (various models)
+ *
+ *  Copyright (c) 2004-2006 Richard Purdie
+ *
+ *  Based on Sharp's 2.4 Backlight Driver
+ *
+ *  Copyright (c) 2008 Marvell International Ltd.
+ *  	Converted to SPI device based LCD/Backlight device driver
+ *  	by Eric Miao <eric.miao@marvell.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 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/lcd.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/corgi_lcd.h>
+#include <linux/slab.h>
+#include <asm/mach/sharpsl_param.h>
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+/* Register Addresses */
+#define RESCTL_ADRS     0x00
+#define PHACTRL_ADRS    0x01
+#define DUTYCTRL_ADRS   0x02
+#define POWERREG0_ADRS  0x03
+#define POWERREG1_ADRS  0x04
+#define GPOR3_ADRS      0x05
+#define PICTRL_ADRS     0x06
+#define POLCTRL_ADRS    0x07
+
+/* Register Bit Definitions */
+#define RESCTL_QVGA     0x01
+#define RESCTL_VGA      0x00
+
+#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
+#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
+#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
+
+#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
+#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
+#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
+
+#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
+#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
+#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
+#define POWER0_COM_ON   0x08  /* COM Power Supply ON */
+#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
+
+#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
+#define POWER0_COM_OFF  0x00  /* COM Power Supply OFF */
+#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
+
+#define PICTRL_INIT_STATE      0x01
+#define PICTRL_INIOFF          0x02
+#define PICTRL_POWER_DOWN      0x04
+#define PICTRL_COM_SIGNAL_OFF  0x08
+#define PICTRL_DAC_SIGNAL_OFF  0x10
+
+#define POLCTRL_SYNC_POL_FALL  0x01
+#define POLCTRL_EN_POL_FALL    0x02
+#define POLCTRL_DATA_POL_FALL  0x04
+#define POLCTRL_SYNC_ACT_H     0x08
+#define POLCTRL_EN_ACT_L       0x10
+
+#define POLCTRL_SYNC_POL_RISE  0x00
+#define POLCTRL_EN_POL_RISE    0x00
+#define POLCTRL_DATA_POL_RISE  0x00
+#define POLCTRL_SYNC_ACT_L     0x00
+#define POLCTRL_EN_ACT_H       0x00
+
+#define PHACTRL_PHASE_MANUAL   0x01
+#define DEFAULT_PHAD_QVGA     (9)
+#define DEFAULT_COMADJ        (125)
+
+struct corgi_lcd {
+	struct spi_device	*spi_dev;
+	struct lcd_device	*lcd_dev;
+	struct backlight_device	*bl_dev;
+
+	int	limit_mask;
+	int	intensity;
+	int	power;
+	int	mode;
+	char	buf[2];
+
+	int	gpio_backlight_on;
+	int	gpio_backlight_cont;
+	int	gpio_backlight_cont_inverted;
+
+	void (*kick_battery)(void);
+};
+
+static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int reg, uint8_t val);
+
+static struct corgi_lcd *the_corgi_lcd;
+static unsigned long corgibl_flags;
+#define CORGIBL_SUSPENDED     0x01
+#define CORGIBL_BATTLOW       0x02
+
+/*
+ * This is only a pseudo I2C interface. We can't use the standard kernel
+ * routines as the interface is write only. We just assume the data is acked...
+ */
+static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data)
+{
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, data);
+	udelay(10);
+}
+
+static void lcdtg_i2c_send_bit(struct corgi_lcd *lcd, uint8_t data)
+{
+	lcdtg_ssp_i2c_send(lcd, data);
+	lcdtg_ssp_i2c_send(lcd, data | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(lcd, data);
+}
+
+static void lcdtg_i2c_send_start(struct corgi_lcd *lcd, uint8_t base)
+{
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(lcd, base);
+}
+
+static void lcdtg_i2c_send_stop(struct corgi_lcd *lcd, uint8_t base)
+{
+	lcdtg_ssp_i2c_send(lcd, base);
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+}
+
+static void lcdtg_i2c_send_byte(struct corgi_lcd *lcd,
+				uint8_t base, uint8_t data)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		if (data & 0x80)
+			lcdtg_i2c_send_bit(lcd, base | POWER0_COM_DOUT);
+		else
+			lcdtg_i2c_send_bit(lcd, base);
+		data <<= 1;
+	}
+}
+
+static void lcdtg_i2c_wait_ack(struct corgi_lcd *lcd, uint8_t base)
+{
+	lcdtg_i2c_send_bit(lcd, base);
+}
+
+static void lcdtg_set_common_voltage(struct corgi_lcd *lcd,
+				     uint8_t base_data, uint8_t data)
+{
+	/* Set Common Voltage to M62332FP via I2C */
+	lcdtg_i2c_send_start(lcd, base_data);
+	lcdtg_i2c_send_byte(lcd, base_data, 0x9c);
+	lcdtg_i2c_wait_ack(lcd, base_data);
+	lcdtg_i2c_send_byte(lcd, base_data, 0x00);
+	lcdtg_i2c_wait_ack(lcd, base_data);
+	lcdtg_i2c_send_byte(lcd, base_data, data);
+	lcdtg_i2c_wait_ack(lcd, base_data);
+	lcdtg_i2c_send_stop(lcd, base_data);
+}
+
+static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int adrs, uint8_t data)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer = {
+		.len		= 1,
+		.cs_change	= 1,
+		.tx_buf		= lcd->buf,
+	};
+
+	lcd->buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(lcd->spi_dev, &msg);
+}
+
+/* Set Phase Adjust */
+static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode)
+{
+	int adj;
+
+	switch(mode) {
+	case CORGI_LCD_MODE_VGA:
+		/* Setting for VGA */
+		adj = sharpsl_param.phadadj;
+		adj = (adj < 0) ? PHACTRL_PHASE_MANUAL :
+				  PHACTRL_PHASE_MANUAL | ((adj & 0xf) << 1);
+		break;
+	case CORGI_LCD_MODE_QVGA:
+	default:
+		/* Setting for QVGA */
+		adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
+		break;
+	}
+
+	corgi_ssp_lcdtg_send(lcd, PHACTRL_ADRS, adj);
+}
+
+static void corgi_lcd_power_on(struct corgi_lcd *lcd)
+{
+	int comadj;
+
+	/* Initialize Internal Logic & Port */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
+			PICTRL_POWER_DOWN | PICTRL_INIOFF |
+			PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF |
+			PICTRL_DAC_SIGNAL_OFF);
+
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF |
+			POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+	/* VDD(+8V), SVSS(-4V) ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+	mdelay(3);
+
+	/* DAC ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+			POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* INIB = H, INI = L  */
+	/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
+			PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
+
+	/* Set Common Voltage */
+	comadj = sharpsl_param.comadj;
+	if (comadj < 0)
+		comadj = DEFAULT_COMADJ;
+
+	lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF |
+				 POWER0_VCC5_OFF, comadj);
+
+	/* VCC5 ON, DAC ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+			POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* GVSS(-8V) ON, VDD ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+	mdelay(2);
+
+	/* COM SIGNAL ON (PICTL[3] = L) */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_INIT_STATE);
+
+	/* COM ON, DAC ON, VCC5_ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+			POWER0_COM_ON | POWER0_VCC5_ON);
+
+	/* VW ON, GVSS ON, VDD ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* Signals output enable */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, 0);
+
+	/* Set Phase Adjust */
+	lcdtg_set_phadadj(lcd, lcd->mode);
+
+	/* Initialize for Input Signals from ATI */
+	corgi_ssp_lcdtg_send(lcd, POLCTRL_ADRS,
+			POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE |
+			POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L |
+			POLCTRL_EN_ACT_H);
+	udelay(1000);
+
+	switch (lcd->mode) {
+	case CORGI_LCD_MODE_VGA:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA);
+		break;
+	case CORGI_LCD_MODE_QVGA:
+	default:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA);
+		break;
+	}
+}
+
+static void corgi_lcd_power_off(struct corgi_lcd *lcd)
+{
+	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
+	msleep(34);
+
+	/* (1)VW OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* (2)COM OFF */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* (3)Set Common Voltage Bias 0V */
+	lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF |
+			POWER0_VCC5_ON, 0);
+
+	/* (4)GVSS OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+
+	/* (5)VCC5 OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (6)Set PDWN, INIOFF, DACOFF */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
+			PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
+			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
+
+	/* (7)DAC OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (8)VDD OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+}
+
+static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+	int mode = CORGI_LCD_MODE_QVGA;
+
+	if (m->xres == 640 || m->xres == 480)
+		mode = CORGI_LCD_MODE_VGA;
+
+	if (lcd->mode == mode)
+		return 0;
+
+	lcdtg_set_phadadj(lcd, mode);
+
+	switch (mode) {
+	case CORGI_LCD_MODE_VGA:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA);
+		break;
+	case CORGI_LCD_MODE_QVGA:
+	default:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA);
+		break;
+	}
+
+	lcd->mode = mode;
+	return 0;
+}
+
+static int corgi_lcd_set_power(struct lcd_device *ld, int power)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		corgi_lcd_power_on(lcd);
+
+	if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		corgi_lcd_power_off(lcd);
+
+	lcd->power = power;
+	return 0;
+}
+
+static int corgi_lcd_get_power(struct lcd_device *ld)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+
+	return lcd->power;
+}
+
+static struct lcd_ops corgi_lcd_ops = {
+	.get_power	= corgi_lcd_get_power,
+	.set_power	= corgi_lcd_set_power,
+	.set_mode	= corgi_lcd_set_mode,
+};
+
+static int corgi_bl_get_intensity(struct backlight_device *bd)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
+
+	return lcd->intensity;
+}
+
+static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
+{
+	int cont;
+
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity);
+
+	/* Bit 5 via GPIO_BACKLIGHT_CONT */
+	cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
+
+	if (gpio_is_valid(lcd->gpio_backlight_cont))
+		gpio_set_value(lcd->gpio_backlight_cont, cont);
+
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_set_value(lcd->gpio_backlight_on, intensity);
+
+	if (lcd->kick_battery)
+		lcd->kick_battery();
+
+	lcd->intensity = intensity;
+	return 0;
+}
+
+static int corgi_bl_update_status(struct backlight_device *bd)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	if (corgibl_flags & CORGIBL_SUSPENDED)
+		intensity = 0;
+
+	if ((corgibl_flags & CORGIBL_BATTLOW) && intensity > lcd->limit_mask)
+		intensity = lcd->limit_mask;
+
+	return corgi_bl_set_intensity(lcd, intensity);
+}
+
+void corgi_lcd_limit_intensity(int limit)
+{
+	if (limit)
+		corgibl_flags |= CORGIBL_BATTLOW;
+	else
+		corgibl_flags &= ~CORGIBL_BATTLOW;
+
+	backlight_update_status(the_corgi_lcd->bl_dev);
+}
+EXPORT_SYMBOL(corgi_lcd_limit_intensity);
+
+static const struct backlight_ops corgi_bl_ops = {
+	.get_brightness	= corgi_bl_get_intensity,
+	.update_status  = corgi_bl_update_status,
+};
+
+#ifdef CONFIG_PM
+static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+
+	corgibl_flags |= CORGIBL_SUSPENDED;
+	corgi_bl_set_intensity(lcd, 0);
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
+	return 0;
+}
+
+static int corgi_lcd_resume(struct spi_device *spi)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+
+	corgibl_flags &= ~CORGIBL_SUSPENDED;
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
+	backlight_update_status(lcd->bl_dev);
+	return 0;
+}
+#else
+#define corgi_lcd_suspend	NULL
+#define corgi_lcd_resume	NULL
+#endif
+
+static int setup_gpio_backlight(struct corgi_lcd *lcd,
+				struct corgi_lcd_platform_data *pdata)
+{
+	struct spi_device *spi = lcd->spi_dev;
+	int err;
+
+	lcd->gpio_backlight_on = -1;
+	lcd->gpio_backlight_cont = -1;
+
+	if (gpio_is_valid(pdata->gpio_backlight_on)) {
+		err = gpio_request(pdata->gpio_backlight_on, "BL_ON");
+		if (err) {
+			dev_err(&spi->dev, "failed to request GPIO%d for "
+				"backlight_on\n", pdata->gpio_backlight_on);
+			return err;
+		}
+
+		lcd->gpio_backlight_on = pdata->gpio_backlight_on;
+		gpio_direction_output(lcd->gpio_backlight_on, 0);
+	}
+
+	if (gpio_is_valid(pdata->gpio_backlight_cont)) {
+		err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT");
+		if (err) {
+			dev_err(&spi->dev, "failed to request GPIO%d for "
+				"backlight_cont\n", pdata->gpio_backlight_cont);
+			goto err_free_backlight_on;
+		}
+
+		lcd->gpio_backlight_cont = pdata->gpio_backlight_cont;
+
+		/* spitz and akita use both GPIOs for backlight, and
+		 * have inverted polarity of GPIO_BACKLIGHT_CONT
+		 */
+		if (gpio_is_valid(lcd->gpio_backlight_on)) {
+			lcd->gpio_backlight_cont_inverted = 1;
+			gpio_direction_output(lcd->gpio_backlight_cont, 1);
+		} else {
+			lcd->gpio_backlight_cont_inverted = 0;
+			gpio_direction_output(lcd->gpio_backlight_cont, 0);
+		}
+	}
+	return 0;
+
+err_free_backlight_on:
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_free(lcd->gpio_backlight_on);
+	return err;
+}
+
+static int __devinit corgi_lcd_probe(struct spi_device *spi)
+{
+	struct backlight_properties props;
+	struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
+	struct corgi_lcd *lcd;
+	int ret = 0;
+
+	if (pdata == NULL) {
+		dev_err(&spi->dev, "platform data not available\n");
+		return -EINVAL;
+	}
+
+	lcd = kzalloc(sizeof(struct corgi_lcd), GFP_KERNEL);
+	if (!lcd) {
+		dev_err(&spi->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	lcd->spi_dev = spi;
+
+	lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev,
+					lcd, &corgi_lcd_ops);
+	if (IS_ERR(lcd->lcd_dev)) {
+		ret = PTR_ERR(lcd->lcd_dev);
+		goto err_free_lcd;
+	}
+	lcd->power = FB_BLANK_POWERDOWN;
+	lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = pdata->max_intensity;
+	lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
+						&corgi_bl_ops, &props);
+	if (IS_ERR(lcd->bl_dev)) {
+		ret = PTR_ERR(lcd->bl_dev);
+		goto err_unregister_lcd;
+	}
+	lcd->bl_dev->props.brightness = pdata->default_intensity;
+	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
+
+	ret = setup_gpio_backlight(lcd, pdata);
+	if (ret)
+		goto err_unregister_bl;
+
+	lcd->kick_battery = pdata->kick_battery;
+
+	dev_set_drvdata(&spi->dev, lcd);
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
+	backlight_update_status(lcd->bl_dev);
+
+	lcd->limit_mask = pdata->limit_mask;
+	the_corgi_lcd = lcd;
+	return 0;
+
+err_unregister_bl:
+	backlight_device_unregister(lcd->bl_dev);
+err_unregister_lcd:
+	lcd_device_unregister(lcd->lcd_dev);
+err_free_lcd:
+	kfree(lcd);
+	return ret;
+}
+
+static int __devexit corgi_lcd_remove(struct spi_device *spi)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+
+	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
+	lcd->bl_dev->props.brightness = 0;
+	backlight_update_status(lcd->bl_dev);
+	backlight_device_unregister(lcd->bl_dev);
+
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_free(lcd->gpio_backlight_on);
+
+	if (gpio_is_valid(lcd->gpio_backlight_cont))
+		gpio_free(lcd->gpio_backlight_cont);
+
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
+	lcd_device_unregister(lcd->lcd_dev);
+	kfree(lcd);
+
+	return 0;
+}
+
+static struct spi_driver corgi_lcd_driver = {
+	.driver		= {
+		.name	= "corgi-lcd",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= corgi_lcd_probe,
+	.remove		= __devexit_p(corgi_lcd_remove),
+	.suspend	= corgi_lcd_suspend,
+	.resume		= corgi_lcd_resume,
+};
+
+module_spi_driver(corgi_lcd_driver);
+
+MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:corgi-lcd");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/cr_bllcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/cr_bllcd.c
new file mode 100644
index 0000000..22489eb
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/cr_bllcd.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Carillo Ranch video subsystem driver.
+ * The Carillo Ranch video subsystem driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Carillo Ranch video subsystem driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors:
+ *   Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ *   Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+/* The LVDS- and panel power controls sits on the
+ * GPIO port of the ISA bridge.
+ */
+
+#define CRVML_DEVICE_LPC    0x27B8
+#define CRVML_REG_GPIOBAR   0x48
+#define CRVML_REG_GPIOEN    0x4C
+#define CRVML_GPIOEN_BIT    (1 << 4)
+#define CRVML_PANEL_PORT    0x38
+#define CRVML_LVDS_ON       0x00000001
+#define CRVML_PANEL_ON      0x00000002
+#define CRVML_BACKLIGHT_OFF 0x00000004
+
+/* The PLL Clock register sits on Host bridge */
+#define CRVML_DEVICE_MCH   0x5001
+#define CRVML_REG_MCHBAR   0x44
+#define CRVML_REG_MCHEN    0x54
+#define CRVML_MCHEN_BIT    (1 << 28)
+#define CRVML_MCHMAP_SIZE  4096
+#define CRVML_REG_CLOCK    0xc3c
+#define CRVML_CLOCK_SHIFT  8
+#define CRVML_CLOCK_MASK   0x00000f00
+
+static struct pci_dev *lpc_dev;
+static u32 gpio_bar;
+
+struct cr_panel {
+	struct backlight_device *cr_backlight_device;
+	struct lcd_device *cr_lcd_device;
+};
+
+static int cr_backlight_set_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+	u32 addr = gpio_bar + CRVML_PANEL_PORT;
+	u32 cur = inl(addr);
+
+	if (bd->props.power == FB_BLANK_UNBLANK)
+		intensity = FB_BLANK_UNBLANK;
+	if (bd->props.fb_blank == FB_BLANK_UNBLANK)
+		intensity = FB_BLANK_UNBLANK;
+	if (bd->props.power == FB_BLANK_POWERDOWN)
+		intensity = FB_BLANK_POWERDOWN;
+	if (bd->props.fb_blank == FB_BLANK_POWERDOWN)
+		intensity = FB_BLANK_POWERDOWN;
+
+	if (intensity == FB_BLANK_UNBLANK) { /* FULL ON */
+		cur &= ~CRVML_BACKLIGHT_OFF;
+		outl(cur, addr);
+	} else if (intensity == FB_BLANK_POWERDOWN) { /* OFF */
+		cur |= CRVML_BACKLIGHT_OFF;
+		outl(cur, addr);
+	} /* anything else, don't bother */
+
+	return 0;
+}
+
+static int cr_backlight_get_intensity(struct backlight_device *bd)
+{
+	u32 addr = gpio_bar + CRVML_PANEL_PORT;
+	u32 cur = inl(addr);
+	u8 intensity;
+
+	if (cur & CRVML_BACKLIGHT_OFF)
+		intensity = FB_BLANK_POWERDOWN;
+	else
+		intensity = FB_BLANK_UNBLANK;
+
+	return intensity;
+}
+
+static const struct backlight_ops cr_backlight_ops = {
+	.get_brightness = cr_backlight_get_intensity,
+	.update_status = cr_backlight_set_intensity,
+};
+
+static void cr_panel_on(void)
+{
+	u32 addr = gpio_bar + CRVML_PANEL_PORT;
+	u32 cur = inl(addr);
+
+	if (!(cur & CRVML_PANEL_ON)) {
+		/* Make sure LVDS controller is down. */
+		if (cur & 0x00000001) {
+			cur &= ~CRVML_LVDS_ON;
+			outl(cur, addr);
+		}
+		/* Power up Panel */
+		schedule_timeout(HZ / 10);
+		cur |= CRVML_PANEL_ON;
+		outl(cur, addr);
+	}
+
+	/* Power up LVDS controller */
+
+	if (!(cur & CRVML_LVDS_ON)) {
+		schedule_timeout(HZ / 10);
+		outl(cur | CRVML_LVDS_ON, addr);
+	}
+}
+
+static void cr_panel_off(void)
+{
+	u32 addr = gpio_bar + CRVML_PANEL_PORT;
+	u32 cur = inl(addr);
+
+	/* Power down LVDS controller first to avoid high currents */
+	if (cur & CRVML_LVDS_ON) {
+		cur &= ~CRVML_LVDS_ON;
+		outl(cur, addr);
+	}
+	if (cur & CRVML_PANEL_ON) {
+		schedule_timeout(HZ / 10);
+		outl(cur & ~CRVML_PANEL_ON, addr);
+	}
+}
+
+static int cr_lcd_set_power(struct lcd_device *ld, int power)
+{
+	if (power == FB_BLANK_UNBLANK)
+		cr_panel_on();
+	if (power == FB_BLANK_POWERDOWN)
+		cr_panel_off();
+
+	return 0;
+}
+
+static struct lcd_ops cr_lcd_ops = {
+	.set_power = cr_lcd_set_power,
+};
+
+static int cr_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct backlight_device *bdp;
+	struct lcd_device *ldp;
+	struct cr_panel *crp;
+	u8 dev_en;
+
+	lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+					CRVML_DEVICE_LPC, NULL);
+	if (!lpc_dev) {
+		printk("INTEL CARILLO RANCH LPC not found.\n");
+		return -ENODEV;
+	}
+
+	pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en);
+	if (!(dev_en & CRVML_GPIOEN_BIT)) {
+		printk(KERN_ERR
+		       "Carillo Ranch GPIO device was not enabled.\n");
+		pci_dev_put(lpc_dev);
+		return -ENODEV;
+	}
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
+					&cr_backlight_ops, &props);
+	if (IS_ERR(bdp)) {
+		pci_dev_put(lpc_dev);
+		return PTR_ERR(bdp);
+	}
+
+	ldp = lcd_device_register("cr-lcd", &pdev->dev, NULL, &cr_lcd_ops);
+	if (IS_ERR(ldp)) {
+		backlight_device_unregister(bdp);
+		pci_dev_put(lpc_dev);
+		return PTR_ERR(ldp);
+	}
+
+	pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
+			      &gpio_bar);
+	gpio_bar &= ~0x3F;
+
+	crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL);
+	if (!crp) {
+		lcd_device_unregister(ldp);
+		backlight_device_unregister(bdp);
+		pci_dev_put(lpc_dev);
+		return -ENOMEM;
+	}
+
+	crp->cr_backlight_device = bdp;
+	crp->cr_lcd_device = ldp;
+	crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
+	crp->cr_backlight_device->props.brightness = 0;
+	cr_backlight_set_intensity(crp->cr_backlight_device);
+	cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
+
+	platform_set_drvdata(pdev, crp);
+
+	return 0;
+}
+
+static int cr_backlight_remove(struct platform_device *pdev)
+{
+	struct cr_panel *crp = platform_get_drvdata(pdev);
+	crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN;
+	crp->cr_backlight_device->props.brightness = 0;
+	crp->cr_backlight_device->props.max_brightness = 0;
+	cr_backlight_set_intensity(crp->cr_backlight_device);
+	cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN);
+	backlight_device_unregister(crp->cr_backlight_device);
+	lcd_device_unregister(crp->cr_lcd_device);
+	pci_dev_put(lpc_dev);
+
+	return 0;
+}
+
+static struct platform_driver cr_backlight_driver = {
+	.probe = cr_backlight_probe,
+	.remove = cr_backlight_remove,
+	.driver = {
+		   .name = "cr_backlight",
+		   },
+};
+
+static struct platform_device *crp;
+
+static int __init cr_backlight_init(void)
+{
+	int ret = platform_driver_register(&cr_backlight_driver);
+
+	if (ret)
+		return ret;
+
+	crp = platform_device_register_simple("cr_backlight", -1, NULL, 0);
+	if (IS_ERR(crp)) {
+		platform_driver_unregister(&cr_backlight_driver);
+		return PTR_ERR(crp);
+	}
+
+	printk("Carillo Ranch Backlight Driver Initialized.\n");
+
+	return 0;
+}
+
+static void __exit cr_backlight_exit(void)
+{
+	platform_device_unregister(crp);
+	platform_driver_unregister(&cr_backlight_driver);
+}
+
+module_init(cr_backlight_init);
+module_exit(cr_backlight_exit);
+
+MODULE_AUTHOR("Tungsten Graphics Inc.");
+MODULE_DESCRIPTION("Carillo Ranch Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/da903x_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/da903x_bl.c
new file mode 100644
index 0000000..30e1968
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/da903x_bl.c
@@ -0,0 +1,204 @@
+/*
+ * Backlight driver for Dialog Semiconductor DA9030/DA9034
+ *
+ * Copyright (C) 2008 Compulab, Ltd.
+ * 	Mike Rapoport <mike@compulab.co.il>
+ *
+ * Copyright (C) 2006-2008 Marvell International Ltd.
+ * 	Eric Miao <eric.miao@marvell.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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/mfd/da903x.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#define DA9030_WLED_CONTROL	0x25
+#define DA9030_WLED_CP_EN	(1 << 6)
+#define DA9030_WLED_TRIM(x)	((x) & 0x7)
+
+#define DA9034_WLED_CONTROL1	0x3C
+#define DA9034_WLED_CONTROL2	0x3D
+#define DA9034_WLED_ISET(x)	((x) & 0x1f)
+
+#define DA9034_WLED_BOOST_EN	(1 << 5)
+
+#define DA9030_MAX_BRIGHTNESS	7
+#define DA9034_MAX_BRIGHTNESS	0x7f
+
+struct da903x_backlight_data {
+	struct device *da903x_dev;
+	int id;
+	int current_brightness;
+};
+
+static int da903x_backlight_set(struct backlight_device *bl, int brightness)
+{
+	struct da903x_backlight_data *data = bl_get_data(bl);
+	struct device *dev = data->da903x_dev;
+	uint8_t val;
+	int ret = 0;
+
+	switch (data->id) {
+	case DA9034_ID_WLED:
+		ret = da903x_update(dev, DA9034_WLED_CONTROL1,
+				brightness, 0x7f);
+		if (ret)
+			return ret;
+
+		if (data->current_brightness && brightness == 0)
+			ret = da903x_clr_bits(dev,
+					DA9034_WLED_CONTROL2,
+					DA9034_WLED_BOOST_EN);
+
+		if (data->current_brightness == 0 && brightness)
+			ret = da903x_set_bits(dev,
+					DA9034_WLED_CONTROL2,
+					DA9034_WLED_BOOST_EN);
+		break;
+	case DA9030_ID_WLED:
+		val = DA9030_WLED_TRIM(brightness);
+		val |= brightness ? DA9030_WLED_CP_EN : 0;
+		ret = da903x_write(dev, DA9030_WLED_CONTROL, val);
+		break;
+	}
+
+	if (ret)
+		return ret;
+
+	data->current_brightness = brightness;
+	return 0;
+}
+
+static int da903x_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	return da903x_backlight_set(bl, brightness);
+}
+
+static int da903x_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct da903x_backlight_data *data = bl_get_data(bl);
+	return data->current_brightness;
+}
+
+static const struct backlight_ops da903x_backlight_ops = {
+	.update_status	= da903x_backlight_update_status,
+	.get_brightness	= da903x_backlight_get_brightness,
+};
+
+static int da903x_backlight_probe(struct platform_device *pdev)
+{
+	struct da9034_backlight_pdata *pdata = pdev->dev.platform_data;
+	struct da903x_backlight_data *data;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	int max_brightness;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	switch (pdev->id) {
+	case DA9030_ID_WLED:
+		max_brightness = DA9030_MAX_BRIGHTNESS;
+		break;
+	case DA9034_ID_WLED:
+		max_brightness = DA9034_MAX_BRIGHTNESS;
+		break;
+	default:
+		dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
+				pdev->id);
+		return -EINVAL;
+	}
+
+	data->id = pdev->id;
+	data->da903x_dev = pdev->dev.parent;
+	data->current_brightness = 0;
+
+	/* adjust the WLED output current */
+	if (pdata)
+		da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
+				DA9034_WLED_ISET(pdata->output_current));
+
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = max_brightness;
+	bl = backlight_device_register(pdev->name, data->da903x_dev, data,
+				       &da903x_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+
+	bl->props.brightness = max_brightness;
+
+	platform_set_drvdata(pdev, bl);
+	backlight_update_status(bl);
+	return 0;
+}
+
+static int da903x_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(bl);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int da903x_backlight_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	return da903x_backlight_set(bl, 0);
+}
+
+static int da903x_backlight_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+
+	backlight_update_status(bl);
+	return 0;
+}
+
+static const struct dev_pm_ops da903x_backlight_pm_ops = {
+	.suspend	= da903x_backlight_suspend,
+	.resume		= da903x_backlight_resume,
+};
+#endif
+
+static struct platform_driver da903x_backlight_driver = {
+	.driver		= {
+		.name	= "da903x-backlight",
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &da903x_backlight_pm_ops,
+#endif
+	},
+	.probe		= da903x_backlight_probe,
+	.remove		= da903x_backlight_remove,
+};
+
+module_platform_driver(da903x_backlight_driver);
+
+MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
+	      "Mike Rapoport <mike@compulab.co.il>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da903x-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/da9052_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/da9052_bl.c
new file mode 100644
index 0000000..b628d68
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/da9052_bl.c
@@ -0,0 +1,187 @@
+/*
+ * Backlight Driver for Dialog DA9052 PMICs
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+#define DA9052_MAX_BRIGHTNESS		0xFF
+
+enum {
+	DA9052_WLEDS_OFF,
+	DA9052_WLEDS_ON,
+};
+
+enum {
+	DA9052_TYPE_WLED1,
+	DA9052_TYPE_WLED2,
+	DA9052_TYPE_WLED3,
+};
+
+static unsigned char wled_bank[] = {
+	DA9052_LED1_CONF_REG,
+	DA9052_LED2_CONF_REG,
+	DA9052_LED3_CONF_REG,
+};
+
+struct da9052_bl {
+	struct da9052 *da9052;
+	uint brightness;
+	uint state;
+	uint led_reg;
+};
+
+static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
+{
+	unsigned char boost_en;
+	unsigned char i_sink;
+	int ret;
+
+	boost_en = 0x3F;
+	i_sink = 0xFF;
+	if (wleds->state == DA9052_WLEDS_OFF) {
+		boost_en = 0x00;
+		i_sink = 0x00;
+	}
+
+	ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en);
+	if (ret < 0)
+		return ret;
+
+	ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink);
+	if (ret < 0)
+		return ret;
+
+	ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0);
+	if (ret < 0)
+		return ret;
+
+	msleep(10);
+
+	if (wleds->brightness) {
+		ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
+				       wleds->brightness);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int da9052_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+	struct da9052_bl *wleds = bl_get_data(bl);
+
+	wleds->brightness = brightness;
+	wleds->state = DA9052_WLEDS_ON;
+
+	return da9052_adjust_wled_brightness(wleds);
+}
+
+static int da9052_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct da9052_bl *wleds = bl_get_data(bl);
+
+	return wleds->brightness;
+}
+
+static const struct backlight_ops da9052_backlight_ops = {
+	.update_status = da9052_backlight_update_status,
+	.get_brightness = da9052_backlight_get_brightness,
+};
+
+static int da9052_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct da9052_bl *wleds;
+
+	wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL);
+	if (!wleds)
+		return -ENOMEM;
+
+	wleds->da9052 = dev_get_drvdata(pdev->dev.parent);
+	wleds->brightness = 0;
+	wleds->led_reg = platform_get_device_id(pdev)->driver_data;
+	wleds->state = DA9052_WLEDS_OFF;
+
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = DA9052_MAX_BRIGHTNESS;
+
+	bl = backlight_device_register(pdev->name, wleds->da9052->dev, wleds,
+				       &da9052_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "Failed to register backlight\n");
+		devm_kfree(&pdev->dev, wleds);
+		return PTR_ERR(bl);
+	}
+
+	bl->props.max_brightness = DA9052_MAX_BRIGHTNESS;
+	bl->props.brightness = 0;
+	platform_set_drvdata(pdev, bl);
+
+	return da9052_adjust_wled_brightness(wleds);
+}
+
+static int da9052_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct da9052_bl *wleds = bl_get_data(bl);
+
+	wleds->brightness = 0;
+	wleds->state = DA9052_WLEDS_OFF;
+	da9052_adjust_wled_brightness(wleds);
+	backlight_device_unregister(bl);
+	devm_kfree(&pdev->dev, wleds);
+
+	return 0;
+}
+
+static struct platform_device_id da9052_wled_ids[] = {
+	{
+		.name		= "da9052-wled1",
+		.driver_data	= DA9052_TYPE_WLED1,
+	},
+	{
+		.name		= "da9052-wled2",
+		.driver_data	= DA9052_TYPE_WLED2,
+	},
+	{
+		.name		= "da9052-wled3",
+		.driver_data	= DA9052_TYPE_WLED3,
+	},
+};
+
+static struct platform_driver da9052_wled_driver = {
+	.probe		= da9052_backlight_probe,
+	.remove		= da9052_backlight_remove,
+	.id_table	= da9052_wled_ids,
+	.driver	= {
+		.name	= "da9052-wled",
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(da9052_wled_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ep93xx_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ep93xx_bl.c
new file mode 100644
index 0000000..08214e1
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ep93xx_bl.c
@@ -0,0 +1,154 @@
+/*
+ * Driver for the Cirrus EP93xx lcd backlight
+ *
+ * Copyright (c) 2010 H Hartley Sweeten <hsweeten@visionengravers.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 as
+ * published by the Free Software Foundation.
+ *
+ * This driver controls the pulse width modulated brightness control output,
+ * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#define EP93XX_MAX_COUNT		255
+#define EP93XX_MAX_BRIGHT		255
+#define EP93XX_DEF_BRIGHT		128
+
+struct ep93xxbl {
+	void __iomem *mmio;
+	int brightness;
+};
+
+static int ep93xxbl_set(struct backlight_device *bl, int brightness)
+{
+	struct ep93xxbl *ep93xxbl = bl_get_data(bl);
+
+	writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio);
+
+	ep93xxbl->brightness = brightness;
+
+	return 0;
+}
+
+static int ep93xxbl_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK ||
+	    bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	return ep93xxbl_set(bl, brightness);
+}
+
+static int ep93xxbl_get_brightness(struct backlight_device *bl)
+{
+	struct ep93xxbl *ep93xxbl = bl_get_data(bl);
+
+	return ep93xxbl->brightness;
+}
+
+static const struct backlight_ops ep93xxbl_ops = {
+	.update_status	= ep93xxbl_update_status,
+	.get_brightness	= ep93xxbl_get_brightness,
+};
+
+static int __init ep93xxbl_probe(struct platform_device *dev)
+{
+	struct ep93xxbl *ep93xxbl;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+
+	ep93xxbl = devm_kzalloc(&dev->dev, sizeof(*ep93xxbl), GFP_KERNEL);
+	if (!ep93xxbl)
+		return -ENOMEM;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	/*
+	 * FIXME - We don't do a request_mem_region here because we are
+	 * sharing the register space with the framebuffer driver (see
+	 * drivers/video/ep93xx-fb.c) and doing so will cause the second
+	 * loaded driver to return -EBUSY.
+	 *
+	 * NOTE: No locking is required; the framebuffer does not touch
+	 * this register.
+	 */
+	ep93xxbl->mmio = devm_ioremap(&dev->dev, res->start,
+				      resource_size(res));
+	if (!ep93xxbl->mmio)
+		return -ENXIO;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = EP93XX_MAX_BRIGHT;
+	bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl,
+				       &ep93xxbl_ops, &props);
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	bl->props.brightness = EP93XX_DEF_BRIGHT;
+
+	platform_set_drvdata(dev, bl);
+
+	ep93xxbl_update_status(bl);
+
+	return 0;
+}
+
+static int ep93xxbl_remove(struct platform_device *dev)
+{
+	struct backlight_device *bl = platform_get_drvdata(dev);
+
+	backlight_device_unregister(bl);
+	platform_set_drvdata(dev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ep93xxbl_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct backlight_device *bl = platform_get_drvdata(dev);
+
+	return ep93xxbl_set(bl, 0);
+}
+
+static int ep93xxbl_resume(struct platform_device *dev)
+{
+	struct backlight_device *bl = platform_get_drvdata(dev);
+
+	backlight_update_status(bl);
+	return 0;
+}
+#else
+#define ep93xxbl_suspend	NULL
+#define ep93xxbl_resume		NULL
+#endif
+
+static struct platform_driver ep93xxbl_driver = {
+	.driver		= {
+		.name	= "ep93xx-bl",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ep93xxbl_probe,
+	.remove		= __devexit_p(ep93xxbl_remove),
+	.suspend	= ep93xxbl_suspend,
+	.resume		= ep93xxbl_resume,
+};
+
+module_platform_driver(ep93xxbl_driver);
+
+MODULE_DESCRIPTION("EP93xx Backlight Driver");
+MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ep93xx-bl");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/generic_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/generic_bl.c
new file mode 100644
index 0000000..9ce6170
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/generic_bl.c
@@ -0,0 +1,139 @@
+/*
+ *  Generic Backlight Driver
+ *
+ *  Copyright (c) 2004-2008 Richard Purdie
+ *
+ *  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
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+static int genericbl_intensity;
+static struct backlight_device *generic_backlight_device;
+static struct generic_bl_info *bl_machinfo;
+
+/* Flag to signal when the battery is low */
+#define GENERICBL_BATTLOW       BL_CORE_DRIVER1
+
+static int genericbl_send_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.state & BL_CORE_FBBLANK)
+		intensity = 0;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		intensity = 0;
+	if (bd->props.state & GENERICBL_BATTLOW)
+		intensity &= bl_machinfo->limit_mask;
+
+	bl_machinfo->set_bl_intensity(intensity);
+
+	genericbl_intensity = intensity;
+
+	if (bl_machinfo->kick_battery)
+		bl_machinfo->kick_battery();
+
+	return 0;
+}
+
+static int genericbl_get_intensity(struct backlight_device *bd)
+{
+	return genericbl_intensity;
+}
+
+/*
+ * Called when the battery is low to limit the backlight intensity.
+ * If limit==0 clear any limit, otherwise limit the intensity
+ */
+void genericbl_limit_intensity(int limit)
+{
+	struct backlight_device *bd = generic_backlight_device;
+
+	mutex_lock(&bd->ops_lock);
+	if (limit)
+		bd->props.state |= GENERICBL_BATTLOW;
+	else
+		bd->props.state &= ~GENERICBL_BATTLOW;
+	backlight_update_status(generic_backlight_device);
+	mutex_unlock(&bd->ops_lock);
+}
+EXPORT_SYMBOL(genericbl_limit_intensity);
+
+static const struct backlight_ops genericbl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = genericbl_get_intensity,
+	.update_status  = genericbl_send_intensity,
+};
+
+static int genericbl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct generic_bl_info *machinfo = pdev->dev.platform_data;
+	const char *name = "generic-bl";
+	struct backlight_device *bd;
+
+	bl_machinfo = machinfo;
+	if (!machinfo->limit_mask)
+		machinfo->limit_mask = -1;
+
+	if (machinfo->name)
+		name = machinfo->name;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = machinfo->max_intensity;
+	bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
+				       &props);
+	if (IS_ERR (bd))
+		return PTR_ERR (bd);
+
+	platform_set_drvdata(pdev, bd);
+
+	bd->props.power = FB_BLANK_UNBLANK;
+	bd->props.brightness = machinfo->default_intensity;
+	backlight_update_status(bd);
+
+	generic_backlight_device = bd;
+
+	printk("Generic Backlight Driver Initialized.\n");
+	return 0;
+}
+
+static int genericbl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	bd->props.power = 0;
+	bd->props.brightness = 0;
+	backlight_update_status(bd);
+
+	backlight_device_unregister(bd);
+
+	printk("Generic Backlight Driver Unloaded\n");
+	return 0;
+}
+
+static struct platform_driver genericbl_driver = {
+	.probe		= genericbl_probe,
+	.remove		= genericbl_remove,
+	.driver		= {
+		.name	= "generic-bl",
+	},
+};
+
+module_platform_driver(genericbl_driver);
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
+MODULE_DESCRIPTION("Generic Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/hp680_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/hp680_bl.c
new file mode 100644
index 0000000..38aa002
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/hp680_bl.c
@@ -0,0 +1,179 @@
+/*
+ *  Backlight Driver for HP Jornada 680
+ *
+ *  Copyright (c) 2005 Andriy Skulysh
+ *
+ *  Based on Sharp's Corgi Backlight Driver
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#include <cpu/dac.h>
+#include <mach/hp6xx.h>
+#include <asm/hd64461.h>
+
+#define HP680_MAX_INTENSITY 255
+#define HP680_DEFAULT_INTENSITY 10
+
+static int hp680bl_suspended;
+static int current_intensity = 0;
+static DEFINE_SPINLOCK(bl_lock);
+
+static void hp680bl_send_intensity(struct backlight_device *bd)
+{
+	unsigned long flags;
+	u16 v;
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (hp680bl_suspended)
+		intensity = 0;
+
+	spin_lock_irqsave(&bl_lock, flags);
+	if (intensity && current_intensity == 0) {
+		sh_dac_enable(DAC_LCD_BRIGHTNESS);
+		v = inw(HD64461_GPBDR);
+		v &= ~HD64461_GPBDR_LCDOFF;
+		outw(v, HD64461_GPBDR);
+		sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+	} else if (intensity == 0 && current_intensity != 0) {
+		sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+		sh_dac_disable(DAC_LCD_BRIGHTNESS);
+		v = inw(HD64461_GPBDR);
+		v |= HD64461_GPBDR_LCDOFF;
+		outw(v, HD64461_GPBDR);
+	} else if (intensity) {
+		sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+	}
+	spin_unlock_irqrestore(&bl_lock, flags);
+
+	current_intensity = intensity;
+}
+
+
+#ifdef CONFIG_PM
+static int hp680bl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	hp680bl_suspended = 1;
+	hp680bl_send_intensity(bd);
+	return 0;
+}
+
+static int hp680bl_resume(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	hp680bl_suspended = 0;
+	hp680bl_send_intensity(bd);
+	return 0;
+}
+#else
+#define hp680bl_suspend	NULL
+#define hp680bl_resume	NULL
+#endif
+
+static int hp680bl_set_intensity(struct backlight_device *bd)
+{
+	hp680bl_send_intensity(bd);
+	return 0;
+}
+
+static int hp680bl_get_intensity(struct backlight_device *bd)
+{
+	return current_intensity;
+}
+
+static const struct backlight_ops hp680bl_ops = {
+	.get_brightness = hp680bl_get_intensity,
+	.update_status  = hp680bl_set_intensity,
+};
+
+static int __devinit hp680bl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct backlight_device *bd;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = HP680_MAX_INTENSITY;
+	bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
+				       &hp680bl_ops, &props);
+	if (IS_ERR(bd))
+		return PTR_ERR(bd);
+
+	platform_set_drvdata(pdev, bd);
+
+	bd->props.brightness = HP680_DEFAULT_INTENSITY;
+	hp680bl_send_intensity(bd);
+
+	return 0;
+}
+
+static int hp680bl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	bd->props.brightness = 0;
+	bd->props.power = 0;
+	hp680bl_send_intensity(bd);
+
+	backlight_device_unregister(bd);
+
+	return 0;
+}
+
+static struct platform_driver hp680bl_driver = {
+	.probe		= hp680bl_probe,
+	.remove		= hp680bl_remove,
+	.suspend	= hp680bl_suspend,
+	.resume		= hp680bl_resume,
+	.driver		= {
+		.name	= "hp680-bl",
+	},
+};
+
+static struct platform_device *hp680bl_device;
+
+static int __init hp680bl_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&hp680bl_driver);
+	if (ret)
+		return ret;
+	hp680bl_device = platform_device_register_simple("hp680-bl", -1,
+							NULL, 0);
+	if (IS_ERR(hp680bl_device)) {
+		platform_driver_unregister(&hp680bl_driver);
+		return PTR_ERR(hp680bl_device);
+	}
+	return 0;
+}
+
+static void __exit hp680bl_exit(void)
+{
+	platform_device_unregister(hp680bl_device);
+ 	platform_driver_unregister(&hp680bl_driver);
+}
+
+module_init(hp680bl_init);
+module_exit(hp680bl_exit);
+
+MODULE_AUTHOR("Andriy Skulysh <askulysh@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 680 Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ili9320.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ili9320.c
new file mode 100644
index 0000000..5118a9f
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ili9320.c
@@ -0,0 +1,331 @@
+/* drivers/video/backlight/ili9320.c
+ *
+ * ILI9320 LCD controller driver core.
+ *
+ * Copyright 2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/spi/spi.h>
+
+#include <video/ili9320.h>
+
+#include "ili9320.h"
+
+
+static inline int ili9320_write_spi(struct ili9320 *ili,
+				    unsigned int reg,
+				    unsigned int value)
+{
+	struct ili9320_spi *spi = &ili->access.spi;
+	unsigned char *addr = spi->buffer_addr;
+	unsigned char *data = spi->buffer_data;
+
+	/* spi message consits of:
+	 * first byte: ID and operation
+	 */
+
+	addr[0] = spi->id | ILI9320_SPI_INDEX | ILI9320_SPI_WRITE;
+	addr[1] = reg >> 8;
+	addr[2] = reg;
+
+	/* second message is the data to transfer */
+
+	data[0] = spi->id | ILI9320_SPI_DATA  | ILI9320_SPI_WRITE;
+ 	data[1] = value >> 8;
+	data[2] = value;
+
+	return spi_sync(spi->dev, &spi->message);
+}
+
+int ili9320_write(struct ili9320 *ili, unsigned int reg, unsigned int value)
+{
+	dev_dbg(ili->dev, "write: reg=%02x, val=%04x\n", reg, value);
+	return ili->write(ili, reg, value);
+}
+
+EXPORT_SYMBOL_GPL(ili9320_write);
+
+int ili9320_write_regs(struct ili9320 *ili,
+		       struct ili9320_reg *values,
+		       int nr_values)
+{
+	int index;
+	int ret;
+
+	for (index = 0; index < nr_values; index++, values++) {
+		ret = ili9320_write(ili, values->address, values->value);
+		if (ret != 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ili9320_write_regs);
+
+static void ili9320_reset(struct ili9320 *lcd)
+{
+	struct ili9320_platdata *cfg = lcd->platdata;
+
+	cfg->reset(1);
+	mdelay(50);
+
+	cfg->reset(0);
+	mdelay(50);
+
+	cfg->reset(1);
+	mdelay(100);
+}
+
+static inline int ili9320_init_chip(struct ili9320 *lcd)
+{
+	int ret;
+
+	ili9320_reset(lcd);
+
+	ret = lcd->client->init(lcd, lcd->platdata);
+	if (ret != 0) {
+		dev_err(lcd->dev, "failed to initialise display\n");
+		return ret;
+	}
+
+	lcd->initialised = 1;
+	return 0;
+}
+
+static inline int ili9320_power_on(struct ili9320 *lcd)
+{
+	if (!lcd->initialised)
+		ili9320_init_chip(lcd);
+
+	lcd->display1 |= (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
+	ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
+
+	return 0;
+}
+
+static inline int ili9320_power_off(struct ili9320 *lcd)
+{
+	lcd->display1 &= ~(ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
+	ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
+
+	return 0;
+}
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+static int ili9320_power(struct ili9320 *lcd, int power)
+{
+	int ret = 0;
+
+	dev_dbg(lcd->dev, "power %d => %d\n", lcd->power, power);
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		ret = ili9320_power_on(lcd);
+	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		ret = ili9320_power_off(lcd);
+
+	if (ret == 0)
+		lcd->power = power;
+	else
+		dev_warn(lcd->dev, "failed to set power mode %d\n", power);
+
+	return ret;
+}
+
+static inline struct ili9320 *to_our_lcd(struct lcd_device *lcd)
+{
+	return lcd_get_data(lcd);
+}
+
+static int ili9320_set_power(struct lcd_device *ld, int power)
+{
+	struct ili9320 *lcd = to_our_lcd(ld);
+
+	return ili9320_power(lcd, power);
+}
+
+static int ili9320_get_power(struct lcd_device *ld)
+{
+	struct ili9320 *lcd = to_our_lcd(ld);
+
+	return lcd->power;
+}
+
+static struct lcd_ops ili9320_ops = {
+	.get_power	= ili9320_get_power,
+	.set_power	= ili9320_set_power,
+};
+
+static void __devinit ili9320_setup_spi(struct ili9320 *ili,
+					struct spi_device *dev)
+{
+	struct ili9320_spi *spi = &ili->access.spi;
+
+	ili->write = ili9320_write_spi;
+	spi->dev = dev;
+
+	/* fill the two messages we are going to use to send the data
+	 * with, the first the address followed by the data. The datasheet
+	 * says they should be done as two distinct cycles of the SPI CS line.
+	 */
+
+	spi->xfer[0].tx_buf = spi->buffer_addr;
+	spi->xfer[1].tx_buf = spi->buffer_data;
+	spi->xfer[0].len = 3;
+	spi->xfer[1].len = 3;
+	spi->xfer[0].bits_per_word = 8;
+	spi->xfer[1].bits_per_word = 8;
+	spi->xfer[0].cs_change = 1;
+
+	spi_message_init(&spi->message);
+	spi_message_add_tail(&spi->xfer[0], &spi->message);
+	spi_message_add_tail(&spi->xfer[1], &spi->message);
+}
+
+int __devinit ili9320_probe_spi(struct spi_device *spi,
+				struct ili9320_client *client)
+{
+	struct ili9320_platdata *cfg = spi->dev.platform_data;
+	struct device *dev = &spi->dev;
+	struct ili9320 *ili;
+	struct lcd_device *lcd;
+	int ret = 0;
+
+	/* verify we where given some information */
+
+	if (cfg == NULL) {
+		dev_err(dev, "no platform data supplied\n");
+		return -EINVAL;
+	}
+
+	if (cfg->hsize <= 0 || cfg->vsize <= 0 || cfg->reset == NULL) {
+		dev_err(dev, "invalid platform data supplied\n");
+		return -EINVAL;
+	}
+
+	/* allocate and initialse our state */
+
+	ili = kzalloc(sizeof(struct ili9320), GFP_KERNEL);
+	if (ili == NULL) {
+		dev_err(dev, "no memory for device\n");
+		return -ENOMEM;
+	}
+
+	ili->access.spi.id = ILI9320_SPI_IDCODE | ILI9320_SPI_ID(1);
+
+	ili->dev = dev;
+	ili->client = client;
+	ili->power = FB_BLANK_POWERDOWN;
+	ili->platdata = cfg;
+
+	dev_set_drvdata(&spi->dev, ili);
+
+	ili9320_setup_spi(ili, spi);
+
+	lcd = lcd_device_register("ili9320", dev, ili, &ili9320_ops);
+	if (IS_ERR(lcd)) {
+		dev_err(dev, "failed to register lcd device\n");
+		ret = PTR_ERR(lcd);
+		goto err_free;
+	}
+
+	ili->lcd = lcd;
+
+	dev_info(dev, "initialising %s\n", client->name);
+
+	ret = ili9320_power(ili, FB_BLANK_UNBLANK);
+	if (ret != 0) {
+		dev_err(dev, "failed to set lcd power state\n");
+		goto err_unregister;
+	}
+
+	return 0;
+
+ err_unregister:
+	lcd_device_unregister(lcd);
+
+ err_free:
+	kfree(ili);
+
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(ili9320_probe_spi);
+
+int __devexit ili9320_remove(struct ili9320 *ili)
+{
+	ili9320_power(ili, FB_BLANK_POWERDOWN);
+
+	lcd_device_unregister(ili->lcd);
+	kfree(ili);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ili9320_remove);
+
+#ifdef CONFIG_PM
+int ili9320_suspend(struct ili9320 *lcd, pm_message_t state)
+{
+	int ret;
+
+	dev_dbg(lcd->dev, "%s: event %d\n", __func__, state.event);
+
+	if (state.event == PM_EVENT_SUSPEND) {
+		ret = ili9320_power(lcd, FB_BLANK_POWERDOWN);
+
+		if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
+			ili9320_write(lcd, ILI9320_POWER1, lcd->power1 |
+				      ILI9320_POWER1_SLP |
+				      ILI9320_POWER1_DSTB);
+			lcd->initialised = 0;
+		}
+
+		return ret;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ili9320_suspend);
+
+int ili9320_resume(struct ili9320 *lcd)
+{
+	dev_info(lcd->dev, "resuming from power state %d\n", lcd->power);
+
+	if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
+		ili9320_write(lcd, ILI9320_POWER1, 0x00);
+	}
+
+	return ili9320_power(lcd, FB_BLANK_UNBLANK);
+}
+
+EXPORT_SYMBOL_GPL(ili9320_resume);
+#endif
+
+/* Power down all displays on reboot, poweroff or halt */
+void ili9320_shutdown(struct ili9320 *lcd)
+{
+	ili9320_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+EXPORT_SYMBOL_GPL(ili9320_shutdown);
+
+MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
+MODULE_DESCRIPTION("ILI9320 LCD Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ili9320.h b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ili9320.h
new file mode 100644
index 0000000..e388eca
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ili9320.h
@@ -0,0 +1,80 @@
+/* drivers/video/backlight/ili9320.h
+ *
+ * ILI9320 LCD controller driver core.
+ *
+ * Copyright 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+/* Holder for register and value pairs. */
+struct ili9320_reg {
+	unsigned short		address;
+	unsigned short		value;
+};
+
+struct ili9320;
+
+struct ili9320_client {
+	const char	*name;
+	int	(*init)(struct ili9320 *ili, struct ili9320_platdata *cfg);
+
+};
+/* Device attached via an SPI bus. */
+struct  ili9320_spi {
+	struct spi_device	*dev;
+	struct spi_message	message;
+	struct spi_transfer	xfer[2];
+
+	unsigned char		id;
+	unsigned char		buffer_addr[4];
+	unsigned char		buffer_data[4];
+};
+
+/* ILI9320 device state. */
+struct ili9320 {
+	union {
+		struct ili9320_spi	spi;	/* SPI attachged device. */
+	} access;				/* Register access method. */
+
+	struct device			*dev;
+	struct lcd_device		*lcd;	/* LCD device we created. */
+	struct ili9320_client		*client;
+	struct ili9320_platdata		*platdata;
+
+	int				 power; /* current power state. */
+	int				 initialised;
+
+	unsigned short			 display1;
+	unsigned short			 power1;
+
+	int (*write)(struct ili9320 *ili, unsigned int reg, unsigned int val);
+};
+
+
+/* ILI9320 register access routines */
+
+extern int ili9320_write(struct ili9320 *ili,
+			 unsigned int reg, unsigned int value);
+
+extern int ili9320_write_regs(struct ili9320 *ili,
+			      struct ili9320_reg *values,
+			      int nr_values);
+
+/* Device probe */
+
+extern int ili9320_probe_spi(struct spi_device *spi,
+			     struct ili9320_client *cli);
+
+extern int ili9320_remove(struct ili9320 *lcd);
+extern void ili9320_shutdown(struct ili9320 *lcd);
+
+/* PM */
+
+extern int ili9320_suspend(struct ili9320 *lcd, pm_message_t state);
+extern int ili9320_resume(struct ili9320 *lcd);
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/jornada720_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/jornada720_bl.c
new file mode 100644
index 0000000..2f8af5d
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/jornada720_bl.c
@@ -0,0 +1,154 @@
+/*
+ *
+ * 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 const 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)
+{
+	struct backlight_properties props;
+	int ret;
+	struct backlight_device *bd;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = BL_MAX_BRIGHT;
+	bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
+				       &jornada_bl_ops, &props);
+
+	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 */
+	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",
+	},
+};
+
+module_platform_driver(jornada_bl_driver);
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/jornada720_lcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/jornada720_lcd.c
new file mode 100644
index 0000000..22d231a
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/jornada720_lcd.c
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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",
+	},
+};
+
+module_platform_driver(jornada_lcd_driver);
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/kb3886_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/kb3886_bl.c
new file mode 100644
index 0000000..72dd555
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/kb3886_bl.c
@@ -0,0 +1,209 @@
+/*
+ *  Backlight Driver for the KB3886 Backlight
+ *
+ *  Copyright (c) 2007-2008 Claudio Nieder
+ *
+ *  Based on corgi_bl.c by Richard Purdie and kb3886 driver by Robert Woerle
+ *
+ *  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
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
+
+#define KB3886_PARENT 0x64
+#define KB3886_IO 0x60
+#define KB3886_ADC_DAC_PWM 0xC4
+#define KB3886_PWM0_WRITE 0x81
+#define KB3886_PWM0_READ 0x41
+
+static DEFINE_MUTEX(bl_mutex);
+
+static void kb3886_bl_set_intensity(int intensity)
+{
+	mutex_lock(&bl_mutex);
+	intensity = intensity&0xff;
+	outb(KB3886_ADC_DAC_PWM, KB3886_PARENT);
+	msleep(10);
+	outb(KB3886_PWM0_WRITE, KB3886_IO);
+	msleep(10);
+	outb(intensity, KB3886_IO);
+	mutex_unlock(&bl_mutex);
+}
+
+struct kb3886bl_machinfo {
+	int max_intensity;
+	int default_intensity;
+	int limit_mask;
+	void (*set_bl_intensity)(int intensity);
+};
+
+static struct kb3886bl_machinfo kb3886_bl_machinfo = {
+	.max_intensity = 0xff,
+	.default_intensity = 0xa0,
+	.limit_mask = 0x7f,
+	.set_bl_intensity = kb3886_bl_set_intensity,
+};
+
+static struct platform_device kb3886bl_device = {
+	.name		= "kb3886-bl",
+	.dev		= {
+		.platform_data	= &kb3886_bl_machinfo,
+	},
+	.id		= -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&kb3886bl_device,
+};
+
+/*
+ * Back to driver
+ */
+
+static int kb3886bl_intensity;
+static struct backlight_device *kb3886_backlight_device;
+static struct kb3886bl_machinfo *bl_machinfo;
+
+static unsigned long kb3886bl_flags;
+#define KB3886BL_SUSPENDED     0x01
+
+static struct dmi_system_id __initdata kb3886bl_device_table[] = {
+	{
+		.ident = "Sahara Touch-iT",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SDV"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "iTouch T201"),
+		},
+	},
+	{ }
+};
+
+static int kb3886bl_send_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (kb3886bl_flags & KB3886BL_SUSPENDED)
+		intensity = 0;
+
+	bl_machinfo->set_bl_intensity(intensity);
+
+	kb3886bl_intensity = intensity;
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int kb3886bl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	kb3886bl_flags |= KB3886BL_SUSPENDED;
+	backlight_update_status(bd);
+	return 0;
+}
+
+static int kb3886bl_resume(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	kb3886bl_flags &= ~KB3886BL_SUSPENDED;
+	backlight_update_status(bd);
+	return 0;
+}
+#else
+#define kb3886bl_suspend	NULL
+#define kb3886bl_resume		NULL
+#endif
+
+static int kb3886bl_get_intensity(struct backlight_device *bd)
+{
+	return kb3886bl_intensity;
+}
+
+static const struct backlight_ops kb3886bl_ops = {
+	.get_brightness = kb3886bl_get_intensity,
+	.update_status  = kb3886bl_send_intensity,
+};
+
+static int kb3886bl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
+
+	bl_machinfo = machinfo;
+	if (!machinfo->limit_mask)
+		machinfo->limit_mask = -1;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = machinfo->max_intensity;
+	kb3886_backlight_device = backlight_device_register("kb3886-bl",
+							    &pdev->dev, NULL,
+							    &kb3886bl_ops,
+							    &props);
+	if (IS_ERR(kb3886_backlight_device))
+		return PTR_ERR(kb3886_backlight_device);
+
+	platform_set_drvdata(pdev, kb3886_backlight_device);
+
+	kb3886_backlight_device->props.power = FB_BLANK_UNBLANK;
+	kb3886_backlight_device->props.brightness = machinfo->default_intensity;
+	backlight_update_status(kb3886_backlight_device);
+
+	return 0;
+}
+
+static int kb3886bl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(bd);
+
+	return 0;
+}
+
+static struct platform_driver kb3886bl_driver = {
+	.probe		= kb3886bl_probe,
+	.remove		= kb3886bl_remove,
+	.suspend	= kb3886bl_suspend,
+	.resume		= kb3886bl_resume,
+	.driver		= {
+		.name	= "kb3886-bl",
+	},
+};
+
+static int __init kb3886_init(void)
+{
+	if (!dmi_check_system(kb3886bl_device_table))
+		return -ENODEV;
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	return platform_driver_register(&kb3886bl_driver);
+}
+
+static void __exit kb3886_exit(void)
+{
+	platform_driver_unregister(&kb3886bl_driver);
+}
+
+module_init(kb3886_init);
+module_exit(kb3886_exit);
+
+MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
+MODULE_DESCRIPTION("Tabletkiosk Sahara Touch-iT Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("dmi:*:svnSDV:pniTouchT201:*");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/l4f00242t03.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/l4f00242t03.c
new file mode 100644
index 0000000..6022b67
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/l4f00242t03.c
@@ -0,0 +1,281 @@
+/*
+ * l4f00242t03.c -- support for Epson L4F00242T03 LCD
+ *
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * 	Inspired by Marek Vasut work in l4f00242t03.c
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+
+struct l4f00242t03_priv {
+	struct spi_device	*spi;
+	struct lcd_device	*ld;
+	int lcd_state;
+	struct regulator *io_reg;
+	struct regulator *core_reg;
+};
+
+
+static void l4f00242t03_reset(unsigned int gpio)
+{
+	pr_debug("l4f00242t03_reset.\n");
+	gpio_set_value(gpio, 1);
+	mdelay(100);
+	gpio_set_value(gpio, 0);
+	mdelay(10);	/* tRES >= 100us */
+	gpio_set_value(gpio, 1);
+	mdelay(20);
+}
+
+#define param(x) ((x) | 0x100)
+
+static void l4f00242t03_lcd_init(struct spi_device *spi)
+{
+	struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+	struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+	const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
+
+	dev_dbg(&spi->dev, "initializing LCD\n");
+
+	regulator_set_voltage(priv->io_reg, 1800000, 1800000);
+	regulator_enable(priv->io_reg);
+
+	regulator_set_voltage(priv->core_reg, 2800000, 2800000);
+	regulator_enable(priv->core_reg);
+
+	l4f00242t03_reset(pdata->reset_gpio);
+
+	gpio_set_value(pdata->data_enable_gpio, 1);
+	msleep(60);
+	spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16));
+}
+
+static void l4f00242t03_lcd_powerdown(struct spi_device *spi)
+{
+	struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+	struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+
+	dev_dbg(&spi->dev, "Powering down LCD\n");
+
+	gpio_set_value(pdata->data_enable_gpio, 0);
+
+	regulator_disable(priv->io_reg);
+	regulator_disable(priv->core_reg);
+}
+
+static int l4f00242t03_lcd_power_get(struct lcd_device *ld)
+{
+	struct l4f00242t03_priv *priv = lcd_get_data(ld);
+
+	return priv->lcd_state;
+}
+
+static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
+{
+	struct l4f00242t03_priv *priv = lcd_get_data(ld);
+	struct spi_device *spi = priv->spi;
+
+	const u16 slpout = 0x11;
+	const u16 dison = 0x29;
+
+	const u16 slpin = 0x10;
+	const u16 disoff = 0x28;
+
+	if (power <= FB_BLANK_NORMAL) {
+		if (priv->lcd_state <= FB_BLANK_NORMAL) {
+			/* Do nothing, the LCD is running */
+		} else if (priv->lcd_state < FB_BLANK_POWERDOWN) {
+			dev_dbg(&spi->dev, "Resuming LCD\n");
+
+			spi_write(spi, (const u8 *)&slpout, sizeof(u16));
+			msleep(60);
+			spi_write(spi, (const u8 *)&dison, sizeof(u16));
+		} else {
+			/* priv->lcd_state == FB_BLANK_POWERDOWN */
+			l4f00242t03_lcd_init(spi);
+			priv->lcd_state = FB_BLANK_VSYNC_SUSPEND;
+			l4f00242t03_lcd_power_set(priv->ld, power);
+		}
+	} else if (power < FB_BLANK_POWERDOWN) {
+		if (priv->lcd_state <= FB_BLANK_NORMAL) {
+			/* Send the display in standby */
+			dev_dbg(&spi->dev, "Standby the LCD\n");
+
+			spi_write(spi, (const u8 *)&disoff, sizeof(u16));
+			msleep(60);
+			spi_write(spi, (const u8 *)&slpin, sizeof(u16));
+		} else if (priv->lcd_state < FB_BLANK_POWERDOWN) {
+			/* Do nothing, the LCD is already in standby */
+		} else {
+			/* priv->lcd_state == FB_BLANK_POWERDOWN */
+			l4f00242t03_lcd_init(spi);
+			priv->lcd_state = FB_BLANK_UNBLANK;
+			l4f00242t03_lcd_power_set(ld, power);
+		}
+	} else {
+		/* power == FB_BLANK_POWERDOWN */
+		if (priv->lcd_state != FB_BLANK_POWERDOWN) {
+			/* Clear the screen before shutting down */
+			spi_write(spi, (const u8 *)&disoff, sizeof(u16));
+			msleep(60);
+			l4f00242t03_lcd_powerdown(spi);
+		}
+	}
+
+	priv->lcd_state = power;
+
+	return 0;
+}
+
+static struct lcd_ops l4f_ops = {
+	.set_power	= l4f00242t03_lcd_power_set,
+	.get_power	= l4f00242t03_lcd_power_get,
+};
+
+static int __devinit l4f00242t03_probe(struct spi_device *spi)
+{
+	struct l4f00242t03_priv *priv;
+	struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+	int ret;
+
+	if (pdata == NULL) {
+		dev_err(&spi->dev, "Uninitialized platform data.\n");
+		return -EINVAL;
+	}
+
+	priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL);
+
+	if (priv == NULL) {
+		dev_err(&spi->dev, "No memory for this device.\n");
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(&spi->dev, priv);
+	spi->bits_per_word = 9;
+	spi_setup(spi);
+
+	priv->spi = spi;
+
+	ret = gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH,
+						"lcd l4f00242t03 reset");
+	if (ret) {
+		dev_err(&spi->dev,
+			"Unable to get the lcd l4f00242t03 reset gpio.\n");
+		goto err;
+	}
+
+	ret = gpio_request_one(pdata->data_enable_gpio, GPIOF_OUT_INIT_LOW,
+						"lcd l4f00242t03 data enable");
+	if (ret) {
+		dev_err(&spi->dev,
+			"Unable to get the lcd l4f00242t03 data en gpio.\n");
+		goto err2;
+	}
+
+	priv->io_reg = regulator_get(&spi->dev, "vdd");
+	if (IS_ERR(priv->io_reg)) {
+		ret = PTR_ERR(priv->io_reg);
+		dev_err(&spi->dev, "%s: Unable to get the IO regulator\n",
+		       __func__);
+		goto err3;
+	}
+
+	priv->core_reg = regulator_get(&spi->dev, "vcore");
+	if (IS_ERR(priv->core_reg)) {
+		ret = PTR_ERR(priv->core_reg);
+		dev_err(&spi->dev, "%s: Unable to get the core regulator\n",
+		       __func__);
+		goto err4;
+	}
+
+	priv->ld = lcd_device_register("l4f00242t03",
+					&spi->dev, priv, &l4f_ops);
+	if (IS_ERR(priv->ld)) {
+		ret = PTR_ERR(priv->ld);
+		goto err5;
+	}
+
+	/* Init the LCD */
+	l4f00242t03_lcd_init(spi);
+	priv->lcd_state = FB_BLANK_VSYNC_SUSPEND;
+	l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_UNBLANK);
+
+	dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
+
+	return 0;
+
+err5:
+	regulator_put(priv->core_reg);
+err4:
+	regulator_put(priv->io_reg);
+err3:
+	gpio_free(pdata->data_enable_gpio);
+err2:
+	gpio_free(pdata->reset_gpio);
+err:
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit l4f00242t03_remove(struct spi_device *spi)
+{
+	struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+	struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data;
+
+	l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
+	lcd_device_unregister(priv->ld);
+
+	dev_set_drvdata(&spi->dev, NULL);
+
+	gpio_free(pdata->data_enable_gpio);
+	gpio_free(pdata->reset_gpio);
+
+	regulator_put(priv->io_reg);
+	regulator_put(priv->core_reg);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static void l4f00242t03_shutdown(struct spi_device *spi)
+{
+	struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+
+	if (priv)
+		l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
+
+}
+
+static struct spi_driver l4f00242t03_driver = {
+	.driver = {
+		.name	= "l4f00242t03",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= l4f00242t03_probe,
+	.remove		= __devexit_p(l4f00242t03_remove),
+	.shutdown	= l4f00242t03_shutdown,
+};
+
+module_spi_driver(l4f00242t03_driver);
+
+MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
+MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
+MODULE_LICENSE("GPL v2");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/lcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/lcd.c
new file mode 100644
index 0000000..79c1b0d
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/lcd.c
@@ -0,0 +1,274 @@
+/*
+ * LCD Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/lcd.h>
+#include <linux/notifier.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+
+#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
+			   defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching lcd power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				 unsigned long event, void *data)
+{
+	struct lcd_device *ld;
+	struct fb_event *evdata = data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	switch (event) {
+	case FB_EVENT_BLANK:
+	case FB_EVENT_MODE_CHANGE:
+	case FB_EVENT_MODE_CHANGE_ALL:
+		break;
+	default:
+		return 0;
+	}
+
+	ld = container_of(self, struct lcd_device, fb_notif);
+	if (!ld->ops)
+		return 0;
+
+	mutex_lock(&ld->ops_lock);
+	if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
+		if (event == FB_EVENT_BLANK) {
+			if (ld->ops->set_power)
+				ld->ops->set_power(ld, *(int *)evdata->data);
+		} else {
+			if (ld->ops->set_mode)
+				ld->ops->set_mode(ld, evdata->data);
+		}
+	}
+	mutex_unlock(&ld->ops_lock);
+	return 0;
+}
+
+static int lcd_register_fb(struct lcd_device *ld)
+{
+	memset(&ld->fb_notif, 0, sizeof(ld->fb_notif));
+	ld->fb_notif.notifier_call = fb_notifier_callback;
+	return fb_register_client(&ld->fb_notif);
+}
+
+static void lcd_unregister_fb(struct lcd_device *ld)
+{
+	fb_unregister_client(&ld->fb_notif);
+}
+#else
+static int lcd_register_fb(struct lcd_device *ld)
+{
+	return 0;
+}
+
+static inline void lcd_unregister_fb(struct lcd_device *ld)
+{
+}
+#endif /* CONFIG_FB */
+
+static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(dev);
+
+	mutex_lock(&ld->ops_lock);
+	if (ld->ops && ld->ops->get_power)
+		rc = sprintf(buf, "%d\n", ld->ops->get_power(ld));
+	else
+		rc = -ENXIO;
+	mutex_unlock(&ld->ops_lock);
+
+	return rc;
+}
+
+static ssize_t lcd_store_power(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int rc = -ENXIO;
+	struct lcd_device *ld = to_lcd_device(dev);
+	unsigned long power;
+
+	rc = kstrtoul(buf, 0, &power);
+	if (rc)
+		return rc;
+
+	mutex_lock(&ld->ops_lock);
+	if (ld->ops && ld->ops->set_power) {
+		pr_debug("lcd: set power to %lu\n", power);
+		ld->ops->set_power(ld, power);
+		rc = count;
+	}
+	mutex_unlock(&ld->ops_lock);
+
+	return rc;
+}
+
+static ssize_t lcd_show_contrast(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int rc = -ENXIO;
+	struct lcd_device *ld = to_lcd_device(dev);
+
+	mutex_lock(&ld->ops_lock);
+	if (ld->ops && ld->ops->get_contrast)
+		rc = sprintf(buf, "%d\n", ld->ops->get_contrast(ld));
+	mutex_unlock(&ld->ops_lock);
+
+	return rc;
+}
+
+static ssize_t lcd_store_contrast(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int rc = -ENXIO;
+	struct lcd_device *ld = to_lcd_device(dev);
+	unsigned long contrast;
+
+	rc = kstrtoul(buf, 0, &contrast);
+	if (rc)
+		return rc;
+
+	mutex_lock(&ld->ops_lock);
+	if (ld->ops && ld->ops->set_contrast) {
+		pr_debug("lcd: set contrast to %lu\n", contrast);
+		ld->ops->set_contrast(ld, contrast);
+		rc = count;
+	}
+	mutex_unlock(&ld->ops_lock);
+
+	return rc;
+}
+
+static ssize_t lcd_show_max_contrast(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct lcd_device *ld = to_lcd_device(dev);
+
+	return sprintf(buf, "%d\n", ld->props.max_contrast);
+}
+
+static struct class *lcd_class;
+
+static void lcd_device_release(struct device *dev)
+{
+	struct lcd_device *ld = to_lcd_device(dev);
+	kfree(ld);
+}
+
+static struct device_attribute lcd_device_attributes[] = {
+	__ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power),
+	__ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
+	__ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
+	__ATTR_NULL,
+};
+
+/**
+ * lcd_device_register - register a new object of lcd_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @devdata: an optional pointer to be stored in the device. The
+ *   methods may retrieve it by using lcd_get_data(ld).
+ * @ops: the lcd operations structure.
+ *
+ * Creates and registers a new lcd device. Returns either an ERR_PTR()
+ * or a pointer to the newly allocated device.
+ */
+struct lcd_device *lcd_device_register(const char *name, struct device *parent,
+		void *devdata, struct lcd_ops *ops)
+{
+	struct lcd_device *new_ld;
+	int rc;
+
+	pr_debug("lcd_device_register: name=%s\n", name);
+
+	new_ld = kzalloc(sizeof(struct lcd_device), GFP_KERNEL);
+	if (!new_ld)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&new_ld->ops_lock);
+	mutex_init(&new_ld->update_lock);
+
+	new_ld->dev.class = lcd_class;
+	new_ld->dev.parent = parent;
+	new_ld->dev.release = lcd_device_release;
+	dev_set_name(&new_ld->dev, name);
+	dev_set_drvdata(&new_ld->dev, devdata);
+
+	rc = device_register(&new_ld->dev);
+	if (rc) {
+		kfree(new_ld);
+		return ERR_PTR(rc);
+	}
+
+	rc = lcd_register_fb(new_ld);
+	if (rc) {
+		device_unregister(&new_ld->dev);
+		return ERR_PTR(rc);
+	}
+
+	new_ld->ops = ops;
+
+	return new_ld;
+}
+EXPORT_SYMBOL(lcd_device_register);
+
+/**
+ * lcd_device_unregister - unregisters a object of lcd_device class.
+ * @ld: the lcd device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via lcd_device_register object.
+ */
+void lcd_device_unregister(struct lcd_device *ld)
+{
+	if (!ld)
+		return;
+
+	mutex_lock(&ld->ops_lock);
+	ld->ops = NULL;
+	mutex_unlock(&ld->ops_lock);
+	lcd_unregister_fb(ld);
+
+	device_unregister(&ld->dev);
+}
+EXPORT_SYMBOL(lcd_device_unregister);
+
+static void __exit lcd_class_exit(void)
+{
+	class_destroy(lcd_class);
+}
+
+static int __init lcd_class_init(void)
+{
+	lcd_class = class_create(THIS_MODULE, "lcd");
+	if (IS_ERR(lcd_class)) {
+		printk(KERN_WARNING "Unable to create backlight class; errno = %ld\n",
+				PTR_ERR(lcd_class));
+		return PTR_ERR(lcd_class);
+	}
+
+	lcd_class->dev_attrs = lcd_device_attributes;
+	return 0;
+}
+
+/*
+ * if this is compiled into the kernel, we need to ensure that the
+ * class is registered before users of the class try to register lcd's
+ */
+postcore_initcall(lcd_class_init);
+module_exit(lcd_class_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
+MODULE_DESCRIPTION("LCD Lowlevel Control Abstraction");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ld9040.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ld9040.c
new file mode 100644
index 0000000..efd352b
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ld9040.c
@@ -0,0 +1,863 @@
+/*
+ * ld9040 AMOLED LCD panel driver.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ * Author: Donghwa Lee  <dh09.lee@samsung.com>
+ * Derived from drivers/video/backlight/s6e63m0.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/wait.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+
+#include "ld9040_gamma.h"
+
+#define SLEEPMSEC		0x1000
+#define ENDDEF			0x2000
+#define	DEFMASK			0xFF00
+#define COMMAND_ONLY		0xFE
+#define DATA_ONLY		0xFF
+
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		24
+#define power_is_on(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+struct ld9040 {
+	struct device			*dev;
+	struct spi_device		*spi;
+	unsigned int			power;
+	unsigned int			current_brightness;
+
+	struct lcd_device		*ld;
+	struct backlight_device		*bd;
+	struct lcd_platform_data	*lcd_pd;
+
+	struct mutex			lock;
+	bool  enabled;
+};
+
+static struct regulator_bulk_data supplies[] = {
+	{ .supply = "vdd3", },
+	{ .supply = "vci", },
+};
+
+static void ld9040_regulator_enable(struct ld9040 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+
+	pd = lcd->lcd_pd;
+	mutex_lock(&lcd->lock);
+	if (!lcd->enabled) {
+		ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
+		if (ret)
+			goto out;
+
+		lcd->enabled = true;
+	}
+	mdelay(pd->power_on_delay);
+out:
+	mutex_unlock(&lcd->lock);
+}
+
+static void ld9040_regulator_disable(struct ld9040 *lcd)
+{
+	int ret = 0;
+
+	mutex_lock(&lcd->lock);
+	if (lcd->enabled) {
+		ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+		if (ret)
+			goto out;
+
+		lcd->enabled = false;
+	}
+out:
+	mutex_unlock(&lcd->lock);
+}
+
+static const unsigned short seq_swreset[] = {
+	0x01, COMMAND_ONLY,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_user_setting[] = {
+	0xF0, 0x5A,
+
+	DATA_ONLY, 0x5A,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_elvss_on[] = {
+	0xB1, 0x0D,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x16,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_gtcon[] = {
+	0xF7, 0x09,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_panel_condition[] = {
+	0xF8, 0x05,
+
+	DATA_ONLY, 0x65,
+	DATA_ONLY, 0x96,
+	DATA_ONLY, 0x71,
+	DATA_ONLY, 0x7D,
+	DATA_ONLY, 0x19,
+	DATA_ONLY, 0x3B,
+	DATA_ONLY, 0x0D,
+	DATA_ONLY, 0x19,
+	DATA_ONLY, 0x7E,
+	DATA_ONLY, 0x0D,
+	DATA_ONLY, 0xE2,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x7E,
+	DATA_ONLY, 0x7D,
+	DATA_ONLY, 0x07,
+	DATA_ONLY, 0x07,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x02,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_gamma_set1[] = {
+	0xF9, 0x00,
+
+	DATA_ONLY, 0xA7,
+	DATA_ONLY, 0xB4,
+	DATA_ONLY, 0xAE,
+	DATA_ONLY, 0xBF,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x91,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0xB2,
+	DATA_ONLY, 0xB4,
+	DATA_ONLY, 0xAA,
+	DATA_ONLY, 0xBB,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0xAC,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0xB3,
+	DATA_ONLY, 0xB1,
+	DATA_ONLY, 0xAA,
+	DATA_ONLY, 0xBC,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0xB3,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_gamma_ctrl[] = {
+	0xFB, 0x02,
+
+	DATA_ONLY, 0x5A,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_gamma_start[] = {
+	0xF9, COMMAND_ONLY,
+
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_apon[] = {
+	0xF3, 0x00,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x0A,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_display_ctrl[] = {
+	0xF2, 0x02,
+
+	DATA_ONLY, 0x08,
+	DATA_ONLY, 0x08,
+	DATA_ONLY, 0x10,
+	DATA_ONLY, 0x10,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_manual_pwr[] = {
+	0xB0, 0x04,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_pwr_ctrl[] = {
+	0xF4, 0x0A,
+
+	DATA_ONLY, 0x87,
+	DATA_ONLY, 0x25,
+	DATA_ONLY, 0x6A,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x02,
+	DATA_ONLY, 0x88,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_sleep_out[] = {
+	0x11, COMMAND_ONLY,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_sleep_in[] = {
+	0x10, COMMAND_ONLY,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_display_on[] = {
+	0x29, COMMAND_ONLY,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_display_off[] = {
+	0x28, COMMAND_ONLY,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vci1_1st_en[] = {
+	0xF3, 0x10,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vl1_en[] = {
+	0xF3, 0x11,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vl2_en[] = {
+	0xF3, 0x13,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vci1_2nd_en[] = {
+	0xF3, 0x33,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vl3_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vreg1_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0x01,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vgh_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0x11,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vgl_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0x31,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x02,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vmos_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xB1,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vint_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xF1,
+	/* DATA_ONLY, 0x71,	VMOS/VBL/VBH not used */
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	/* DATA_ONLY, 0x02,	VMOS/VBL/VBH not used */
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vbh_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xF9,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_vbl_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xFD,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_gam_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xFF,
+	/* DATA_ONLY, 0x73,	VMOS/VBL/VBH not used */
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	/* DATA_ONLY, 0x02,	VMOS/VBL/VBH not used */
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_sd_amp_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xFF,
+	/* DATA_ONLY, 0x73,	VMOS/VBL/VBH not used */
+	DATA_ONLY, 0x80,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	/* DATA_ONLY, 0x02,	VMOS/VBL/VBH not used */
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_gls_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xFF,
+	/* DATA_ONLY, 0x73,	VMOS/VBL/VBH not used */
+	DATA_ONLY, 0x81,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	/* DATA_ONLY, 0x02,	VMOS/VBL/VBH not used */
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_els_en[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xFF,
+	/* DATA_ONLY, 0x73,	VMOS/VBL/VBH not used */
+	DATA_ONLY, 0x83,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	/* DATA_ONLY, 0x02,	VMOS/VBL/VBH not used */
+	ENDDEF, 0x00
+};
+
+static const unsigned short seq_el_on[] = {
+	0xF3, 0x37,
+
+	DATA_ONLY, 0xFF,
+	/* DATA_ONLY, 0x73,	VMOS/VBL/VBH not used */
+	DATA_ONLY, 0x87,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	/* DATA_ONLY, 0x02,	VMOS/VBL/VBH not used */
+	ENDDEF, 0x00
+};
+
+static int ld9040_spi_write_byte(struct ld9040 *lcd, int addr, int data)
+{
+	u16 buf[1];
+	struct spi_message msg;
+
+	struct spi_transfer xfer = {
+		.len		= 2,
+		.tx_buf		= buf,
+	};
+
+	buf[0] = (addr << 8) | data;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(lcd->spi, &msg);
+}
+
+static int ld9040_spi_write(struct ld9040 *lcd, unsigned char address,
+	unsigned char command)
+{
+	int ret = 0;
+
+	if (address != DATA_ONLY)
+		ret = ld9040_spi_write_byte(lcd, 0x0, address);
+	if (command != COMMAND_ONLY)
+		ret = ld9040_spi_write_byte(lcd, 0x1, command);
+
+	return ret;
+}
+
+static int ld9040_panel_send_sequence(struct ld9040 *lcd,
+	const unsigned short *wbuf)
+{
+	int ret = 0, i = 0;
+
+	while ((wbuf[i] & DEFMASK) != ENDDEF) {
+		if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
+			ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]);
+			if (ret)
+				break;
+		} else
+			udelay(wbuf[i+1]*1000);
+		i += 2;
+	}
+
+	return ret;
+}
+
+static int _ld9040_gamma_ctl(struct ld9040 *lcd, const unsigned int *gamma)
+{
+	unsigned int i = 0;
+	int ret = 0;
+
+	/* start gamma table updating. */
+	ret = ld9040_panel_send_sequence(lcd, seq_gamma_start);
+	if (ret) {
+		dev_err(lcd->dev, "failed to disable gamma table updating.\n");
+		goto gamma_err;
+	}
+
+	for (i = 0 ; i < GAMMA_TABLE_COUNT; i++) {
+		ret = ld9040_spi_write(lcd, DATA_ONLY, gamma[i]);
+		if (ret) {
+			dev_err(lcd->dev, "failed to set gamma table.\n");
+			goto gamma_err;
+		}
+	}
+
+	/* update gamma table. */
+	ret = ld9040_panel_send_sequence(lcd, seq_gamma_ctrl);
+	if (ret)
+		dev_err(lcd->dev, "failed to update gamma table.\n");
+
+gamma_err:
+	return ret;
+}
+
+static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma)
+{
+	int ret = 0;
+
+	ret = _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
+
+	return ret;
+}
+
+
+static int ld9040_ldi_init(struct ld9040 *lcd)
+{
+	int ret, i;
+	static const unsigned short *init_seq[] = {
+		seq_user_setting,
+		seq_panel_condition,
+		seq_display_ctrl,
+		seq_manual_pwr,
+		seq_elvss_on,
+		seq_gtcon,
+		seq_gamma_set1,
+		seq_gamma_ctrl,
+		seq_sleep_out,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
+		ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
+		/* workaround: minimum delay time for transferring CMD */
+		udelay(300);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int ld9040_ldi_enable(struct ld9040 *lcd)
+{
+	int ret = 0;
+
+	ret = ld9040_panel_send_sequence(lcd, seq_display_on);
+
+	return ret;
+}
+
+static int ld9040_ldi_disable(struct ld9040 *lcd)
+{
+	int ret;
+
+	ret = ld9040_panel_send_sequence(lcd, seq_display_off);
+	ret = ld9040_panel_send_sequence(lcd, seq_sleep_in);
+
+	return ret;
+}
+
+static int ld9040_power_on(struct ld9040 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+	pd = lcd->lcd_pd;
+	if (!pd) {
+		dev_err(lcd->dev, "platform data is NULL.\n");
+		return -EFAULT;
+	}
+
+	/* lcd power on */
+	ld9040_regulator_enable(lcd);
+
+	if (!pd->reset) {
+		dev_err(lcd->dev, "reset is NULL.\n");
+		return -EFAULT;
+	} else {
+		pd->reset(lcd->ld);
+		mdelay(pd->reset_delay);
+	}
+
+	ret = ld9040_ldi_init(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "failed to initialize ldi.\n");
+		return ret;
+	}
+
+	ret = ld9040_ldi_enable(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "failed to enable ldi.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ld9040_power_off(struct ld9040 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+
+	pd = lcd->lcd_pd;
+	if (!pd) {
+		dev_err(lcd->dev, "platform data is NULL.\n");
+		return -EFAULT;
+	}
+
+	ret = ld9040_ldi_disable(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "lcd setting failed.\n");
+		return -EIO;
+	}
+
+	mdelay(pd->power_off_delay);
+
+	/* lcd power off */
+	ld9040_regulator_disable(lcd);
+
+	return 0;
+}
+
+static int ld9040_power(struct ld9040 *lcd, int power)
+{
+	int ret = 0;
+
+	if (power_is_on(power) && !power_is_on(lcd->power))
+		ret = ld9040_power_on(lcd);
+	else if (!power_is_on(power) && power_is_on(lcd->power))
+		ret = ld9040_power_off(lcd);
+
+	if (!ret)
+		lcd->power = power;
+
+	return ret;
+}
+
+static int ld9040_set_power(struct lcd_device *ld, int power)
+{
+	struct ld9040 *lcd = lcd_get_data(ld);
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+		power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	return ld9040_power(lcd, power);
+}
+
+static int ld9040_get_power(struct lcd_device *ld)
+{
+	struct ld9040 *lcd = lcd_get_data(ld);
+
+	return lcd->power;
+}
+
+static int ld9040_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+static int ld9040_set_brightness(struct backlight_device *bd)
+{
+	int ret = 0, brightness = bd->props.brightness;
+	struct ld9040 *lcd = bl_get_data(bd);
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bd->props.max_brightness) {
+		dev_err(&bd->dev, "lcd brightness should be %d to %d.\n",
+			MIN_BRIGHTNESS, MAX_BRIGHTNESS);
+		return -EINVAL;
+	}
+
+	ret = ld9040_gamma_ctl(lcd, bd->props.brightness);
+	if (ret) {
+		dev_err(&bd->dev, "lcd brightness setting failed.\n");
+		return -EIO;
+	}
+
+	return ret;
+}
+
+static struct lcd_ops ld9040_lcd_ops = {
+	.set_power = ld9040_set_power,
+	.get_power = ld9040_get_power,
+};
+
+static const struct backlight_ops ld9040_backlight_ops  = {
+	.get_brightness = ld9040_get_brightness,
+	.update_status = ld9040_set_brightness,
+};
+
+
+static int ld9040_probe(struct spi_device *spi)
+{
+	int ret = 0;
+	struct ld9040 *lcd = NULL;
+	struct lcd_device *ld = NULL;
+	struct backlight_device *bd = NULL;
+	struct backlight_properties props;
+
+	lcd = kzalloc(sizeof(struct ld9040), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	/* ld9040 lcd panel uses 3-wire 9bits SPI Mode. */
+	spi->bits_per_word = 9;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&spi->dev, "spi setup failed.\n");
+		goto out_free_lcd;
+	}
+
+	lcd->spi = spi;
+	lcd->dev = &spi->dev;
+
+	lcd->lcd_pd = spi->dev.platform_data;
+	if (!lcd->lcd_pd) {
+		dev_err(&spi->dev, "platform data is NULL.\n");
+		goto out_free_lcd;
+	}
+
+	mutex_init(&lcd->lock);
+
+	ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
+	if (ret) {
+		dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
+		goto out_free_lcd;
+	}
+
+	ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
+	if (IS_ERR(ld)) {
+		ret = PTR_ERR(ld);
+		goto out_free_lcd;
+	}
+
+	lcd->ld = ld;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = MAX_BRIGHTNESS;
+
+	bd = backlight_device_register("ld9040-bl", &spi->dev,
+		lcd, &ld9040_backlight_ops, &props);
+	if (IS_ERR(bd)) {
+		ret = PTR_ERR(bd);
+		goto out_unregister_lcd;
+	}
+
+	bd->props.brightness = MAX_BRIGHTNESS;
+	lcd->bd = bd;
+
+	/*
+	 * if lcd panel was on from bootloader like u-boot then
+	 * do not lcd on.
+	 */
+	if (!lcd->lcd_pd->lcd_enabled) {
+		/*
+		 * if lcd panel was off from bootloader then
+		 * current lcd status is powerdown and then
+		 * it enables lcd panel.
+		 */
+		lcd->power = FB_BLANK_POWERDOWN;
+
+		ld9040_power(lcd, FB_BLANK_UNBLANK);
+	} else
+		lcd->power = FB_BLANK_UNBLANK;
+
+	dev_set_drvdata(&spi->dev, lcd);
+
+	dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
+	return 0;
+
+out_unregister_lcd:
+	lcd_device_unregister(lcd->ld);
+out_free_lcd:
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+
+	kfree(lcd);
+	return ret;
+}
+
+static int __devexit ld9040_remove(struct spi_device *spi)
+{
+	struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+
+	ld9040_power(lcd, FB_BLANK_POWERDOWN);
+	backlight_device_unregister(lcd->bd);
+	lcd_device_unregister(lcd->ld);
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+	kfree(lcd);
+
+	return 0;
+}
+
+#if defined(CONFIG_PM)
+static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+	int ret = 0;
+	struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+
+	dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+
+	/*
+	 * when lcd panel is suspend, lcd panel becomes off
+	 * regardless of status.
+	 */
+	ret = ld9040_power(lcd, FB_BLANK_POWERDOWN);
+
+	return ret;
+}
+
+static int ld9040_resume(struct spi_device *spi)
+{
+	int ret = 0;
+	struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+
+	lcd->power = FB_BLANK_POWERDOWN;
+
+	ret = ld9040_power(lcd, FB_BLANK_UNBLANK);
+
+	return ret;
+}
+#else
+#define ld9040_suspend		NULL
+#define ld9040_resume		NULL
+#endif
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void ld9040_shutdown(struct spi_device *spi)
+{
+	struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
+
+	ld9040_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver ld9040_driver = {
+	.driver = {
+		.name	= "ld9040",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ld9040_probe,
+	.remove		= __devexit_p(ld9040_remove),
+	.shutdown	= ld9040_shutdown,
+	.suspend	= ld9040_suspend,
+	.resume		= ld9040_resume,
+};
+
+module_spi_driver(ld9040_driver);
+
+MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
+MODULE_DESCRIPTION("ld9040 LCD Driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ld9040_gamma.h b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ld9040_gamma.h
new file mode 100644
index 0000000..038d9c8
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ld9040_gamma.h
@@ -0,0 +1,200 @@
+/*
+ * Gamma level definitions.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.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 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _LD9040_BRIGHTNESS_H
+#define _LD9040_BRIGHTNESS_H
+
+#define MAX_GAMMA_LEVEL		25
+#define GAMMA_TABLE_COUNT	21
+
+/* gamma value: 2.2 */
+static const unsigned int ld9040_22_300[] = {
+	0x00, 0xa7, 0xb4, 0xae, 0xbf, 0x00, 0x91,
+	0x00, 0xb2, 0xb4, 0xaa, 0xbb, 0x00, 0xac,
+	0x00, 0xb3, 0xb1, 0xaa, 0xbc, 0x00, 0xb3
+};
+
+static const unsigned int ld9040_22_290[] = {
+	0x00, 0xa9, 0xb7, 0xae, 0xbd, 0x00, 0x89,
+	0x00, 0xb7, 0xb6, 0xa8, 0xba, 0x00, 0xa4,
+	0x00, 0xb1, 0xb4, 0xaa, 0xbb, 0x00, 0xaa
+};
+
+static const unsigned int ld9040_22_280[] = {
+	0x00, 0xa9, 0xb6, 0xad, 0xbf, 0x00, 0x86,
+	0x00, 0xb8, 0xb5, 0xa8, 0xbc, 0x00, 0xa0,
+	0x00, 0xb3, 0xb3, 0xa9, 0xbc, 0x00, 0xa7
+};
+
+static const unsigned int ld9040_22_270[] = {
+	0x00, 0xa8, 0xb8, 0xae, 0xbe, 0x00, 0x84,
+	0x00, 0xb9, 0xb7, 0xa8, 0xbc, 0x00, 0x9d,
+	0x00, 0xb2, 0xb5, 0xaa, 0xbc, 0x00, 0xa4
+
+};
+static const unsigned int ld9040_22_260[] = {
+	0x00, 0xa4, 0xb8, 0xb0, 0xbf, 0x00, 0x80,
+	0x00, 0xb8, 0xb6, 0xaa, 0xbc, 0x00, 0x9a,
+	0x00, 0xb0, 0xb5, 0xab, 0xbd, 0x00, 0xa0
+};
+
+static const unsigned int ld9040_22_250[] = {
+	0x00, 0xa4, 0xb9, 0xaf, 0xc1, 0x00, 0x7d,
+	0x00, 0xb9, 0xb6, 0xaa, 0xbb, 0x00, 0x97,
+	0x00, 0xb1, 0xb5, 0xaa, 0xbf, 0x00, 0x9d
+};
+
+static const unsigned int ld9040_22_240[] = {
+	0x00, 0xa2, 0xb9, 0xaf, 0xc2, 0x00, 0x7a,
+	0x00, 0xb9, 0xb7, 0xaa, 0xbd, 0x00, 0x94,
+	0x00, 0xb0, 0xb5, 0xab, 0xbf, 0x00, 0x9a
+};
+
+static const unsigned int ld9040_22_230[] = {
+	0x00, 0xa0, 0xb9, 0xaf, 0xc3, 0x00, 0x77,
+	0x00, 0xb9, 0xb7, 0xab, 0xbe, 0x00, 0x90,
+	0x00, 0xb0, 0xb6, 0xab, 0xbf, 0x00, 0x97
+};
+
+static const unsigned int ld9040_22_220[] = {
+	0x00, 0x9e, 0xba, 0xb0, 0xc2, 0x00, 0x75,
+	0x00, 0xb9, 0xb8, 0xab, 0xbe, 0x00, 0x8e,
+	0x00, 0xb0, 0xb6, 0xac, 0xbf, 0x00, 0x94
+};
+
+static const unsigned int ld9040_22_210[] = {
+	0x00, 0x9c, 0xb9, 0xb0, 0xc4, 0x00, 0x72,
+	0x00, 0xb8, 0xb8, 0xac, 0xbf, 0x00, 0x8a,
+	0x00, 0xb0, 0xb6, 0xac, 0xc0, 0x00, 0x91
+};
+
+static const unsigned int ld9040_22_200[] = {
+	0x00, 0x9a, 0xba, 0xb1, 0xc4, 0x00, 0x6f,
+	0x00, 0xb8, 0xb8, 0xad, 0xc0, 0x00, 0x86,
+	0x00, 0xb0, 0xb7, 0xad, 0xc0, 0x00, 0x8d
+};
+
+static const unsigned int ld9040_22_190[] = {
+	0x00, 0x97, 0xba, 0xb2, 0xc5, 0x00, 0x6c,
+	0x00, 0xb8, 0xb8, 0xae, 0xc1, 0x00, 0x82,
+	0x00, 0xb0, 0xb6, 0xae, 0xc2, 0x00, 0x89
+};
+
+static const unsigned int ld9040_22_180[] = {
+	0x00, 0x93, 0xba, 0xb3, 0xc5, 0x00, 0x69,
+	0x00, 0xb8, 0xb9, 0xae, 0xc1, 0x00, 0x7f,
+	0x00, 0xb0, 0xb6, 0xae, 0xc3, 0x00, 0x85
+};
+
+static const unsigned int ld9040_22_170[] = {
+	0x00, 0x8b, 0xb9, 0xb3, 0xc7, 0x00, 0x65,
+	0x00, 0xb7, 0xb8, 0xaf, 0xc3, 0x00, 0x7a,
+	0x00, 0x80, 0xb6, 0xae, 0xc4, 0x00, 0x81
+};
+
+static const unsigned int ld9040_22_160[] = {
+	0x00, 0x89, 0xba, 0xb3, 0xc8, 0x00, 0x62,
+	0x00, 0xb6, 0xba, 0xaf, 0xc3, 0x00, 0x76,
+	0x00, 0xaf, 0xb7, 0xae, 0xc4, 0x00, 0x7e
+};
+
+static const unsigned int ld9040_22_150[] = {
+	0x00, 0x82, 0xba, 0xb4, 0xc7, 0x00, 0x5f,
+	0x00, 0xb5, 0xba, 0xb0, 0xc3, 0x00, 0x72,
+	0x00, 0xae, 0xb8, 0xb0, 0xc3, 0x00, 0x7a
+};
+
+static const unsigned int ld9040_22_140[] = {
+	0x00, 0x7b, 0xbb, 0xb4, 0xc8, 0x00, 0x5b,
+	0x00, 0xb5, 0xba, 0xb1, 0xc4, 0x00, 0x6e,
+	0x00, 0xae, 0xb9, 0xb0, 0xc5, 0x00, 0x75
+};
+
+static const unsigned int ld9040_22_130[] = {
+	0x00, 0x71, 0xbb, 0xb5, 0xc8, 0x00, 0x57,
+	0x00, 0xb5, 0xbb, 0xb0, 0xc5, 0x00, 0x6a,
+	0x00, 0xae, 0xb9, 0xb1, 0xc6, 0x00, 0x70
+};
+
+static const unsigned int ld9040_22_120[] = {
+	0x00, 0x47, 0xba, 0xb6, 0xca, 0x00, 0x53,
+	0x00, 0xb5, 0xbb, 0xb3, 0xc6, 0x00, 0x65,
+	0x00, 0xae, 0xb8, 0xb3, 0xc7, 0x00, 0x6c
+};
+
+static const unsigned int ld9040_22_110[] = {
+	0x00, 0x13, 0xbb, 0xb7, 0xca, 0x00, 0x4f,
+	0x00, 0xb4, 0xbb, 0xb3, 0xc7, 0x00, 0x60,
+	0x00, 0xad, 0xb8, 0xb4, 0xc7, 0x00, 0x67
+};
+
+static const unsigned int ld9040_22_100[] = {
+	0x00, 0x13, 0xba, 0xb8, 0xcb, 0x00, 0x4b,
+	0x00, 0xb3, 0xbc, 0xb4, 0xc7, 0x00, 0x5c,
+	0x00, 0xac, 0xb8, 0xb4, 0xc8, 0x00, 0x62
+};
+
+static const unsigned int ld9040_22_90[] = {
+	0x00, 0x13, 0xb9, 0xb8, 0xcd, 0x00, 0x46,
+	0x00, 0xb1, 0xbc, 0xb5, 0xc8, 0x00, 0x56,
+	0x00, 0xaa, 0xb8, 0xb4, 0xc9, 0x00, 0x5d
+};
+
+static const unsigned int ld9040_22_80[] = {
+	0x00, 0x13, 0xba, 0xb9, 0xcd, 0x00, 0x41,
+	0x00, 0xb0, 0xbe, 0xb5, 0xc9, 0x00, 0x51,
+	0x00, 0xa9, 0xb9, 0xb5, 0xca, 0x00, 0x57
+};
+
+static const unsigned int ld9040_22_70[] = {
+	0x00, 0x13, 0xb9, 0xb9, 0xd0, 0x00, 0x3c,
+	0x00, 0xaf, 0xbf, 0xb6, 0xcb, 0x00, 0x4b,
+	0x00, 0xa8, 0xb9, 0xb5, 0xcc, 0x00, 0x52
+};
+
+static const unsigned int ld9040_22_50[] = {
+	0x00, 0x13, 0xb2, 0xba, 0xd2, 0x00, 0x30,
+	0x00, 0xaf, 0xc0, 0xb8, 0xcd, 0x00, 0x3d,
+	0x00, 0xa8, 0xb8, 0xb7, 0xcd, 0x00, 0x44
+};
+
+struct ld9040_gamma {
+	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
+} gamma_table = {
+	.gamma_22_table[0] = (unsigned int *)&ld9040_22_50,
+	.gamma_22_table[1] = (unsigned int *)&ld9040_22_70,
+	.gamma_22_table[2] = (unsigned int *)&ld9040_22_80,
+	.gamma_22_table[3] = (unsigned int *)&ld9040_22_90,
+	.gamma_22_table[4] = (unsigned int *)&ld9040_22_100,
+	.gamma_22_table[5] = (unsigned int *)&ld9040_22_110,
+	.gamma_22_table[6] = (unsigned int *)&ld9040_22_120,
+	.gamma_22_table[7] = (unsigned int *)&ld9040_22_130,
+	.gamma_22_table[8] = (unsigned int *)&ld9040_22_140,
+	.gamma_22_table[9] = (unsigned int *)&ld9040_22_150,
+	.gamma_22_table[10] = (unsigned int *)&ld9040_22_160,
+	.gamma_22_table[11] = (unsigned int *)&ld9040_22_170,
+	.gamma_22_table[12] = (unsigned int *)&ld9040_22_180,
+	.gamma_22_table[13] = (unsigned int *)&ld9040_22_190,
+	.gamma_22_table[14] = (unsigned int *)&ld9040_22_200,
+	.gamma_22_table[15] = (unsigned int *)&ld9040_22_210,
+	.gamma_22_table[16] = (unsigned int *)&ld9040_22_220,
+	.gamma_22_table[17] = (unsigned int *)&ld9040_22_230,
+	.gamma_22_table[18] = (unsigned int *)&ld9040_22_240,
+	.gamma_22_table[19] = (unsigned int *)&ld9040_22_250,
+	.gamma_22_table[20] = (unsigned int *)&ld9040_22_260,
+	.gamma_22_table[21] = (unsigned int *)&ld9040_22_270,
+	.gamma_22_table[22] = (unsigned int *)&ld9040_22_280,
+	.gamma_22_table[23] = (unsigned int *)&ld9040_22_290,
+	.gamma_22_table[24] = (unsigned int *)&ld9040_22_300,
+};
+
+#endif
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/lms283gf05.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/lms283gf05.c
new file mode 100644
index 0000000..4161f9e
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/lms283gf05.c
@@ -0,0 +1,233 @@
+/*
+ * lms283gf05.c -- support for Samsung LMS283GF05 LCD
+ *
+ * Copyright (c) 2009 Marek Vasut <marek.vasut@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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/lms283gf05.h>
+#include <linux/module.h>
+
+struct lms283gf05_state {
+	struct spi_device	*spi;
+	struct lcd_device	*ld;
+};
+
+struct lms283gf05_seq {
+	unsigned char		reg;
+	unsigned short		value;
+	unsigned char		delay;
+};
+
+/* Magic sequences supplied by manufacturer, for details refer to datasheet */
+static struct lms283gf05_seq disp_initseq[] = {
+	/* REG, VALUE, DELAY */
+	{ 0x07, 0x0000, 0 },
+	{ 0x13, 0x0000, 10 },
+
+	{ 0x11, 0x3004, 0 },
+	{ 0x14, 0x200F, 0 },
+	{ 0x10, 0x1a20, 0 },
+	{ 0x13, 0x0040, 50 },
+
+	{ 0x13, 0x0060, 0 },
+	{ 0x13, 0x0070, 200 },
+
+	{ 0x01, 0x0127, 0 },
+	{ 0x02,	0x0700, 0 },
+	{ 0x03, 0x1030, 0 },
+	{ 0x08, 0x0208, 0 },
+	{ 0x0B, 0x0620, 0 },
+	{ 0x0C, 0x0110, 0 },
+	{ 0x30, 0x0120, 0 },
+	{ 0x31, 0x0127, 0 },
+	{ 0x32, 0x0000, 0 },
+	{ 0x33, 0x0503, 0 },
+	{ 0x34, 0x0727, 0 },
+	{ 0x35, 0x0124, 0 },
+	{ 0x36, 0x0706, 0 },
+	{ 0x37, 0x0701, 0 },
+	{ 0x38, 0x0F00, 0 },
+	{ 0x39, 0x0F00, 0 },
+	{ 0x40, 0x0000, 0 },
+	{ 0x41, 0x0000, 0 },
+	{ 0x42, 0x013f, 0 },
+	{ 0x43, 0x0000, 0 },
+	{ 0x44, 0x013f, 0 },
+	{ 0x45, 0x0000, 0 },
+	{ 0x46, 0xef00, 0 },
+	{ 0x47, 0x013f, 0 },
+	{ 0x48, 0x0000, 0 },
+	{ 0x07, 0x0015, 30 },
+
+	{ 0x07, 0x0017, 0 },
+
+	{ 0x20, 0x0000, 0 },
+	{ 0x21, 0x0000, 0 },
+	{ 0x22, 0x0000, 0 }
+};
+
+static struct lms283gf05_seq disp_pdwnseq[] = {
+	{ 0x07, 0x0016, 30 },
+
+	{ 0x07, 0x0004, 0 },
+	{ 0x10, 0x0220, 20 },
+
+	{ 0x13, 0x0060, 50 },
+
+	{ 0x13, 0x0040, 50 },
+
+	{ 0x13, 0x0000, 0 },
+	{ 0x10, 0x0000, 0 }
+};
+
+
+static void lms283gf05_reset(unsigned long gpio, bool inverted)
+{
+	gpio_set_value(gpio, !inverted);
+	mdelay(100);
+	gpio_set_value(gpio, inverted);
+	mdelay(20);
+	gpio_set_value(gpio, !inverted);
+	mdelay(20);
+}
+
+static void lms283gf05_toggle(struct spi_device *spi,
+			struct lms283gf05_seq *seq, int sz)
+{
+	char buf[3];
+	int i;
+
+	for (i = 0; i < sz; i++) {
+		buf[0] = 0x74;
+		buf[1] = 0x00;
+		buf[2] = seq[i].reg;
+		spi_write(spi, buf, 3);
+
+		buf[0] = 0x76;
+		buf[1] = seq[i].value >> 8;
+		buf[2] = seq[i].value & 0xff;
+		spi_write(spi, buf, 3);
+
+		mdelay(seq[i].delay);
+	}
+}
+
+static int lms283gf05_power_set(struct lcd_device *ld, int power)
+{
+	struct lms283gf05_state *st = lcd_get_data(ld);
+	struct spi_device *spi = st->spi;
+	struct lms283gf05_pdata *pdata = spi->dev.platform_data;
+
+	if (power <= FB_BLANK_NORMAL) {
+		if (pdata)
+			lms283gf05_reset(pdata->reset_gpio,
+					pdata->reset_inverted);
+		lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq));
+	} else {
+		lms283gf05_toggle(spi, disp_pdwnseq, ARRAY_SIZE(disp_pdwnseq));
+		if (pdata)
+			gpio_set_value(pdata->reset_gpio,
+					pdata->reset_inverted);
+	}
+
+	return 0;
+}
+
+static struct lcd_ops lms_ops = {
+	.set_power	= lms283gf05_power_set,
+	.get_power	= NULL,
+};
+
+static int __devinit lms283gf05_probe(struct spi_device *spi)
+{
+	struct lms283gf05_state *st;
+	struct lms283gf05_pdata *pdata = spi->dev.platform_data;
+	struct lcd_device *ld;
+	int ret = 0;
+
+	if (pdata != NULL) {
+		ret = gpio_request(pdata->reset_gpio, "LMS285GF05 RESET");
+		if (ret)
+			return ret;
+
+		ret = gpio_direction_output(pdata->reset_gpio,
+						!pdata->reset_inverted);
+		if (ret)
+			goto err;
+	}
+
+	st = kzalloc(sizeof(struct lms283gf05_state), GFP_KERNEL);
+	if (st == NULL) {
+		dev_err(&spi->dev, "No memory for device state\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops);
+	if (IS_ERR(ld)) {
+		ret = PTR_ERR(ld);
+		goto err2;
+	}
+
+	st->spi = spi;
+	st->ld = ld;
+
+	dev_set_drvdata(&spi->dev, st);
+
+	/* kick in the LCD */
+	if (pdata)
+		lms283gf05_reset(pdata->reset_gpio, pdata->reset_inverted);
+	lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq));
+
+	return 0;
+
+err2:
+	kfree(st);
+err:
+	if (pdata != NULL)
+		gpio_free(pdata->reset_gpio);
+
+	return ret;
+}
+
+static int __devexit lms283gf05_remove(struct spi_device *spi)
+{
+	struct lms283gf05_state *st = dev_get_drvdata(&spi->dev);
+	struct lms283gf05_pdata *pdata = st->spi->dev.platform_data;
+
+	lcd_device_unregister(st->ld);
+
+	if (pdata != NULL)
+		gpio_free(pdata->reset_gpio);
+
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver lms283gf05_driver = {
+	.driver = {
+		.name	= "lms283gf05",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= lms283gf05_probe,
+	.remove		= __devexit_p(lms283gf05_remove),
+};
+
+module_spi_driver(lms283gf05_driver);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("LCD283GF05 LCD");
+MODULE_LICENSE("GPL v2");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/locomolcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/locomolcd.c
new file mode 100644
index 0000000..3a6d541
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/locomolcd.c
@@ -0,0 +1,245 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+/* LCD power functions */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#include <asm/hardware/locomo.h>
+#include <asm/irq.h>
+#include <asm/mach/sharpsl_param.h>
+#include <asm/mach-types.h>
+
+#include "../../../arch/arm/mach-sa1100/generic.h"
+
+static struct backlight_device *locomolcd_bl_device;
+static struct locomo_dev *locomolcd_dev;
+static unsigned long locomolcd_flags;
+#define LOCOMOLCD_SUSPENDED     0x01
+
+static void locomolcd_on(int comadj)
+{
+	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
+	mdelay(2);
+
+	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
+	mdelay(2);
+
+	locomo_m62332_senddata(locomolcd_dev, comadj, 0);
+	mdelay(5);
+
+	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
+	mdelay(10);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
+
+	/* Set CPSD */
+	locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
+	mdelay(10);
+
+	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
+}
+
+static void locomolcd_off(int comadj)
+{
+	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
+	locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
+	mdelay(1);
+
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
+	mdelay(110);
+
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
+	mdelay(700);
+
+	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
+	locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
+	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
+}
+
+void locomolcd_power(int on)
+{
+	int comadj = sharpsl_param.comadj;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	if (!locomolcd_dev) {
+		local_irq_restore(flags);
+		return;
+	}
+
+	/* read comadj */
+	if (comadj == -1 && machine_is_collie())
+		comadj = 128;
+	if (comadj == -1 && machine_is_poodle())
+		comadj = 118;
+
+	if (on)
+		locomolcd_on(comadj);
+	else
+		locomolcd_off(comadj);
+
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(locomolcd_power);
+
+
+static int current_intensity;
+
+static int locomolcd_set_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
+		intensity = 0;
+
+	switch (intensity) {
+	/* AC and non-AC are handled differently, but produce same results in sharp code? */
+	case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break;
+	case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break;
+	case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break;
+	case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break;
+	case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break;
+
+	default:
+		return -ENODEV;
+	}
+	current_intensity = intensity;
+	return 0;
+}
+
+static int locomolcd_get_intensity(struct backlight_device *bd)
+{
+	return current_intensity;
+}
+
+static const struct backlight_ops locomobl_data = {
+	.get_brightness = locomolcd_get_intensity,
+	.update_status  = locomolcd_set_intensity,
+};
+
+#ifdef CONFIG_PM
+static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state)
+{
+	locomolcd_flags |= LOCOMOLCD_SUSPENDED;
+	locomolcd_set_intensity(locomolcd_bl_device);
+	return 0;
+}
+
+static int locomolcd_resume(struct locomo_dev *dev)
+{
+	locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
+	locomolcd_set_intensity(locomolcd_bl_device);
+	return 0;
+}
+#else
+#define locomolcd_suspend	NULL
+#define locomolcd_resume	NULL
+#endif
+
+static int locomolcd_probe(struct locomo_dev *ldev)
+{
+	struct backlight_properties props;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	locomolcd_dev = ldev;
+
+	locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
+
+	/* the poodle_lcd_power function is called for the first time
+	 * from fs_initcall, which is before locomo is activated.
+	 * We need to recall poodle_lcd_power here*/
+	if (machine_is_poodle())
+		locomolcd_power(1);
+
+	local_irq_restore(flags);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = 4;
+	locomolcd_bl_device = backlight_device_register("locomo-bl",
+							&ldev->dev, NULL,
+							&locomobl_data, &props);
+
+	if (IS_ERR (locomolcd_bl_device))
+		return PTR_ERR (locomolcd_bl_device);
+
+	/* Set up frontlight so that screen is readable */
+	locomolcd_bl_device->props.brightness = 2;
+	locomolcd_set_intensity(locomolcd_bl_device);
+
+	return 0;
+}
+
+static int locomolcd_remove(struct locomo_dev *dev)
+{
+	unsigned long flags;
+
+	locomolcd_bl_device->props.brightness = 0;
+	locomolcd_bl_device->props.power = 0;
+	locomolcd_set_intensity(locomolcd_bl_device);
+
+	backlight_device_unregister(locomolcd_bl_device);
+	local_irq_save(flags);
+	locomolcd_dev = NULL;
+	local_irq_restore(flags);
+	return 0;
+}
+
+static struct locomo_driver poodle_lcd_driver = {
+	.drv = {
+		.name = "locomo-backlight",
+	},
+	.devid	= LOCOMO_DEVID_BACKLIGHT,
+	.probe	= locomolcd_probe,
+	.remove	= locomolcd_remove,
+	.suspend = locomolcd_suspend,
+	.resume = locomolcd_resume,
+};
+
+
+static int __init locomolcd_init(void)
+{
+	return locomo_driver_register(&poodle_lcd_driver);
+}
+
+static void __exit locomolcd_exit(void)
+{
+	locomo_driver_unregister(&poodle_lcd_driver);
+}
+
+module_init(locomolcd_init);
+module_exit(locomolcd_exit);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("Collie LCD driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/lp855x_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/lp855x_bl.c
new file mode 100644
index 0000000..72a0e0c
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/lp855x_bl.c
@@ -0,0 +1,331 @@
+/*
+ * TI LP855x Backlight Driver
+ *
+ *			Copyright (C) 2011 Texas Instruments
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/lp855x.h>
+
+/* Registers */
+#define BRIGHTNESS_CTRL		(0x00)
+#define DEVICE_CTRL		(0x01)
+
+#define BUF_SIZE		20
+#define DEFAULT_BL_NAME		"lcd-backlight"
+#define MAX_BRIGHTNESS		255
+
+struct lp855x {
+	const char *chipname;
+	enum lp855x_chip_id chip_id;
+	struct i2c_client *client;
+	struct backlight_device *bl;
+	struct device *dev;
+	struct mutex xfer_lock;
+	struct lp855x_platform_data *pdata;
+};
+
+static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
+{
+	int ret;
+
+	mutex_lock(&lp->xfer_lock);
+	ret = i2c_smbus_read_byte_data(lp->client, reg);
+	if (ret < 0) {
+		mutex_unlock(&lp->xfer_lock);
+		dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+		return ret;
+	}
+	mutex_unlock(&lp->xfer_lock);
+
+	*data = (u8)ret;
+	return 0;
+}
+
+static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
+{
+	int ret;
+
+	mutex_lock(&lp->xfer_lock);
+	ret = i2c_smbus_write_byte_data(lp->client, reg, data);
+	mutex_unlock(&lp->xfer_lock);
+
+	return ret;
+}
+
+static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
+{
+	u8 start, end;
+
+	switch (lp->chip_id) {
+	case LP8550:
+	case LP8551:
+	case LP8552:
+	case LP8553:
+		start = EEPROM_START;
+		end = EEPROM_END;
+		break;
+	case LP8556:
+		start = EPROM_START;
+		end = EPROM_END;
+		break;
+	default:
+		return false;
+	}
+
+	return (addr >= start && addr <= end);
+}
+
+static int lp855x_init_registers(struct lp855x *lp)
+{
+	u8 val, addr;
+	int i, ret;
+	struct lp855x_platform_data *pd = lp->pdata;
+
+	val = pd->initial_brightness;
+	ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+	if (ret)
+		return ret;
+
+	val = pd->device_control;
+	ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
+	if (ret)
+		return ret;
+
+	if (pd->load_new_rom_data && pd->size_program) {
+		for (i = 0; i < pd->size_program; i++) {
+			addr = pd->rom_data[i].addr;
+			val = pd->rom_data[i].val;
+			if (!lp855x_is_valid_rom_area(lp, addr))
+				continue;
+
+			ret = lp855x_write_byte(lp, addr, val);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int lp855x_bl_update_status(struct backlight_device *bl)
+{
+	struct lp855x *lp = bl_get_data(bl);
+	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		bl->props.brightness = 0;
+
+	if (mode == PWM_BASED) {
+		struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+		int br = bl->props.brightness;
+		int max_br = bl->props.max_brightness;
+
+		if (pd->pwm_set_intensity)
+			pd->pwm_set_intensity(br, max_br);
+
+	} else if (mode == REGISTER_BASED) {
+		u8 val = bl->props.brightness;
+		lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+	}
+
+	return 0;
+}
+
+static int lp855x_bl_get_brightness(struct backlight_device *bl)
+{
+	struct lp855x *lp = bl_get_data(bl);
+	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+	if (mode == PWM_BASED) {
+		struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+		int max_br = bl->props.max_brightness;
+
+		if (pd->pwm_get_intensity)
+			bl->props.brightness = pd->pwm_get_intensity(max_br);
+
+	} else if (mode == REGISTER_BASED) {
+		u8 val = 0;
+
+		lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
+		bl->props.brightness = val;
+	}
+
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops lp855x_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.update_status = lp855x_bl_update_status,
+	.get_brightness = lp855x_bl_get_brightness,
+};
+
+static int lp855x_backlight_register(struct lp855x *lp)
+{
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct lp855x_platform_data *pdata = lp->pdata;
+	char *name = pdata->name ? : DEFAULT_BL_NAME;
+
+	props.type = BACKLIGHT_PLATFORM;
+	props.max_brightness = MAX_BRIGHTNESS;
+
+	if (pdata->initial_brightness > props.max_brightness)
+		pdata->initial_brightness = props.max_brightness;
+
+	props.brightness = pdata->initial_brightness;
+
+	bl = backlight_device_register(name, lp->dev, lp,
+				       &lp855x_bl_ops, &props);
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	lp->bl = bl;
+
+	return 0;
+}
+
+static void lp855x_backlight_unregister(struct lp855x *lp)
+{
+	if (lp->bl)
+		backlight_device_unregister(lp->bl);
+}
+
+static ssize_t lp855x_get_chip_id(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct lp855x *lp = dev_get_drvdata(dev);
+	return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname);
+}
+
+static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct lp855x *lp = dev_get_drvdata(dev);
+	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+	char *strmode = NULL;
+
+	if (mode == PWM_BASED)
+		strmode = "pwm based";
+	else if (mode == REGISTER_BASED)
+		strmode = "register based";
+
+	return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
+}
+
+static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
+static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
+
+static struct attribute *lp855x_attributes[] = {
+	&dev_attr_chip_id.attr,
+	&dev_attr_bl_ctl_mode.attr,
+	NULL,
+};
+
+static const struct attribute_group lp855x_attr_group = {
+	.attrs = lp855x_attributes,
+};
+
+static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+	struct lp855x *lp;
+	struct lp855x_platform_data *pdata = cl->dev.platform_data;
+	enum lp855x_brightness_ctrl_mode mode;
+	int ret;
+
+	if (!pdata) {
+		dev_err(&cl->dev, "no platform data supplied\n");
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+		return -EIO;
+
+	lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
+	if (!lp)
+		return -ENOMEM;
+
+	mode = pdata->mode;
+	lp->client = cl;
+	lp->dev = &cl->dev;
+	lp->pdata = pdata;
+	lp->chipname = id->name;
+	lp->chip_id = id->driver_data;
+	i2c_set_clientdata(cl, lp);
+
+	mutex_init(&lp->xfer_lock);
+
+	ret = lp855x_init_registers(lp);
+	if (ret) {
+		dev_err(lp->dev, "i2c communication err: %d", ret);
+		if (mode == REGISTER_BASED)
+			goto err_dev;
+	}
+
+	ret = lp855x_backlight_register(lp);
+	if (ret) {
+		dev_err(lp->dev,
+			"failed to register backlight. err: %d\n", ret);
+		goto err_dev;
+	}
+
+	ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
+	if (ret) {
+		dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
+		goto err_sysfs;
+	}
+
+	backlight_update_status(lp->bl);
+	return 0;
+
+err_sysfs:
+	lp855x_backlight_unregister(lp);
+err_dev:
+	return ret;
+}
+
+static int __devexit lp855x_remove(struct i2c_client *cl)
+{
+	struct lp855x *lp = i2c_get_clientdata(cl);
+
+	lp->bl->props.brightness = 0;
+	backlight_update_status(lp->bl);
+	sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
+	lp855x_backlight_unregister(lp);
+
+	return 0;
+}
+
+static const struct i2c_device_id lp855x_ids[] = {
+	{"lp8550", LP8550},
+	{"lp8551", LP8551},
+	{"lp8552", LP8552},
+	{"lp8553", LP8553},
+	{"lp8556", LP8556},
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lp855x_ids);
+
+static struct i2c_driver lp855x_driver = {
+	.driver = {
+		   .name = "lp855x",
+		   },
+	.probe = lp855x_probe,
+	.remove = __devexit_p(lp855x_remove),
+	.id_table = lp855x_ids,
+};
+
+module_i2c_driver(lp855x_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
+MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ltv350qv.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ltv350qv.c
new file mode 100644
index 0000000..333949f
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ltv350qv.c
@@ -0,0 +1,329 @@
+/*
+ * Power control for Samsung LTV350QV Quarter VGA LCD Panel
+ *
+ * Copyright (C) 2006, 2007 Atmel Corporation
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include "ltv350qv.h"
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+struct ltv350qv {
+	struct spi_device	*spi;
+	u8			*buffer;
+	int			power;
+	struct lcd_device	*ld;
+};
+
+/*
+ * The power-on and power-off sequences are taken from the
+ * LTV350QV-F04 data sheet from Samsung. The register definitions are
+ * taken from the S6F2002 command list also from Samsung. Both
+ * documents are distributed with the AVR32 Linux BSP CD from Atmel.
+ *
+ * There's still some voodoo going on here, but it's a lot better than
+ * in the first incarnation of the driver where all we had was the raw
+ * numbers from the initialization sequence.
+ */
+static int ltv350qv_write_reg(struct ltv350qv *lcd, u8 reg, u16 val)
+{
+	struct spi_message msg;
+	struct spi_transfer index_xfer = {
+		.len		= 3,
+		.cs_change	= 1,
+	};
+	struct spi_transfer value_xfer = {
+		.len		= 3,
+	};
+
+	spi_message_init(&msg);
+
+	/* register index */
+	lcd->buffer[0] = LTV_OPC_INDEX;
+	lcd->buffer[1] = 0x00;
+	lcd->buffer[2] = reg & 0x7f;
+	index_xfer.tx_buf = lcd->buffer;
+	spi_message_add_tail(&index_xfer, &msg);
+
+	/* register value */
+	lcd->buffer[4] = LTV_OPC_DATA;
+	lcd->buffer[5] = val >> 8;
+	lcd->buffer[6] = val;
+	value_xfer.tx_buf = lcd->buffer + 4;
+	spi_message_add_tail(&value_xfer, &msg);
+
+	return spi_sync(lcd->spi, &msg);
+}
+
+/* The comments are taken straight from the data sheet */
+static int ltv350qv_power_on(struct ltv350qv *lcd)
+{
+	int ret;
+
+	/* Power On Reset Display off State */
+	if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000))
+		goto err;
+	msleep(15);
+
+	/* Power Setting Function 1 */
+	if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE))
+		goto err;
+	if (ltv350qv_write_reg(lcd, LTV_PWRCTL2, LTV_VCOML_ENABLE))
+		goto err_power1;
+
+	/* Power Setting Function 2 */
+	if (ltv350qv_write_reg(lcd, LTV_PWRCTL1,
+			       LTV_VCOM_DISABLE | LTV_DRIVE_CURRENT(5)
+			       | LTV_SUPPLY_CURRENT(5)))
+		goto err_power2;
+
+	msleep(55);
+
+	/* Instruction Setting */
+	ret = ltv350qv_write_reg(lcd, LTV_IFCTL,
+				 LTV_NMD | LTV_REV | LTV_NL(0x1d));
+	ret |= ltv350qv_write_reg(lcd, LTV_DATACTL,
+				  LTV_DS_SAME | LTV_CHS_480
+				  | LTV_DF_RGB | LTV_RGB_BGR);
+	ret |= ltv350qv_write_reg(lcd, LTV_ENTRY_MODE,
+				  LTV_VSPL_ACTIVE_LOW
+				  | LTV_HSPL_ACTIVE_LOW
+				  | LTV_DPL_SAMPLE_RISING
+				  | LTV_EPL_ACTIVE_LOW
+				  | LTV_SS_RIGHT_TO_LEFT);
+	ret |= ltv350qv_write_reg(lcd, LTV_GATECTL1, LTV_CLW(3));
+	ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
+				  LTV_NW_INV_1LINE | LTV_FWI(3));
+	ret |= ltv350qv_write_reg(lcd, LTV_VBP, 0x000a);
+	ret |= ltv350qv_write_reg(lcd, LTV_HBP, 0x0021);
+	ret |= ltv350qv_write_reg(lcd, LTV_SOTCTL, LTV_SDT(3) | LTV_EQ(0));
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(0), 0x0103);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(1), 0x0301);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(2), 0x1f0f);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(3), 0x1f0f);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(4), 0x0707);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(5), 0x0307);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(6), 0x0707);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(7), 0x0000);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(8), 0x0004);
+	ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(9), 0x0000);
+	if (ret)
+		goto err_settings;
+
+	/* Wait more than 2 frames */
+	msleep(20);
+
+	/* Display On Sequence */
+	ret = ltv350qv_write_reg(lcd, LTV_PWRCTL1,
+				 LTV_VCOM_DISABLE | LTV_VCOMOUT_ENABLE
+				 | LTV_POWER_ON | LTV_DRIVE_CURRENT(5)
+				 | LTV_SUPPLY_CURRENT(5));
+	ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
+				  LTV_NW_INV_1LINE | LTV_DSC | LTV_FWI(3));
+	if (ret)
+		goto err_disp_on;
+
+	/* Display should now be ON. Phew. */
+	return 0;
+
+err_disp_on:
+	/*
+	 * Try to recover. Error handling probably isn't very useful
+	 * at this point, just make a best effort to switch the panel
+	 * off.
+	 */
+	ltv350qv_write_reg(lcd, LTV_PWRCTL1,
+			   LTV_VCOM_DISABLE | LTV_DRIVE_CURRENT(5)
+			   | LTV_SUPPLY_CURRENT(5));
+	ltv350qv_write_reg(lcd, LTV_GATECTL2,
+			   LTV_NW_INV_1LINE | LTV_FWI(3));
+err_settings:
+err_power2:
+err_power1:
+	ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
+	msleep(1);
+err:
+	ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
+	return -EIO;
+}
+
+static int ltv350qv_power_off(struct ltv350qv *lcd)
+{
+	int ret;
+
+	/* Display Off Sequence */
+	ret = ltv350qv_write_reg(lcd, LTV_PWRCTL1,
+				 LTV_VCOM_DISABLE
+				 | LTV_DRIVE_CURRENT(5)
+				 | LTV_SUPPLY_CURRENT(5));
+	ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
+				  LTV_NW_INV_1LINE | LTV_FWI(3));
+
+	/* Power down setting 1 */
+	ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
+
+	/* Wait at least 1 ms */
+	msleep(1);
+
+	/* Power down setting 2 */
+	ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
+
+	/*
+	 * No point in trying to recover here. If we can't switch the
+	 * panel off, what are we supposed to do other than inform the
+	 * user about the failure?
+	 */
+	if (ret)
+		return -EIO;
+
+	/* Display power should now be OFF */
+	return 0;
+}
+
+static int ltv350qv_power(struct ltv350qv *lcd, int power)
+{
+	int ret = 0;
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		ret = ltv350qv_power_on(lcd);
+	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		ret = ltv350qv_power_off(lcd);
+
+	if (!ret)
+		lcd->power = power;
+
+	return ret;
+}
+
+static int ltv350qv_set_power(struct lcd_device *ld, int power)
+{
+	struct ltv350qv *lcd = lcd_get_data(ld);
+
+	return ltv350qv_power(lcd, power);
+}
+
+static int ltv350qv_get_power(struct lcd_device *ld)
+{
+	struct ltv350qv *lcd = lcd_get_data(ld);
+
+	return lcd->power;
+}
+
+static struct lcd_ops ltv_ops = {
+	.get_power	= ltv350qv_get_power,
+	.set_power	= ltv350qv_set_power,
+};
+
+static int __devinit ltv350qv_probe(struct spi_device *spi)
+{
+	struct ltv350qv *lcd;
+	struct lcd_device *ld;
+	int ret;
+
+	lcd = kzalloc(sizeof(struct ltv350qv), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->spi = spi;
+	lcd->power = FB_BLANK_POWERDOWN;
+	lcd->buffer = kzalloc(8, GFP_KERNEL);
+	if (!lcd->buffer) {
+		ret = -ENOMEM;
+		goto out_free_lcd;
+	}
+
+	ld = lcd_device_register("ltv350qv", &spi->dev, lcd, &ltv_ops);
+	if (IS_ERR(ld)) {
+		ret = PTR_ERR(ld);
+		goto out_free_buffer;
+	}
+	lcd->ld = ld;
+
+	ret = ltv350qv_power(lcd, FB_BLANK_UNBLANK);
+	if (ret)
+		goto out_unregister;
+
+	dev_set_drvdata(&spi->dev, lcd);
+
+	return 0;
+
+out_unregister:
+	lcd_device_unregister(ld);
+out_free_buffer:
+	kfree(lcd->buffer);
+out_free_lcd:
+	kfree(lcd);
+	return ret;
+}
+
+static int __devexit ltv350qv_remove(struct spi_device *spi)
+{
+	struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+
+	ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
+	lcd_device_unregister(lcd->ld);
+	kfree(lcd->buffer);
+	kfree(lcd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ltv350qv_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+
+	return ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static int ltv350qv_resume(struct spi_device *spi)
+{
+	struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+
+	return ltv350qv_power(lcd, FB_BLANK_UNBLANK);
+}
+#else
+#define ltv350qv_suspend	NULL
+#define ltv350qv_resume		NULL
+#endif
+
+/* Power down all displays on reboot, poweroff or halt */
+static void ltv350qv_shutdown(struct spi_device *spi)
+{
+	struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
+
+	ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver ltv350qv_driver = {
+	.driver = {
+		.name		= "ltv350qv",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= ltv350qv_probe,
+	.remove		= __devexit_p(ltv350qv_remove),
+	.shutdown	= ltv350qv_shutdown,
+	.suspend	= ltv350qv_suspend,
+	.resume		= ltv350qv_resume,
+};
+
+module_spi_driver(ltv350qv_driver);
+
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
+MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:ltv350qv");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ltv350qv.h b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ltv350qv.h
new file mode 100644
index 0000000..189112e
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ltv350qv.h
@@ -0,0 +1,95 @@
+/*
+ * Register definitions for Samsung LTV350QV Quarter VGA LCD Panel
+ *
+ * Copyright (C) 2006, 2007 Atmel Corporation
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+#ifndef __LTV350QV_H
+#define __LTV350QV_H
+
+#define LTV_OPC_INDEX	0x74
+#define LTV_OPC_DATA	0x76
+
+#define LTV_ID		0x00		/* ID Read */
+#define LTV_IFCTL	0x01		/* Display Interface Control */
+#define LTV_DATACTL	0x02		/* Display Data Control */
+#define LTV_ENTRY_MODE	0x03		/* Entry Mode */
+#define LTV_GATECTL1	0x04		/* Gate Control 1 */
+#define LTV_GATECTL2	0x05		/* Gate Control 2 */
+#define LTV_VBP		0x06		/* Vertical Back Porch */
+#define LTV_HBP		0x07		/* Horizontal Back Porch */
+#define LTV_SOTCTL	0x08		/* Source Output Timing Control */
+#define LTV_PWRCTL1	0x09		/* Power Control 1 */
+#define LTV_PWRCTL2	0x0a		/* Power Control 2 */
+#define LTV_GAMMA(x)	(0x10 + (x))	/* Gamma control */
+
+/* Bit definitions for LTV_IFCTL */
+#define LTV_IM			(1 << 15)
+#define LTV_NMD			(1 << 14)
+#define LTV_SSMD		(1 << 13)
+#define LTV_REV			(1 <<  7)
+#define LTV_NL(x)		(((x) & 0x001f) << 0)
+
+/* Bit definitions for LTV_DATACTL */
+#define LTV_DS_SAME		(0 << 12)
+#define LTV_DS_D_TO_S		(1 << 12)
+#define LTV_DS_S_TO_D		(2 << 12)
+#define LTV_CHS_384		(0 <<  9)
+#define LTV_CHS_480		(1 <<  9)
+#define LTV_CHS_492		(2 <<  9)
+#define LTV_DF_RGB		(0 <<  6)
+#define LTV_DF_RGBX		(1 <<  6)
+#define LTV_DF_XRGB		(2 <<  6)
+#define LTV_RGB_RGB		(0 <<  2)
+#define LTV_RGB_BGR		(1 <<  2)
+#define LTV_RGB_GRB		(2 <<  2)
+#define LTV_RGB_RBG		(3 <<  2)
+
+/* Bit definitions for LTV_ENTRY_MODE */
+#define LTV_VSPL_ACTIVE_LOW	(0 << 15)
+#define LTV_VSPL_ACTIVE_HIGH	(1 << 15)
+#define LTV_HSPL_ACTIVE_LOW	(0 << 14)
+#define LTV_HSPL_ACTIVE_HIGH	(1 << 14)
+#define LTV_DPL_SAMPLE_RISING	(0 << 13)
+#define LTV_DPL_SAMPLE_FALLING	(1 << 13)
+#define LTV_EPL_ACTIVE_LOW	(0 << 12)
+#define LTV_EPL_ACTIVE_HIGH	(1 << 12)
+#define LTV_SS_LEFT_TO_RIGHT	(0 <<  8)
+#define LTV_SS_RIGHT_TO_LEFT	(1 <<  8)
+#define LTV_STB			(1 <<  1)
+
+/* Bit definitions for LTV_GATECTL1 */
+#define LTV_CLW(x)		(((x) & 0x0007) << 12)
+#define LTV_GAON		(1 <<  5)
+#define LTV_SDR			(1 <<  3)
+
+/* Bit definitions for LTV_GATECTL2 */
+#define LTV_NW_INV_FRAME	(0 << 14)
+#define LTV_NW_INV_1LINE	(1 << 14)
+#define LTV_NW_INV_2LINE	(2 << 14)
+#define LTV_DSC			(1 << 12)
+#define LTV_GIF			(1 <<  8)
+#define LTV_FHN			(1 <<  7)
+#define LTV_FTI(x)		(((x) & 0x0003) << 4)
+#define LTV_FWI(x)		(((x) & 0x0003) << 0)
+
+/* Bit definitions for LTV_SOTCTL */
+#define LTV_SDT(x)		(((x) & 0x0007) << 10)
+#define LTV_EQ(x)		(((x) & 0x0007) <<  2)
+
+/* Bit definitions for LTV_PWRCTL1 */
+#define LTV_VCOM_DISABLE	(1 << 14)
+#define LTV_VCOMOUT_ENABLE	(1 << 11)
+#define LTV_POWER_ON		(1 <<  9)
+#define LTV_DRIVE_CURRENT(x)	(((x) & 0x0007) << 4)	/* 0=off, 5=max */
+#define LTV_SUPPLY_CURRENT(x)	(((x) & 0x0007) << 0)	/* 0=off, 5=max */
+
+/* Bit definitions for LTV_PWRCTL2 */
+#define LTV_VCOML_ENABLE	(1 << 13)
+#define LTV_VCOML_VOLTAGE(x)	(((x) & 0x001f) << 8)	/* 0=1V, 31=-1V */
+#define LTV_VCOMH_VOLTAGE(x)	(((x) & 0x001f) << 0)	/* 0=3V, 31=4.5V */
+
+#endif /* __LTV350QV_H */
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/max8925_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/max8925_bl.c
new file mode 100644
index 0000000..e833ac7
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/max8925_bl.c
@@ -0,0 +1,193 @@
+/*
+ * Backlight driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *      Haojian Zhuang <haojian.zhuang@marvell.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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/mfd/max8925.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#define MAX_BRIGHTNESS		(0xff)
+#define MIN_BRIGHTNESS		(0)
+
+#define LWX_FREQ(x)		(((x - 601) / 100) & 0x7)
+
+struct max8925_backlight_data {
+	struct max8925_chip	*chip;
+
+	int		current_brightness;
+};
+
+static int max8925_backlight_set(struct backlight_device *bl, int brightness)
+{
+	struct max8925_backlight_data *data = bl_get_data(bl);
+	struct max8925_chip *chip = data->chip;
+	unsigned char value;
+	int ret;
+
+	if (brightness > MAX_BRIGHTNESS)
+		value = MAX_BRIGHTNESS;
+	else
+		value = brightness;
+
+	ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+	if (ret < 0)
+		goto out;
+
+	if (!data->current_brightness && brightness)
+		/* enable WLED output */
+		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+	else if (!brightness)
+		/* disable WLED output */
+		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+	if (ret < 0)
+		goto out;
+	dev_dbg(chip->dev, "set brightness %d\n", value);
+	data->current_brightness = value;
+	return 0;
+out:
+	dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n",
+		value, ret);
+	return ret;
+}
+
+static int max8925_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	return max8925_backlight_set(bl, brightness);
+}
+
+static int max8925_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct max8925_backlight_data *data = bl_get_data(bl);
+	struct max8925_chip *chip = data->chip;
+	int ret;
+
+	ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+	if (ret < 0)
+		return -EINVAL;
+	data->current_brightness = ret;
+	dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
+	return ret;
+}
+
+static const struct backlight_ops max8925_backlight_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= max8925_backlight_update_status,
+	.get_brightness	= max8925_backlight_get_brightness,
+};
+
+static int __devinit max8925_backlight_probe(struct platform_device *pdev)
+{
+	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_platform_data *max8925_pdata;
+	struct max8925_backlight_pdata *pdata = NULL;
+	struct max8925_backlight_data *data;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+	char name[MAX8925_NAME_SIZE];
+	unsigned char value;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource!\n");
+		return -EINVAL;
+	}
+
+	if (pdev->dev.parent->platform_data) {
+		max8925_pdata = pdev->dev.parent->platform_data;
+		pdata = max8925_pdata->backlight;
+	}
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "platform data isn't assigned to "
+			"backlight\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
+			    GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	strncpy(name, res->name, MAX8925_NAME_SIZE);
+	data->chip = chip;
+	data->current_brightness = 0;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = MAX_BRIGHTNESS;
+	bl = backlight_device_register(name, &pdev->dev, data,
+					&max8925_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+	bl->props.brightness = MAX_BRIGHTNESS;
+
+	platform_set_drvdata(pdev, bl);
+
+	value = 0;
+	if (pdata->lxw_scl)
+		value |= (1 << 7);
+	if (pdata->lxw_freq)
+		value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+	if (pdata->dual_string)
+		value |= (1 << 1);
+	ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+	if (ret < 0)
+		goto out;
+
+	backlight_update_status(bl);
+	return 0;
+out:
+	backlight_device_unregister(bl);
+	return ret;
+}
+
+static int __devexit max8925_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(bl);
+	return 0;
+}
+
+static struct platform_driver max8925_backlight_driver = {
+	.driver		= {
+		.name	= "max8925-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= max8925_backlight_probe,
+	.remove		= __devexit_p(max8925_backlight_remove),
+};
+
+module_platform_driver(max8925_backlight_driver);
+
+MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:max8925-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/omap1_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/omap1_bl.c
new file mode 100644
index 0000000..0175bfb
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/omap1_bl.c
@@ -0,0 +1,199 @@
+/*
+ * Backlight driver for OMAP based boards.
+ *
+ * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this package; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/slab.h>
+
+#include <mach/hardware.h>
+#include <plat/board.h>
+#include <plat/mux.h>
+
+#define OMAPBL_MAX_INTENSITY		0xff
+
+struct omap_backlight {
+	int powermode;
+	int current_intensity;
+
+	struct device *dev;
+	struct omap_backlight_config *pdata;
+};
+
+static void inline omapbl_send_intensity(int intensity)
+{
+	omap_writeb(intensity, OMAP_PWL_ENABLE);
+}
+
+static void inline omapbl_send_enable(int enable)
+{
+	omap_writeb(enable, OMAP_PWL_CLK_ENABLE);
+}
+
+static void omapbl_blank(struct omap_backlight *bl, int mode)
+{
+	if (bl->pdata->set_power)
+		bl->pdata->set_power(bl->dev, mode);
+
+	switch (mode) {
+	case FB_BLANK_NORMAL:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_POWERDOWN:
+		omapbl_send_intensity(0);
+		omapbl_send_enable(0);
+		break;
+
+	case FB_BLANK_UNBLANK:
+		omapbl_send_intensity(bl->current_intensity);
+		omapbl_send_enable(1);
+		break;
+	}
+}
+
+#ifdef CONFIG_PM
+static int omapbl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct backlight_device *dev = platform_get_drvdata(pdev);
+	struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+
+	omapbl_blank(bl, FB_BLANK_POWERDOWN);
+	return 0;
+}
+
+static int omapbl_resume(struct platform_device *pdev)
+{
+	struct backlight_device *dev = platform_get_drvdata(pdev);
+	struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+
+	omapbl_blank(bl, bl->powermode);
+	return 0;
+}
+#else
+#define omapbl_suspend	NULL
+#define omapbl_resume	NULL
+#endif
+
+static int omapbl_set_power(struct backlight_device *dev, int state)
+{
+	struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+
+	omapbl_blank(bl, state);
+	bl->powermode = state;
+
+	return 0;
+}
+
+static int omapbl_update_status(struct backlight_device *dev)
+{
+	struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+
+	if (bl->current_intensity != dev->props.brightness) {
+		if (bl->powermode == FB_BLANK_UNBLANK)
+			omapbl_send_intensity(dev->props.brightness);
+		bl->current_intensity = dev->props.brightness;
+	}
+
+	if (dev->props.fb_blank != bl->powermode)
+		omapbl_set_power(dev, dev->props.fb_blank);
+
+	return 0;
+}
+
+static int omapbl_get_intensity(struct backlight_device *dev)
+{
+	struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
+	return bl->current_intensity;
+}
+
+static const struct backlight_ops omapbl_ops = {
+	.get_brightness = omapbl_get_intensity,
+	.update_status  = omapbl_update_status,
+};
+
+static int omapbl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct backlight_device *dev;
+	struct omap_backlight *bl;
+	struct omap_backlight_config *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return -ENXIO;
+
+	bl = devm_kzalloc(&pdev->dev, sizeof(struct omap_backlight),
+			  GFP_KERNEL);
+	if (unlikely(!bl))
+		return -ENOMEM;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = OMAPBL_MAX_INTENSITY;
+	dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
+					&props);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	bl->powermode = FB_BLANK_POWERDOWN;
+	bl->current_intensity = 0;
+
+	bl->pdata = pdata;
+	bl->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, dev);
+
+	omap_cfg_reg(PWL);	/* Conflicts with UART3 */
+
+	dev->props.fb_blank = FB_BLANK_UNBLANK;
+	dev->props.brightness = pdata->default_intensity;
+	omapbl_update_status(dev);
+
+	printk(KERN_INFO "OMAP LCD backlight initialised\n");
+
+	return 0;
+}
+
+static int omapbl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *dev = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(dev);
+
+	return 0;
+}
+
+static struct platform_driver omapbl_driver = {
+	.probe		= omapbl_probe,
+	.remove		= omapbl_remove,
+	.suspend	= omapbl_suspend,
+	.resume		= omapbl_resume,
+	.driver		= {
+		.name	= "omap-bl",
+	},
+};
+
+module_platform_driver(omapbl_driver);
+
+MODULE_AUTHOR("Andrzej Zaborowski <balrog@zabor.org>");
+MODULE_DESCRIPTION("OMAP LCD Backlight driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/ot200_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ot200_bl.c
new file mode 100644
index 0000000..f519d55
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/ot200_bl.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Bachmann electronic GmbH
+ *	Christian Gmeiner <christian.gmeiner@gmail.com>
+ *
+ * Backlight driver for ot200 visualisation device from
+ * Bachmann electronic GmbH.
+ *
+ * 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 published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/gpio.h>
+#include <linux/cs5535.h>
+
+static struct cs5535_mfgpt_timer *pwm_timer;
+
+/* this array defines the mapping of brightness in % to pwm frequency */
+static const u8 dim_table[101] = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+				  2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+				  4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,
+				  10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16,
+				  17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28,
+				  30, 31, 33, 35, 37, 39, 41, 43, 45, 47, 50,
+				  53, 55, 58, 61, 65, 68, 72, 75, 79, 84, 88,
+				  93, 97, 103, 108, 114, 120, 126, 133, 140,
+				  147, 155, 163};
+
+struct ot200_backlight_data {
+	int current_brightness;
+};
+
+#define GPIO_DIMM	27
+#define SCALE		1
+#define CMP1MODE	0x2	/* compare on GE; output high on compare
+				 * greater than or equal */
+#define PWM_SETUP	(SCALE | CMP1MODE << 6 | MFGPT_SETUP_CNTEN)
+#define MAX_COMP2	163
+
+static int ot200_backlight_update_status(struct backlight_device *bl)
+{
+	struct ot200_backlight_data *data = bl_get_data(bl);
+	int brightness = bl->props.brightness;
+
+	if (bl->props.state & BL_CORE_FBBLANK)
+		brightness = 0;
+
+	/* enable or disable PWM timer */
+	if (brightness == 0)
+		cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, 0);
+	else if (data->current_brightness == 0) {
+		cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+		cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP,
+			MFGPT_SETUP_CNTEN);
+	}
+
+	/* apply new brightness value */
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+		MAX_COMP2 - dim_table[brightness]);
+	data->current_brightness = brightness;
+
+	return 0;
+}
+
+static int ot200_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct ot200_backlight_data *data = bl_get_data(bl);
+	return data->current_brightness;
+}
+
+static const struct backlight_ops ot200_backlight_ops = {
+	.update_status	= ot200_backlight_update_status,
+	.get_brightness	= ot200_backlight_get_brightness,
+};
+
+static int ot200_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_device *bl;
+	struct ot200_backlight_data *data;
+	struct backlight_properties props;
+	int retval = 0;
+
+	/* request gpio */
+	if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) {
+		dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM);
+		return -ENODEV;
+	}
+
+	/* request timer */
+	pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY);
+	if (!pwm_timer) {
+		dev_err(&pdev->dev, "MFGPT 7 not available\n");
+		retval = -ENODEV;
+		goto error_mfgpt_alloc;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		retval = -ENOMEM;
+		goto error_kzalloc;
+	}
+
+	/* setup gpio */
+	cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_ENABLE);
+	cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_AUX1);
+
+	/* setup timer */
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, 0);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP2, MAX_COMP2);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, PWM_SETUP);
+
+	data->current_brightness = 100;
+	props.max_brightness = 100;
+	props.brightness = 100;
+	props.type = BACKLIGHT_RAW;
+
+	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data,
+					&ot200_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		retval = PTR_ERR(bl);
+		goto error_backlight_device_register;
+	}
+
+	platform_set_drvdata(pdev, bl);
+
+	return 0;
+
+error_backlight_device_register:
+	kfree(data);
+error_kzalloc:
+	cs5535_mfgpt_free_timer(pwm_timer);
+error_mfgpt_alloc:
+	gpio_free(GPIO_DIMM);
+	return retval;
+}
+
+static int ot200_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct ot200_backlight_data *data = bl_get_data(bl);
+
+	backlight_device_unregister(bl);
+
+	/* on module unload set brightness to 100% */
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+		MAX_COMP2 - dim_table[100]);
+
+	cs5535_mfgpt_free_timer(pwm_timer);
+	gpio_free(GPIO_DIMM);
+
+	kfree(data);
+	return 0;
+}
+
+static struct platform_driver ot200_backlight_driver = {
+	.driver		= {
+		.name	= "ot200-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ot200_backlight_probe,
+	.remove		= ot200_backlight_remove,
+};
+
+module_platform_driver(ot200_backlight_driver);
+
+MODULE_DESCRIPTION("backlight driver for ot200 visualisation device");
+MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ot200-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/pandora_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/pandora_bl.c
new file mode 100644
index 0000000..4ec3074
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/pandora_bl.c
@@ -0,0 +1,171 @@
+/*
+ * Backlight driver for Pandora handheld.
+ * Pandora uses TWL4030 PWM0 -> TPS61161 combo for control backlight.
+ * Based on pwm_bl.c
+ *
+ * Copyright 2009,2012 Gražvydas Ignotas <notasas@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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/i2c/twl.h>
+#include <linux/err.h>
+
+#define TWL_PWM0_ON		0x00
+#define TWL_PWM0_OFF		0x01
+
+#define TWL_INTBR_GPBR1		0x0c
+#define TWL_INTBR_PMBR1		0x0d
+
+#define TWL_PMBR1_PWM0_MUXMASK	0x0c
+#define TWL_PMBR1_PWM0		0x04
+#define PWM0_CLK_ENABLE		BIT(0)
+#define PWM0_ENABLE		BIT(2)
+
+/* range accepted by hardware */
+#define MIN_VALUE 9
+#define MAX_VALUE 63
+#define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE)
+
+#define PANDORABL_WAS_OFF BL_CORE_DRIVER1
+
+static int pandora_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+	u8 r;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+	if (bl->props.state & BL_CORE_FBBLANK)
+		brightness = 0;
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	if ((unsigned int)brightness > MAX_USER_VALUE)
+		brightness = MAX_USER_VALUE;
+
+	if (brightness == 0) {
+		if (bl->props.state & PANDORABL_WAS_OFF)
+			goto done;
+
+		/* first disable PWM0 output, then clock */
+		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+		r &= ~PWM0_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+		r &= ~PWM0_CLK_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+		goto done;
+	}
+
+	if (bl->props.state & PANDORABL_WAS_OFF) {
+		/*
+		 * set PWM duty cycle to max. TPS61161 seems to use this
+		 * to calibrate it's PWM sensitivity when it starts.
+		 */
+		twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
+					TWL_PWM0_OFF);
+
+		/* first enable clock, then PWM0 out */
+		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+		r &= ~PWM0_ENABLE;
+		r |= PWM0_CLK_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+		r |= PWM0_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+		/*
+		 * TI made it very easy to enable digital control, so easy that
+		 * it often triggers unintentionally and disabes PWM control,
+		 * so wait until 1 wire mode detection window ends.
+		 */
+		usleep_range(2000, 10000);
+	}
+
+	twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
+				TWL_PWM0_OFF);
+
+done:
+	if (brightness != 0)
+		bl->props.state &= ~PANDORABL_WAS_OFF;
+	else
+		bl->props.state |= PANDORABL_WAS_OFF;
+
+	return 0;
+}
+
+static int pandora_backlight_get_brightness(struct backlight_device *bl)
+{
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops pandora_backlight_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= pandora_backlight_update_status,
+	.get_brightness	= pandora_backlight_get_brightness,
+};
+
+static int pandora_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct backlight_device *bl;
+	u8 r;
+
+	memset(&props, 0, sizeof(props));
+	props.max_brightness = MAX_USER_VALUE;
+	props.type = BACKLIGHT_RAW;
+	bl = backlight_device_register(pdev->name, &pdev->dev,
+			NULL, &pandora_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+
+	platform_set_drvdata(pdev, bl);
+
+	/* 64 cycle period, ON position 0 */
+	twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
+
+	bl->props.state |= PANDORABL_WAS_OFF;
+	bl->props.brightness = MAX_USER_VALUE;
+	backlight_update_status(bl);
+
+	/* enable PWM function in pin mux */
+	twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_PMBR1);
+	r &= ~TWL_PMBR1_PWM0_MUXMASK;
+	r |= TWL_PMBR1_PWM0;
+	twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_PMBR1);
+
+	return 0;
+}
+
+static int pandora_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	backlight_device_unregister(bl);
+	return 0;
+}
+
+static struct platform_driver pandora_backlight_driver = {
+	.driver		= {
+		.name	= "pandora-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pandora_backlight_probe,
+	.remove		= pandora_backlight_remove,
+};
+
+module_platform_driver(pandora_backlight_driver);
+
+MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("Pandora Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pandora-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/pcf50633-backlight.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/pcf50633-backlight.c
new file mode 100644
index 0000000..c65853c
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/pcf50633-backlight.c
@@ -0,0 +1,171 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *      PCF50633 backlight device driver
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/backlight.h>
+#include <linux/fb.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/backlight.h>
+
+struct pcf50633_bl {
+	struct pcf50633 *pcf;
+	struct backlight_device *bl;
+
+	unsigned int brightness;
+	unsigned int brightness_limit;
+};
+
+/*
+ * pcf50633_bl_set_brightness_limit
+ *
+ * Update the brightness limit for the pc50633 backlight. The actual brightness
+ * will not go above the limit. This is useful to limit power drain for example
+ * on low battery.
+ *
+ * @dev: Pointer to a pcf50633 device
+ * @limit: The brightness limit. Valid values are 0-63
+ */
+int pcf50633_bl_set_brightness_limit(struct pcf50633 *pcf, unsigned int limit)
+{
+	struct pcf50633_bl *pcf_bl = platform_get_drvdata(pcf->bl_pdev);
+
+	if (!pcf_bl)
+		return -ENODEV;
+
+	pcf_bl->brightness_limit = limit & 0x3f;
+	backlight_update_status(pcf_bl->bl);
+
+    return 0;
+}
+
+static int pcf50633_bl_update_status(struct backlight_device *bl)
+{
+	struct pcf50633_bl *pcf_bl = bl_get_data(bl);
+	unsigned int new_brightness;
+
+
+	if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK) ||
+		bl->props.power != FB_BLANK_UNBLANK)
+		new_brightness = 0;
+	else if (bl->props.brightness < pcf_bl->brightness_limit)
+		new_brightness = bl->props.brightness;
+	else
+		new_brightness = pcf_bl->brightness_limit;
+
+
+	if (pcf_bl->brightness == new_brightness)
+		return 0;
+
+	if (new_brightness) {
+		pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDOUT,
+					new_brightness);
+		if (!pcf_bl->brightness)
+			pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDENA, 1);
+	} else {
+		pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDENA, 0);
+	}
+
+	pcf_bl->brightness = new_brightness;
+
+	return 0;
+}
+
+static int pcf50633_bl_get_brightness(struct backlight_device *bl)
+{
+	struct pcf50633_bl *pcf_bl = bl_get_data(bl);
+	return pcf_bl->brightness;
+}
+
+static const struct backlight_ops pcf50633_bl_ops = {
+	.get_brightness = pcf50633_bl_get_brightness,
+	.update_status	= pcf50633_bl_update_status,
+	.options	= BL_CORE_SUSPENDRESUME,
+};
+
+static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
+{
+	struct pcf50633_bl *pcf_bl;
+	struct device *parent = pdev->dev.parent;
+	struct pcf50633_platform_data *pcf50633_data = parent->platform_data;
+	struct pcf50633_bl_platform_data *pdata = pcf50633_data->backlight_data;
+	struct backlight_properties bl_props;
+
+	pcf_bl = devm_kzalloc(&pdev->dev, sizeof(*pcf_bl), GFP_KERNEL);
+	if (!pcf_bl)
+		return -ENOMEM;
+
+	bl_props.type = BACKLIGHT_RAW;
+	bl_props.max_brightness = 0x3f;
+	bl_props.power = FB_BLANK_UNBLANK;
+
+	if (pdata) {
+		bl_props.brightness = pdata->default_brightness;
+		pcf_bl->brightness_limit = pdata->default_brightness_limit;
+	} else {
+		bl_props.brightness = 0x3f;
+		pcf_bl->brightness_limit = 0x3f;
+	}
+
+	pcf_bl->pcf = dev_to_pcf50633(pdev->dev.parent);
+
+	pcf_bl->bl = backlight_device_register(pdev->name, &pdev->dev, pcf_bl,
+						&pcf50633_bl_ops, &bl_props);
+
+	if (IS_ERR(pcf_bl->bl))
+		return PTR_ERR(pcf_bl->bl);
+
+	platform_set_drvdata(pdev, pcf_bl);
+
+	pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDDIM, pdata->ramp_time);
+
+	/* Should be different from bl_props.brightness, so we do not exit
+	 * update_status early the first time it's called */
+	pcf_bl->brightness = pcf_bl->bl->props.brightness + 1;
+
+	backlight_update_status(pcf_bl->bl);
+
+	return 0;
+}
+
+static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
+{
+	struct pcf50633_bl *pcf_bl = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(pcf_bl->bl);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver pcf50633_bl_driver = {
+	.probe =	pcf50633_bl_probe,
+	.remove =	__devexit_p(pcf50633_bl_remove),
+	.driver = {
+		.name = "pcf50633-backlight",
+	},
+};
+
+module_platform_driver(pcf50633_bl_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("PCF50633 backlight driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcf50633-backlight");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/platform_lcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/platform_lcd.c
new file mode 100644
index 0000000..b667234
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/platform_lcd.c
@@ -0,0 +1,164 @@
+/* drivers/video/backlight/platform_lcd.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Generic platform-device LCD power control interface.
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/slab.h>
+
+#include <video/platform_lcd.h>
+
+struct platform_lcd {
+	struct device		*us;
+	struct lcd_device	*lcd;
+	struct plat_lcd_data	*pdata;
+
+	unsigned int		 power;
+	unsigned int		 suspended : 1;
+};
+
+static inline struct platform_lcd *to_our_lcd(struct lcd_device *lcd)
+{
+	return lcd_get_data(lcd);
+}
+
+static int platform_lcd_get_power(struct lcd_device *lcd)
+{
+	struct platform_lcd *plcd = to_our_lcd(lcd);
+
+	return plcd->power;
+}
+
+static int platform_lcd_set_power(struct lcd_device *lcd, int power)
+{
+	struct platform_lcd *plcd = to_our_lcd(lcd);
+	int lcd_power = 1;
+
+	if (power == FB_BLANK_POWERDOWN || plcd->suspended)
+		lcd_power = 0;
+
+	plcd->pdata->set_power(plcd->pdata, lcd_power);
+	plcd->power = power;
+
+	return 0;
+}
+
+static int platform_lcd_match(struct lcd_device *lcd, struct fb_info *info)
+{
+	struct platform_lcd *plcd = to_our_lcd(lcd);
+	struct plat_lcd_data *pdata = plcd->pdata;
+
+	if (pdata->match_fb)
+		return pdata->match_fb(pdata, info);
+
+	return plcd->us->parent == info->device;
+}
+
+static struct lcd_ops platform_lcd_ops = {
+	.get_power	= platform_lcd_get_power,
+	.set_power	= platform_lcd_set_power,
+	.check_fb	= platform_lcd_match,
+};
+
+static int __devinit platform_lcd_probe(struct platform_device *pdev)
+{
+	struct plat_lcd_data *pdata;
+	struct platform_lcd *plcd;
+	struct device *dev = &pdev->dev;
+	int err;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(dev, "no platform data supplied\n");
+		return -EINVAL;
+	}
+
+	plcd = devm_kzalloc(&pdev->dev, sizeof(struct platform_lcd),
+			    GFP_KERNEL);
+	if (!plcd) {
+		dev_err(dev, "no memory for state\n");
+		return -ENOMEM;
+	}
+
+	plcd->us = dev;
+	plcd->pdata = pdata;
+	plcd->lcd = lcd_device_register(dev_name(dev), dev,
+					plcd, &platform_lcd_ops);
+	if (IS_ERR(plcd->lcd)) {
+		dev_err(dev, "cannot register lcd device\n");
+		err = PTR_ERR(plcd->lcd);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, plcd);
+	platform_lcd_set_power(plcd->lcd, FB_BLANK_NORMAL);
+
+	return 0;
+
+ err:
+	return err;
+}
+
+static int __devexit platform_lcd_remove(struct platform_device *pdev)
+{
+	struct platform_lcd *plcd = platform_get_drvdata(pdev);
+
+	lcd_device_unregister(plcd->lcd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int platform_lcd_suspend(struct device *dev)
+{
+	struct platform_lcd *plcd = dev_get_drvdata(dev);
+
+	plcd->suspended = 1;
+	platform_lcd_set_power(plcd->lcd, plcd->power);
+
+	return 0;
+}
+
+static int platform_lcd_resume(struct device *dev)
+{
+	struct platform_lcd *plcd = dev_get_drvdata(dev);
+
+	plcd->suspended = 0;
+	platform_lcd_set_power(plcd->lcd, plcd->power);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
+			platform_lcd_resume);
+#endif
+
+static struct platform_driver platform_lcd_driver = {
+	.driver		= {
+		.name	= "platform-lcd",
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &platform_lcd_pm_ops,
+#endif
+	},
+	.probe		= platform_lcd_probe,
+	.remove		= __devexit_p(platform_lcd_remove),
+};
+
+module_platform_driver(platform_lcd_driver);
+
+MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:platform-lcd");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/progear_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/progear_bl.c
new file mode 100644
index 0000000..6af183d
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/progear_bl.c
@@ -0,0 +1,160 @@
+/*
+ *  Backlight Driver for Frontpath ProGear HX1050+
+ *
+ *  Copyright (c) 2006 Marcin Juszkiewicz
+ *
+ *  Based on Progear LCD driver by M Schacht
+ *  <mschacht at alumni dot washington dot edu>
+ *
+ *  Based on Sharp's Corgi Backlight Driver
+ *  Based on Backlight Driver for HP Jornada 680
+ *
+ *  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
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/pci.h>
+
+#define PMU_LPCR               0xB0
+#define SB_MPS1                0x61
+#define HW_LEVEL_MAX           0x77
+#define HW_LEVEL_MIN           0x4f
+
+static struct pci_dev *pmu_dev = NULL;
+static struct pci_dev *sb_dev = NULL;
+
+static int progearbl_set_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN);
+
+	return 0;
+}
+
+static int progearbl_get_intensity(struct backlight_device *bd)
+{
+	u8 intensity;
+	pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity);
+
+	return intensity - HW_LEVEL_MIN;
+}
+
+static const struct backlight_ops progearbl_ops = {
+	.get_brightness = progearbl_get_intensity,
+	.update_status = progearbl_set_intensity,
+};
+
+static int progearbl_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	u8 temp;
+	struct backlight_device *progear_backlight_device;
+	int ret;
+
+	pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
+	if (!pmu_dev) {
+		printk("ALI M7101 PMU not found.\n");
+		return -ENODEV;
+	}
+
+	sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+	if (!sb_dev) {
+		printk("ALI 1533 SB not found.\n");
+		ret = -ENODEV;
+		goto put_pmu;
+	}
+
+	/*     Set SB_MPS1 to enable brightness control. */
+	pci_read_config_byte(sb_dev, SB_MPS1, &temp);
+	pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
+	progear_backlight_device = backlight_device_register("progear-bl",
+							     &pdev->dev, NULL,
+							     &progearbl_ops,
+							     &props);
+	if (IS_ERR(progear_backlight_device)) {
+		ret = PTR_ERR(progear_backlight_device);
+		goto put_sb;
+	}
+
+	platform_set_drvdata(pdev, progear_backlight_device);
+
+	progear_backlight_device->props.power = FB_BLANK_UNBLANK;
+	progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
+	progearbl_set_intensity(progear_backlight_device);
+
+	return 0;
+put_sb:
+	pci_dev_put(sb_dev);
+put_pmu:
+	pci_dev_put(pmu_dev);
+	return ret;
+}
+
+static int progearbl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+	backlight_device_unregister(bd);
+
+	return 0;
+}
+
+static struct platform_driver progearbl_driver = {
+	.probe = progearbl_probe,
+	.remove = progearbl_remove,
+	.driver = {
+		   .name = "progear-bl",
+		   },
+};
+
+static struct platform_device *progearbl_device;
+
+static int __init progearbl_init(void)
+{
+	int ret = platform_driver_register(&progearbl_driver);
+
+	if (ret)
+		return ret;
+	progearbl_device = platform_device_register_simple("progear-bl", -1,
+								NULL, 0);
+	if (IS_ERR(progearbl_device)) {
+		platform_driver_unregister(&progearbl_driver);
+		return PTR_ERR(progearbl_device);
+	}
+
+	return 0;
+}
+
+static void __exit progearbl_exit(void)
+{
+	pci_dev_put(pmu_dev);
+	pci_dev_put(sb_dev);
+
+	platform_device_unregister(progearbl_device);
+	platform_driver_unregister(&progearbl_driver);
+}
+
+module_init(progearbl_init);
+module_exit(progearbl_exit);
+
+MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>");
+MODULE_DESCRIPTION("ProGear Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/pwm_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/pwm_bl.c
new file mode 100644
index 0000000..342b7d7
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/pwm_bl.c
@@ -0,0 +1,213 @@
+/*
+ * linux/drivers/video/backlight/pwm_bl.c
+ *
+ * simple PWM based backlight control, board code has to setup
+ * 1) pin configuration so PWM waveforms can output
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/pwm_backlight.h>
+#include <linux/slab.h>
+
+struct pwm_bl_data {
+	struct pwm_device	*pwm;
+	struct device		*dev;
+	unsigned int		period;
+	unsigned int		lth_brightness;
+	int			(*notify)(struct device *,
+					  int brightness);
+	void			(*notify_after)(struct device *,
+					int brightness);
+	int			(*check_fb)(struct device *, struct fb_info *);
+};
+
+static int pwm_backlight_update_status(struct backlight_device *bl)
+{
+	struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+	int brightness = bl->props.brightness;
+	int max = bl->props.max_brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (pb->notify)
+		brightness = pb->notify(pb->dev, brightness);
+
+	if (brightness == 0) {
+		pwm_config(pb->pwm, 0, pb->period);
+		pwm_disable(pb->pwm);
+	} else {
+		brightness = pb->lth_brightness +
+			(brightness * (pb->period - pb->lth_brightness) / max);
+		pwm_config(pb->pwm, brightness, pb->period);
+		pwm_enable(pb->pwm);
+	}
+
+	if (pb->notify_after)
+		pb->notify_after(pb->dev, brightness);
+
+	return 0;
+}
+
+static int pwm_backlight_get_brightness(struct backlight_device *bl)
+{
+	return bl->props.brightness;
+}
+
+static int pwm_backlight_check_fb(struct backlight_device *bl,
+				  struct fb_info *info)
+{
+	struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+
+	return !pb->check_fb || pb->check_fb(pb->dev, info);
+}
+
+static const struct backlight_ops pwm_backlight_ops = {
+	.update_status	= pwm_backlight_update_status,
+	.get_brightness	= pwm_backlight_get_brightness,
+	.check_fb	= pwm_backlight_check_fb,
+};
+
+static int pwm_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
+	struct backlight_device *bl;
+	struct pwm_bl_data *pb;
+	int ret;
+
+	if (!data) {
+		dev_err(&pdev->dev, "failed to find platform data\n");
+		return -EINVAL;
+	}
+
+	if (data->init) {
+		ret = data->init(&pdev->dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
+	if (!pb) {
+		dev_err(&pdev->dev, "no memory for state\n");
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	pb->period = data->pwm_period_ns;
+	pb->notify = data->notify;
+	pb->notify_after = data->notify_after;
+	pb->check_fb = data->check_fb;
+	pb->lth_brightness = data->lth_brightness *
+		(data->pwm_period_ns / data->max_brightness);
+	pb->dev = &pdev->dev;
+
+	pb->pwm = pwm_request(data->pwm_id, "backlight");
+	if (IS_ERR(pb->pwm)) {
+		dev_err(&pdev->dev, "unable to request PWM for backlight\n");
+		ret = PTR_ERR(pb->pwm);
+		goto err_alloc;
+	} else
+		dev_dbg(&pdev->dev, "got pwm for backlight\n");
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = data->max_brightness;
+	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
+				       &pwm_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		ret = PTR_ERR(bl);
+		goto err_bl;
+	}
+
+	bl->props.brightness = data->dft_brightness;
+	backlight_update_status(bl);
+
+	platform_set_drvdata(pdev, bl);
+	return 0;
+
+err_bl:
+	pwm_free(pb->pwm);
+err_alloc:
+	if (data->exit)
+		data->exit(&pdev->dev);
+	return ret;
+}
+
+static int pwm_backlight_remove(struct platform_device *pdev)
+{
+	struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+
+	backlight_device_unregister(bl);
+	pwm_config(pb->pwm, 0, pb->period);
+	pwm_disable(pb->pwm);
+	pwm_free(pb->pwm);
+	if (data->exit)
+		data->exit(&pdev->dev);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int pwm_backlight_suspend(struct device *dev)
+{
+	struct backlight_device *bl = dev_get_drvdata(dev);
+	struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+
+	if (pb->notify)
+		pb->notify(pb->dev, 0);
+	pwm_config(pb->pwm, 0, pb->period);
+	pwm_disable(pb->pwm);
+	if (pb->notify_after)
+		pb->notify_after(pb->dev, 0);
+	return 0;
+}
+
+static int pwm_backlight_resume(struct device *dev)
+{
+	struct backlight_device *bl = dev_get_drvdata(dev);
+
+	backlight_update_status(bl);
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend,
+			 pwm_backlight_resume);
+
+#endif
+
+static struct platform_driver pwm_backlight_driver = {
+	.driver		= {
+		.name	= "pwm-backlight",
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &pwm_backlight_pm_ops,
+#endif
+	},
+	.probe		= pwm_backlight_probe,
+	.remove		= pwm_backlight_remove,
+};
+
+module_platform_driver(pwm_backlight_driver);
+
+MODULE_DESCRIPTION("PWM based Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pwm-backlight");
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/s6e63m0.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/s6e63m0.c
new file mode 100644
index 0000000..e264f55
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/s6e63m0.c
@@ -0,0 +1,917 @@
+/*
+ * S6E63M0 AMOLED LCD panel driver.
+ *
+ * Author: InKi Dae  <inki.dae@samsung.com>
+ *
+ * Derived from drivers/video/omap/lcd-apollon.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/wait.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/backlight.h>
+#include <linux/module.h>
+
+#include "s6e63m0_gamma.h"
+
+#define SLEEPMSEC		0x1000
+#define ENDDEF			0x2000
+#define	DEFMASK			0xFF00
+#define COMMAND_ONLY		0xFE
+#define DATA_ONLY		0xFF
+
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		10
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+struct s6e63m0 {
+	struct device			*dev;
+	struct spi_device		*spi;
+	unsigned int			power;
+	unsigned int			current_brightness;
+	unsigned int			gamma_mode;
+	unsigned int			gamma_table_count;
+	struct lcd_device		*ld;
+	struct backlight_device		*bd;
+	struct lcd_platform_data	*lcd_pd;
+};
+
+static const unsigned short SEQ_PANEL_CONDITION_SET[] = {
+	0xF8, 0x01,
+	DATA_ONLY, 0x27,
+	DATA_ONLY, 0x27,
+	DATA_ONLY, 0x07,
+	DATA_ONLY, 0x07,
+	DATA_ONLY, 0x54,
+	DATA_ONLY, 0x9f,
+	DATA_ONLY, 0x63,
+	DATA_ONLY, 0x86,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x33,
+	DATA_ONLY, 0x0d,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_DISPLAY_CONDITION_SET[] = {
+	0xf2, 0x02,
+	DATA_ONLY, 0x03,
+	DATA_ONLY, 0x1c,
+	DATA_ONLY, 0x10,
+	DATA_ONLY, 0x10,
+
+	0xf7, 0x03,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_GAMMA_SETTING[] = {
+	0xfa, 0x00,
+	DATA_ONLY, 0x18,
+	DATA_ONLY, 0x08,
+	DATA_ONLY, 0x24,
+	DATA_ONLY, 0x64,
+	DATA_ONLY, 0x56,
+	DATA_ONLY, 0x33,
+	DATA_ONLY, 0xb6,
+	DATA_ONLY, 0xba,
+	DATA_ONLY, 0xa8,
+	DATA_ONLY, 0xac,
+	DATA_ONLY, 0xb1,
+	DATA_ONLY, 0x9d,
+	DATA_ONLY, 0xc1,
+	DATA_ONLY, 0xc1,
+	DATA_ONLY, 0xb7,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x9c,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x9f,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0xd6,
+
+	0xfa, 0x01,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_ETC_CONDITION_SET[] = {
+	0xf6, 0x00,
+	DATA_ONLY, 0x8c,
+	DATA_ONLY, 0x07,
+
+	0xb3, 0xc,
+
+	0xb5, 0x2c,
+	DATA_ONLY, 0x12,
+	DATA_ONLY, 0x0c,
+	DATA_ONLY, 0x0a,
+	DATA_ONLY, 0x10,
+	DATA_ONLY, 0x0e,
+	DATA_ONLY, 0x17,
+	DATA_ONLY, 0x13,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x2a,
+	DATA_ONLY, 0x24,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x1b,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x17,
+
+	DATA_ONLY, 0x2b,
+	DATA_ONLY, 0x26,
+	DATA_ONLY, 0x22,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x3a,
+	DATA_ONLY, 0x34,
+	DATA_ONLY, 0x30,
+	DATA_ONLY, 0x2c,
+	DATA_ONLY, 0x29,
+	DATA_ONLY, 0x26,
+	DATA_ONLY, 0x25,
+	DATA_ONLY, 0x23,
+	DATA_ONLY, 0x21,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x1e,
+	DATA_ONLY, 0x1e,
+
+	0xb6, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x11,
+	DATA_ONLY, 0x22,
+	DATA_ONLY, 0x33,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x44,
+
+	DATA_ONLY, 0x55,
+	DATA_ONLY, 0x55,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+
+	0xb7, 0x2c,
+	DATA_ONLY, 0x12,
+	DATA_ONLY, 0x0c,
+	DATA_ONLY, 0x0a,
+	DATA_ONLY, 0x10,
+	DATA_ONLY, 0x0e,
+	DATA_ONLY, 0x17,
+	DATA_ONLY, 0x13,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x2a,
+	DATA_ONLY, 0x24,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x1b,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x17,
+
+	DATA_ONLY, 0x2b,
+	DATA_ONLY, 0x26,
+	DATA_ONLY, 0x22,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x3a,
+	DATA_ONLY, 0x34,
+	DATA_ONLY, 0x30,
+	DATA_ONLY, 0x2c,
+	DATA_ONLY, 0x29,
+	DATA_ONLY, 0x26,
+	DATA_ONLY, 0x25,
+	DATA_ONLY, 0x23,
+	DATA_ONLY, 0x21,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x1e,
+	DATA_ONLY, 0x1e,
+
+	0xb8, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x11,
+	DATA_ONLY, 0x22,
+	DATA_ONLY, 0x33,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x44,
+
+	DATA_ONLY, 0x55,
+	DATA_ONLY, 0x55,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+
+	0xb9, 0x2c,
+	DATA_ONLY, 0x12,
+	DATA_ONLY, 0x0c,
+	DATA_ONLY, 0x0a,
+	DATA_ONLY, 0x10,
+	DATA_ONLY, 0x0e,
+	DATA_ONLY, 0x17,
+	DATA_ONLY, 0x13,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x2a,
+	DATA_ONLY, 0x24,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x1b,
+	DATA_ONLY, 0x1a,
+	DATA_ONLY, 0x17,
+
+	DATA_ONLY, 0x2b,
+	DATA_ONLY, 0x26,
+	DATA_ONLY, 0x22,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x3a,
+	DATA_ONLY, 0x34,
+	DATA_ONLY, 0x30,
+	DATA_ONLY, 0x2c,
+	DATA_ONLY, 0x29,
+	DATA_ONLY, 0x26,
+	DATA_ONLY, 0x25,
+	DATA_ONLY, 0x23,
+	DATA_ONLY, 0x21,
+	DATA_ONLY, 0x20,
+	DATA_ONLY, 0x1e,
+	DATA_ONLY, 0x1e,
+
+	0xba, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x11,
+	DATA_ONLY, 0x22,
+	DATA_ONLY, 0x33,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x44,
+	DATA_ONLY, 0x44,
+
+	DATA_ONLY, 0x55,
+	DATA_ONLY, 0x55,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+	DATA_ONLY, 0x66,
+
+	0xc1, 0x4d,
+	DATA_ONLY, 0x96,
+	DATA_ONLY, 0x1d,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x01,
+	DATA_ONLY, 0xdf,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	DATA_ONLY, 0x1f,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x00,
+	DATA_ONLY, 0x03,
+	DATA_ONLY, 0x06,
+	DATA_ONLY, 0x09,
+	DATA_ONLY, 0x0d,
+	DATA_ONLY, 0x0f,
+	DATA_ONLY, 0x12,
+	DATA_ONLY, 0x15,
+	DATA_ONLY, 0x18,
+
+	0xb2, 0x10,
+	DATA_ONLY, 0x10,
+	DATA_ONLY, 0x0b,
+	DATA_ONLY, 0x05,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_ACL_ON[] = {
+	/* ACL on */
+	0xc0, 0x01,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_ACL_OFF[] = {
+	/* ACL off */
+	0xc0, 0x00,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_ELVSS_ON[] = {
+	/* ELVSS on */
+	0xb1, 0x0b,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_ELVSS_OFF[] = {
+	/* ELVSS off */
+	0xb1, 0x0a,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_STAND_BY_OFF[] = {
+	0x11, COMMAND_ONLY,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_STAND_BY_ON[] = {
+	0x10, COMMAND_ONLY,
+
+	ENDDEF, 0x0000
+};
+
+static const unsigned short SEQ_DISPLAY_ON[] = {
+	0x29, COMMAND_ONLY,
+
+	ENDDEF, 0x0000
+};
+
+
+static int s6e63m0_spi_write_byte(struct s6e63m0 *lcd, int addr, int data)
+{
+	u16 buf[1];
+	struct spi_message msg;
+
+	struct spi_transfer xfer = {
+		.len		= 2,
+		.tx_buf		= buf,
+	};
+
+	buf[0] = (addr << 8) | data;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(lcd->spi, &msg);
+}
+
+static int s6e63m0_spi_write(struct s6e63m0 *lcd, unsigned char address,
+	unsigned char command)
+{
+	int ret = 0;
+
+	if (address != DATA_ONLY)
+		ret = s6e63m0_spi_write_byte(lcd, 0x0, address);
+	if (command != COMMAND_ONLY)
+		ret = s6e63m0_spi_write_byte(lcd, 0x1, command);
+
+	return ret;
+}
+
+static int s6e63m0_panel_send_sequence(struct s6e63m0 *lcd,
+	const unsigned short *wbuf)
+{
+	int ret = 0, i = 0;
+
+	while ((wbuf[i] & DEFMASK) != ENDDEF) {
+		if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
+			ret = s6e63m0_spi_write(lcd, wbuf[i], wbuf[i+1]);
+			if (ret)
+				break;
+		} else
+			udelay(wbuf[i+1]*1000);
+		i += 2;
+	}
+
+	return ret;
+}
+
+static int _s6e63m0_gamma_ctl(struct s6e63m0 *lcd, const unsigned int *gamma)
+{
+	unsigned int i = 0;
+	int ret = 0;
+
+	/* disable gamma table updating. */
+	ret = s6e63m0_spi_write(lcd, 0xfa, 0x00);
+	if (ret) {
+		dev_err(lcd->dev, "failed to disable gamma table updating.\n");
+		goto gamma_err;
+	}
+
+	for (i = 0 ; i < GAMMA_TABLE_COUNT; i++) {
+		ret = s6e63m0_spi_write(lcd, DATA_ONLY, gamma[i]);
+		if (ret) {
+			dev_err(lcd->dev, "failed to set gamma table.\n");
+			goto gamma_err;
+		}
+	}
+
+	/* update gamma table. */
+	ret = s6e63m0_spi_write(lcd, 0xfa, 0x01);
+	if (ret)
+		dev_err(lcd->dev, "failed to update gamma table.\n");
+
+gamma_err:
+	return ret;
+}
+
+static int s6e63m0_gamma_ctl(struct s6e63m0 *lcd, int gamma)
+{
+	int ret = 0;
+
+	ret = _s6e63m0_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
+
+	return ret;
+}
+
+
+static int s6e63m0_ldi_init(struct s6e63m0 *lcd)
+{
+	int ret, i;
+	const unsigned short *init_seq[] = {
+		SEQ_PANEL_CONDITION_SET,
+		SEQ_DISPLAY_CONDITION_SET,
+		SEQ_GAMMA_SETTING,
+		SEQ_ETC_CONDITION_SET,
+		SEQ_ACL_ON,
+		SEQ_ELVSS_ON,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
+		ret = s6e63m0_panel_send_sequence(lcd, init_seq[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int s6e63m0_ldi_enable(struct s6e63m0 *lcd)
+{
+	int ret = 0, i;
+	const unsigned short *enable_seq[] = {
+		SEQ_STAND_BY_OFF,
+		SEQ_DISPLAY_ON,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(enable_seq); i++) {
+		ret = s6e63m0_panel_send_sequence(lcd, enable_seq[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int s6e63m0_ldi_disable(struct s6e63m0 *lcd)
+{
+	int ret;
+
+	ret = s6e63m0_panel_send_sequence(lcd, SEQ_STAND_BY_ON);
+
+	return ret;
+}
+
+static int s6e63m0_power_on(struct s6e63m0 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+	struct backlight_device *bd = NULL;
+
+	pd = lcd->lcd_pd;
+	if (!pd) {
+		dev_err(lcd->dev, "platform data is NULL.\n");
+		return -EFAULT;
+	}
+
+	bd = lcd->bd;
+	if (!bd) {
+		dev_err(lcd->dev, "backlight device is NULL.\n");
+		return -EFAULT;
+	}
+
+	if (!pd->power_on) {
+		dev_err(lcd->dev, "power_on is NULL.\n");
+		return -EFAULT;
+	} else {
+		pd->power_on(lcd->ld, 1);
+		mdelay(pd->power_on_delay);
+	}
+
+	if (!pd->reset) {
+		dev_err(lcd->dev, "reset is NULL.\n");
+		return -EFAULT;
+	} else {
+		pd->reset(lcd->ld);
+		mdelay(pd->reset_delay);
+	}
+
+	ret = s6e63m0_ldi_init(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "failed to initialize ldi.\n");
+		return ret;
+	}
+
+	ret = s6e63m0_ldi_enable(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "failed to enable ldi.\n");
+		return ret;
+	}
+
+	/* set brightness to current value after power on or resume. */
+	ret = s6e63m0_gamma_ctl(lcd, bd->props.brightness);
+	if (ret) {
+		dev_err(lcd->dev, "lcd gamma setting failed.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int s6e63m0_power_off(struct s6e63m0 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+
+	pd = lcd->lcd_pd;
+	if (!pd) {
+		dev_err(lcd->dev, "platform data is NULL.\n");
+		return -EFAULT;
+	}
+
+	ret = s6e63m0_ldi_disable(lcd);
+	if (ret) {
+		dev_err(lcd->dev, "lcd setting failed.\n");
+		return -EIO;
+	}
+
+	mdelay(pd->power_off_delay);
+
+	if (!pd->power_on) {
+		dev_err(lcd->dev, "power_on is NULL.\n");
+		return -EFAULT;
+	} else
+		pd->power_on(lcd->ld, 0);
+
+	return 0;
+}
+
+static int s6e63m0_power(struct s6e63m0 *lcd, int power)
+{
+	int ret = 0;
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		ret = s6e63m0_power_on(lcd);
+	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		ret = s6e63m0_power_off(lcd);
+
+	if (!ret)
+		lcd->power = power;
+
+	return ret;
+}
+
+static int s6e63m0_set_power(struct lcd_device *ld, int power)
+{
+	struct s6e63m0 *lcd = lcd_get_data(ld);
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+		power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	return s6e63m0_power(lcd, power);
+}
+
+static int s6e63m0_get_power(struct lcd_device *ld)
+{
+	struct s6e63m0 *lcd = lcd_get_data(ld);
+
+	return lcd->power;
+}
+
+static int s6e63m0_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+static int s6e63m0_set_brightness(struct backlight_device *bd)
+{
+	int ret = 0, brightness = bd->props.brightness;
+	struct s6e63m0 *lcd = bl_get_data(bd);
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bd->props.max_brightness) {
+		dev_err(&bd->dev, "lcd brightness should be %d to %d.\n",
+			MIN_BRIGHTNESS, MAX_BRIGHTNESS);
+		return -EINVAL;
+	}
+
+	ret = s6e63m0_gamma_ctl(lcd, bd->props.brightness);
+	if (ret) {
+		dev_err(&bd->dev, "lcd brightness setting failed.\n");
+		return -EIO;
+	}
+
+	return ret;
+}
+
+static struct lcd_ops s6e63m0_lcd_ops = {
+	.set_power = s6e63m0_set_power,
+	.get_power = s6e63m0_get_power,
+};
+
+static const struct backlight_ops s6e63m0_backlight_ops  = {
+	.get_brightness = s6e63m0_get_brightness,
+	.update_status = s6e63m0_set_brightness,
+};
+
+static ssize_t s6e63m0_sysfs_show_gamma_mode(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct s6e63m0 *lcd = dev_get_drvdata(dev);
+	char temp[10];
+
+	switch (lcd->gamma_mode) {
+	case 0:
+		sprintf(temp, "2.2 mode\n");
+		strcat(buf, temp);
+		break;
+	case 1:
+		sprintf(temp, "1.9 mode\n");
+		strcat(buf, temp);
+		break;
+	case 2:
+		sprintf(temp, "1.7 mode\n");
+		strcat(buf, temp);
+		break;
+	default:
+		dev_info(dev, "gamma mode could be 0:2.2, 1:1.9 or 2:1.7)n");
+		break;
+	}
+
+	return strlen(buf);
+}
+
+static ssize_t s6e63m0_sysfs_store_gamma_mode(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t len)
+{
+	struct s6e63m0 *lcd = dev_get_drvdata(dev);
+	struct backlight_device *bd = NULL;
+	int brightness, rc;
+
+	rc = kstrtouint(buf, 0, &lcd->gamma_mode);
+	if (rc < 0)
+		return rc;
+
+	bd = lcd->bd;
+
+	brightness = bd->props.brightness;
+
+	switch (lcd->gamma_mode) {
+	case 0:
+		_s6e63m0_gamma_ctl(lcd, gamma_table.gamma_22_table[brightness]);
+		break;
+	case 1:
+		_s6e63m0_gamma_ctl(lcd, gamma_table.gamma_19_table[brightness]);
+		break;
+	case 2:
+		_s6e63m0_gamma_ctl(lcd, gamma_table.gamma_17_table[brightness]);
+		break;
+	default:
+		dev_info(dev, "gamma mode could be 0:2.2, 1:1.9 or 2:1.7\n");
+		_s6e63m0_gamma_ctl(lcd, gamma_table.gamma_22_table[brightness]);
+		break;
+	}
+	return len;
+}
+
+static DEVICE_ATTR(gamma_mode, 0644,
+		s6e63m0_sysfs_show_gamma_mode, s6e63m0_sysfs_store_gamma_mode);
+
+static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct s6e63m0 *lcd = dev_get_drvdata(dev);
+	char temp[3];
+
+	sprintf(temp, "%d\n", lcd->gamma_table_count);
+	strcpy(buf, temp);
+
+	return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444,
+		s6e63m0_sysfs_show_gamma_table, NULL);
+
+static int __devinit s6e63m0_probe(struct spi_device *spi)
+{
+	int ret = 0;
+	struct s6e63m0 *lcd = NULL;
+	struct lcd_device *ld = NULL;
+	struct backlight_device *bd = NULL;
+	struct backlight_properties props;
+
+	lcd = kzalloc(sizeof(struct s6e63m0), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	/* s6e63m0 lcd panel uses 3-wire 9bits SPI Mode. */
+	spi->bits_per_word = 9;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&spi->dev, "spi setup failed.\n");
+		goto out_free_lcd;
+	}
+
+	lcd->spi = spi;
+	lcd->dev = &spi->dev;
+
+	lcd->lcd_pd = (struct lcd_platform_data *)spi->dev.platform_data;
+	if (!lcd->lcd_pd) {
+		dev_err(&spi->dev, "platform data is NULL.\n");
+		goto out_free_lcd;
+	}
+
+	ld = lcd_device_register("s6e63m0", &spi->dev, lcd, &s6e63m0_lcd_ops);
+	if (IS_ERR(ld)) {
+		ret = PTR_ERR(ld);
+		goto out_free_lcd;
+	}
+
+	lcd->ld = ld;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = MAX_BRIGHTNESS;
+
+	bd = backlight_device_register("s6e63m0bl-bl", &spi->dev, lcd,
+		&s6e63m0_backlight_ops, &props);
+	if (IS_ERR(bd)) {
+		ret =  PTR_ERR(bd);
+		goto out_lcd_unregister;
+	}
+
+	bd->props.brightness = MAX_BRIGHTNESS;
+	lcd->bd = bd;
+
+	/*
+	 * it gets gamma table count available so it gets user
+	 * know that.
+	 */
+	lcd->gamma_table_count =
+	    sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int));
+
+	ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode);
+	if (ret < 0)
+		dev_err(&(spi->dev), "failed to add sysfs entries\n");
+
+	ret = device_create_file(&(spi->dev), &dev_attr_gamma_table);
+	if (ret < 0)
+		dev_err(&(spi->dev), "failed to add sysfs entries\n");
+
+	/*
+	 * if lcd panel was on from bootloader like u-boot then
+	 * do not lcd on.
+	 */
+	if (!lcd->lcd_pd->lcd_enabled) {
+		/*
+		 * if lcd panel was off from bootloader then
+		 * current lcd status is powerdown and then
+		 * it enables lcd panel.
+		 */
+		lcd->power = FB_BLANK_POWERDOWN;
+
+		s6e63m0_power(lcd, FB_BLANK_UNBLANK);
+	} else
+		lcd->power = FB_BLANK_UNBLANK;
+
+	dev_set_drvdata(&spi->dev, lcd);
+
+	dev_info(&spi->dev, "s6e63m0 panel driver has been probed.\n");
+
+	return 0;
+
+out_lcd_unregister:
+	lcd_device_unregister(ld);
+out_free_lcd:
+	kfree(lcd);
+	return ret;
+}
+
+static int __devexit s6e63m0_remove(struct spi_device *spi)
+{
+	struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+
+	s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+	device_remove_file(&spi->dev, &dev_attr_gamma_table);
+	device_remove_file(&spi->dev, &dev_attr_gamma_mode);
+	backlight_device_unregister(lcd->bd);
+	lcd_device_unregister(lcd->ld);
+	kfree(lcd);
+
+	return 0;
+}
+
+#if defined(CONFIG_PM)
+static unsigned int before_power;
+
+static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg)
+{
+	int ret = 0;
+	struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+
+	dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+
+	before_power = lcd->power;
+
+	/*
+	 * when lcd panel is suspend, lcd panel becomes off
+	 * regardless of status.
+	 */
+	ret = s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+
+	return ret;
+}
+
+static int s6e63m0_resume(struct spi_device *spi)
+{
+	int ret = 0;
+	struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+
+	/*
+	 * after suspended, if lcd panel status is FB_BLANK_UNBLANK
+	 * (at that time, before_power is FB_BLANK_UNBLANK) then
+	 * it changes that status to FB_BLANK_POWERDOWN to get lcd on.
+	 */
+	if (before_power == FB_BLANK_UNBLANK)
+		lcd->power = FB_BLANK_POWERDOWN;
+
+	dev_dbg(&spi->dev, "before_power = %d\n", before_power);
+
+	ret = s6e63m0_power(lcd, before_power);
+
+	return ret;
+}
+#else
+#define s6e63m0_suspend		NULL
+#define s6e63m0_resume		NULL
+#endif
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6e63m0_shutdown(struct spi_device *spi)
+{
+	struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
+
+	s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver s6e63m0_driver = {
+	.driver = {
+		.name	= "s6e63m0",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= s6e63m0_probe,
+	.remove		= __devexit_p(s6e63m0_remove),
+	.shutdown	= s6e63m0_shutdown,
+	.suspend	= s6e63m0_suspend,
+	.resume		= s6e63m0_resume,
+};
+
+module_spi_driver(s6e63m0_driver);
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("S6E63M0 LCD Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/s6e63m0_gamma.h b/ap/os/linux/linux-3.4.x/drivers/video/backlight/s6e63m0_gamma.h
new file mode 100644
index 0000000..2c44bdb
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/s6e63m0_gamma.h
@@ -0,0 +1,266 @@
+/* linux/drivers/video/samsung/s6e63m0_brightness.h
+ *
+ * Gamma level definitions.
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * InKi Dae <inki.dae@samsung.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 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S6E63M0_BRIGHTNESS_H
+#define _S6E63M0_BRIGHTNESS_H
+
+#define MAX_GAMMA_LEVEL		11
+#define GAMMA_TABLE_COUNT	21
+
+/* gamma value: 2.2 */
+static const unsigned int s6e63m0_22_300[] = {
+	0x18, 0x08, 0x24, 0x5f, 0x50, 0x2d, 0xB6,
+	0xB9, 0xA7, 0xAd, 0xB1, 0x9f, 0xbe, 0xC0,
+	0xB5, 0x00, 0xa0, 0x00, 0xa4, 0x00, 0xdb
+};
+
+static const unsigned int s6e63m0_22_280[] = {
+	0x18, 0x08, 0x24, 0x64, 0x56, 0x33, 0xB6,
+	0xBA, 0xA8, 0xAC, 0xB1, 0x9D, 0xC1, 0xC1,
+	0xB7, 0x00, 0x9C, 0x00, 0x9F, 0x00, 0xD6
+};
+
+static const unsigned int s6e63m0_22_260[] = {
+	0x18, 0x08, 0x24, 0x66, 0x58, 0x34, 0xB6,
+	0xBA, 0xA7, 0xAF, 0xB3, 0xA0, 0xC1, 0xC2,
+	0xB7, 0x00, 0x97, 0x00, 0x9A, 0x00, 0xD1
+
+};
+
+static const unsigned int s6e63m0_22_240[] = {
+	0x18, 0x08, 0x24, 0x62, 0x54, 0x30, 0xB9,
+	0xBB, 0xA9, 0xB0, 0xB3, 0xA1, 0xC1, 0xC3,
+	0xB7, 0x00, 0x91, 0x00, 0x95, 0x00, 0xDA
+
+};
+static const unsigned int s6e63m0_22_220[] = {
+	0x18, 0x08, 0x24, 0x63, 0x53, 0x31, 0xB8,
+	0xBC, 0xA9, 0xB0, 0xB5, 0xA2, 0xC4, 0xC4,
+	0xB8, 0x00, 0x8B, 0x00, 0x8E, 0x00, 0xC2
+};
+
+static const unsigned int s6e63m0_22_200[] = {
+	0x18, 0x08, 0x24, 0x66, 0x55, 0x34, 0xBA,
+	0xBD, 0xAB, 0xB1, 0xB5, 0xA3, 0xC5, 0xC6,
+	0xB9, 0x00, 0x85, 0x00, 0x88, 0x00, 0xBA
+};
+
+static const unsigned int s6e63m0_22_170[] = {
+	0x18, 0x08, 0x24, 0x69, 0x54, 0x37, 0xBB,
+	0xBE, 0xAC, 0xB4, 0xB7, 0xA6, 0xC7, 0xC8,
+	0xBC, 0x00, 0x7B, 0x00, 0x7E, 0x00, 0xAB
+};
+
+static const unsigned int s6e63m0_22_140[] = {
+	0x18, 0x08, 0x24, 0x6C, 0x54, 0x3A, 0xBC,
+	0xBF, 0xAC, 0xB7, 0xBB, 0xA9, 0xC9, 0xC9,
+	0xBE, 0x00, 0x71, 0x00, 0x73, 0x00, 0x9E
+};
+
+static const unsigned int s6e63m0_22_110[] = {
+	0x18, 0x08, 0x24, 0x70, 0x51, 0x3E, 0xBF,
+	0xC1, 0xAF, 0xB9, 0xBC, 0xAB, 0xCC, 0xCC,
+	0xC2, 0x00, 0x65, 0x00, 0x67, 0x00, 0x8D
+};
+
+static const unsigned int s6e63m0_22_90[] = {
+	0x18, 0x08, 0x24, 0x73, 0x4A, 0x3D, 0xC0,
+	0xC2, 0xB1, 0xBB, 0xBE, 0xAC, 0xCE, 0xCF,
+	0xC5, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x82
+};
+
+static const unsigned int s6e63m0_22_30[] = {
+	0x18, 0x08, 0x24, 0x78, 0xEC, 0x3D, 0xC8,
+	0xC2, 0xB6, 0xC4, 0xC7, 0xB6, 0xD5, 0xD7,
+	0xCC, 0x00, 0x39, 0x00, 0x36, 0x00, 0x51
+};
+
+/* gamma value: 1.9 */
+static const unsigned int s6e63m0_19_300[] = {
+	0x18, 0x08, 0x24, 0x61, 0x5F, 0x39, 0xBA,
+	0xBD, 0xAD, 0xB1, 0xB6, 0xA5, 0xC4, 0xC5,
+	0xBC, 0x00, 0xA0, 0x00, 0xA4, 0x00, 0xDB
+};
+
+static const unsigned int s6e63m0_19_280[] = {
+	0x18, 0x08, 0x24, 0x61, 0x60, 0x39, 0xBB,
+	0xBE, 0xAD, 0xB2, 0xB6, 0xA6, 0xC5, 0xC7,
+	0xBD, 0x00, 0x9B, 0x00, 0x9E, 0x00, 0xD5
+};
+
+static const unsigned int s6e63m0_19_260[] = {
+	0x18, 0x08, 0x24, 0x63, 0x61, 0x3B, 0xBA,
+	0xBE, 0xAC, 0xB3, 0xB8, 0xA7, 0xC6, 0xC8,
+	0xBD, 0x00, 0x96, 0x00, 0x98, 0x00, 0xCF
+};
+
+static const unsigned int s6e63m0_19_240[] = {
+	0x18, 0x08, 0x24, 0x67, 0x64, 0x3F, 0xBB,
+	0xBE, 0xAD, 0xB3, 0xB9, 0xA7, 0xC8, 0xC9,
+	0xBE, 0x00, 0x90, 0x00, 0x92, 0x00, 0xC8
+};
+
+static const unsigned int s6e63m0_19_220[] = {
+	0x18, 0x08, 0x24, 0x68, 0x64, 0x40, 0xBC,
+	0xBF, 0xAF, 0xB4, 0xBA, 0xA9, 0xC8, 0xCA,
+	0xBE, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0xC0
+};
+
+static const unsigned int s6e63m0_19_200[] = {
+	0x18, 0x08, 0x24, 0x68, 0x64, 0x3F, 0xBE,
+	0xC0, 0xB0, 0xB6, 0xBB, 0xAB, 0xC8, 0xCB,
+	0xBF, 0x00, 0x85, 0x00, 0x86, 0x00, 0xB8
+};
+
+static const unsigned int s6e63m0_19_170[] = {
+	0x18, 0x08, 0x24, 0x69, 0x64, 0x40, 0xBF,
+	0xC1, 0xB0, 0xB9, 0xBE, 0xAD, 0xCB, 0xCD,
+	0xC2, 0x00, 0x7A, 0x00, 0x7B, 0x00, 0xAA
+};
+
+static const unsigned int s6e63m0_19_140[] = {
+	0x18, 0x08, 0x24, 0x6E, 0x65, 0x45, 0xC0,
+	0xC3, 0xB2, 0xBA, 0xBE, 0xAE, 0xCD, 0xD0,
+	0xC4, 0x00, 0x70, 0x00, 0x70, 0x00, 0x9C
+};
+
+static const unsigned int s6e63m0_19_110[] = {
+	0x18, 0x08, 0x24, 0x6F, 0x65, 0x46, 0xC2,
+	0xC4, 0xB3, 0xBF, 0xC2, 0xB2, 0xCF, 0xD1,
+	0xC6, 0x00, 0x64, 0x00, 0x64, 0x00, 0x8D
+};
+
+static const unsigned int s6e63m0_19_90[] = {
+	0x18, 0x08, 0x24, 0x74, 0x60, 0x4A, 0xC3,
+	0xC6, 0xB5, 0xBF, 0xC3, 0xB2, 0xD2, 0xD3,
+	0xC8, 0x00, 0x5B, 0x00, 0x5B, 0x00, 0x81
+};
+
+static const unsigned int s6e63m0_19_30[] = {
+	0x18, 0x08, 0x24, 0x84, 0x45, 0x4F, 0xCA,
+	0xCB, 0xBC, 0xC9, 0xCB, 0xBC, 0xDA, 0xDA,
+	0xD0, 0x00, 0x35, 0x00, 0x34, 0x00, 0x4E
+};
+
+/* gamma value: 1.7 */
+static const unsigned int s6e63m0_17_300[] = {
+	0x18, 0x08, 0x24, 0x70, 0x70, 0x4F, 0xBF,
+	0xC2, 0xB2, 0xB8, 0xBC, 0xAC, 0xCB, 0xCD,
+	0xC3, 0x00, 0xA0, 0x00, 0xA4, 0x00, 0xDB
+};
+
+static const unsigned int s6e63m0_17_280[] = {
+	0x18, 0x08, 0x24, 0x71, 0x71, 0x50, 0xBF,
+	0xC2, 0xB2, 0xBA, 0xBE, 0xAE, 0xCB, 0xCD,
+	0xC3, 0x00, 0x9C, 0x00, 0x9F, 0x00, 0xD6
+};
+
+static const unsigned int s6e63m0_17_260[] = {
+	0x18, 0x08, 0x24, 0x72, 0x72, 0x50, 0xC0,
+	0xC3, 0xB4, 0xB9, 0xBE, 0xAE, 0xCC, 0xCF,
+	0xC4, 0x00, 0x97, 0x00, 0x9A, 0x00, 0xD1
+};
+
+static const unsigned int s6e63m0_17_240[] = {
+	0x18, 0x08, 0x24, 0x71, 0x72, 0x4F, 0xC2,
+	0xC4, 0xB5, 0xBB, 0xBF, 0xB0, 0xCC, 0xCF,
+	0xC3, 0x00, 0x91, 0x00, 0x95, 0x00, 0xCA
+};
+
+static const unsigned int s6e63m0_17_220[] = {
+	0x18, 0x08, 0x24, 0x71, 0x73, 0x4F, 0xC2,
+	0xC5, 0xB5, 0xBD, 0xC0, 0xB2, 0xCD, 0xD1,
+	0xC5, 0x00, 0x8B, 0x00, 0x8E, 0x00, 0xC2
+};
+
+static const unsigned int s6e63m0_17_200[] = {
+	0x18, 0x08, 0x24, 0x72, 0x75, 0x51, 0xC2,
+	0xC6, 0xB5, 0xBF, 0xC1, 0xB3, 0xCE, 0xD1,
+	0xC6, 0x00, 0x85, 0x00, 0x88, 0x00, 0xBA
+};
+
+static const unsigned int s6e63m0_17_170[] = {
+	0x18, 0x08, 0x24, 0x75, 0x77, 0x54, 0xC3,
+	0xC7, 0xB7, 0xC0, 0xC3, 0xB4, 0xD1, 0xD3,
+	0xC9, 0x00, 0x7B, 0x00, 0x7E, 0x00, 0xAB
+};
+
+static const unsigned int s6e63m0_17_140[] = {
+	0x18, 0x08, 0x24, 0x7B, 0x77, 0x58, 0xC3,
+	0xC8, 0xB8, 0xC2, 0xC6, 0xB6, 0xD3, 0xD4,
+	0xCA, 0x00, 0x71, 0x00, 0x73, 0x00, 0x9E
+};
+
+static const unsigned int s6e63m0_17_110[] = {
+	0x18, 0x08, 0x24, 0x81, 0x7B, 0x5D, 0xC6,
+	0xCA, 0xBB, 0xC3, 0xC7, 0xB8, 0xD6, 0xD8,
+	0xCD, 0x00, 0x65, 0x00, 0x67, 0x00, 0x8D
+};
+
+static const unsigned int s6e63m0_17_90[] = {
+	0x18, 0x08, 0x24, 0x82, 0x7A, 0x5B, 0xC8,
+	0xCB, 0xBD, 0xC5, 0xCA, 0xBA, 0xD6, 0xD8,
+	0xCE, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x82
+};
+
+static const unsigned int s6e63m0_17_30[] = {
+	0x18, 0x08, 0x24, 0x8F, 0x73, 0x63, 0xD1,
+	0xD0, 0xC5, 0xCC, 0xD1, 0xC2, 0xDE, 0xE0,
+	0xD6, 0x00, 0x39, 0x00, 0x36, 0x00, 0x51
+};
+
+struct s6e63m0_gamma {
+	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
+	unsigned int *gamma_19_table[MAX_GAMMA_LEVEL];
+	unsigned int *gamma_17_table[MAX_GAMMA_LEVEL];
+};
+
+static struct s6e63m0_gamma gamma_table = {
+	.gamma_22_table[0] = (unsigned int *)&s6e63m0_22_30,
+	.gamma_22_table[1] = (unsigned int *)&s6e63m0_22_90,
+	.gamma_22_table[2] = (unsigned int *)&s6e63m0_22_110,
+	.gamma_22_table[3] = (unsigned int *)&s6e63m0_22_140,
+	.gamma_22_table[4] = (unsigned int *)&s6e63m0_22_170,
+	.gamma_22_table[5] = (unsigned int *)&s6e63m0_22_200,
+	.gamma_22_table[6] = (unsigned int *)&s6e63m0_22_220,
+	.gamma_22_table[7] = (unsigned int *)&s6e63m0_22_240,
+	.gamma_22_table[8] = (unsigned int *)&s6e63m0_22_260,
+	.gamma_22_table[9] = (unsigned int *)&s6e63m0_22_280,
+	.gamma_22_table[10] = (unsigned int *)&s6e63m0_22_300,
+
+	.gamma_19_table[0] = (unsigned int *)&s6e63m0_19_30,
+	.gamma_19_table[1] = (unsigned int *)&s6e63m0_19_90,
+	.gamma_19_table[2] = (unsigned int *)&s6e63m0_19_110,
+	.gamma_19_table[3] = (unsigned int *)&s6e63m0_19_140,
+	.gamma_19_table[4] = (unsigned int *)&s6e63m0_19_170,
+	.gamma_19_table[5] = (unsigned int *)&s6e63m0_19_200,
+	.gamma_19_table[6] = (unsigned int *)&s6e63m0_19_220,
+	.gamma_19_table[7] = (unsigned int *)&s6e63m0_19_240,
+	.gamma_19_table[8] = (unsigned int *)&s6e63m0_19_260,
+	.gamma_19_table[9] = (unsigned int *)&s6e63m0_19_280,
+	.gamma_19_table[10] = (unsigned int *)&s6e63m0_19_300,
+
+	.gamma_17_table[0] = (unsigned int *)&s6e63m0_17_30,
+	.gamma_17_table[1] = (unsigned int *)&s6e63m0_17_90,
+	.gamma_17_table[2] = (unsigned int *)&s6e63m0_17_110,
+	.gamma_17_table[3] = (unsigned int *)&s6e63m0_17_140,
+	.gamma_17_table[4] = (unsigned int *)&s6e63m0_17_170,
+	.gamma_17_table[5] = (unsigned int *)&s6e63m0_17_200,
+	.gamma_17_table[6] = (unsigned int *)&s6e63m0_17_220,
+	.gamma_17_table[7] = (unsigned int *)&s6e63m0_17_240,
+	.gamma_17_table[8] = (unsigned int *)&s6e63m0_17_260,
+	.gamma_17_table[9] = (unsigned int *)&s6e63m0_17_280,
+	.gamma_17_table[10] = (unsigned int *)&s6e63m0_17_300,
+};
+
+#endif
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/tdo24m.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/tdo24m.c
new file mode 100644
index 0000000..2368b8e
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/tdo24m.c
@@ -0,0 +1,467 @@
+/*
+ * tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ * 	Eric Miao <eric.miao@marvell.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 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+#include <linux/fb.h>
+#include <linux/lcd.h>
+#include <linux/slab.h>
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+#define TDO24M_SPI_BUFF_SIZE	(4)
+#define MODE_QVGA	0
+#define MODE_VGA	1
+
+struct tdo24m {
+	struct spi_device	*spi_dev;
+	struct lcd_device	*lcd_dev;
+
+	struct spi_message	msg;
+	struct spi_transfer	xfer;
+	uint8_t			*buf;
+
+	int (*adj_mode)(struct tdo24m *lcd, int mode);
+	int color_invert;
+
+	int			power;
+	int			mode;
+};
+
+/* use bit 30, 31 as the indicator of command parameter number */
+#define CMD0(x)		((0 << 30) | (x))
+#define CMD1(x, x1)	((1 << 30) | ((x) << 9) | 0x100 | (x1))
+#define CMD2(x, x1, x2)	((2 << 30) | ((x) << 18) | 0x20000 |\
+			((x1) << 9) | 0x100 | (x2))
+#define CMD_NULL	(-1)
+
+static uint32_t lcd_panel_reset[] = {
+	CMD0(0x1), /* reset */
+	CMD0(0x0), /* nop */
+	CMD0(0x0), /* nop */
+	CMD0(0x0), /* nop */
+	CMD_NULL,
+};
+
+static uint32_t lcd_panel_on[] = {
+	CMD0(0x29),		/* Display ON */
+	CMD2(0xB8, 0xFF, 0xF9),	/* Output Control */
+	CMD0(0x11),		/* Sleep out */
+	CMD1(0xB0, 0x16),	/* Wake */
+	CMD_NULL,
+};
+
+static uint32_t lcd_panel_off[] = {
+	CMD0(0x28),		/* Display OFF */
+	CMD2(0xB8, 0x80, 0x02),	/* Output Control */
+	CMD0(0x10),		/* Sleep in */
+	CMD1(0xB0, 0x00),	/* Deep stand by in */
+	CMD_NULL,
+};
+
+static uint32_t lcd_vga_pass_through_tdo24m[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x80),
+	CMD1(0xE1, 0x00),
+	CMD1(0x36, 0x50),
+	CMD1(0x3B, 0x00),
+	CMD_NULL,
+};
+
+static uint32_t lcd_qvga_pass_through_tdo24m[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x81),
+	CMD1(0xE1, 0x00),
+	CMD1(0x36, 0x50),
+	CMD1(0x3B, 0x22),
+	CMD_NULL,
+};
+
+static uint32_t lcd_vga_transfer_tdo24m[] = {
+	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
+	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd2, 0x14, 0x00),	/* CKV 1,2 timing control */
+	CMD2(0xd3, 0x1a, 0x0f),	/* OEV timing control */
+	CMD2(0xd4, 0x1f, 0xaf),	/* ASW timing control (1) */
+	CMD1(0xd5, 0x14),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+	CMD_NULL,
+};
+
+static uint32_t lcd_qvga_transfer[] = {
+	CMD1(0xd6, 0x02),	/* Blanking period control (1) */
+	CMD2(0xd7, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd8, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd9, 0x00, 0x08),	/* CKV 1,2 timing control */
+	CMD2(0xde, 0x05, 0x0a),	/* OEV timing control */
+	CMD2(0xdf, 0x0a, 0x19),	/* ASW timing control (1) */
+	CMD1(0xe0, 0x0a),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+	CMD_NULL,
+};
+
+static uint32_t lcd_vga_pass_through_tdo35s[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x80),
+	CMD1(0xE1, 0x00),
+	CMD1(0x3B, 0x00),
+	CMD_NULL,
+};
+
+static uint32_t lcd_qvga_pass_through_tdo35s[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x81),
+	CMD1(0xE1, 0x00),
+	CMD1(0x3B, 0x22),
+	CMD_NULL,
+};
+
+static uint32_t lcd_vga_transfer_tdo35s[] = {
+	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
+	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd2, 0x00, 0x1e),	/* CKV 1,2 timing control */
+	CMD2(0xd3, 0x14, 0x28),	/* OEV timing control */
+	CMD2(0xd4, 0x28, 0x64),	/* ASW timing control (1) */
+	CMD1(0xd5, 0x28),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+	CMD_NULL,
+};
+
+static uint32_t lcd_panel_config[] = {
+	CMD2(0xb8, 0xff, 0xf9),	/* Output control */
+	CMD0(0x11),		/* sleep out */
+	CMD1(0xba, 0x01),	/* Display mode (1) */
+	CMD1(0xbb, 0x00),	/* Display mode (2) */
+	CMD1(0x3a, 0x60),	/* Display mode 18-bit RGB */
+	CMD1(0xbf, 0x10),	/* Drive system change control */
+	CMD1(0xb1, 0x56),	/* Booster operation setup */
+	CMD1(0xb2, 0x33),	/* Booster mode setup */
+	CMD1(0xb3, 0x11),	/* Booster frequency setup */
+	CMD1(0xb4, 0x02),	/* Op amp/system clock */
+	CMD1(0xb5, 0x35),	/* VCS voltage */
+	CMD1(0xb6, 0x40),	/* VCOM voltage */
+	CMD1(0xb7, 0x03),	/* External display signal */
+	CMD1(0xbd, 0x00),	/* ASW slew rate */
+	CMD1(0xbe, 0x00),	/* Dummy data for QuadData operation */
+	CMD1(0xc0, 0x11),	/* Sleep out FR count (A) */
+	CMD1(0xc1, 0x11),	/* Sleep out FR count (B) */
+	CMD1(0xc2, 0x11),	/* Sleep out FR count (C) */
+	CMD2(0xc3, 0x20, 0x40),	/* Sleep out FR count (D) */
+	CMD2(0xc4, 0x60, 0xc0),	/* Sleep out FR count (E) */
+	CMD2(0xc5, 0x10, 0x20),	/* Sleep out FR count (F) */
+	CMD1(0xc6, 0xc0),	/* Sleep out FR count (G) */
+	CMD2(0xc7, 0x33, 0x43),	/* Gamma 1 fine tuning (1) */
+	CMD1(0xc8, 0x44),	/* Gamma 1 fine tuning (2) */
+	CMD1(0xc9, 0x33),	/* Gamma 1 inclination adjustment */
+	CMD1(0xca, 0x00),	/* Gamma 1 blue offset adjustment */
+	CMD2(0xec, 0x01, 0xf0),	/* Horizontal clock cycles */
+	CMD_NULL,
+};
+
+static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array)
+{
+	struct spi_transfer *x = &lcd->xfer;
+	uint32_t data, *p = array;
+	int nparams, err = 0;
+
+	for (; *p != CMD_NULL; p++) {
+		if (!lcd->color_invert && *p == CMD0(0x21))
+			continue;
+
+		nparams = (*p >> 30) & 0x3;
+
+		data = *p << (7 - nparams);
+		switch (nparams) {
+		case 0:
+			lcd->buf[0] = (data >> 8) & 0xff;
+			lcd->buf[1] = data & 0xff;
+			break;
+		case 1:
+			lcd->buf[0] = (data >> 16) & 0xff;
+			lcd->buf[1] = (data >> 8) & 0xff;
+			lcd->buf[2] = data & 0xff;
+			break;
+		case 2:
+			lcd->buf[0] = (data >> 24) & 0xff;
+			lcd->buf[1] = (data >> 16) & 0xff;
+			lcd->buf[2] = (data >> 8) & 0xff;
+			lcd->buf[3] = data & 0xff;
+			break;
+		default:
+			continue;
+		}
+		x->len = nparams + 2;
+		err = spi_sync(lcd->spi_dev, &lcd->msg);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+static int tdo24m_adj_mode(struct tdo24m *lcd, int mode)
+{
+	switch (mode) {
+	case MODE_VGA:
+		tdo24m_writes(lcd, lcd_vga_pass_through_tdo24m);
+		tdo24m_writes(lcd, lcd_panel_config);
+		tdo24m_writes(lcd, lcd_vga_transfer_tdo24m);
+		break;
+	case MODE_QVGA:
+		tdo24m_writes(lcd, lcd_qvga_pass_through_tdo24m);
+		tdo24m_writes(lcd, lcd_panel_config);
+		tdo24m_writes(lcd, lcd_qvga_transfer);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	lcd->mode = mode;
+	return 0;
+}
+
+static int tdo35s_adj_mode(struct tdo24m *lcd, int mode)
+{
+	switch (mode) {
+	case MODE_VGA:
+		tdo24m_writes(lcd, lcd_vga_pass_through_tdo35s);
+		tdo24m_writes(lcd, lcd_panel_config);
+		tdo24m_writes(lcd, lcd_vga_transfer_tdo35s);
+		break;
+	case MODE_QVGA:
+		tdo24m_writes(lcd, lcd_qvga_pass_through_tdo35s);
+		tdo24m_writes(lcd, lcd_panel_config);
+		tdo24m_writes(lcd, lcd_qvga_transfer);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	lcd->mode = mode;
+	return 0;
+}
+
+static int tdo24m_power_on(struct tdo24m *lcd)
+{
+	int err;
+
+	err = tdo24m_writes(lcd, lcd_panel_on);
+	if (err)
+		goto out;
+
+	err = tdo24m_writes(lcd, lcd_panel_reset);
+	if (err)
+		goto out;
+
+	err = lcd->adj_mode(lcd, lcd->mode);
+out:
+	return err;
+}
+
+static int tdo24m_power_off(struct tdo24m *lcd)
+{
+	return tdo24m_writes(lcd, lcd_panel_off);
+}
+
+static int tdo24m_power(struct tdo24m *lcd, int power)
+{
+	int ret = 0;
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		ret = tdo24m_power_on(lcd);
+	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		ret = tdo24m_power_off(lcd);
+
+	if (!ret)
+		lcd->power = power;
+
+	return ret;
+}
+
+
+static int tdo24m_set_power(struct lcd_device *ld, int power)
+{
+	struct tdo24m *lcd = lcd_get_data(ld);
+	return tdo24m_power(lcd, power);
+}
+
+static int tdo24m_get_power(struct lcd_device *ld)
+{
+	struct tdo24m *lcd = lcd_get_data(ld);
+	return lcd->power;
+}
+
+static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m)
+{
+	struct tdo24m *lcd = lcd_get_data(ld);
+	int mode = MODE_QVGA;
+
+	if (m->xres == 640 || m->xres == 480)
+		mode = MODE_VGA;
+
+	if (lcd->mode == mode)
+		return 0;
+
+	return lcd->adj_mode(lcd, mode);
+}
+
+static struct lcd_ops tdo24m_ops = {
+	.get_power	= tdo24m_get_power,
+	.set_power	= tdo24m_set_power,
+	.set_mode	= tdo24m_set_mode,
+};
+
+static int __devinit tdo24m_probe(struct spi_device *spi)
+{
+	struct tdo24m *lcd;
+	struct spi_message *m;
+	struct spi_transfer *x;
+	struct tdo24m_platform_data *pdata;
+	enum tdo24m_model model;
+	int err;
+
+	pdata = spi->dev.platform_data;
+	if (pdata)
+		model = pdata->model;
+	else
+		model = TDO24M;
+
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_3;
+	err = spi_setup(spi);
+	if (err)
+		return err;
+
+	lcd = kzalloc(sizeof(struct tdo24m), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->spi_dev = spi;
+	lcd->power = FB_BLANK_POWERDOWN;
+	lcd->mode = MODE_VGA;	/* default to VGA */
+
+	lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL);
+	if (lcd->buf == NULL) {
+		kfree(lcd);
+		return -ENOMEM;
+	}
+
+	m = &lcd->msg;
+	x = &lcd->xfer;
+
+	spi_message_init(m);
+
+	x->cs_change = 1;
+	x->tx_buf = &lcd->buf[0];
+	spi_message_add_tail(x, m);
+
+	switch (model) {
+	case TDO24M:
+		lcd->color_invert = 1;
+		lcd->adj_mode = tdo24m_adj_mode;
+		break;
+	case TDO35S:
+		lcd->adj_mode = tdo35s_adj_mode;
+		lcd->color_invert = 0;
+		break;
+	default:
+		dev_err(&spi->dev, "Unsupported model");
+		goto out_free;
+	}
+
+	lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev,
+					lcd, &tdo24m_ops);
+	if (IS_ERR(lcd->lcd_dev)) {
+		err = PTR_ERR(lcd->lcd_dev);
+		goto out_free;
+	}
+
+	dev_set_drvdata(&spi->dev, lcd);
+	err = tdo24m_power(lcd, FB_BLANK_UNBLANK);
+	if (err)
+		goto out_unregister;
+
+	return 0;
+
+out_unregister:
+	lcd_device_unregister(lcd->lcd_dev);
+out_free:
+	kfree(lcd->buf);
+	kfree(lcd);
+	return err;
+}
+
+static int __devexit tdo24m_remove(struct spi_device *spi)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	tdo24m_power(lcd, FB_BLANK_POWERDOWN);
+	lcd_device_unregister(lcd->lcd_dev);
+	kfree(lcd->buf);
+	kfree(lcd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tdo24m_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	return tdo24m_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static int tdo24m_resume(struct spi_device *spi)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	return tdo24m_power(lcd, FB_BLANK_UNBLANK);
+}
+#else
+#define tdo24m_suspend	NULL
+#define tdo24m_resume	NULL
+#endif
+
+/* Power down all displays on reboot, poweroff or halt */
+static void tdo24m_shutdown(struct spi_device *spi)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	tdo24m_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver tdo24m_driver = {
+	.driver = {
+		.name		= "tdo24m",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= tdo24m_probe,
+	.remove		= __devexit_p(tdo24m_remove),
+	.shutdown	= tdo24m_shutdown,
+	.suspend	= tdo24m_suspend,
+	.resume		= tdo24m_resume,
+};
+
+module_spi_driver(tdo24m_driver);
+
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:tdo24m");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/tosa_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/tosa_bl.c
new file mode 100644
index 0000000..2b241ab
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/tosa_bl.c
@@ -0,0 +1,189 @@
+/*
+ *  LCD / Backlight control code for Sharp SL-6000x (tosa)
+ *
+ *  Copyright (c) 2005		Dirk Opfer
+ *  Copyright (c) 2007,2008	Dmitry Baryshkov
+ *
+ *  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
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/slab.h>
+
+#include <asm/mach/sharpsl_param.h>
+
+#include <mach/tosa.h>
+
+#define COMADJ_DEFAULT	97
+
+#define DAC_CH1		0
+#define DAC_CH2		1
+
+struct tosa_bl_data {
+	struct i2c_client *i2c;
+	struct backlight_device *bl;
+
+	int comadj;
+};
+
+static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness)
+{
+	struct spi_device *spi = data->i2c->dev.platform_data;
+
+	i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj);
+
+	/* SetBacklightDuty */
+	i2c_smbus_write_byte_data(data->i2c, DAC_CH2, (u8)(brightness & 0xff));
+
+	/* SetBacklightVR */
+	gpio_set_value(TOSA_GPIO_BL_C20MA, brightness & 0x100);
+
+	tosa_bl_enable(spi, brightness);
+}
+
+static int tosa_bl_update_status(struct backlight_device *dev)
+{
+	struct backlight_properties *props = &dev->props;
+	struct tosa_bl_data *data = dev_get_drvdata(&dev->dev);
+	int power = max(props->power, props->fb_blank);
+	int brightness = props->brightness;
+
+	if (power)
+		brightness = 0;
+
+	tosa_bl_set_backlight(data, brightness);
+
+	return 0;
+}
+
+static int tosa_bl_get_brightness(struct backlight_device *dev)
+{
+	struct backlight_properties *props = &dev->props;
+
+	return props->brightness;
+}
+
+static const struct backlight_ops bl_ops = {
+	.get_brightness		= tosa_bl_get_brightness,
+	.update_status		= tosa_bl_update_status,
+};
+
+static int __devinit tosa_bl_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct backlight_properties props;
+	struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL);
+	int ret = 0;
+	if (!data)
+		return -ENOMEM;
+
+	data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
+
+	ret = gpio_request(TOSA_GPIO_BL_C20MA, "backlight");
+	if (ret) {
+		dev_dbg(&data->bl->dev, "Unable to request gpio!\n");
+		goto err_gpio_bl;
+	}
+	ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0);
+	if (ret)
+		goto err_gpio_dir;
+
+	i2c_set_clientdata(client, data);
+	data->i2c = client;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = 512 - 1;
+	data->bl = backlight_device_register("tosa-bl", &client->dev, data,
+					     &bl_ops, &props);
+	if (IS_ERR(data->bl)) {
+		ret = PTR_ERR(data->bl);
+		goto err_reg;
+	}
+
+	data->bl->props.brightness = 69;
+	data->bl->props.power = FB_BLANK_UNBLANK;
+
+	backlight_update_status(data->bl);
+
+	return 0;
+
+err_reg:
+	data->bl = NULL;
+err_gpio_dir:
+	gpio_free(TOSA_GPIO_BL_C20MA);
+err_gpio_bl:
+	kfree(data);
+	return ret;
+}
+
+static int __devexit tosa_bl_remove(struct i2c_client *client)
+{
+	struct tosa_bl_data *data = i2c_get_clientdata(client);
+
+	backlight_device_unregister(data->bl);
+	data->bl = NULL;
+
+	gpio_free(TOSA_GPIO_BL_C20MA);
+
+	kfree(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tosa_bl_suspend(struct i2c_client *client, pm_message_t pm)
+{
+	struct tosa_bl_data *data = i2c_get_clientdata(client);
+
+	tosa_bl_set_backlight(data, 0);
+
+	return 0;
+}
+
+static int tosa_bl_resume(struct i2c_client *client)
+{
+	struct tosa_bl_data *data = i2c_get_clientdata(client);
+
+	backlight_update_status(data->bl);
+	return 0;
+}
+#else
+#define tosa_bl_suspend NULL
+#define tosa_bl_resume NULL
+#endif
+
+static const struct i2c_device_id tosa_bl_id[] = {
+	{ "tosa-bl", 0 },
+	{ },
+};
+
+
+static struct i2c_driver tosa_bl_driver = {
+	.driver = {
+		.name		= "tosa-bl",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= tosa_bl_probe,
+	.remove		= __devexit_p(tosa_bl_remove),
+	.suspend	= tosa_bl_suspend,
+	.resume		= tosa_bl_resume,
+	.id_table	= tosa_bl_id,
+};
+
+module_i2c_driver(tosa_bl_driver);
+
+MODULE_AUTHOR("Dmitry Baryshkov");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/tosa_lcd.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/tosa_lcd.c
new file mode 100644
index 0000000..2231aec
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/tosa_lcd.c
@@ -0,0 +1,293 @@
+/*
+ *  LCD / Backlight control code for Sharp SL-6000x (tosa)
+ *
+ *  Copyright (c) 2005		Dirk Opfer
+ *  Copyright (c) 2007,2008	Dmitry Baryshkov
+ *
+ *  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
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/lcd.h>
+#include <linux/fb.h>
+
+#include <asm/mach/sharpsl_param.h>
+
+#include <mach/tosa.h>
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+#define TG_REG0_VQV	0x0001
+#define TG_REG0_COLOR	0x0002
+#define TG_REG0_UD	0x0004
+#define TG_REG0_LR	0x0008
+
+#define	DAC_BASE	0x4e
+
+struct tosa_lcd_data {
+	struct spi_device *spi;
+	struct lcd_device *lcd;
+	struct i2c_client *i2c;
+
+	int lcd_power;
+	bool is_vga;
+};
+
+static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data)
+{
+	u8 buf[1];
+	struct spi_message msg;
+	struct spi_transfer xfer = {
+		.len		= 1,
+		.cs_change	= 1,
+		.tx_buf		= buf,
+	};
+
+	buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(spi, &msg);
+}
+
+int tosa_bl_enable(struct spi_device *spi, int enable)
+{
+	/* bl_enable GP04=1 otherwise GP04=0*/
+	return tosa_tg_send(spi, TG_GPODR2, enable? 0x01 : 0x00);
+}
+EXPORT_SYMBOL(tosa_bl_enable);
+
+static void tosa_lcd_tg_init(struct tosa_lcd_data *data)
+{
+	/* TG on */
+	gpio_set_value(TOSA_GPIO_TG_ON, 0);
+
+	mdelay(60);
+
+	/* delayed 0clk TCTL signal for VGA */
+	tosa_tg_send(data->spi, TG_TPOSCTL, 0x00);
+	/* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
+	tosa_tg_send(data->spi, TG_GPOSR, 0x02);
+}
+
+static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
+{
+	struct spi_device *spi = data->spi;
+	int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
+
+	if (data->is_vga)
+		value |= TG_REG0_VQV;
+
+	tosa_tg_send(spi, TG_PNLCTL, value);
+
+	/* TG LCD pannel power up */
+	tosa_tg_send(spi, TG_PINICTL,0x4);
+	mdelay(50);
+
+	/* TG LCD GVSS */
+	tosa_tg_send(spi, TG_PINICTL,0x0);
+
+	if (!data->i2c) {
+		/* after the pannel is powered up the first time, we can access the i2c bus */
+		/* so probe for the DAC */
+		struct i2c_adapter *adap = i2c_get_adapter(0);
+		struct i2c_board_info info = {
+			.type	= "tosa-bl",
+			.addr	= DAC_BASE,
+			.platform_data = data->spi,
+		};
+		data->i2c = i2c_new_device(adap, &info);
+	}
+}
+
+static void tosa_lcd_tg_off(struct tosa_lcd_data *data)
+{
+	struct spi_device *spi = data->spi;
+
+	/* TG LCD VHSA off */
+	tosa_tg_send(spi, TG_PINICTL,0x4);
+	mdelay(50);
+
+	/* TG LCD signal off */
+	tosa_tg_send(spi, TG_PINICTL,0x6);
+	mdelay(50);
+
+	/* TG Off */
+	gpio_set_value(TOSA_GPIO_TG_ON, 1);
+	mdelay(100);
+}
+
+int tosa_lcd_set_power(struct lcd_device *lcd, int power)
+{
+	struct tosa_lcd_data *data = lcd_get_data(lcd);
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(data->lcd_power))
+		tosa_lcd_tg_on(data);
+
+	if (!POWER_IS_ON(power) && POWER_IS_ON(data->lcd_power))
+		tosa_lcd_tg_off(data);
+
+	data->lcd_power = power;
+	return 0;
+}
+
+static int tosa_lcd_get_power(struct lcd_device *lcd)
+{
+	struct tosa_lcd_data *data = lcd_get_data(lcd);
+
+	return data->lcd_power;
+}
+
+static int tosa_lcd_set_mode(struct lcd_device *lcd, struct fb_videomode *mode)
+{
+	struct tosa_lcd_data *data = lcd_get_data(lcd);
+
+	if (mode->xres == 320 || mode->yres == 320)
+		data->is_vga = false;
+	else
+		data->is_vga = true;
+
+	if (POWER_IS_ON(data->lcd_power))
+		tosa_lcd_tg_on(data);
+
+	return 0;
+}
+
+static struct lcd_ops tosa_lcd_ops = {
+	.set_power = tosa_lcd_set_power,
+	.get_power = tosa_lcd_get_power,
+	.set_mode = tosa_lcd_set_mode,
+};
+
+static int __devinit tosa_lcd_probe(struct spi_device *spi)
+{
+	int ret;
+	struct tosa_lcd_data *data;
+
+	data = kzalloc(sizeof(struct tosa_lcd_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->is_vga = true; /* default to VGA mode */
+
+	/*
+	 * bits_per_word cannot be configured in platform data
+	 */
+	spi->bits_per_word = 8;
+
+	ret = spi_setup(spi);
+	if (ret < 0)
+		goto err_spi;
+
+	data->spi = spi;
+	dev_set_drvdata(&spi->dev, data);
+
+	ret = gpio_request(TOSA_GPIO_TG_ON, "tg #pwr");
+	if (ret < 0)
+		goto err_gpio_tg;
+
+	mdelay(60);
+
+	ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0);
+	if (ret < 0)
+		goto err_gpio_dir;
+
+	mdelay(60);
+	tosa_lcd_tg_init(data);
+
+	tosa_lcd_tg_on(data);
+
+	data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data,
+			&tosa_lcd_ops);
+
+	if (IS_ERR(data->lcd)) {
+		ret = PTR_ERR(data->lcd);
+		data->lcd = NULL;
+		goto err_register;
+	}
+
+	return 0;
+
+err_register:
+	tosa_lcd_tg_off(data);
+err_gpio_dir:
+	gpio_free(TOSA_GPIO_TG_ON);
+err_gpio_tg:
+	dev_set_drvdata(&spi->dev, NULL);
+err_spi:
+	kfree(data);
+	return ret;
+}
+
+static int __devexit tosa_lcd_remove(struct spi_device *spi)
+{
+	struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+
+	lcd_device_unregister(data->lcd);
+
+	if (data->i2c)
+		i2c_unregister_device(data->i2c);
+
+	tosa_lcd_tg_off(data);
+
+	gpio_free(TOSA_GPIO_TG_ON);
+	dev_set_drvdata(&spi->dev, NULL);
+	kfree(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+
+	tosa_lcd_tg_off(data);
+
+	return 0;
+}
+
+static int tosa_lcd_resume(struct spi_device *spi)
+{
+	struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+
+	tosa_lcd_tg_init(data);
+	if (POWER_IS_ON(data->lcd_power))
+		tosa_lcd_tg_on(data);
+	else
+		tosa_lcd_tg_off(data);
+
+	return 0;
+}
+#else
+#define tosa_lcd_suspend	NULL
+#define tosa_lcd_resume NULL
+#endif
+
+static struct spi_driver tosa_lcd_driver = {
+	.driver = {
+		.name		= "tosa-lcd",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= tosa_lcd_probe,
+	.remove		= __devexit_p(tosa_lcd_remove),
+	.suspend	= tosa_lcd_suspend,
+	.resume		= tosa_lcd_resume,
+};
+
+module_spi_driver(tosa_lcd_driver);
+
+MODULE_AUTHOR("Dmitry Baryshkov");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
+MODULE_ALIAS("spi:tosa-lcd");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/vgg2432a4.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/vgg2432a4.c
new file mode 100644
index 0000000..b617fae
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/vgg2432a4.c
@@ -0,0 +1,270 @@
+/* drivers/video/backlight/vgg2432a4.c
+ *
+ * VGG2432A4 (ILI9320) LCD controller driver.
+ *
+ * Copyright 2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+
+#include <linux/spi/spi.h>
+
+#include <video/ili9320.h>
+
+#include "ili9320.h"
+
+/* Device initialisation sequences */
+
+static struct ili9320_reg vgg_init1[] = {
+	{
+		.address = ILI9320_POWER1,
+		.value	 = ILI9320_POWER1_AP(0) | ILI9320_POWER1_BT(0),
+	}, {
+		.address = ILI9320_POWER2,
+		.value	 = (ILI9320_POWER2_VC(7) |
+			    ILI9320_POWER2_DC0(0) | ILI9320_POWER2_DC1(0)),
+	}, {
+		.address = ILI9320_POWER3,
+		.value	 = ILI9320_POWER3_VRH(0),
+	}, {
+		.address = ILI9320_POWER4,
+		.value	 = ILI9320_POWER4_VREOUT(0),
+	},
+};
+
+static struct ili9320_reg vgg_init2[] = {
+	{
+		.address = ILI9320_POWER1,
+		.value   = (ILI9320_POWER1_AP(3) | ILI9320_POWER1_APE |
+			    ILI9320_POWER1_BT(7) | ILI9320_POWER1_SAP),
+	}, {
+		.address = ILI9320_POWER2,
+		.value   = ILI9320_POWER2_VC(7) | ILI9320_POWER2_DC0(3),
+	}
+};
+
+static struct ili9320_reg vgg_gamma[] = {
+	{
+		.address = ILI9320_GAMMA1,
+		.value	 = 0x0000,
+	}, {
+		.address = ILI9320_GAMMA2,
+		.value   = 0x0505,
+	}, {
+		.address = ILI9320_GAMMA3,
+		.value	 = 0x0004,
+	}, {
+		.address = ILI9320_GAMMA4,
+		.value	 = 0x0006,
+	}, {
+		.address = ILI9320_GAMMA5,
+		.value	 = 0x0707,
+	}, {
+		.address = ILI9320_GAMMA6,
+		.value	 = 0x0105,
+	}, {
+		.address = ILI9320_GAMMA7,
+		.value	 = 0x0002,
+	}, {
+		.address = ILI9320_GAMMA8,
+		.value	 = 0x0707,
+	}, {
+		.address = ILI9320_GAMMA9,
+		.value	 = 0x0704,
+	}, {
+		.address = ILI9320_GAMMA10,
+		.value	 = 0x807,
+	}
+
+};
+
+static struct ili9320_reg vgg_init0[] = {
+	[0]	= {
+		/* set direction and scan mode gate */
+		.address = ILI9320_DRIVER,
+		.value	 = ILI9320_DRIVER_SS,
+	}, {
+		.address = ILI9320_DRIVEWAVE,
+		.value	 = (ILI9320_DRIVEWAVE_MUSTSET |
+			    ILI9320_DRIVEWAVE_EOR | ILI9320_DRIVEWAVE_BC),
+	}, {
+		.address = ILI9320_ENTRYMODE,
+		.value	 = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR,
+	}, {
+		.address = ILI9320_RESIZING,
+		.value	 = 0x0,
+	},
+};
+
+
+static int vgg2432a4_lcd_init(struct ili9320 *lcd,
+			      struct ili9320_platdata *cfg)
+{
+	unsigned int addr;
+	int ret;
+
+	/* Set VCore before anything else (VGG243237-6UFLWA) */
+	ret = ili9320_write(lcd, 0x00e5, 0x8000);
+	if (ret)
+		goto err_initial;
+
+	/* Start the oscillator up before we can do anything else. */
+	ret = ili9320_write(lcd, ILI9320_OSCILATION, ILI9320_OSCILATION_OSC);
+	if (ret)
+		goto err_initial;
+
+	/* must wait at-lesat 10ms after starting */
+	mdelay(15);
+
+	ret = ili9320_write_regs(lcd, vgg_init0, ARRAY_SIZE(vgg_init0));
+	if (ret != 0)
+		goto err_initial;
+
+	ili9320_write(lcd, ILI9320_DISPLAY2, cfg->display2);
+	ili9320_write(lcd, ILI9320_DISPLAY3, cfg->display3);
+	ili9320_write(lcd, ILI9320_DISPLAY4, cfg->display4);
+
+	ili9320_write(lcd, ILI9320_RGB_IF1, cfg->rgb_if1);
+	ili9320_write(lcd, ILI9320_FRAMEMAKER, 0x0);
+	ili9320_write(lcd, ILI9320_RGB_IF2, cfg->rgb_if2);
+
+	ret = ili9320_write_regs(lcd, vgg_init1, ARRAY_SIZE(vgg_init1));
+	if (ret != 0)
+		goto err_vgg;
+
+	mdelay(300);
+
+	ret = ili9320_write_regs(lcd, vgg_init2, ARRAY_SIZE(vgg_init2));
+	if (ret != 0)
+		goto err_vgg2;
+
+	mdelay(100);
+
+	ili9320_write(lcd, ILI9320_POWER3, 0x13c);
+
+	mdelay(100);
+
+	ili9320_write(lcd, ILI9320_POWER4, 0x1c00);
+	ili9320_write(lcd, ILI9320_POWER7, 0x000e);
+
+	mdelay(100);
+
+	ili9320_write(lcd, ILI9320_GRAM_HORIZ_ADDR, 0x00);
+	ili9320_write(lcd, ILI9320_GRAM_VERT_ADD, 0x00);
+
+	ret = ili9320_write_regs(lcd, vgg_gamma, ARRAY_SIZE(vgg_gamma));
+	if (ret != 0)
+		goto err_vgg3;
+
+	ili9320_write(lcd, ILI9320_HORIZ_START, 0x0);
+	ili9320_write(lcd, ILI9320_HORIZ_END, cfg->hsize - 1);
+	ili9320_write(lcd, ILI9320_VERT_START, 0x0);
+	ili9320_write(lcd, ILI9320_VERT_END, cfg->vsize - 1);
+
+	ili9320_write(lcd, ILI9320_DRIVER2,
+		      ILI9320_DRIVER2_NL(((cfg->vsize - 240) / 8) + 0x1D));
+
+	ili9320_write(lcd, ILI9320_BASE_IMAGE, 0x1);
+	ili9320_write(lcd, ILI9320_VERT_SCROLL, 0x00);
+
+	for (addr = ILI9320_PARTIAL1_POSITION; addr <= ILI9320_PARTIAL2_END;
+	     addr++) {
+		ili9320_write(lcd, addr, 0x0);
+	}
+
+	ili9320_write(lcd, ILI9320_INTERFACE1, 0x10);
+	ili9320_write(lcd, ILI9320_INTERFACE2, cfg->interface2);
+	ili9320_write(lcd, ILI9320_INTERFACE3, cfg->interface3);
+	ili9320_write(lcd, ILI9320_INTERFACE4, cfg->interface4);
+	ili9320_write(lcd, ILI9320_INTERFACE5, cfg->interface5);
+	ili9320_write(lcd, ILI9320_INTERFACE6, cfg->interface6);
+
+	lcd->display1 = (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_DTE |
+			 ILI9320_DISPLAY1_GON | ILI9320_DISPLAY1_BASEE |
+			 0x40);
+
+	ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
+
+	return 0;
+
+ err_vgg3:
+ err_vgg2:
+ err_vgg:
+ err_initial:
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state)
+{
+	return ili9320_suspend(dev_get_drvdata(&spi->dev), state);
+}
+
+static int vgg2432a4_resume(struct spi_device *spi)
+{
+	return ili9320_resume(dev_get_drvdata(&spi->dev));
+}
+#else
+#define vgg2432a4_suspend	NULL
+#define vgg2432a4_resume 	NULL
+#endif
+
+static struct ili9320_client vgg2432a4_client = {
+	.name	= "VGG2432A4",
+	.init	= vgg2432a4_lcd_init,
+};
+
+/* Device probe */
+
+static int __devinit vgg2432a4_probe(struct spi_device *spi)
+{
+	int ret;
+
+	ret = ili9320_probe_spi(spi, &vgg2432a4_client);
+	if (ret != 0) {
+		dev_err(&spi->dev, "failed to initialise ili9320\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devexit vgg2432a4_remove(struct spi_device *spi)
+{
+	return ili9320_remove(dev_get_drvdata(&spi->dev));
+}
+
+static void vgg2432a4_shutdown(struct spi_device *spi)
+{
+	ili9320_shutdown(dev_get_drvdata(&spi->dev));
+}
+
+static struct spi_driver vgg2432a4_driver = {
+	.driver = {
+		.name		= "VGG2432A4",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= vgg2432a4_probe,
+	.remove		= __devexit_p(vgg2432a4_remove),
+	.shutdown	= vgg2432a4_shutdown,
+	.suspend	= vgg2432a4_suspend,
+	.resume		= vgg2432a4_resume,
+};
+
+module_spi_driver(vgg2432a4_driver);
+
+MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
+MODULE_DESCRIPTION("VGG2432A4 LCD Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:VGG2432A4");
diff --git a/ap/os/linux/linux-3.4.x/drivers/video/backlight/wm831x_bl.c b/ap/os/linux/linux-3.4.x/drivers/video/backlight/wm831x_bl.c
new file mode 100644
index 0000000..5d365de
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/video/backlight/wm831x_bl.c
@@ -0,0 +1,240 @@
+/*
+ * Backlight driver for Wolfson Microelectronics WM831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectonics plc
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/regulator.h>
+
+struct wm831x_backlight_data {
+	struct wm831x *wm831x;
+	int isink_reg;
+	int current_brightness;
+};
+
+static int wm831x_backlight_set(struct backlight_device *bl, int brightness)
+{
+	struct wm831x_backlight_data *data = bl_get_data(bl);
+	struct wm831x *wm831x = data->wm831x;
+	int power_up = !data->current_brightness && brightness;
+	int power_down = data->current_brightness && !brightness;
+	int ret;
+
+	if (power_up) {
+		/* Enable the ISINK */
+		ret = wm831x_set_bits(wm831x, data->isink_reg,
+				      WM831X_CS1_ENA, WM831X_CS1_ENA);
+		if (ret < 0)
+			goto err;
+
+		/* Enable the DC-DC */
+		ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE,
+				      WM831X_DC4_ENA, WM831X_DC4_ENA);
+		if (ret < 0)
+			goto err;
+	}
+
+	if (power_down) {
+		/* DCDC first */
+		ret = wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE,
+				      WM831X_DC4_ENA, 0);
+		if (ret < 0)
+			goto err;
+
+		/* ISINK */
+		ret = wm831x_set_bits(wm831x, data->isink_reg,
+				      WM831X_CS1_DRIVE | WM831X_CS1_ENA, 0);
+		if (ret < 0)
+			goto err;
+	}
+
+	/* Set the new brightness */
+	ret = wm831x_set_bits(wm831x, data->isink_reg,
+			      WM831X_CS1_ISEL_MASK, brightness);
+	if (ret < 0)
+		goto err;
+
+	if (power_up) {
+		/* Drive current through the ISINK */
+		ret = wm831x_set_bits(wm831x, data->isink_reg,
+				      WM831X_CS1_DRIVE, WM831X_CS1_DRIVE);
+		if (ret < 0)
+			return ret;
+	}
+
+	data->current_brightness = brightness;
+
+	return 0;
+
+err:
+	/* If we were in the middle of a power transition always shut down
+	 * for safety.
+	 */
+	if (power_up || power_down) {
+		wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
+		wm831x_set_bits(wm831x, data->isink_reg, WM831X_CS1_ENA, 0);
+	}
+
+	return ret;
+}
+
+static int wm831x_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	return wm831x_backlight_set(bl, brightness);
+}
+
+static int wm831x_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct wm831x_backlight_data *data = bl_get_data(bl);
+	return data->current_brightness;
+}
+
+static const struct backlight_ops wm831x_backlight_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.update_status	= wm831x_backlight_update_status,
+	.get_brightness	= wm831x_backlight_get_brightness,
+};
+
+static int wm831x_backlight_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *wm831x_pdata;
+	struct wm831x_backlight_pdata *pdata;
+	struct wm831x_backlight_data *data;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	int ret, i, max_isel, isink_reg, dcdc_cfg;
+
+	/* We need platform data */
+	if (pdev->dev.parent->platform_data) {
+		wm831x_pdata = pdev->dev.parent->platform_data;
+		pdata = wm831x_pdata->backlight;
+	} else {
+		pdata = NULL;
+	}
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+
+	/* Figure out the maximum current we can use */
+	for (i = 0; i < WM831X_ISINK_MAX_ISEL; i++) {
+		if (wm831x_isinkv_values[i] > pdata->max_uA)
+			break;
+	}
+
+	if (i == 0) {
+		dev_err(&pdev->dev, "Invalid max_uA: %duA\n", pdata->max_uA);
+		return -EINVAL;
+	}
+	max_isel = i - 1;
+
+	if (pdata->max_uA != wm831x_isinkv_values[max_isel])
+		dev_warn(&pdev->dev,
+			 "Maximum current is %duA not %duA as requested\n",
+			 wm831x_isinkv_values[max_isel], pdata->max_uA);
+
+	switch (pdata->isink) {
+	case 1:
+		isink_reg = WM831X_CURRENT_SINK_1;
+		dcdc_cfg = 0;
+		break;
+	case 2:
+		isink_reg = WM831X_CURRENT_SINK_2;
+		dcdc_cfg = WM831X_DC4_FBSRC;
+		break;
+	default:
+		dev_err(&pdev->dev, "Invalid ISINK %d\n", pdata->isink);
+		return -EINVAL;
+	}
+
+	/* Configure the ISINK to use for feedback */
+	ret = wm831x_reg_unlock(wm831x);
+	if (ret < 0)
+		return ret;
+
+	ret = wm831x_set_bits(wm831x, WM831X_DC4_CONTROL, WM831X_DC4_FBSRC,
+			      dcdc_cfg);
+
+	wm831x_reg_lock(wm831x);
+	if (ret < 0)
+		return ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	data->wm831x = wm831x;
+	data->current_brightness = 0;
+	data->isink_reg = isink_reg;
+
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = max_isel;
+	bl = backlight_device_register("wm831x", &pdev->dev, data,
+				       &wm831x_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+
+	bl->props.brightness = max_isel;
+
+	platform_set_drvdata(pdev, bl);
+
+	/* Disable the DCDC if it was started so we can bootstrap */
+	wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
+
+	backlight_update_status(bl);
+
+	return 0;
+}
+
+static int wm831x_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(bl);
+	return 0;
+}
+
+static struct platform_driver wm831x_backlight_driver = {
+	.driver		= {
+		.name	= "wm831x-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_backlight_probe,
+	.remove		= wm831x_backlight_remove,
+};
+
+module_platform_driver(wm831x_backlight_driver);
+
+MODULE_DESCRIPTION("Backlight Driver for WM831x PMICs");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-backlight");