Index: linux-2.6.24/arch/arm/plat-s3c24xx/devs.c
===================================================================
--- linux-2.6.24.orig/arch/arm/plat-s3c24xx/devs.c	2008-02-16 15:27:01.000000000 +0100
+++ linux-2.6.24/arch/arm/plat-s3c24xx/devs.c	2008-02-16 15:28:43.000000000 +0100
@@ -24,6 +24,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/arch/fb.h>
+#include <asm/arch/lcd.h>
 #include <asm/arch/ts.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -613,6 +614,23 @@
 
 EXPORT_SYMBOL(s3c_device_timer3);
 
+/* LCD backlight */
+
+struct platform_device s3c_device_bl = {
+	.name		  = "s3c2410-bl",
+	.id		  = -1,
+};
+
+EXPORT_SYMBOL(s3c_device_bl);
+
+static struct s3c2410_bl_mach_info s3c2410bl_info;
+
+void __init set_s3c2410bl_info(struct s3c2410_bl_mach_info *hard_s3c2410bl_info)
+{
+	memcpy(&s3c2410bl_info, hard_s3c2410bl_info, sizeof(struct s3c2410_bl_mach_info));
+	s3c_device_bl.dev.platform_data = &s3c2410bl_info;
+}
+
 #ifdef CONFIG_CPU_S3C2440
 
 /* Camif Controller */
Index: linux-2.6.24/include/asm/arch-s3c2410/lcd.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/include/asm/arch-s3c2410/lcd.h	2008-02-16 15:28:43.000000000 +0100
@@ -0,0 +1,33 @@
+/* linux/include/asm/arch-s3c2410/lcd.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.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.
+ *
+ *
+ *  Changelog:
+ *     14-Mar-2005     RTP     Created file
+ *     07-Apr-2005     RTP     Renamed to s3c2410_lcd.h
+ *     03-Aug-2005     RTP     Renamed to lcd.h
+ */
+
+#ifndef __ASM_ARM_LCD_H
+#define __ASM_ARM_LCD_H
+
+struct s3c2410_bl_mach_info {
+	int		lcd_power_value;
+	int		backlight_power_value;
+	int		brightness_value;
+	int             backlight_max;
+	int             backlight_default;
+	void            (*backlight_power)(int);
+	void            (*set_brightness)(int);
+	void		(*lcd_power)(int);
+};
+
+void __init set_s3c2410bl_info(struct s3c2410_bl_mach_info *hard_s3c2410bl_info);
+
+#endif /* __ASM_ARM_LCD_H */
Index: linux-2.6.24/include/asm-arm/plat-s3c24xx/devs.h
===================================================================
--- linux-2.6.24.orig/include/asm-arm/plat-s3c24xx/devs.h	2008-02-16 15:27:01.000000000 +0100
+++ linux-2.6.24/include/asm-arm/plat-s3c24xx/devs.h	2008-02-16 15:28:43.000000000 +0100
@@ -44,6 +44,8 @@
 extern struct platform_device s3c_device_usbgadget;
 extern struct platform_device s3c_device_ts;
 
+extern struct platform_device s3c_device_bl;
+
 /* s3c2440 specific devices */
 
 #ifdef CONFIG_CPU_S3C2440
Index: linux-2.6.24/drivers/video/backlight/Kconfig
===================================================================
--- linux-2.6.24.orig/drivers/video/backlight/Kconfig	2008-02-16 15:27:01.000000000 +0100
+++ linux-2.6.24/drivers/video/backlight/Kconfig	2008-02-16 15:28:43.000000000 +0100
@@ -67,6 +67,14 @@
 	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
 	  enable the LCD/backlight driver.
 
+config BACKLIGHT_S3C2410
+	tristate "Samsung S3C2410 Backlight Driver"
+	depends on (BACKLIGHT_DEVICE || LCD_CLASS_DEVICE) && ARCH_S3C2410
+	default y
+	help
+	  If you have a backlight controler connected on a Samsung S3C2410,
+	  say y here to enable the driver.
+
 config BACKLIGHT_HP680
 	tristate "HP Jornada 680 Backlight Driver"
 	depends on BACKLIGHT_CLASS_DEVICE && SH_HP6XX
Index: linux-2.6.24/drivers/video/backlight/Makefile
===================================================================
--- linux-2.6.24.orig/drivers/video/backlight/Makefile	2008-02-16 15:27:01.000000000 +0100
+++ linux-2.6.24/drivers/video/backlight/Makefile	2008-02-16 15:28:43.000000000 +0100
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_CORGI)	+= corgi_bl.o
+obj-$(CONFIG_BACKLIGHT_S3C2410)	+= s3c2410_lcd.o
 obj-$(CONFIG_BACKLIGHT_HP680)	+= hp680_bl.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO)	+= locomolcd.o
 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
Index: linux-2.6.24/drivers/video/backlight/s3c2410_lcd.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.24/drivers/video/backlight/s3c2410_lcd.c	2008-02-16 15:28:43.000000000 +0100
@@ -0,0 +1,248 @@
+/*
+ * linux/drivers/video/backlight/s3c2410_lcd.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * 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.
+ *
+ *	    S3C2410 LCD Controller Backlight Driver
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <asm/arch/lcd.h>
+#include <asm/arch/regs-gpio.h>
+
+struct s3c2410bl_devs {
+	struct backlight_device *bl;
+	struct lcd_device	*lcd;
+};
+
+static char suspended;
+
+static int s3c2410bl_get_lcd_power(struct lcd_device *lcd)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)lcd_get_data(lcd);
+
+	if (info)
+		return info->lcd_power_value;
+
+	return 0;
+}
+
+static int s3c2410bl_set_lcd_power(struct lcd_device *lcd, int power)
+{
+	struct s3c2410_bl_mach_info *info;
+	int lcd_power = 1;
+
+	info = (struct s3c2410_bl_mach_info *)lcd_get_data(lcd);
+
+	if (info && info->lcd_power) {
+		info->lcd_power_value = power;
+		if (power != FB_BLANK_UNBLANK)
+			lcd_power = 0;
+		if (suspended)
+			lcd_power = 0;
+		info->lcd_power(lcd_power);
+	}
+
+	return 0;
+}
+static int s3c2410bl_get_bl_brightness(struct backlight_device *bl)
+{
+	struct s3c2410_bl_mach_info *info;
+
+	info = (struct s3c2410_bl_mach_info *)bl_get_data(bl);
+
+	if(info)
+		return info->brightness_value;
+
+	return 0;
+}
+
+static int s3c2410bl_set_bl_brightness(struct backlight_device *bl)
+{
+	struct s3c2410_bl_mach_info *info;
+	int brightness = bl->props.brightness;
+	int power = 1;
+
+	info = (struct s3c2410_bl_mach_info *)bl_get_data(bl);
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		power = 0;
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		power = 0;
+	if (suspended)
+		power = 0;
+
+	if (info && info->set_brightness) {
+		if ( brightness )
+		{
+			info->brightness_value = brightness;
+			info->set_brightness(brightness);
+		}
+		else
+			power = 0;
+	}
+	if (info && info->backlight_power) {
+		info->backlight_power_value = power;
+		info->backlight_power(power);
+	}
+
+	return 0;
+}
+
+static int is_s3c2410fb(struct fb_info *info)
+{
+	return (!strcmp(info->fix.id,"s3c2410fb"));
+}
+
+static struct backlight_ops s3c2410bl_ops = {
+	.get_brightness = s3c2410bl_get_bl_brightness,
+	.update_status	= s3c2410bl_set_bl_brightness,
+	.check_fb 	= is_s3c2410fb
+};
+static struct lcd_ops s3c2410lcd_ops = {
+	.get_power	= s3c2410bl_get_lcd_power,
+	.set_power	= s3c2410bl_set_lcd_power,
+	.check_fb	= is_s3c2410fb
+};
+
+static int __init s3c2410bl_probe(struct platform_device *pdev)
+{
+	struct s3c2410bl_devs *devs;
+	struct s3c2410_bl_mach_info *info;
+
+	suspended = 0;
+
+	info = (struct s3c2410_bl_mach_info *)pdev->dev.platform_data;
+
+	if (!info) {
+		printk(KERN_ERR "Hm... too bad : no platform data for bl\n");
+		return -EINVAL;
+	}
+
+	devs = (struct s3c2410bl_devs *)kmalloc(sizeof(*devs), GFP_KERNEL);
+	if (!devs) {
+		return -ENOMEM;
+	}
+
+	/* Register the backlight device */
+	devs->bl = backlight_device_register ("s3c2410-bl", &pdev->dev, info,
+		&s3c2410bl_ops);
+
+	if (IS_ERR (devs->bl)) {
+		kfree(devs);
+		return PTR_ERR (devs->bl);
+	}
+
+	devs->bl->props.max_brightness = info->backlight_max;
+
+	/* Set default brightness */
+	devs->bl->props.power = FB_BLANK_UNBLANK;
+	devs->bl->props.brightness = info->backlight_default;
+	s3c2410bl_set_bl_brightness(devs->bl);
+
+	devs->lcd = lcd_device_register("s3c2410-lcd", &pdev->dev, info, &s3c2410lcd_ops);
+
+	if (IS_ERR (devs->lcd)) {
+		backlight_device_unregister(devs->bl);
+		kfree(devs);
+		return PTR_ERR (devs->lcd);
+	}
+	platform_set_drvdata(pdev, devs);
+
+	printk(KERN_ERR "s3c2410 Backlight Driver Initialized.\n");
+	return 0;
+}
+
+static int s3c2410bl_remove(struct platform_device *pdev)
+{
+	struct s3c2410bl_devs *devs = platform_get_drvdata(pdev);
+
+	if (devs) {
+		if (devs->bl) {
+			devs->bl->props.power = FB_BLANK_POWERDOWN;
+			s3c2410bl_set_bl_brightness(devs->bl);
+			backlight_device_unregister(devs->bl);
+		}
+		if (devs->lcd) {
+			lcd_device_unregister(devs->lcd);
+		}
+		kfree(devs);
+	}
+
+	printk("s3c2410 Backlight Driver Unloaded\n");
+
+	return 0;
+
+}
+
+#ifdef CONFIG_PM
+static int s3c2410bl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct s3c2410bl_devs *devs = platform_get_drvdata(pdev);
+	struct s3c2410_bl_mach_info *info = (struct s3c2410_bl_mach_info *)pdev->dev.platform_data;
+
+	if (devs) {
+		suspended = 1;
+		s3c2410bl_set_bl_brightness(devs->bl);
+		s3c2410bl_set_lcd_power(devs->lcd, info->lcd_power_value);
+	}
+
+	return 0;
+}
+
+static int s3c2410bl_resume(struct platform_device *pdev)
+{
+	struct s3c2410bl_devs *devs = platform_get_drvdata(pdev);
+	struct s3c2410_bl_mach_info *info = (struct s3c2410_bl_mach_info *)pdev->dev.platform_data;
+
+	if (devs) {
+		suspended = 0;
+		s3c2410bl_set_lcd_power(devs->lcd, info->lcd_power_value);
+		s3c2410bl_set_bl_brightness(devs->bl);
+	}
+	return 0;
+}
+#else
+#define s3c2410bl_suspend NULL
+#define s3c2410bl_resume  NULL
+#endif
+
+static struct platform_driver s3c2410bl_driver = {
+	.driver		= {
+		.name	= "s3c2410-bl",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= s3c2410bl_probe,
+	.remove		= s3c2410bl_remove,
+	.suspend        = s3c2410bl_suspend,
+	.resume         = s3c2410bl_resume,
+};
+
+
+
+static int __init s3c2410bl_init(void)
+{
+	return platform_driver_register(&s3c2410bl_driver);
+}
+
+static void __exit s3c2410bl_cleanup(void)
+{
+	platform_driver_unregister(&s3c2410bl_driver);
+}
+
+module_init(s3c2410bl_init);
+module_exit(s3c2410bl_cleanup);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("s3c2410 Backlight Driver");
+MODULE_LICENSE("GPL");
+

