1,耳机按键;2,针对raho的震动(time 精度还不行);3,modem控制驱动;4,一些log开关的修改

This commit is contained in:
root
2010-10-13 12:22:33 +08:00
parent f2364dedad
commit 8c72b7d9ce
15 changed files with 681 additions and 70 deletions

View File

@@ -1846,6 +1846,13 @@ struct platform_device rk2818_device_dm9k = {
};
#endif
#ifdef CONFIG_STE
struct platform_device rk2818_device_ste = {
.name = "ste",
.id = -1,
};
#endif
#ifdef CONFIG_HEADSET_DET
struct rk2818_headset_data rk2818_headset_info = {
.irq = FPGA_PIO0_00,
@@ -1862,6 +1869,81 @@ struct platform_device rk28_device_headset = {
};
#endif
// adc ---> key
#define PLAY_ON_PIN RK2818_PIN_PA3
#define PLAY_ON_LEVEL 1
static ADC_keyst gAdcValueTab[] =
{
{0x65, AD2KEY2},///VOLUME_DOWN
{0xd3, AD2KEY1},///VOLUME_UP
{0x130, AD2KEY3},///MENU
{0x19d, AD2KEY4},///HOME
{0x202, AD2KEY5},///BACK
{0x2d0, AD2KEY6},///CALL
{0x267, AD2KEY7},///SEARCH
{0, 0}///table end
};
static unsigned char gInitKeyCode[] =
{
AD2KEY1,AD2KEY2,AD2KEY3,AD2KEY4,AD2KEY5,AD2KEY6,AD2KEY7,
ENDCALL,KEYSTART,KEY_WAKEUP,
};
struct adc_key_data rk2818_adc_key = {
.pin_playon = PLAY_ON_PIN,
.playon_level = PLAY_ON_LEVEL,
.adc_empty = 1000,
.adc_invalid = 20,
.adc_drift = 50,
.adc_chn = 1,
.adc_key_table = gAdcValueTab,
.initKeyCode = gInitKeyCode,
.adc_key_cnt = 10,
};
struct rk2818_adckey_platform_data rk2818_adckey_platdata = {
.adc_key = &rk2818_adc_key,
};
//headset key
#ifdef CONFIG_HEADSET_KEY
static ADC_keyst gHskeyValueTab[] =
{
{0, KEY_HEADSETHOOK},
{0, 0}///table end
};
static unsigned char gInitHsKeyCode[] =
{
KEY_HEADSETHOOK,
};
struct adc_key_data rk2818_hs_key = {
.pin_playon = 0,
.playon_level = 0,
.adc_empty = 0,
.adc_invalid = 0,
.adc_drift = 50,
.adc_chn = 2,
.adc_key_table = gHskeyValueTab,
.initKeyCode = gInitHsKeyCode,
.adc_key_cnt = 1,
};
struct rk2818_adckey_platform_data rk2818_hskey_platdata = {
.adc_key = &rk2818_hs_key,
};
struct platform_device rk2818_device_hskey = {
.name = "rk2818-hskey",
.id = -1,
.dev = {
.platform_data = &rk2818_hskey_platdata,
}
};
#endif
#ifdef CONFIG_INPUT_LPSENSOR_CM3602
static int capella_cm3602_power(int on);
@@ -2012,6 +2094,9 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_HEADSET_DET
&rk28_device_headset,
#endif
#ifdef CONFIG_HEADSET_KEY
&rk2818_device_hskey,
#endif
#ifdef CONFIG_DWC_OTG
&rk2818_device_dwc_otg,
#endif
@@ -2022,6 +2107,9 @@ static struct platform_device *devices[] __initdata = {
&android_usb_device,
&usb_mass_storage_device,
#endif
#ifdef CONFIG_STE
&rk2818_device_ste,
#endif
#ifdef CONFIG_ANDROID_TIMED_GPIO
&rk28_device_vibrator,
#endif
@@ -2057,50 +2145,13 @@ static void rk2818_power_off(void)
gpio_set_value(POWER_PIN, 0);/*power down*/
}
// adc ---> key
#define PLAY_ON_PIN RK2818_PIN_PA3
#define PLAY_ON_LEVEL 1
static ADC_keyst gAdcValueTab[] =
{
{0x65, AD2KEY1},///VOLUME_DOWN
{0xd3, AD2KEY2},///VOLUME_UP
{0x130, AD2KEY3},///MENU
{0x19d, AD2KEY4},///HOME
{0x202, AD2KEY5},///BACK
{0x2d0, AD2KEY6},///CALL
{0x267, AD2KEY7},///SEARCH
{0, 0}///table end
};
static unsigned char gInitKeyCode[] =
{
AD2KEY1,AD2KEY2,AD2KEY3,AD2KEY4,AD2KEY5,AD2KEY6,AD2KEY7,
ENDCALL,KEYSTART,KEY_WAKEUP,
};
struct adc_key_data rk2818_adc_key = {
.pin_playon = PLAY_ON_PIN,
.playon_level = PLAY_ON_LEVEL,
.adc_empty = 1000,
.adc_invalid = 20,
.adc_drift = 50,
.adc_chn = 1,
.adc_key_table = gAdcValueTab,
.initKeyCode = gInitKeyCode,
.adc_key_cnt = 10,
};
struct rk2818_adckey_platform_data rk2818_adckey_platdata = {
.adc_key = &rk2818_adc_key,
};
#if CONFIG_ANDROID_TIMED_GPIO
#if defined(CONFIG_ANDROID_TIMED_GPIO)
static struct timed_gpio timed_gpios[] = {
{
.name = "vibrator",
.gpio = FPGA_PIO1_12,
.max_timeout = 1000,
.active_low = 1,
.active_low = 0,
},
};

View File

@@ -237,6 +237,7 @@ struct rk2818_rtc_platform_data {
#define KEYMENU AD2KEY6 ///CALL
#define KEY_PLAY_SHORT_PRESS KEYSTART //code for short press the play key
#define KEY_PLAY_LONG_PRESS ENDCALL //code for long press the play key
#define KEY_HEADSETHOOK 226
//ADC Registers
typedef struct tagADC_keyst

View File

@@ -69,7 +69,11 @@ MUX_CFG(GPIOB3_U0RTSN_SEL_NAME, B, 13, 1, 0, DEFAULT) /* 0 : gpio_b3 1
MUX_CFG(GPIOB2_U0CTSN_SEL_NAME, B, 12, 1, 0, DEFAULT) /* 0 : gpio_b2 1 : uart0_cts_n */
MUX_CFG(GPIOF2_APWM0_SEL_NAME, B, 11, 1, 0, INITIAL) /* 0 : gpio_f2 1 : pwm0 */
MUX_CFG(GPIOC_LCDC16BIT_SEL_NAME, B, 10, 1, 1, INITIAL) /* 0 : gpio_d0 ~ gpio_d7 1 : lcdc_data8 ~ lcdc_data15 */
#if defined(CONFIG_MACH_RAHO)||defined(CONFIG_MACH_RAHO_0928)
MUX_CFG(GPIOC_LCDC24BIT_SEL_NAME, B, 9, 1, 0, INITIAL) /* 0 : gpio_c2 ~ gpio_c7 1 : lcdc_data18 ~ lcdc_data23 */
#else
MUX_CFG(GPIOC_LCDC24BIT_SEL_NAME, B, 9, 1, 1, INITIAL) /* 0 : gpio_c2 ~ gpio_c7 1 : lcdc_data18 ~ lcdc_data23 */
#endif
MUX_CFG(GPIOC_LCDC18BIT_SEL_NAME, B, 8, 1, 1, INITIAL) /* 0 : gpio_c0/c1 1 : lcdc_data16 ~ lcdc_data17 */
MUX_CFG(CXGPIO_LCDDEN_SEL_NAME, B, 7, 1, 1, INITIAL) /* 0 : gpio2_26 1 : lcdc_denable */
MUX_CFG(CXGPIO_LCDVSYNC_SEL_NAME, B, 6, 1, 1, INITIAL) /* 0 : gpio2_25 1 : lcdc_vsync */

View File

@@ -61,6 +61,16 @@ static struct rk2818_headset_data *prk2818_headset_info;
static irqreturn_t headset_interrupt(int irq, void *dev_id);
unsigned int headset_irq_type;
int headset_status(void)
{
if(Headset_dev.cur_headset_status & BIT_HEADSET)
return 1;
else
return 0;
}
EXPORT_SYMBOL_GPL(headset_status);
static void headsetobserve_work(void)
{
if(gpio_get_value(prk2818_headset_info->irq)){

View File

@@ -432,6 +432,17 @@ config KEYBOARD_RK28ADC
To compile this driver as a module, choose M here: the
module will be called rk2818_adckey.
config HEADSET_KEY
tristate "RK2818 headset Keypad support"
depends on RK28_ADC
default y
help
Say Y here to enable the headset adc keypad on SDK board
based on RK2818.
To compile this driver as a module, choose M here: the
module will be called rk2818_hskey.
config KEYBOARD_RK28ADC_IT50
tristate "RK2818 ADC Keypad it50 support"

View File

@@ -39,4 +39,5 @@ obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
obj-$(CONFIG_KEYBOARD_RK28ADC) += rk2818_adckey.o
obj-$(CONFIG_KEYBOARD_RK28ADC_IT50) += rk2818_adckey_t50.o
obj-$(CONFIG_HEADSET_KEY) += rk2818_hskey.o

View File

@@ -59,8 +59,10 @@ struct rk28_adckey *pRk28AdcKey;
unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data)
{
while(ptab->adc_value != 0)
while(ptab->adc_keycode != 0)
{
if((ptab->adc_value == 0)&&(advalue >= 0 && advalue <= 5))
return ptab->adc_keycode;
if((advalue > ptab->adc_value - rk2818_adckey_data->adc_drift) && (advalue < ptab->adc_value + rk2818_adckey_data->adc_drift))
return ptab->adc_keycode;
ptab++;
@@ -69,6 +71,8 @@ unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_ke
return 0;
}
EXPORT_SYMBOL_GPL(rk28_get_keycode);
static irqreturn_t rk28_playkey_irq(int irq, void *handle)
{

View File

@@ -0,0 +1,284 @@
/*
* linux/drivers/input/keyboard/rk28_adckey.c
*
* This driver program support to AD key which use for rk28 chip
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/gpio.h>
#include <mach/adc.h>
#include <mach/board.h>
#if 1
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
//#define KEY_PHYS_NAME "rk2818_adckey/input0"
static unsigned int gLastKeyCode = 0;
static int gSampleTimes = 0;
static int gADValue = 0;
static struct rk28_hskey *phsKey;
//key code tab
struct rk28_hskey
{
struct input_dev *input_dev;
struct timer_list timer;
unsigned char * keycodes;
};
extern int headset_status(void);
extern unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data);
#if 0
unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data)
{
while(ptab->adc_keycode != 0)
{
if((ptab->adc_value == 0)&&(advalue >= 0 && advalue <= 5))
return ptab->adc_keycode;
if((advalue > ptab->adc_value - rk2818_adckey_data->adc_drift) && (advalue < ptab->adc_value + rk2818_adckey_data->adc_drift))
return ptab->adc_keycode;
ptab++;
}
return 0;
}
void rk28_send_wakeup_key( void )
{
input_report_key(phsKey->input_dev,KEY_WAKEUP,1);
input_sync(phsKey->input_dev);
input_report_key(phsKey->input_dev,KEY_WAKEUP,0);
input_sync(phsKey->input_dev);
DBG("Wake up system\n");
}
#endif
static int rk28_Hskey_open(struct input_dev *dev)
{
//struct rk28_adckey *adckey = input_get_drvdata(dev);
DBG("===========rk28_Hskey_open===========\n");
return 0;
}
static void rk28_Hskey_close(struct input_dev *dev)
{
DBG("===========rk28_Hskey_close===========\n");
//struct rk28_adckey *adckey = input_get_drvdata(dev);
//
}
#ifdef CONFIG_PM
static int rk28_hskey_suspend(struct platform_device *pdev, pm_message_t state)
{
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
return 0;
}
static int rk28_hskey_resume(struct platform_device *pdev)
{
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
//struct input_dev *input_dev = adckey->input_dev;
#if 0
mutex_lock(&input_dev->mutex);
mutex_unlock(&input_dev->mutex);
#endif
return 0;
}
#else
#define rk28_hskey_suspend NULL
#define rk28_hskey_resume NULL
#endif
static void rk28_hskeyscan_timer(unsigned long data)
{
unsigned int adcvalue = 0x3FF,code = 0;
struct adc_key_data *rk2818_adckey_data = (struct adc_key_data *)data;
phsKey->timer.expires = jiffies + msecs_to_jiffies(10);
add_timer(&phsKey->timer);
if(headset_status())
{
if(gSampleTimes<4)
{
gADValue += gAdcValue[rk2818_adckey_data->adc_chn];
gSampleTimes++;
}
else
{
gADValue = gADValue/4;
code=rk28_get_keycode(gADValue,rk2818_adckey_data->adc_key_table,rk2818_adckey_data);
gADValue = 0;
gSampleTimes = 0;
if(code && !gLastKeyCode)
{
gLastKeyCode = code;
input_report_key(phsKey->input_dev,gLastKeyCode,1);
input_sync(phsKey->input_dev);
DBG("===========headset key press code=%d ===========\n",code);
}
else if(!code && gLastKeyCode)
{
input_report_key(phsKey->input_dev,gLastKeyCode,0);
input_sync(phsKey->input_dev);
gLastKeyCode = 0;
DBG("===========headset key release code=%d ===========\n",code);
}
}
}
else
{
if(gLastKeyCode)
{
input_report_key(phsKey->input_dev,code,0);
input_sync(phsKey->input_dev);
gLastKeyCode = 0;
DBG("===========headset key release code=%d ===========\n",code);
}
gADValue = 0;
gSampleTimes = 0;
}
}
static int __devinit rk28_adckey_probe(struct platform_device *pdev)
{
struct rk28_hskey *hskey;
struct input_dev *input_dev;
int error,i,irq_num;
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
if (!(pdata->adc_key))
return -1;
hskey = kzalloc(sizeof(struct rk28_hskey), GFP_KERNEL);
if (hskey == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
return -ENOMEM;
}
hskey->keycodes = pdata->adc_key->initKeyCode;
/* Create and register the input driver. */
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(&pdev->dev, "failed to allocate input device\n");
error = -ENOMEM;
goto failed_free;
}
input_dev->name = pdev->name;
input_dev->open = rk28_Hskey_open;
input_dev->close = rk28_Hskey_close;
input_dev->dev.parent = &pdev->dev;
//input_dev->phys = KEY_PHYS_NAME;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->keycode = hskey->keycodes;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = pdata->adc_key->adc_key_cnt;
for (i = 0; i < pdata->adc_key->adc_key_cnt; i++)
set_bit(pdata->adc_key->initKeyCode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
hskey->input_dev = input_dev;
input_set_drvdata(input_dev, hskey);
input_dev->evbit[0] = BIT_MASK(EV_KEY);
platform_set_drvdata(pdev, hskey);
phsKey = hskey;
/* Register the input device */
error = input_register_device(input_dev);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
goto failed_free_dev;
}
setup_timer(&hskey->timer, rk28_hskeyscan_timer, (unsigned long)(pdata->adc_key));
hskey->timer.expires = jiffies+50;
add_timer(&hskey->timer);
printk(KERN_INFO "rk2818_hskey: driver initialized\n");
return 0;
free_gpio_irq:
free_irq(irq_num,NULL);
free_gpio:
gpio_free(pdata->adc_key->pin_playon);
failed_free_dev:
platform_set_drvdata(pdev, NULL);
input_free_device(input_dev);
failed_free:
kfree(hskey);
return error;
}
static int __devexit rk28_adckey_remove(struct platform_device *pdev)
{
struct rk28_hskey *adckey = platform_get_drvdata(pdev);
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
input_unregister_device(adckey->input_dev);
input_free_device(adckey->input_dev);
platform_set_drvdata(pdev, NULL);
kfree(adckey);
return 0;
}
static struct platform_driver rk28_hskey_driver =
{
.probe = rk28_adckey_probe,
.remove = __devexit_p(rk28_adckey_remove),
.suspend = rk28_hskey_suspend,
.resume = rk28_hskey_resume,
.driver = {
.name = "rk2818-hskey",
.owner = THIS_MODULE,
},
};
int __init rk28_hskey_init(void)
{
return platform_driver_register(&rk28_hskey_driver);
}
static void __exit rk28_hskey_exit(void)
{
platform_driver_unregister(&rk28_hskey_driver);
}
module_init(rk28_hskey_init);
module_exit(rk28_hskey_exit);
MODULE_DESCRIPTION("rk2818 headset Key Controller Driver");
MODULE_AUTHOR("luowei lw@rock-chips.com");
MODULE_LICENSE("GPL");

View File

@@ -96,7 +96,7 @@
#define VIPREGNTSC 0x00000000
#define VIPREGPAL 0x00000400
//--------------------------
#define CONFIG_RK28CAMERA_TR 1
#define CONFIG_RK28CAMERA_TR 0
#define CONFIG_RK28CAMERA_DEBUG 0
#if (CONFIG_RK28CAMERA_TR)
#define RK28CAMERA_TR(format, ...) printk(format, ## __VA_ARGS__)
@@ -107,6 +107,7 @@
#endif
#else
#define RK28CAMERA_TR(format, ...)
#define RK28CAMERA_DG(format, ...)
#endif
#define MIN(x,y) ((x<y) ? x: y)

View File

@@ -284,6 +284,10 @@ config APANIC_PLABEL
If your platform uses a different flash partition label for storing
crashdumps, enter it here.
config STE
bool "STE modem control driver"
default n
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"

View File

@@ -28,3 +28,4 @@ obj-y += eeprom/
obj-y += cb710/
obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o
obj-$(CONFIG_APANIC) += apanic.o
obj-$(CONFIG_STE) += ste.o

203
drivers/misc/ste.c Normal file
View File

@@ -0,0 +1,203 @@
#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/ste.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/circ_buf.h>
#include <linux/interrupt.h>
#include <mach/spi_fpga.h>
#include <linux/delay.h>
#if 1
#define D(x...) printk(x)
#else
#define D(x...)
#endif
static int misc_opened;
#define AP_TD_UNDEFINED_GBIN5 FPGA_PIO2_02
#define AP_RESET_TD FPGA_PIO2_04
#define AP_SHUTDOWN_TD_PMU FPGA_PIO2_05
#define AP_PW_EN_TD FPGA_PIO2_03
#define PIN_BPSEND_ACK RK2818_PIN_PE0
#define PIN_APSEND_ACK RK2818_PIN_PF7
static int bp_power_on(void)
{
int ret=0;
ret = gpio_request(AP_TD_UNDEFINED_GBIN5, NULL);
if (ret) {
printk("%s:failed to request fpga s %d\n",__FUNCTION__,__LINE__);
goto err;
}
ret = gpio_request(AP_RESET_TD, NULL);
if (ret) {
printk("%s:failed to request fpga s %d\n",__FUNCTION__,__LINE__);
goto err0;
}
ret = gpio_request(AP_SHUTDOWN_TD_PMU, NULL);
if (ret) {
printk("%s:failed to request fpga %d\n",__FUNCTION__,__LINE__);
goto err1;
}
ret = gpio_request(AP_PW_EN_TD, NULL);
if (ret) {
printk("%s:failed to request fpga %d\n",__FUNCTION__,__LINE__);
goto err2;
}
gpio_set_value(AP_TD_UNDEFINED_GBIN5, 1);
gpio_direction_output(AP_TD_UNDEFINED_GBIN5, 1);
gpio_direction_input(AP_RESET_TD);
gpio_set_value(AP_SHUTDOWN_TD_PMU, 0);
gpio_direction_output(AP_SHUTDOWN_TD_PMU, 0);
gpio_set_value(AP_PW_EN_TD, 0);
gpio_direction_output(AP_PW_EN_TD, 0);
mdelay(1);
gpio_set_value(AP_PW_EN_TD, 1);
mdelay(1200);
gpio_set_value(AP_PW_EN_TD, 0);
return true;
err2:
gpio_free(AP_SHUTDOWN_TD_PMU);
err1:
gpio_free(AP_RESET_TD);
err0:
gpio_free(AP_TD_UNDEFINED_GBIN5);
err:
return false;
}
static int bp_power_off(void)
{
D("+++--++++++%s_________ \r\n",__FUNCTION__);
gpio_set_value(AP_TD_UNDEFINED_GBIN5, 0);
gpio_set_value(AP_PW_EN_TD, 0);
//gpio_direction_output(AP_PW_EN_TD, 0);
mdelay(1);
gpio_set_value(AP_PW_EN_TD, 1);
mdelay(1200);
gpio_set_value(AP_PW_EN_TD, 0);
mdelay(5000);
gpio_set_value(AP_SHUTDOWN_TD_PMU, 1);
mdelay(1200);
// gpio_free(AP_PW_EN_TD);
D("++++--+++++%s ok_________\r\n",__FUNCTION__);
return 0;
}
//add end
static int ste_open(struct inode *inode, struct file *file)
{
D("%s\n", __func__);
if (misc_opened)
return -EBUSY;
misc_opened = 1;
return 0;
}
static int ste_release(struct inode *inode, struct file *file)
{
D("%s\n", __func__);
misc_opened = 0;
return 0;
}
static int ste_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
{
int val;
D("%s cmd %d\n", __func__, _IOC_NR(cmd));
switch (cmd) {
case STE_IOCTL_EN_APSEND_ACK:
D("%s:STE_IOCTL_EN_APSEND_ACK\n");
gpio_direction_output(PIN_APSEND_ACK,GPIO_LOW);
msleep(50);
gpio_direction_output(PIN_APSEND_ACK,GPIO_HIGH);
msleep(50);
break;
case STE_IOCTL_GET_ACK:
val = gpio_get_value(PIN_BPSEND_ACK);
D("%s:STE_IOCTL_GET_ACK pin status is %d\n",__func__,val);
return put_user(val, (unsigned long __user *)arg);
break;
case STE_IOCTL_POWER_ON:
D("%s:STE_IOCTL_POWER_ON\n",__func__);
bp_power_on();
break;
case STE_IOCTL_POWER_OFF:
D("%s:STE_IOCTL_POWER_OFF\n",__func__);
bp_power_off();
break;
default:
pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
return -EINVAL;
}
return 0;
}
static struct file_operations ste_fops = {
.owner = THIS_MODULE,
.open = ste_open,
.release = ste_release,
.ioctl = ste_ioctl
};
static struct miscdevice ste_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = STE_NAME,
.fops = &ste_fops
};
static int ste_probe(struct platform_device *pdev)
{
int rc = -EIO;
D("%s-----------\n",__FUNCTION__);
rc = misc_register(&ste_misc);
if (rc < 0) {
pr_err("%s: could not register misc device\n", __func__);
// goto err_unregister_input_device;
}
return rc;
}
static struct platform_driver ste_driver = {
.probe = ste_probe,
.driver = {
.name = "ste",
.owner = THIS_MODULE
},
};
static int __init ste_init(void)
{
return platform_driver_register(&ste_driver);
}
static void __exit ste_exit(void)
{
platform_driver_unregister(&ste_driver);
}
module_init(ste_init);
module_exit(ste_exit);

View File

@@ -26,7 +26,7 @@
#define RTC_RATE 100 * 1000
#define S35392_TEST 0
#if 1
#if 0
#define DBG(x...) printk(x)
#else
#define DBG(x...)
@@ -56,7 +56,7 @@ static int s35392a_set_reg(struct s35392a *s35392a, const char reg, char *buf, i
ret = i2c_transfer(client->adapter,&msg,1);
for(i=0;i<len;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
return ret;
}
@@ -219,11 +219,11 @@ static int s35392a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
/* This chip expects the bits of each byte to be in reverse order */
for(i=0;i<7;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
for (i = 0; i < 7; ++i)
buf[i] = bitrev8(buf[i]);
for(i=0;i<7;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
err = s35392a_set_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf));
return err;
@@ -239,12 +239,12 @@ static int s35392a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
if (err < 0)
return err;
for(i=0;i<7;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
/* This chip returns the bits of each byte in reverse order */
for (i = 0; i < 7; ++i)
buf[i] = bitrev8(buf[i]);
for(i=0;i<7;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
tm->tm_sec = bcd2bin(buf[S35392A_BYTE_SECS]);
tm->tm_min = bcd2bin(buf[S35392A_BYTE_MINS]);
tm->tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_BYTE_HOURS]);
@@ -272,11 +272,11 @@ static int s35392a_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm
if(err < 0)
return err;
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
for(i = 0;i < 3;++i)
buf[i] = bitrev8(buf[i]);
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
tm->time.tm_wday = -1;
tm->time.tm_hour = -1;
tm->time.tm_min = -1;
@@ -330,11 +330,11 @@ static int s35392a_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *
buf[S35392A_ALARM_MINS] = tm->time.tm_min >= 0?
bin2bcd(tm->time.tm_min) | S35392A_ALARM_ENABLE:0;
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
for(i = 0;i < 3;++i)
buf[i] = bitrev8(buf[i]);
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
if(tm->enabled)
{
data = 0x00;
@@ -346,7 +346,7 @@ static int s35392a_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *
data = 0x02;
s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
printk("data = 0x%x\n",data);
DBG("data = 0x%x\n",data);
err = s35392a_set_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf));
return err;
}
@@ -370,11 +370,11 @@ static int s35392a_i2c_read_alarm0(struct i2c_client *client, struct rtc_wkalrm
if(err < 0)
return err;
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
for(i = 0;i < 3;++i)
buf[i] = bitrev8(buf[i]);
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
tm->time.tm_wday = -1;
tm->time.tm_hour = -1;
tm->time.tm_min = -1;
@@ -428,11 +428,11 @@ static int s35392a_i2c_set_alarm0(struct i2c_client *client, struct rtc_wkalrm
buf[S35392A_ALARM_MINS] = tm->time.tm_min >= 0?
bin2bcd(tm->time.tm_min) | S35392A_ALARM_ENABLE:0;
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
for(i = 0;i < 3;++i)
buf[i] = bitrev8(buf[i]);
for(i=0;i<3;i++)
printk("buf[%d]=0x%x\n",i,buf[i]);
DBG("buf[%d]=0x%x\n",i,buf[i]);
if(tm->enabled)
{
data = 0x00;
@@ -444,7 +444,7 @@ static int s35392a_i2c_set_alarm0(struct i2c_client *client, struct rtc_wkalrm
data = 0x02;
s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
printk("data = 0x%x\n",data);
DBG("data = 0x%x\n",data);
err = s35392a_set_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf));
return err;
}
@@ -743,7 +743,7 @@ static void s35392a_work_func(struct work_struct *work)
struct s35392a *s35392a = container_of(work, struct s35392a, work);
struct i2c_client *client = s35392a->client;
printk("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");
DBG("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");
char data = 0x00;
s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
@@ -751,7 +751,7 @@ static void s35392a_work_func(struct work_struct *work)
s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
printk("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");
DBG("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");
enable_irq(client->irq);
}
@@ -774,7 +774,7 @@ static int s35392a_probe(struct i2c_client *client,
struct rtc_time tm;
char buf[1];
printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
err = -ENODEV;
goto exit;
@@ -843,7 +843,7 @@ static int s35392a_probe(struct i2c_client *client,
if(err = request_irq(client->irq, s35392a_wakeup_irq,IRQF_TRIGGER_LOW,NULL,s35392a) <0)
{
printk("unable to request rtc irq\n");
DBG("unable to request rtc irq\n");
goto exit_dummy;
}
}
@@ -854,7 +854,7 @@ static int s35392a_probe(struct i2c_client *client,
if(err = request_irq(client->irq, s35392a_wakeup_irq,IRQF_TRIGGER_HIGH,NULL,s35392a) <0)
{
printk("unable to request rtc irq\n");
DBG("unable to request rtc irq\n");
goto exit_dummy;
}
}
@@ -871,7 +871,7 @@ static int s35392a_probe(struct i2c_client *client,
}
#endif
printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
return 0;
exit_dummy:
@@ -916,7 +916,7 @@ static struct i2c_driver s35392a_driver = {
static int __init s35392a_rtc_init(void)
{
printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
return i2c_add_driver(&s35392a_driver);
}

View File

@@ -23,6 +23,11 @@
#include "timed_output.h"
#include "timed_gpio.h"
#if defined(CONFIG_MACH_RAHO)||defined(CONFIG_MACH_RAHO_0928)
#define GPIO_TYPE 1 //ʹ<><CAB9>FPGA<47><41>չ<EFBFBD><D5B9>IO<49><4F><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>ж<EFBFBD><D0B6>ڲ<EFBFBD>ֱ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>IO
#else
#define GPIO_TYPE 0
#endif
struct timed_gpio_data {
struct timed_output_dev dev;
@@ -31,14 +36,30 @@ struct timed_gpio_data {
unsigned gpio;
int max_timeout;
u8 active_low;
#if (GPIO_TYPE == 1)
struct work_struct timed_gpio_work;
#endif
};
#if (GPIO_TYPE == 1)
static void timed_gpio_work_handler(struct work_struct *work)
{
struct timed_gpio_data *data =
container_of(work, struct timed_gpio_data, timed_gpio_work);
gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
}
#endif
static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
{
struct timed_gpio_data *data =
container_of(timer, struct timed_gpio_data, timer);
#if (GPIO_TYPE == 0)
gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
#else
schedule_work(&data->timed_gpio_work);
#endif
return HRTIMER_NORESTART;
}
@@ -59,9 +80,8 @@ static void gpio_enable(struct timed_output_dev *dev, int value)
{
struct timed_gpio_data *data =
container_of(dev, struct timed_gpio_data, dev);
unsigned long flags;
spin_lock_irqsave(&data->lock, flags);
//unsigned long flags;
//spin_lock_irqsave(&data->lock, flags);
/* cancel previous timer and set GPIO according to value */
hrtimer_cancel(&data->timer);
@@ -76,7 +96,7 @@ static void gpio_enable(struct timed_output_dev *dev, int value)
HRTIMER_MODE_REL);
}
spin_unlock_irqrestore(&data->lock, flags);
//spin_unlock_irqrestore(&data->lock, flags);
}
static int timed_gpio_probe(struct platform_device *pdev)
@@ -126,7 +146,9 @@ static int timed_gpio_probe(struct platform_device *pdev)
gpio_dat->active_low = cur_gpio->active_low;
gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low);
}
#if (GPIO_TYPE == 1)
INIT_WORK(&gpio_dat->timed_gpio_work, timed_gpio_work_handler);
#endif
platform_set_drvdata(pdev, gpio_data);
return 0;

14
include/linux/ste.h Normal file
View File

@@ -0,0 +1,14 @@
#include <linux/types.h>
#include <linux/ioctl.h>
#define STE_IOCTL_MAGIC 'd'
#define STE_IOCTL_GET_ACK \
_IOR(STE_IOCTL_MAGIC, 1, int *)
#define STE_IOCTL_EN_APSEND_ACK \
_IOW(STE_IOCTL_MAGIC, 2, int *)
#define STE_IOCTL_POWER_ON \
_IOW(STE_IOCTL_MAGIC, 3, int *)
#define STE_IOCTL_POWER_OFF \
_IOW(STE_IOCTL_MAGIC, 4, int *)
#define STE_NAME "STE"