mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
1,添加耳机检测;2,添加l/p sensor;3,修改raho充电;4,恢复raho sdcard 检测
This commit is contained in:
@@ -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"
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rk2818_gpioBank<6E><6B><EFBFBD>飬<EFBFBD><E9A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GPIO<49>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ID<49>ͼĴ<CDBC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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/
|
||||
|
||||
2
drivers/headset_observe/Kconfig
Normal file
2
drivers/headset_observe/Kconfig
Normal file
@@ -0,0 +1,2 @@
|
||||
config HEADSET_DET
|
||||
tristate "headset detech support"
|
||||
2
drivers/headset_observe/Makefile
Normal file
2
drivers/headset_observe/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_HEADSET_DET) += rk2818_headset.o
|
||||
|
||||
147
drivers/headset_observe/rk2818_headset.c
Normal file
147
drivers/headset_observe/rk2818_headset.c
Normal file
@@ -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
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD>״̬ */
|
||||
#define BIT_HEADSET (1 << 0)//<2F><>MIC<49>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
#define BIT_HEADSET_NO_MIC (1 << 1)//<2F><><EFBFBD><EFBFBD>MIC<49>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
|
||||
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();//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>һ<EFBFBD>μ<EFBFBD><CEBC><EFBFBD>һ<EFBFBD><D2BB>
|
||||
|
||||
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");
|
||||
9
drivers/headset_observe/rk2818_headset.h
Normal file
9
drivers/headset_observe/rk2818_headset.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef RK2818_HEADSET_H
|
||||
#define RK2818_HEADSET_H
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ<DDBD><E1B9B9> */
|
||||
struct rk2818_headset_data {
|
||||
unsigned int irq;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
340
drivers/input/misc/capella_cm3602.c
Normal file
340
drivers/input/misc/capella_cm3602.c
Normal file
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD>ë<EFBFBD>̵<EFBFBD>ѹ*/
|
||||
if(gBatVoltage >= BATT_MAX_VOL_VALUE + 10)
|
||||
gBatVoltage = BATT_MAX_VOL_VALUE + 10;
|
||||
|
||||
37
include/linux/capella_cm3602.h
Normal file
37
include/linux/capella_cm3602.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user