#include <asm/mach/map.h>
#include <mach/gpio.h>
#include <mach/adc.h>
+#include <mach/board.h>
#if 0
#define DBG(x...) printk(x)
#define DBG(x...)
#endif
-//ROCKCHIP AD KEY CODE ,for demo board
-// key ---> EV
-#define AD2KEY1 114 ///VOLUME_DOWN
-#define AD2KEY2 115 ///VOLUME_UP
-#define AD2KEY3 59 ///MENU
-#define AD2KEY4 102 ///HOME
-#define AD2KEY5 158 ///BACK
-#define AD2KEY6 61 ///CALL
-
-#define KEYSTART 28 //ENTER
-#define KEYMENU AD2KEY6 ///CALL
-#define KEY_PLAYON_PIN RK2818_PIN_PE1
-#define ENDCALL 62
-
-#define Valuedrift 50
-#define ADEmpty 1000
-#define ADInvalid 20
-#define ADKEYNUM 10
-
-#define ADKEYCH 1 //ADͨµÀ
-
#define KEY_PHYS_NAME "rk2818_adckey/input0"
volatile int gADSampleTimes = 0;
volatile int gStatePlaykey = 0;
-
volatile unsigned int gCodeCount = 0;
volatile unsigned int gThisCode = 0;
volatile unsigned int gLastCode = 0;
-
-//ADC Registers
-typedef struct tagADC_keyst
-{
- unsigned int adc_value;
- unsigned int adc_keycode;
-}ADC_keyst,*pADC_keyst;
-
-// adc ---> key
-static ADC_keyst gAdcValueTab[] =
-{
- {95, AD2KEY1},
- {249, AD2KEY2},
- {406, AD2KEY3},
- {561, AD2KEY4},
- {726, AD2KEY5},
- {899, AD2KEY6},
- {ADEmpty,0}
-};
+volatile unsigned int gFlagShortPlay = 0;
+volatile unsigned int gFlagLongPlay = 0;
+volatile unsigned int gPlayCount = 0;
//key code tab
-static unsigned char gInitKeyCode[ADKEYNUM] =
-{
- AD2KEY1,AD2KEY2,AD2KEY3,AD2KEY4,AD2KEY5,AD2KEY6,
- ENDCALL,KEYSTART,KEY_WAKEUP,
-};
-
-
struct rk28_adckey
{
struct semaphore lock;
struct rk28_adc_client *client;
struct input_dev *input_dev;
struct timer_list timer;
- unsigned char keycodes[ADKEYNUM];
+ unsigned char * keycodes;
void __iomem *mmio_base;
};
struct rk28_adckey *pRk28AdcKey;
-unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab)
+unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data)
{
- while(ptab->adc_value != ADEmpty)
+ while(ptab->adc_value != 0)
{
- if((advalue > ptab->adc_value - Valuedrift) && (advalue < ptab->adc_value + Valuedrift))
- 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++;
}
static irqreturn_t rk28_playkey_irq(int irq, void *handle)
{
- input_report_key(pRk28AdcKey->input_dev,KEYSTART,1);
- input_sync(pRk28AdcKey->input_dev);
- input_report_key(pRk28AdcKey->input_dev,KEYSTART,0);
- input_sync(pRk28AdcKey->input_dev);
- printk("Enter::%s,LINE=%d,KEYSTART=%d,0\n",__FUNCTION__,__LINE__,KEYSTART);
+
+ //gFlagPlay = 1;
+ //DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
return IRQ_HANDLED;
}
-
void rk28_send_wakeup_key( void )
{
- input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,1);
- input_sync(pRk28AdcKey->input_dev);
- input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,0);
- input_sync(pRk28AdcKey->input_dev);
+ input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,1);
+ input_sync(pRk28AdcKey->input_dev);
+ input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,0);
+ input_sync(pRk28AdcKey->input_dev);
+ DBG("Wake up system\n");
}
static int rk28_adckey_open(struct input_dev *dev)
static void rk28_adkeyscan_timer(unsigned long data)
{
unsigned int adcvalue = -1, code;
-
+ struct adc_key_data *rk2818_adckey_data = (struct adc_key_data *)data;
+
pRk28AdcKey->timer.expires = jiffies + msecs_to_jiffies(10);
add_timer(&pRk28AdcKey->timer);
-
+
+ /*handle long press of play key*/
+ if(gpio_get_value(rk2818_adckey_data->pin_playon) == rk2818_adckey_data->playon_level)
+ {
+ if(++gPlayCount > 20000)
+ gPlayCount = 101;
+ if((2 == gPlayCount) && (0 == gFlagShortPlay))
+ {
+ gFlagShortPlay = 1;
+ }
+ else if((100 == gPlayCount) && (0 == gFlagLongPlay))
+ {
+ gFlagLongPlay = 1;
+ gFlagShortPlay = 0;
+ input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_LONG_PRESS,1);
+ input_sync(pRk28AdcKey->input_dev);
+ DBG("Enter::%s,LINE=%d,KEY_PLAY_LONG_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_LONG_PRESS);
+ }
+ }
+ else
+ {
+ if (1 == gFlagShortPlay)
+ {
+ input_report_key(pRk28AdcKey->input_dev,ENDCALL,1);
+ input_sync(pRk28AdcKey->input_dev);
+ input_report_key(pRk28AdcKey->input_dev,ENDCALL,0);
+ input_sync(pRk28AdcKey->input_dev);
+ DBG("Wake up system,ENDCALL=%d\n",ENDCALL);
+
+ input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,1);
+ input_sync(pRk28AdcKey->input_dev);
+ DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
+ input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,0);
+ input_sync(pRk28AdcKey->input_dev);
+ DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,0\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
+ }
+ else if(1 == gFlagLongPlay)
+ {
+ input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_LONG_PRESS,0);
+ input_sync(pRk28AdcKey->input_dev);
+ DBG("Enter::%s,LINE=%d,KEY_PLAY_LONG_PRESS=%d,0\n",__FUNCTION__,__LINE__,KEY_PLAY_LONG_PRESS);
+ }
+
+ gFlagShortPlay = 0;
+ gFlagLongPlay = 0;
+ gPlayCount = 0;
+ }
+
+ /*handle long press of adc key*/
if (gADSampleTimes < 4)
{
gADSampleTimes ++;
gADSampleTimes = 0;
//rk28_read_adc(pRk28AdcKey);
- adcvalue = gAdcValue[ADKEYCH];
- if((adcvalue > ADEmpty) || (adcvalue < ADInvalid))
+ adcvalue = gAdcValue[rk2818_adckey_data->adc_chn];
+ //printk("=========== adcvalue=0x%x ===========\n",adcvalue);
+
+ if((adcvalue > rk2818_adckey_data->adc_empty) || (adcvalue < rk2818_adckey_data->adc_invalid))
{
- if(gLastCode == 0)
- return;
+ //DBG("adcvalue invalid !!!\n");
+ if(gLastCode == 0) {
+ return;
+ }
else
{
if(gLastCode == KEYMENU)
}
}
- DBG("adcvalue=0x%x\n",adcvalue);
+ //DBG("adcvalue=0x%x\n",adcvalue);
- code=rk28_get_keycode(adcvalue,gAdcValueTab);
+ code=rk28_get_keycode(adcvalue,rk2818_adckey_data->adc_key_table,rk2818_adckey_data);
if(code)
{
if(code == KEYMENU)
{
struct rk28_adckey *adckey;
struct input_dev *input_dev;
- int error,i;
+ int error,i,irq_num;
+ struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
+ if (!(pdata->adc_key))
+ return -1;
+
adckey = kzalloc(sizeof(struct rk28_adckey), GFP_KERNEL);
if (adckey == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
return -ENOMEM;
}
- memcpy(adckey->keycodes, gInitKeyCode, sizeof(adckey->keycodes));
+ //memcpy(adckey->keycodes, gInitKeyCode, sizeof(adckey->keycodes));
+ adckey->keycodes = pdata->adc_key->initKeyCode;
/* Create and register the input driver. */
input_dev = input_allocate_device();
input_dev->keycode = adckey->keycodes;
input_dev->keycodesize = sizeof(unsigned char);
- input_dev->keycodemax = ARRAY_SIZE(gInitKeyCode);
- for (i = 0; i < ARRAY_SIZE(gInitKeyCode); i++)
- set_bit(gInitKeyCode[i], input_dev->keybit);
+ 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);
adckey->input_dev = input_dev;
goto failed_free_dev;
}
- error = gpio_request(KEY_PLAYON_PIN, "play key gpio");
+ error = gpio_request(pdata->adc_key->pin_playon, "play key gpio");
if (error) {
dev_err(&pdev->dev, "failed to request play key gpio\n");
goto free_gpio;
}
- gpio_pull_updown(KEY_PLAYON_PIN,GPIOPullUp);
- error = request_irq(gpio_to_irq(KEY_PLAYON_PIN),rk28_playkey_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
- if(error)
- {
- printk("unable to request play key irq\n");
- goto free_gpio_irq;
- }
+ irq_num = gpio_to_irq(pdata->adc_key->pin_playon);
+
+ if(pdata->adc_key->playon_level)
+ {
+ gpio_pull_updown(pdata->adc_key->pin_playon,GPIOPullDown);
+ error = request_irq(irq_num,rk28_playkey_irq,IRQF_TRIGGER_RISING,NULL,NULL);
+ if(error)
+ {
+ printk("unable to request play key irq\n");
+ goto free_gpio_irq;
+ }
+ }
+ else
+ {
+ gpio_pull_updown(pdata->adc_key->pin_playon,GPIOPullUp);
+ error = request_irq(irq_num,rk28_playkey_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
+ if(error)
+ {
+ printk("unable to request play key irq\n");
+ goto free_gpio_irq;
+ }
+ }
+
+ enable_irq_wake(irq_num); // so play/wakeup key can wake up system
- setup_timer(&adckey->timer, rk28_adkeyscan_timer, (unsigned long)adckey);
+ setup_timer(&adckey->timer, rk28_adkeyscan_timer, (unsigned long)(pdata->adc_key));
adckey->timer.expires = jiffies+50;
add_timer(&adckey->timer);
printk(KERN_INFO "rk2818_adckey: driver initialized\n");
return 0;
free_gpio_irq:
- free_irq(gpio_to_irq(KEY_PLAYON_PIN),NULL);
+ free_irq(irq_num,NULL);
free_gpio:
- gpio_free(KEY_PLAYON_PIN);
+ gpio_free(pdata->adc_key->pin_playon);
failed_free_dev:
platform_set_drvdata(pdev, NULL);
input_free_device(input_dev);
static int __devexit rk28_adckey_remove(struct platform_device *pdev)
{
struct rk28_adckey *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);
- free_irq(gpio_to_irq(KEY_PLAYON_PIN),NULL);
- gpio_free(KEY_PLAYON_PIN);
-
+ free_irq(gpio_to_irq(pdata->adc_key->pin_playon), NULL);
+ gpio_free(pdata->adc_key->pin_playon);
return 0;
}