1,添加耳机检测;2,添加l/p sensor;3,修改raho充电;4,恢复raho sdcard 检测

This commit is contained in:
root
2010-08-19 17:32:53 +08:00
parent ad2abac46f
commit a7e06e1aee
13 changed files with 605 additions and 10 deletions

View File

@@ -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

View 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"

View 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/

View File

@@ -0,0 +1,2 @@
config HEADSET_DET
tristate "headset detech support"

View File

@@ -0,0 +1,2 @@
obj-$(CONFIG_HEADSET_DET) += rk2818_headset.o

View 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");

View 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

View 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

View 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

View 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);

View File

@@ -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
}

View File

@@ -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;

View 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