1,添加耳机检测;2,添加l/p sensor;3,修改raho充电;4,恢复raho sdcard 检测
authorroot <root@dxj.(none)>
Thu, 19 Aug 2010 09:32:53 +0000 (17:32 +0800)
committerroot <root@dxj.(none)>
Thu, 19 Aug 2010 09:32:53 +0000 (17:32 +0800)
13 files changed:
arch/arm/mach-rk2818/board-raho.c
drivers/Kconfig
drivers/Makefile
drivers/headset_observe/Kconfig [new file with mode: 0644]
drivers/headset_observe/Makefile [new file with mode: 0644]
drivers/headset_observe/rk2818_headset.c [new file with mode: 0644]
drivers/headset_observe/rk2818_headset.h [new file with mode: 0644]
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/capella_cm3602.c [new file with mode: 0644]
drivers/mmc/host/rk2818-sdmmc.c
drivers/power/rk2818_battery.c
include/linux/capella_cm3602.h [new file with mode: 0644]

index 64f5356d85e35e8ec74499e4f5174ed9221e4c52..dc5014ecbf4212195b2a72c21bc0ea0e0dfcf619 100755 (executable)
@@ -43,6 +43,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/dm9000.h>
+#include <linux/capella_cm3602.h>
 
 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */
 
@@ -54,6 +55,7 @@
 #include "../../../drivers/input/touchscreen/xpt2046_ts.h"
 #include "../../../drivers/staging/android/timed_gpio.h"
 #include "../../../sound/soc/codecs/wm8994.h"
+#include "../../../drivers/headset_observe/rk2818_headset.h"
 
 /* --------------------------------------------------------------------
  *  ÉùÃ÷ÁËrk2818_gpioBankÊý×飬²¢¶¨ÒåÁËGPIO¼Ä´æÆ÷×éIDºÍ¼Ä´æÆ÷»ùµØÖ·¡£
@@ -812,7 +814,7 @@ struct soc_camera_link rk2818_iclink = {
  * battery  devices
  * author: lw@rock-chips.com
  *****************************************************************************************/
-#define CHARGEOK_PIN   RK2818_PIN_PB1
+#define CHARGEOK_PIN   SPI_GPIO_P6_06//RK2818_PIN_PB1
 struct rk2818_battery_platform_data rk2818_battery_platdata = {
        .charge_ok_pin = CHARGEOK_PIN,
 };
@@ -1033,7 +1035,7 @@ static struct spi_board_info board_spi_devices[] = {
        {       /* fpga ice65l08xx */
                .modalias       = "spi_fpga",
                .chip_select    = 1,
-               .max_speed_hz   = 8 * 1000 * 1000,
+               .max_speed_hz   = 18 * 1000 * 1000,
                .bus_num        = 0,
                .mode   = SPI_MODE_0,
                //.platform_data = &rk2818_spi_platdata,
@@ -1097,7 +1099,6 @@ void lcd_set_iomux(u8 enable)
             printk(">>>>>> lcd cs gpio_request err \n ");           
             goto pin_err;
         }  
-        
         rk2818_mux_api_set(GPIOE_I2C0_SEL_NAME, 1);    
 
         ret = gpio_request(RK2818_PIN_PE4, NULL); 
@@ -1107,7 +1108,6 @@ void lcd_set_iomux(u8 enable)
             printk(">>>>>> lcd clk gpio_request err \n "); 
             goto pin_err;
         }  
-        
         ret = gpio_request(RK2818_PIN_PE5, NULL); 
         if(ret != 0)
         {
@@ -1118,13 +1118,11 @@ void lcd_set_iomux(u8 enable)
     }
     else
     {
-        // gpio_free(RK2818_PIN_PH6);
-         //rk2818_mux_api_set(GPIOH6_IQ_SEL_NAME, 1);
-        // rk2818_mux_api_mode_resume(GPIOH6_IQ_SEL_NAME);
+         gpio_free(RK2818_PIN_PH6);
+         rk2818_mux_api_mode_resume(GPIOH6_IQ_SEL_NAME);
 
          gpio_free(RK2818_PIN_PE4);   
          gpio_free(RK2818_PIN_PE5); 
-         //rk2818_mux_api_set(GPIOE_I2C0_SEL_NAME, 0);
          rk2818_mux_api_mode_resume(GPIOE_I2C0_SEL_NAME);
     }
     return ;
@@ -1287,6 +1285,45 @@ struct platform_device rk2818_device_dm9k = {
 };
 #endif
 
+#ifdef CONFIG_HEADSET_DET
+struct rk2818_headset_data rk2818_headset_info = {
+    .irq = FPGA_PIO0_00,
+};
+
+struct platform_device rk28_device_headset = {
+               .name   = "rk2818_headsetdet",
+               .id     = 0,
+               .dev    = {
+                   .platform_data = &rk2818_headset_info,
+               }
+};
+#endif
+
+#ifdef CONFIG_INPUT_LPSENSOR_CM3602 
+static int capella_cm3602_power(int on)
+{      /* TODO eolsen Add Voltage reg control */       
+    if (on) {          
+    //         gpio_direction_output(MAHIMAHI_GPIO_PROXIMITY_EN, 0);
+    }
+    else {             
+    //         gpio_direction_output(MAHIMAHI_GPIO_PROXIMITY_EN, 1);
+    }  
+    return 0;
+}
+
+static struct capella_cm3602_platform_data capella_cm3602_pdata = {    
+       .power = capella_cm3602_power,
+       //.p_out = MAHIMAHI_GPIO_PROXIMITY_INT_N
+       };
+
+struct platform_device rk2818_device_cm3605 = {        
+           .name = CAPELLA_CM3602,
+               .id = -1,
+               .dev = {                
+               .platform_data = &capella_cm3602_pdata  
+                       }
+       };
+#endif
 
 /*****************************************************************************************
  * nand flash devices
@@ -1380,7 +1417,12 @@ static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_DM9000
        &rk2818_device_dm9k,
 #endif
-
+#ifdef CONFIG_INPUT_LPSENSOR_CM3602 
+    &rk2818_device_cm3605,
+#endif
+#ifdef CONFIG_HEADSET_DET
+    &rk28_device_headset,
+#endif
 #ifdef CONFIG_DWC_OTG
        &rk2818_device_dwc_otg,
 #endif
index d03c2e90610b297380597506d2130be4de20f308..24aee0fcf34a50d9b30dd1480c8ad0aa94adf8c4 100644 (file)
@@ -54,6 +54,8 @@ source "drivers/spi/Kconfig"
 
 source "drivers/fpga/Kconfig"
 
+source "drivers/headset_observe/Kconfig"
+
 source "drivers/pps/Kconfig"
 
 source "drivers/gpio/Kconfig"
index f7101a6135717f93748b90e0d6e541bb8c838c42..92e2365041fc5ec0d43de407b76e7143d33d98ea 100644 (file)
@@ -46,6 +46,7 @@ obj-$(CONFIG_ATA)             += ata/
 obj-$(CONFIG_MTD)              += mtd/
 obj-$(CONFIG_SPI)              += spi/
 obj-$(CONFIG_SPI_FPGA)         += fpga/
+obj-$(CONFIG_HEADSET_DET)              += headset_observe/
 obj-y                          += net/
 obj-$(CONFIG_ATM)              += atm/
 obj-$(CONFIG_FUSION)           += message/
diff --git a/drivers/headset_observe/Kconfig b/drivers/headset_observe/Kconfig
new file mode 100644 (file)
index 0000000..4d93ecd
--- /dev/null
@@ -0,0 +1,2 @@
+config HEADSET_DET
+       tristate "headset detech support"
diff --git a/drivers/headset_observe/Makefile b/drivers/headset_observe/Makefile
new file mode 100644 (file)
index 0000000..4feac18
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_HEADSET_DET)              += rk2818_headset.o
+
diff --git a/drivers/headset_observe/rk2818_headset.c b/drivers/headset_observe/rk2818_headset.c
new file mode 100644 (file)
index 0000000..1c94f93
--- /dev/null
@@ -0,0 +1,147 @@
+/* arch/arm/mach-rockchip/rk28_headset.c
+ *
+ * Copyright (C) 2009 Rockchip Corporation.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/hrtimer.h>
+#include <linux/switch.h>
+#include <linux/input.h>
+#include <linux/debugfs.h>
+#include <linux/wakelock.h>
+#include <asm/gpio.h>
+#include <asm/atomic.h>
+#include <asm/mach-types.h>
+#include "rk2818_headset.h"
+
+/* Debug */
+#if 0
+#define DBG    printk
+#else
+#define DBG
+#endif
+
+/* ¶ú»ú״̬ */
+#define BIT_HEADSET             (1 << 0)//´øMICµÄ¶ú»ú
+#define BIT_HEADSET_NO_MIC      (1 << 1)//²»´øMICµÄ¶ú»ú
+
+struct rk2818_headset_dev{
+       struct switch_dev sdev;
+       int cur_headset_status; 
+       int pre_headset_status; 
+       struct mutex mutex_lock;
+};
+
+static struct rk2818_headset_dev Headset_dev;
+static struct work_struct g_headsetobserve_work;
+static struct rk2818_headset_data *prk2818_headset_info;
+
+static void headsetobserve_work(void)
+{
+    if(gpio_get_value(prk2818_headset_info->irq))
+        Headset_dev.cur_headset_status = BIT_HEADSET;
+    else
+        Headset_dev.cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
+
+    if(Headset_dev.cur_headset_status != Headset_dev.pre_headset_status)
+    {
+        Headset_dev.pre_headset_status = Headset_dev.cur_headset_status;
+        mutex_lock(&Headset_dev.mutex_lock);
+               switch_set_state(&Headset_dev.sdev, Headset_dev.cur_headset_status);
+               mutex_unlock(&Headset_dev.mutex_lock);
+               DBG("---------------cur_headset_status = [0x%x]\n", Headset_dev.cur_headset_status);
+    }
+}
+
+static irqreturn_t headset_interrupt(int irq, void *dev_id)
+{
+       schedule_work(&g_headsetobserve_work);
+       DBG("---------------headset_interrupt---------------\n");
+       
+       return IRQ_HANDLED;
+}
+
+static ssize_t h2w_print_name(struct switch_dev *sdev, char *buf)
+{
+       return sprintf(buf, "Headset\n");
+}
+
+static int rockchip_headsetobserve_probe(struct platform_device *pdev)
+{
+       int ret;
+       
+       DBG("RockChip headset observe driver\n");
+       prk2818_headset_info = pdev->dev.platform_data;
+       
+       Headset_dev.cur_headset_status = 0;
+       Headset_dev.pre_headset_status = 0;     
+       Headset_dev.sdev.name = "h2w";
+       Headset_dev.sdev.print_name = h2w_print_name;
+       mutex_init(&Headset_dev.mutex_lock);
+
+       ret = switch_dev_register(&Headset_dev.sdev);
+       if (ret < 0)
+               return 0;
+
+    INIT_WORK(&g_headsetobserve_work, headsetobserve_work);
+    
+    ret = gpio_request(prk2818_headset_info->irq, "headset_det");
+       if (ret) {
+               DBG( "headsetobserve: failed to request FPGA_PIO0_00\n");
+               return ret;
+       }
+
+    gpio_direction_input(prk2818_headset_info->irq);
+
+    headsetobserve_work();//³õʼ»¯µÚÒ»´Î¼ì²âÒ»´Î
+    
+       prk2818_headset_info->irq = gpio_to_irq(prk2818_headset_info->irq);
+       ret = request_irq(prk2818_headset_info->irq, headset_interrupt, IRQF_TRIGGER_FALLING, NULL, NULL);
+       if (ret ) {
+               DBG("headsetobserve: request irq failed\n");
+        return ret;
+       }
+
+       return 0;       
+}
+
+static struct platform_driver rockchip_headsetobserve_driver = {
+       .probe  = rockchip_headsetobserve_probe,
+       .driver = {
+               .name   = "rk2818_headsetdet",
+               .owner  = THIS_MODULE,
+       },
+};
+
+
+static int __init rockchip_headsetobserve_init(void)
+{
+       platform_driver_register(&rockchip_headsetobserve_driver);
+       return 0;
+}
+module_init(rockchip_headsetobserve_init);
+MODULE_DESCRIPTION("Rockchip Headset Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/headset_observe/rk2818_headset.h b/drivers/headset_observe/rk2818_headset.h
new file mode 100644 (file)
index 0000000..6c9ee28
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef RK2818_HEADSET_H
+#define RK2818_HEADSET_H
+
+/* ¶ú»úÊý¾Ý½á¹¹Ìå */
+struct rk2818_headset_data {
+    unsigned int irq;
+};
+
+#endif
index 0b0b6182cadd54061003abff18de2ed484e47e8d..be5f93b05e534be2a1e383da2d28be3fddf93534 100644 (file)
@@ -12,6 +12,9 @@ menuconfig INPUT_MISC
 
 if INPUT_MISC
 
+config INPUT_LPSENSOR_CM3602
+       tristate "l/p sensor input support"
+       
 config INPUT_PCSPKR
        tristate "PC Speaker support"
        depends on PCSPKR_PLATFORM
index 42a5a5a90e75be5229ab58300890ba30e2b492fc..785b8ca2841512078ee255415dae4f3a6998b690 100644 (file)
@@ -4,6 +4,7 @@
 
 # Each configuration option enables a list of files.
 
+obj-$(CONFIG_INPUT_LPSENSOR_CM3602)            += capella_cm3602.o
 obj-$(CONFIG_INPUT_APANEL)             += apanel.o
 obj-$(CONFIG_INPUT_ATI_REMOTE)         += ati_remote.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)                += ati_remote2.o
diff --git a/drivers/input/misc/capella_cm3602.c b/drivers/input/misc/capella_cm3602.c
new file mode 100644 (file)
index 0000000..0fb6b2d
--- /dev/null
@@ -0,0 +1,340 @@
+/* drivers/input/misc/capella_cm3602.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Iliyan Malchev <malchev@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/capella_cm3602.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/circ_buf.h>
+#include <mach/spi_fpga.h>
+
+#define D(x...) printk(x)
+
+static struct capella_cm3602_data {
+       struct input_dev *input_dev;
+       struct capella_cm3602_platform_data *pdata;
+       struct workqueue_struct *cm3602_workqueue;
+       struct work_struct              cm3602_work;
+       struct timer_list       cm3602_timer;
+       int enabled;
+} the_data;
+
+static int misc_opened;
+
+static bool time_enable = true;
+
+static int capella_cm3602_report(struct capella_cm3602_data *data)
+{
+       //int val = gpio_get_value(data->pdata->p_out);
+       int val = spi_gpio_get_pinlevel(SPI_GPIO_P6_04);
+       if (val < 0) {
+               pr_err("%s: gpio_get_value error %d\n", __func__, val);
+               return val;
+       }
+
+       D("proximity %d\n", val);
+       /* 0 is close, 1 is far */
+       input_report_abs(data->input_dev, ABS_DISTANCE, val);
+       input_sync(data->input_dev);
+       return val;
+}
+
+static irqreturn_t capella_cm3602_irq_handler(int irq, void *data)
+{
+       struct capella_cm3602_data *ip = data;
+       printk("------------------capella_cm3602_irq_handler------------\n");
+       //int val = capella_cm3602_report(ip);
+       input_report_abs(ip->input_dev, ABS_DISTANCE, 0);
+       input_sync(ip->input_dev);
+       add_timer(&ip->cm3602_timer);
+       time_enable = true;
+       return IRQ_HANDLED;
+}
+
+static int capella_cm3602_enable(struct capella_cm3602_data *data)
+{
+       int rc;
+       D("%s\n", __func__);
+       time_enable = true;
+       if (data->enabled) {
+               D("%s: already enabled\n", __func__);
+               return 0;
+       }
+       spi_gpio_set_pinlevel(SPI_GPIO_P4_07, SPI_GPIO_LOW);            //CM3605_PWD output
+       spi_gpio_set_pinlevel(SPI_GPIO_P4_08, SPI_GPIO_LOW);            //CM3605_PS_SHUTDOWN
+       data->pdata->power(1);
+       data->enabled = !rc;
+       if (!rc)
+               capella_cm3602_report(data);
+       return rc;
+}
+
+static int capella_cm3602_disable(struct capella_cm3602_data *data)
+{
+       int rc = -EIO;
+       D("%s\n", __func__);
+       time_enable = false;
+       if (!data->enabled) {
+               D("%s: already disabled\n", __func__);
+               return 0;
+       }
+       spi_gpio_set_pinlevel(SPI_GPIO_P4_07, SPI_GPIO_HIGH);           //CM3605_PWD output
+       spi_gpio_set_pinlevel(SPI_GPIO_P4_08, SPI_GPIO_HIGH);           //CM3605_PS_SHUTDOWN
+       data->pdata->power(0);
+       data->enabled = 0;
+       return rc;
+}
+
+void cm3602_work_handler(struct work_struct *work)
+{
+       struct capella_cm3602_data *pdata;
+       int val = spi_gpio_get_pinlevel(SPI_GPIO_P6_04);
+
+       pdata = container_of(work, struct capella_cm3602_data, cm3602_work);
+       printk("-------------------cm3602_work_handler,pinlevel:%d----------------\n",val);
+       if (val == 1)
+       {
+               time_enable = false;
+               input_report_abs(pdata->input_dev, ABS_DISTANCE, val);
+               input_sync(pdata->input_dev);
+       }
+       
+}
+
+static void cm3602_timer(unsigned long data)
+{
+       struct capella_cm3602_data *ip = data;
+       printk("------------------cm3602_timer,%d------------\n",time_enable);
+       
+       if(time_enable)
+       {
+               ip->cm3602_timer.expires = jiffies + HZ;
+               add_timer(&ip->cm3602_timer);
+               queue_work(ip->cm3602_workqueue, &ip->cm3602_work);
+       }
+
+}
+
+static int capella_cm3602_setup(struct capella_cm3602_data *ip)
+{
+       int rc = -EIO;
+       struct capella_cm3602_platform_data *pdata = ip->pdata;
+       //int irq = gpio_to_irq(pdata->p_out);
+       char b[20];
+       
+       D("%s\n", __func__);
+/*
+       rc = gpio_request(pdata->p_out, "gpio_proximity_out");
+       if (rc < 0) {
+               pr_err("%s: gpio %d request failed (%d)\n",
+                       __func__, pdata->p_out, rc);
+               goto done;
+       }
+
+       rc = gpio_direction_input(pdata->p_out);
+       if (rc < 0) {
+               pr_err("%s: failed to set gpio %d as input (%d)\n",
+                       __func__, pdata->p_out, rc);
+               goto fail_free_p_out;
+       }
+*/
+
+       rc = spi_request_gpio_irq(SPI_GPIO_P6_04,capella_cm3602_irq_handler,SPI_GPIO_EDGE_FALLING,ip);
+       if (rc < 0) {
+               pr_err("%s: request_irq failed for gpio %d (%d)\n",
+                       __func__, 
+                       pdata->p_out, rc);
+               goto fail_free_p_out;
+       }
+
+       //spi_gpio_set_pindirection(SPI_GPIO_P6_04, SPI_GPIO_IN);
+       //spi_gpio_get_pinlevel(SPI_GPIO_P6_04);
+       
+       sprintf(b,"cm3602_workqueue");
+       ip->cm3602_workqueue = create_freezeable_workqueue(b);
+       if(!ip->cm3602_workqueue)
+       {
+               printk("cannot create cm3602 workqueue\n");
+               return -EBUSY;
+       }
+       INIT_WORK(&ip->cm3602_work, cm3602_work_handler);
+       setup_timer(&ip->cm3602_timer,cm3602_timer,(unsigned long)ip);
+       ip->cm3602_timer.expires = jiffies + HZ;
+       //add_timer(&ip->cm3602_timer);
+/*
+       rc = set_irq_wake(irq, 1);
+       if (rc < 0) {
+               pr_err("%s: failed to set irq %d as a wake interrupt\n",
+                       __func__, irq);
+               goto fail_free_irq;
+
+       }
+*/
+       goto done;
+/*
+fail_free_irq:
+       free_irq(irq, 0);*/
+fail_free_p_out:
+       gpio_free(pdata->p_out);
+done:
+       return rc;
+}
+
+static int capella_cm3602_open(struct inode *inode, struct file *file)
+{
+       D("%s\n", __func__);
+       if (misc_opened)
+               return -EBUSY;
+       misc_opened = 1;
+       return 0;
+}
+
+static int capella_cm3602_release(struct inode *inode, struct file *file)
+{
+       D("%s\n", __func__);
+       misc_opened = 0;
+       return capella_cm3602_disable(&the_data);
+}
+
+static long capella_cm3602_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int val;
+       D("%s cmd %d\n", __func__, _IOC_NR(cmd));
+       switch (cmd) {
+       case CAPELLA_CM3602_IOCTL_ENABLE:
+               if (get_user(val, (unsigned long __user *)arg))
+                       return -EFAULT;
+               if (val)
+                       return capella_cm3602_enable(&the_data);
+               else
+                       return capella_cm3602_disable(&the_data);
+               break;
+       case CAPELLA_CM3602_IOCTL_GET_ENABLED:
+               return put_user(the_data.enabled, (unsigned long __user *)arg);
+               break;
+       default:
+               pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
+               return -EINVAL;
+       }
+}
+
+static struct file_operations capella_cm3602_fops = {
+       .owner = THIS_MODULE,
+       .open = capella_cm3602_open,
+       .release = capella_cm3602_release,
+       .unlocked_ioctl = capella_cm3602_ioctl
+};
+
+struct miscdevice capella_cm3602_misc = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "cm3602",
+       .fops = &capella_cm3602_fops
+};
+
+static int capella_cm3602_probe(struct platform_device *pdev)
+{
+       int rc = -EIO;
+       struct input_dev *input_dev;
+       struct capella_cm3602_data *ip;
+       struct capella_cm3602_platform_data *pdata;
+
+       D("%s: probe\n", __func__);
+       printk("%s: probe]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n", __func__);
+       pdata = pdev->dev.platform_data;
+       if (!pdata) {
+               pr_err("%s: missing pdata!\n", __func__);
+               goto done;
+       }
+       if (!pdata->power) {
+               pr_err("%s: incomplete pdata!\n", __func__);
+               goto done;
+       }
+
+       ip = &the_data;
+       platform_set_drvdata(pdev, ip);
+
+       D("%s: allocating input device\n", __func__);
+       input_dev = input_allocate_device();
+       if (!input_dev) {
+               pr_err("%s: could not allocate input device\n", __func__);
+               rc = -ENOMEM;
+               goto done;
+       }
+       ip->input_dev = input_dev;
+       ip->pdata = pdata;
+       input_set_drvdata(input_dev, ip);
+
+       input_dev->name = "proximity";
+
+       set_bit(EV_ABS, input_dev->evbit);
+       input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
+
+       D("%s: registering input device\n", __func__);
+       rc = input_register_device(input_dev);
+       if (rc < 0) {
+               pr_err("%s: could not register input device\n", __func__);
+               goto err_free_input_device;
+       }
+
+       D("%s: registering misc device\n", __func__);
+       rc = misc_register(&capella_cm3602_misc);
+       if (rc < 0) {
+               pr_err("%s: could not register misc device\n", __func__);
+               goto err_unregister_input_device;
+       }
+
+       rc = capella_cm3602_setup(ip);
+       if (!rc)
+               goto done;
+
+       misc_deregister(&capella_cm3602_misc);
+err_unregister_input_device:
+       input_unregister_device(input_dev);
+       goto done;
+err_free_input_device:
+       input_free_device(input_dev);
+done:
+       return rc;
+}
+
+static struct platform_driver capella_cm3602_driver = {
+       .probe = capella_cm3602_probe,
+       .driver = {
+               .name = CAPELLA_CM3602,
+               .owner = THIS_MODULE
+       },
+};
+
+static int __init capella_cm3602_init(void)
+{
+       return platform_driver_register(&capella_cm3602_driver);
+}
+
+static void __exit capella_cm3602_exit(void)
+{
+       platform_driver_unregister(&capella_cm3602_driver);
+}
+
+module_init(capella_cm3602_init);
+module_exit(capella_cm3602_exit);
+
index 2bf247e30be0c95d41354cb04f333b3fb2a84bdb..765f51b07994c0e552620406ca9c97f972ff7d7c 100755 (executable)
@@ -902,8 +902,12 @@ static int rk2818_sdmmc_get_cd(struct mmc_host *mmc)
 {
        struct rk2818_sdmmc_host *host = mmc_priv(mmc);
        u32 cdetect = readl(host->regs + SDMMC_CDETECT);
-       
+
+#ifdef CONFIG_MACH_RAHO        
+    return 1;
+#else
        return (cdetect & SDMMC_CARD_DETECT_N)?0:1;
+#endif
 
 }
 
index b70850d44d2aefa07af8e04b650c39200b7bc2ad..2c19ac375050e195414f3598707be3f3bca847b1 100755 (executable)
@@ -188,7 +188,12 @@ static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat)
        int temp[2] = {0,0};
        value = gAdcValue[CHN_BAT_ADC];
        if(0 != gAdcValue[3])
+#ifdef         CONFIG_MACH_RAHO
+    gBatVoltage = (value * BAT_1V2_VALUE * 3)/(gAdcValue[3]*2);
+#else    
        gBatVoltage = (value * BAT_1V2_VALUE * 2)/gAdcValue[3]; // channel 3 is about 1.42v,need modified
+#endif    
+    
        /*Ïû³ýë´Ìµçѹ*/
        if(gBatVoltage >= BATT_MAX_VOL_VALUE + 10)
                gBatVoltage = BATT_MAX_VOL_VALUE + 10;
diff --git a/include/linux/capella_cm3602.h b/include/linux/capella_cm3602.h
new file mode 100644 (file)
index 0000000..7f1de9b
--- /dev/null
@@ -0,0 +1,37 @@
+/* include/linux/capella_cm3602.h
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Iliyan Malchev <malchev@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_CAPELLA_CM3602_H
+#define __LINUX_CAPELLA_CM3602_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define CAPELLA_CM3602_IOCTL_MAGIC 'c'
+#define CAPELLA_CM3602_IOCTL_GET_ENABLED \
+               _IOR(CAPELLA_CM3602_IOCTL_MAGIC, 1, int *)
+#define CAPELLA_CM3602_IOCTL_ENABLE \
+               _IOW(CAPELLA_CM3602_IOCTL_MAGIC, 2, int *)
+
+#ifdef __KERNEL__
+#define CAPELLA_CM3602 "capella_cm3602"
+struct capella_cm3602_platform_data {
+       int (*power)(int); /* power to the chip */
+       int p_out; /* proximity-sensor outpuCAPELLA_CM3602_IOCTL_ENABLE,t */
+};
+#endif /* __KERNEL__ */
+
+#endif