From a7e06e1aee8ddc1b01f13e417fb2229e81632dd0 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 19 Aug 2010 17:32:53 +0800 Subject: [PATCH] =?utf8?q?1=EF=BC=8C=E6=B7=BB=E5=8A=A0=E8=80=B3=E6=9C=BA?= =?utf8?q?=E6=A3=80=E6=B5=8B=EF=BC=9B2=EF=BC=8C=E6=B7=BB=E5=8A=A0l/p=20sen?= =?utf8?q?sor;3=EF=BC=8C=E4=BF=AE=E6=94=B9raho=E5=85=85=E7=94=B5=EF=BC=9B4?= =?utf8?q?=EF=BC=8C=E6=81=A2=E5=A4=8Draho=20sdcard=20=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- arch/arm/mach-rk2818/board-raho.c | 60 +++- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/headset_observe/Kconfig | 2 + drivers/headset_observe/Makefile | 2 + drivers/headset_observe/rk2818_headset.c | 147 ++++++++++ drivers/headset_observe/rk2818_headset.h | 9 + drivers/input/misc/Kconfig | 3 + drivers/input/misc/Makefile | 1 + drivers/input/misc/capella_cm3602.c | 340 +++++++++++++++++++++++ drivers/mmc/host/rk2818-sdmmc.c | 6 +- drivers/power/rk2818_battery.c | 5 + include/linux/capella_cm3602.h | 37 +++ 13 files changed, 605 insertions(+), 10 deletions(-) create mode 100644 drivers/headset_observe/Kconfig create mode 100644 drivers/headset_observe/Makefile create mode 100644 drivers/headset_observe/rk2818_headset.c create mode 100644 drivers/headset_observe/rk2818_headset.h create mode 100644 drivers/input/misc/capella_cm3602.c create mode 100644 include/linux/capella_cm3602.h diff --git a/arch/arm/mach-rk2818/board-raho.c b/arch/arm/mach-rk2818/board-raho.c index 64f5356d85e3..dc5014ecbf42 100755 --- a/arch/arm/mach-rk2818/board-raho.c +++ b/arch/arm/mach-rk2818/board-raho.c @@ -43,6 +43,7 @@ #include #include #include +#include #include /* 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 diff --git a/drivers/Kconfig b/drivers/Kconfig index d03c2e90610b..24aee0fcf34a 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -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" diff --git a/drivers/Makefile b/drivers/Makefile index f7101a613571..92e2365041fc 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -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 index 000000000000..4d93ecd9ede4 --- /dev/null +++ b/drivers/headset_observe/Kconfig @@ -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 index 000000000000..4feac185c7e5 --- /dev/null +++ b/drivers/headset_observe/Makefile @@ -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 index 000000000000..1c94f93fac54 --- /dev/null +++ b/drivers/headset_observe/rk2818_headset.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 index 000000000000..6c9ee28def3b --- /dev/null +++ b/drivers/headset_observe/rk2818_headset.h @@ -0,0 +1,9 @@ +#ifndef RK2818_HEADSET_H +#define RK2818_HEADSET_H + +/* ¶ú»úÊý¾Ý½á¹¹Ìå */ +struct rk2818_headset_data { + unsigned int irq; +}; + +#endif diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 0b0b6182cadd..be5f93b05e53 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -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 diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 42a5a5a90e75..785b8ca28415 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -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 index 000000000000..0fb6b2d703a6 --- /dev/null +++ b/drivers/input/misc/capella_cm3602.c @@ -0,0 +1,340 @@ +/* drivers/input/misc/capella_cm3602.c + * + * Copyright (C) 2009 Google, Inc. + * Author: Iliyan Malchev + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); + diff --git a/drivers/mmc/host/rk2818-sdmmc.c b/drivers/mmc/host/rk2818-sdmmc.c index 2bf247e30be0..765f51b07994 100755 --- a/drivers/mmc/host/rk2818-sdmmc.c +++ b/drivers/mmc/host/rk2818-sdmmc.c @@ -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 } diff --git a/drivers/power/rk2818_battery.c b/drivers/power/rk2818_battery.c index b70850d44d2a..2c19ac375050 100755 --- a/drivers/power/rk2818_battery.c +++ b/drivers/power/rk2818_battery.c @@ -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 index 000000000000..7f1de9b912a2 --- /dev/null +++ b/include/linux/capella_cm3602.h @@ -0,0 +1,37 @@ +/* include/linux/capella_cm3602.h + * + * Copyright (C) 2009 Google, Inc. + * Author: Iliyan Malchev + * + * 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 +#include + +#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 -- 2.34.1