xxm update FIH: 1,add light sensor 2,update rk29_FIH_defconfig
authorroot <root@rockchip-MID.(none)>
Tue, 19 Apr 2011 09:54:22 +0000 (17:54 +0800)
committerroot <root@rockchip-MID.(none)>
Tue, 19 Apr 2011 09:54:22 +0000 (17:54 +0800)
arch/arm/configs/rk29_FIH_defconfig
arch/arm/mach-rk29/board-rk29-fih.c
arch/arm/mach-rk29/include/mach/rk29_lightsensor.h [new file with mode: 0644]
drivers/input/Kconfig
drivers/input/Makefile
drivers/input/lightsensor/Kconfig [new file with mode: 0644]
drivers/input/lightsensor/Makefile [new file with mode: 0644]
drivers/input/lightsensor/rk29_lightsensor.c [new file with mode: 0644]

index 3122657edecbb0edbfca978966e8e99c969c3b5e..91f50f4f16d47cee01a5ae8e4ff39f7b9082c813 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.32.27
-# Thu Mar 24 18:04:14 2011
+# Tue Apr 19 11:02:26 2011
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -198,9 +198,9 @@ CONFIG_MMU=y
 CONFIG_ARCH_RK29=y
 CONFIG_WIFI_CONTROL_FUNC=y
 # CONFIG_MACH_RK29SDK is not set
+# CONFIG_MACH_RK29SDK_DDR3 is not set
 # CONFIG_MACH_RK29WINACCORD is not set
 CONFIG_MACH_RK29FIH=y
-# CONFIG_MACH_RK29_AIGO is not set
 # CONFIG_MACH_RK29_MALATA is not set
 # CONFIG_MACH_RK29_PHONESDK is not set
 # CONFIG_MACH_RK29_A22 is not set
@@ -457,6 +457,8 @@ CONFIG_BT_HCIUART_H4=y
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_BT_MRVL is not set
 CONFIG_BT_HCIBCM4325=y
+CONFIG_IDBLOCK=y
+# CONFIG_WIFI_MAC is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -600,6 +602,7 @@ CONFIG_ANDROID_PMEM=y
 CONFIG_APANIC=y
 CONFIG_APANIC_PLABEL="kpanic"
 # CONFIG_STE is not set
+# CONFIG_MTK23D is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -610,8 +613,7 @@ CONFIG_APANIC_PLABEL="kpanic"
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_RK29_SUPPORT_MODEM is not set
-CONFIG_RK29_GPS=y
-CONFIG_GPS_GNS7560=y
+# CONFIG_RK29_GPS is not set
 
 #
 # Motion Sensors Support
@@ -749,6 +751,7 @@ CONFIG_WLAN_80211=y
 # CONFIG_WIFI_NONE is not set
 CONFIG_BCM4329=y
 # CONFIG_MV8686 is not set
+# CONFIG_BCM4319 is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -811,6 +814,7 @@ CONFIG_KEYS_RK29=y
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ILI2102_IIC is not set
 # CONFIG_TOUCHSCREEN_IT7250 is not set
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
@@ -838,6 +842,7 @@ CONFIG_MXT224_MAX_Y=4095
 # CONFIG_SINTEK_3FA16 is not set
 # CONFIG_EETI_EGALAX is not set
 # CONFIG_TOUCHSCREEN_IT7260 is not set
+# CONFIG_TOUCHSCREEN_GT801_IIC is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_LPSENSOR_ISL29028 is not set
 # CONFIG_INPUT_LPSENSOR_CM3602 is not set
@@ -852,8 +857,15 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
 # CONFIG_INPUT_GPIO is not set
 # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Magnetometer sensors
+#
+# CONFIG_COMPASS_AK8975 is not set
+# CONFIG_COMPASS_AK8973 is not set
 # CONFIG_G_SENSOR_DEVICE is not set
 # CONFIG_INPUT_JOGBALL is not set
+# CONFIG_LIGHT_SENSOR_DEVICE is not set
 
 #
 # Hardware I/O ports
@@ -864,7 +876,7 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
@@ -889,7 +901,8 @@ CONFIG_UART0_CTS_RTS_RK29=y
 CONFIG_UART1_RK29=y
 CONFIG_UART2_RK29=y
 CONFIG_UART2_CTS_RTS_RK29=y
-# CONFIG_UART3_RK29 is not set
+CONFIG_UART3_RK29=y
+CONFIG_UART3_CTS_RTS_RK29=y
 CONFIG_SERIAL_RK29_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -917,7 +930,6 @@ CONFIG_I2C_RK29=y
 CONFIG_I2C0_RK29=y
 CONFIG_I2C1_RK29=y
 CONFIG_I2C2_RK29=y
-CONFIG_I2C3_RK29=y
 CONFIG_I2C_DEV_RK29=y
 
 #
@@ -935,7 +947,11 @@ CONFIG_ADC=y
 # CONFIG_ADC_RK28 is not set
 CONFIG_ADC_RK29=y
 # CONFIG_SPI_FPGA is not set
-# CONFIG_HEADSET_DET is not set
+
+#
+# Headset device support
+#
+CONFIG_RK_HEADSET_DET=y
 
 #
 # PPS support
@@ -944,7 +960,7 @@ CONFIG_ADC_RK29=y
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
+CONFIG_GPIO_SYSFS=y
 
 #
 # Memory mapped GPIO expanders:
@@ -1079,6 +1095,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
+# CONFIG_SOC_CAMERA_MT9M112 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
 CONFIG_SOC_CAMERA_MT9P111=y
 # CONFIG_SOC_CAMERA_MT9D112 is not set
@@ -1195,6 +1212,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_RK2818 is not set
 CONFIG_FB_RK29=y
+# CONFIG_FB_WORK_IPP is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1219,13 +1237,18 @@ CONFIG_DISPLAY_SUPPORT=y
 # CONFIG_LCD_TJ048NC01CA is not set
 # CONFIG_LCD_HL070VM4AU is not set
 # CONFIG_LCD_HSD070IDW1 is not set
+# CONFIG_LCD_RGB_TFT480800_25_E is not set
 # CONFIG_LCD_HSD100PXN is not set
 # CONFIG_LCD_B101AW06 is not set
+# CONFIG_LCD_LS035Y8DX02A is not set
 # CONFIG_LCD_A060SE02 is not set
 # CONFIG_LCD_S1D13521 is not set
 # CONFIG_LCD_NT35582 is not set
 # CONFIG_LCD_NT35580 is not set
-# CONFIG_LCD_ANX7150_720P is not set
+# CONFIG_LCD_IPS1P5680_V1_E is not set
+# CONFIG_LCD_MCU_TFT480800_25_E is not set
+# CONFIG_LCD_ILI9803_CPT4_3 is not set
+# CONFIG_DEFAULT_OUT_HDMI is not set
 CONFIG_LCD_AT070TNA2=y
 
 #
@@ -1291,6 +1314,8 @@ CONFIG_SND_RK29_SOC_I2S=y
 CONFIG_SND_RK29_SOC_I2S_8CH=y
 # CONFIG_SND_RK29_SOC_WM8988 is not set
 CONFIG_SND_RK29_SOC_WM8900=y
+# CONFIG_SND_RK29_SOC_alc5621 is not set
+# CONFIG_SND_RK29_SOC_alc5631 is not set
 # CONFIG_SND_RK29_SOC_WM8994 is not set
 # CONFIG_SND_RK29_CODEC_SOC_MASTER is not set
 CONFIG_SND_RK29_CODEC_SOC_SLAVE=y
@@ -1505,7 +1530,7 @@ CONFIG_DWC_CONN_EN=y
 CONFIG_DWC_OTG=y
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_EMBEDDED_SDIO=y
 # CONFIG_MMC_PARANOID_SD_INIT is not set
 
index f674db444dc3a018c3349af99fbc101f223ee043..292a56203a6ef6d6e457e63b539063f4aaad5597 100755 (executable)
@@ -45,6 +45,7 @@
 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */
 #include <mach/vpu_mem.h>
 #include <mach/sram.h>
+#include <mach/rk29_lightsensor.h>
 
 #include <linux/regulator/rk29-pwm-regulator.h>
 #include <linux/regulator/machine.h>
@@ -1069,7 +1070,7 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
  *****************************************************************************************/
 #ifdef CONFIG_VIDEO_RK29
 #define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_MT9P111         /* back camera sensor */
-#define SENSOR_IIC_ADDR_0          0x78
+#define SENSOR_IIC_ADDR_0          0x78 
 #define SENSOR_IIC_ADAPTER_ID_0    1
 #define SENSOR_POWER_PIN_0         RK29_PIN5_PD7
 #define SENSOR_RESET_PIN_0         INVALID_GPIO
@@ -1895,6 +1896,17 @@ static struct platform_device rk29_device_keys = {
 };
 #endif
 
+/*****************************************************************************************
+ * mc3202 light sensor
+ * author: sevenxuemin@sina.com
+ *****************************************************************************************/
+#ifdef CONFIG_CM3202
+static struct platform_device rk29_device_lsr = {
+       .name           = "rk29-lsr",
+       .id                     = -1,
+};
+
+#endif
 static void __init rk29_board_iomux_init(void)
 {
        #ifdef CONFIG_RK29_PWM_REGULATOR
@@ -1918,7 +1930,6 @@ static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_UART3_RK29
        &rk29_device_uart3,
 #endif
-
 #ifdef CONFIG_RK29_PWM_REGULATOR
        &rk29_device_pwm_regulator,
 #endif
@@ -2021,6 +2032,9 @@ static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_VIDEO_RK29XX_VOUT
        &rk29_v4l2_output_devce,
 #endif
+#ifdef CONFIG_CM3202
+       &rk29_device_lsr,
+#endif
 };
 
 /*****************************************************************************************
diff --git a/arch/arm/mach-rk29/include/mach/rk29_lightsensor.h b/arch/arm/mach-rk29/include/mach/rk29_lightsensor.h
new file mode 100644 (file)
index 0000000..1029986
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __RK29_LIGHTSENSOR_H__
+#define __RK29_LIGHTSENSOR_H__
+
+#include <linux/ioctl.h>
+
+
+#define STARTUP_LEV_LOW                        0
+#define SHUTDOWN_LEV_HIGH              1
+
+#define LSR_GPIO                               RK29_PIN6_PC7
+#define LSR_IOCTL_NR_ENABLE            1
+#define LSR_IOCTL_NR_SETRATE   2
+#define LSR_IOCTL_NR_DEVNAME   3
+#define LSR_IOCTL_NR_SWICTH            4
+
+
+#define LSR_IOCTL_ENABLE               _IOR('l', LSR_IOCTL_NR_ENABLE, unsigned long )
+#define LSR_IOCTL_SETRATE              _IOR('l', LSR_IOCTL_NR_SETRATE, unsigned long )
+#define LSR_IOCTL_DEVNAME              _IOR('l', LSR_IOCTL_NR_DEVNAME, unsigned long )
+#define LSR_IOCTL_SWICTH               _IOR('l', LSR_IOCTL_NR_SWICTH, unsigned long )
+
+#define LSR_ON                                 0
+#define LSR_OFF                                        1
+#define LSR_NAME                               "rk29-lsr"
+
+#define        RATE(x)                                 (1000/(x))
+
+struct rk29_lsr_platform_data {
+       int                             gpio;
+       char                            *desc;
+       int                             adc_chn;
+       struct adc_client       *client; 
+       struct timer_list       timer;
+       struct input_dev        *input_dev;
+       unsigned int            delay_time;
+       unsigned int            rate;
+       int                                     oldresult;
+       struct mutex            lsr_mutex;
+       int                             active_low;
+       unsigned int            lsr_state;
+       unsigned int            timer_on;
+};
+
+
+
+#endif
index 2969c752afd42e4894f70919742f58a5240839c6..85b41ff032d7869c5d55b4991e435f0bf743e14f 100755 (executable)
@@ -187,6 +187,9 @@ source "drivers/input/gsensor/Kconfig"
 
 source "drivers/input/jogball/Kconfig"
 
+source "drivers/input/lightsensor/Kconfig"
+
+
 endif
 
 menu "Hardware I/O ports"
index fb698381957d02842f39978172bc0d9182a341fe..f9357d4c0bc7b04e090471262332ff4a0638e12e 100755 (executable)
@@ -26,6 +26,6 @@ obj-$(CONFIG_INPUT_JOGBALL)   += jogball/
 
 obj-$(CONFIG_INPUT_APMPOWER)   += apm-power.o
 obj-$(CONFIG_INPUT_KEYRESET)   += keyreset.o
-
+obj-$(CONFIG_LIGHT_SENSOR_DEVICE) += lightsensor/
 obj-$(CONFIG_XEN_KBDDEV_FRONTEND)      += xen-kbdfront.o
 obj-y += magnetometer/
\ No newline at end of file
diff --git a/drivers/input/lightsensor/Kconfig b/drivers/input/lightsensor/Kconfig
new file mode 100644 (file)
index 0000000..f42def7
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# gsensor drivers configuration
+#
+
+menuconfig LIGHT_SENSOR_DEVICE
+       bool "light_sensor device support"
+       default n       
+       help
+         Enable this to be able to choose the drivers for controlling the
+         light_sensor on some platforms, for example on PDAs.
+
+if LIGHT_SENSOR_DEVICE
+
+config CM3202
+  bool "cm3202"
+       depends on LIGHT_SENSOR_DEVICE
+       default y
+       help     
+         To have support for your specific gsesnor you will have to
+         select the proper drivers which depend on this option.
+
+endif
diff --git a/drivers/input/lightsensor/Makefile b/drivers/input/lightsensor/Makefile
new file mode 100644 (file)
index 0000000..9439d02
--- /dev/null
@@ -0,0 +1,3 @@
+# gsensor drivers
+
+obj-$(CONFIG_CM3202)   += rk29_lightsensor.o
diff --git a/drivers/input/lightsensor/rk29_lightsensor.c b/drivers/input/lightsensor/rk29_lightsensor.c
new file mode 100644 (file)
index 0000000..db9edc5
--- /dev/null
@@ -0,0 +1,369 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <asm/gpio.h>
+#include <asm/uaccess.h>
+#include <linux/timer.h>
+#include <linux/input.h>
+#include <linux/adc.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+
+
+#include <mach/rk29_lightsensor.h>
+
+struct rk29_lsr_platform_data *lightsensor;
+static void lsr_report_value(struct input_dev *input_dev, int value)
+{
+    input_report_abs(input_dev, ABS_X, value);
+    //input_sync(input_dev);
+}
+
+
+static inline void timer_callback(unsigned long data)
+{
+       int ret;
+       unsigned int rate;
+       adc_async_read(lightsensor->client);
+       mutex_lock(&lightsensor->lsr_mutex);
+       rate = lightsensor->rate;
+       mutex_unlock(&lightsensor->lsr_mutex);
+       if(lightsensor->client->result != lightsensor->oldresult)
+               {
+                       lsr_report_value(lightsensor->input_dev, lightsensor->client->result);
+                       lightsensor->oldresult = lightsensor->client->result;
+               }
+       ret = mod_timer( &lightsensor->timer, jiffies + msecs_to_jiffies(RATE(rate)));
+       if(ret)
+               printk("Error in mod_timer\n");
+}
+static inline void set_lsr_value(bool state)
+{
+       if(state)
+               lightsensor->lsr_state = 1;
+       else
+               lightsensor->lsr_state = 0;
+       gpio_direction_output(LSR_GPIO, lightsensor->lsr_state);
+       gpio_set_value(LSR_GPIO, lightsensor->lsr_state);       
+}
+
+static inline unsigned int get_lsr_value(void)
+{
+       if(0 == lightsensor->lsr_state)
+               return 0;
+       else
+               return 1;
+}
+
+static inline unsigned int get_adc_value(void)
+{
+
+       return lightsensor->client->result;
+}
+
+static inline unsigned int set_lsr_rate(unsigned int value)
+{
+       mutex_lock(&lightsensor->lsr_mutex);
+       if(value <= 0)
+               value = 1;
+       if(value >= 100)
+               value = 100;
+       lightsensor->rate = value;
+       mutex_unlock(&lightsensor->lsr_mutex);
+       return 0;
+}
+static inline unsigned int set_lsr_timer(unsigned int value)
+{
+       if(value > 0)
+               {
+                       if(1 != lightsensor->timer_on)
+                               {
+                                       add_timer(&lightsensor->timer);
+                                       lightsensor->timer_on = 1;
+                               }
+                               
+               }
+       if(value == 0)
+               {
+                       if(0 != lightsensor->timer_on)
+                               {
+                                       del_timer(&lightsensor->timer);
+                                       lightsensor->timer_on = 0;
+                               }
+                               
+               }               
+       return 0;
+}
+
+
+
+static ssize_t lsr_store_value(struct device *dev,
+                                         struct device_attribute *attr,
+                                         const char *buf, size_t count)
+{
+       unsigned long val;
+       if(0 == count)
+               return count;
+       if (strict_strtoul(buf, 10, &val) < 0)
+               return -EINVAL;
+       if(val)
+               set_lsr_value(true);
+       else
+               set_lsr_value(false);
+       return count;
+}
+
+static ssize_t lsr_show_value(struct device *dev,
+                                struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "lsr value:%d\nadc value:%d\n", get_lsr_value(),get_adc_value());   
+}
+
+static DEVICE_ATTR(value, S_IWUSR|S_IRUGO, lsr_show_value, lsr_store_value );
+
+static struct attribute *lsr_attributes[] = {
+       &dev_attr_value.attr,
+       NULL
+};
+
+static const struct attribute_group lsr_attr_group = {
+       .attrs = lsr_attributes,
+};
+static int rk29_lsr_io_init(struct platform_device *dev)
+{
+       int err;
+       struct platform_device *pdev = dev;
+       struct rk29_lsr_platform_data *pdata = pdev->dev.platform_data;
+
+       err = gpio_request(pdata->gpio, pdata->desc ?: "rk29-lsr");
+       if (err) {
+               gpio_free(pdata->gpio);
+               printk("-------request RK29_PIN6_PB1 fail--------\n");
+               return -1;
+       }
+
+       gpio_direction_output(pdata->gpio, pdata->active_low);
+       gpio_set_value(pdata->gpio, pdata->active_low);
+       set_lsr_value(STARTUP_LEV_LOW);
+       err = sysfs_create_group(&pdev->dev.kobj, &lsr_attr_group);
+       return 0;
+}
+static int rk29_lsr_io_deinit(struct platform_device *dev)
+{
+       struct platform_device *pdev = dev;
+       struct rk29_lsr_platform_data *pdata = pdev->dev.platform_data;
+
+       gpio_direction_output(pdata->gpio, pdata->active_low);
+       gpio_set_value(pdata->gpio, pdata->active_low);
+
+       gpio_free(pdata->gpio);
+       sysfs_remove_group(&pdev->dev.kobj, &lsr_attr_group);
+       return 0;
+}
+static void callback(struct adc_client *client, void *callback_param, int result)
+{
+       client->result = result;
+}
+static int rk29_lsr_adc_init(struct platform_device *dev)
+{
+       struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
+       pdata->client = adc_register(pdata->adc_chn, callback, "lsr_adc");
+       if(!pdata->client)
+               return -EINVAL;
+       mutex_init(&pdata->lsr_mutex);
+       return 0;
+}
+static void rk29_lsr_adc_deinit(struct platform_device *dev)
+{
+       struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
+       adc_unregister(pdata->client);
+       mutex_destroy(&pdata->lsr_mutex);
+}
+
+static void rk29_lsr_timer_init(struct platform_device *dev)
+{
+       int ret;
+       struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
+       setup_timer(&pdata->timer, timer_callback, 0);
+       lightsensor->timer_on = 1;
+       ret = mod_timer( &pdata->timer, jiffies + msecs_to_jiffies(pdata->delay_time) );
+       if(ret)
+               printk("Error in mod_timer\n");
+       return ;
+}
+static void rk29_lsr_timer_deinit(struct platform_device *dev)
+{
+       struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
+       del_timer(&pdata->timer);
+       lightsensor->timer_on = 0;
+}
+
+static void rk29_lsr_input_init(struct platform_device *dev)
+{
+       int ret;
+       struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
+       pdata->input_dev = input_allocate_device();
+       if (!pdata->input_dev) {
+               printk(KERN_ERR"rk29_lsr_input_init: Failed to allocate input device\n");
+               goto init_input_register_device_failed;
+       }
+       pdata->input_dev->name = "lsensor";
+       pdata->input_dev->dev.parent = &dev->dev;
+       pdata->input_dev->evbit[0] = BIT(EV_ABS);
+       input_set_abs_params(pdata->input_dev,ABS_X,0,0x3ff,0,0);
+       ret = input_register_device(pdata->input_dev);
+       return ;
+init_input_register_device_failed:
+input_free_device(pdata->input_dev);
+}
+
+static void rk29_lsr_input_deinit(struct platform_device *dev)
+{
+       struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
+       input_unregister_device(pdata->input_dev);
+    input_free_device(pdata->input_dev);
+}
+
+static int __devinit lsr_probe(struct platform_device *pdev)
+{
+       lightsensor = kzalloc(sizeof(struct rk29_lsr_platform_data), GFP_KERNEL);
+       if(!lightsensor)
+       {
+        dev_err(&pdev->dev, "no memory for state\n");
+        goto err_kzalloc_lightsensor;
+    }
+       lightsensor->gpio               = LSR_GPIO;
+       lightsensor->desc               = "rk29-lsr";
+       lightsensor->adc_chn    = 1;
+       lightsensor->delay_time = 1000;
+       lightsensor->rate               = 100;
+       lightsensor->oldresult  = 0;
+       lightsensor->active_low = STARTUP_LEV_LOW;
+       pdev->dev.platform_data = lightsensor; 
+       rk29_lsr_io_init(pdev);
+       rk29_lsr_adc_init(pdev);
+       rk29_lsr_timer_init(pdev);
+       rk29_lsr_input_init(pdev);
+       return 0;
+
+err_kzalloc_lightsensor:
+       kfree(lightsensor);
+       return 0; 
+
+}
+
+static int __devexit lsr_remove(struct platform_device *pdev)
+{
+       rk29_lsr_io_deinit(pdev);
+       rk29_lsr_adc_deinit(pdev);
+       rk29_lsr_timer_deinit(pdev);
+       rk29_lsr_input_deinit(pdev);
+       kfree(lightsensor);
+       return 0;
+}
+
+static int lsr_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       set_lsr_timer(0);
+       set_lsr_value(LSR_OFF);
+       return 0;
+}
+
+static int lsr_resume(struct platform_device *pdev)
+{
+       set_lsr_timer(1);
+       set_lsr_value(LSR_ON);
+       return 0; 
+}
+
+
+
+static struct platform_driver lsr_device_driver = {
+       .probe          = lsr_probe,
+       .remove         = __devexit_p(lsr_remove),
+       .suspend        = lsr_suspend,
+       .resume         = lsr_resume,
+       .driver         = {
+               .name   = LSR_NAME,
+               .owner  = THIS_MODULE,
+       }
+};
+
+static int lsr_adc_open(struct inode * inode, struct file * file)
+{
+       set_lsr_value(LSR_ON);
+       return 0;
+}
+
+static int lsr_adc_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd, unsigned long arg)
+{
+       int ret = 0;
+       switch(cmd)
+               {
+                       case LSR_IOCTL_ENABLE:
+                               set_lsr_value(arg);
+                               break;
+                       case LSR_IOCTL_SETRATE:
+                               set_lsr_rate(arg);
+                               break;
+                       case LSR_IOCTL_DEVNAME:
+                               ret = copy_to_user((void __user *)arg,lightsensor->input_dev->name,strlen(lightsensor->input_dev->name)+1);
+                               break;
+                       case LSR_IOCTL_SWICTH:
+                               set_lsr_timer(arg);
+                               break;
+                       default:
+                               break;
+               }
+       return ret;
+}
+
+static ssize_t lsr_adc_read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
+{
+       int ret;
+       ret = copy_to_user(userbuf,&lightsensor->client->result,bytes);
+       return ret;
+}
+
+static struct file_operations lsr_adc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = lsr_adc_open,
+       .read           = lsr_adc_read,
+       .ioctl          = lsr_adc_ioctl,
+};
+
+static struct miscdevice misc_lsr_adc_device = {
+       .minor  = MISC_DYNAMIC_MINOR,
+       .name   = LSR_NAME,
+       .fops   = &lsr_adc_fops,
+};
+
+static int __init lsr_init(void)
+{
+       platform_driver_register(&lsr_device_driver);
+       misc_register(&misc_lsr_adc_device);
+       return 0;
+}
+
+static void __exit lsr_exit(void)
+{
+       platform_driver_unregister(&lsr_device_driver);
+       misc_deregister(&misc_lsr_adc_device);
+}
+
+module_init(lsr_init);
+module_exit(lsr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Seven Huang <sevenxuemin@sina.com>");
+MODULE_DESCRIPTION("Light sensor for Backlight");
+MODULE_ALIAS("platform:gpio-lightsensor");