1428 lines
48 KiB
C
1428 lines
48 KiB
C
/* Qisda Tony 090324, add keypad [
|
|
* drivers/input/keyboard/s3c-keypad-qisda.c
|
|
* KeyPad Interface on S3C in Qisda eBook
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of this archive
|
|
* for more details.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/input.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/miscdevice.h>
|
|
#include <linux/irq.h>
|
|
#include <asm/arch/regs-irq.h>
|
|
#include <asm/hardware.h>
|
|
#include <asm/io.h>
|
|
#include <asm/delay.h>
|
|
#include <asm/irq.h>
|
|
|
|
#include <asm/arch/regs-gpio.h>
|
|
/*Qisda , wenny cheng , 20091224 , board id info {*/
|
|
#include <../include/asm-arm/plat-s3c24xx/common-smdk.h>
|
|
/*Qisda , wenny cheng , 20091224 , board id info }*/
|
|
|
|
/* Qisda, ShiYong Lin, 2009/08/18, Detect insertion source {*/
|
|
#include <asm/arch/regs-udc-hs.h>
|
|
#include <asm/arch/regs-s3c2416-clock.h>
|
|
/* } Qisda, ShiYong Lin, 2009/08/18, Detect insertion source */
|
|
|
|
#define DPRINTK(x...) printk("S3C-Keypad-qisda " x)
|
|
//#define DPRINTK(x...) /* !!!! */
|
|
|
|
|
|
#define DEVICE_NAME "s3c-keypad-qisda"
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
//#define IN_2416_EMU_BOARD
|
|
|
|
/* Qisda, ShiYong Lin, 2009/07/18, Set Power key as EINT for sys shutdown{*/
|
|
//#define POWER_KEY_FOR_SYS_SHUTDOWN
|
|
/* Qisda, ShiYong Lin, 2009/07/18, Set Power key as EINT for sys shutdown}*/
|
|
|
|
#define QISDA_TILT_0 0
|
|
#define QISDA_TILT_90 1
|
|
#define QISDA_TILT_180 3
|
|
#define QISDA_TILT_270 2
|
|
|
|
/*Qisda , wenny cheng , 20091224 , board id info {*/
|
|
//static int hw_version_for_keypad = 0;
|
|
extern int board_id;
|
|
/*Qisda , wenny cheng , 20091224 , board id info }*/
|
|
|
|
extern int average_adc_value_keep1; /*joey add to keep ADC will always return lower one 2009/12/28*/
|
|
extern int average_adc_value_keep2; /*joey add to keep ADC will always return lower one 2009/12/28*/
|
|
|
|
// Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event {
|
|
int sleeping_cha_event = 0;
|
|
// Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event }
|
|
|
|
/*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
|
|
#define OP_MODE_DELAY_REQUEST KEY_F9
|
|
/*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
|
|
|
|
#if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
|
|
#define MAX_KEYPAD_QISDA 23 /*shiyong joey for asus 2009/12/15*/
|
|
static int keypad_keycode_qisda[] = {
|
|
KEY_PAGEDOWN, KEY_PAGEUP, KEY_VOLUMEDOWN, KEY_VOLUMEUP,
|
|
KEY_F1, KEY_F2, KEY_F3, KEY_INSERT, KEY_ESC,
|
|
/* Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP {*/
|
|
KEY_CHA_STA_WALL_CHARGER, KEY_CHA_STA_UNPLUG,
|
|
KEY_CHA_STA_USB, KEY_BATTERY_FAIL,
|
|
KEY_SLEEP, KEY_TIMER_TICK,
|
|
KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_SOUND,
|
|
KEY_SD_INSERT, KEY_BATTERY /*shiyong joey for asus 2009/12/15*/
|
|
};
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_QISDA_QD060B00
|
|
|
|
#define QISDA_E600
|
|
//#define QISDA_L600
|
|
//#define QISDA_BQ060B00_DVT
|
|
|
|
|
|
#define MAX_KEYPAD_QISDA 29
|
|
static int keypad_keycode_qisda[] = {
|
|
KEY_MENU, KEY_SEARCH, KEY_PAGEDOWN, KEY_PAGEUP,
|
|
KEY_BACK, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_WAKEUP,
|
|
KEY_REFRESH, KEY_ENTER, KEY_UP, KEY_DOWN,
|
|
KEY_LEFT, KEY_RIGHT,
|
|
KEY_F1, KEY_F2, KEY_F3, KEY_F4,
|
|
KEY_F5, KEY_F6,
|
|
/* Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP {*/
|
|
KEY_CLOSE, KEY_CHA_STA_WALL_CHARGER, KEY_CHA_STA_UNPLUG,
|
|
KEY_CHA_STA_USB, KEY_BATTERY_FAIL,
|
|
KEY_SLEEP, KEY_TIMER_TICK, KEY_BATTERY,
|
|
/* } Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP */
|
|
/*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
|
|
KEY_F9
|
|
/*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
|
|
};
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_QISDA_QD090B00
|
|
#define MAX_KEYPAD_QISDA 27
|
|
static int keypad_keycode_qisda[] = {
|
|
KEY_MENU, KEY_SEARCH, KEY_PAGEDOWN, KEY_PAGEUP,
|
|
KEY_BACK, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_WAKEUP,
|
|
KEY_REFRESH, KEY_ENTER, KEY_UP, KEY_DOWN,
|
|
KEY_F1, KEY_F2, KEY_F3, KEY_F4,
|
|
KEY_F5, KEY_F6,
|
|
/* Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP {*/
|
|
KEY_CLOSE, KEY_CHA_STA_WALL_CHARGER, KEY_CHA_STA_UNPLUG,
|
|
KEY_CHA_STA_USB, KEY_BATTERY_FAIL,
|
|
KEY_SLEEP, KEY_TIMER_TICK, KEY_BATTERY,
|
|
/* } Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP */
|
|
/*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
|
|
KEY_F9
|
|
/*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
|
|
};
|
|
#endif
|
|
|
|
struct s3c_keypad_qisda {
|
|
struct input_dev *dev;
|
|
int keycodes[MAX_KEYPAD_QISDA];
|
|
int pressed[MAX_KEYPAD_QISDA];
|
|
};
|
|
|
|
|
|
//static struct work_struct wqReadData;
|
|
static struct timer_list keypad_timer_qisda;
|
|
static int is_timer_on_qisda = FALSE;
|
|
static int keypad_set_irq = FALSE;
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
|
|
static struct timer_list charger_source_timer;
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
|
|
/*joey add timer to avoid bouncing with usb in/out 20100127*/
|
|
static struct timer_list battery_status_timer;
|
|
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
|
|
static struct timer_list power_fail_timer;
|
|
static struct work_struct power_fail_workq;
|
|
u32 is_pwr_fail_timer_on = 0;
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
|
|
int charging_source = 3;
|
|
struct input_dev *Message_dev = NULL;
|
|
//static unsigned prevmask = 1;
|
|
static void keypad_port_initialize(void)
|
|
{
|
|
#ifdef CONFIG_QISDA_AS090B00
|
|
//Set gpio as input and pull-up enable
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD10, S3C2410_GPD10_INP); //T_SENSOR2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_INP); //T_SENSOR1
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); // power
|
|
s3c2410_gpio_pullup(S3C2410_GPF0, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_INP); // Menu
|
|
s3c2410_gpio_pullup(S3C2410_GPD14, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD15, S3C2410_GPD15_INP); // Return
|
|
s3c2410_gpio_pullup(S3C2410_GPD15, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_INP); // Function
|
|
s3c2410_gpio_pullup(S3C2410_GPG6, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // VOL+
|
|
s3c2410_gpio_pullup(S3C2410_GPH4, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_INP); // VOL-
|
|
s3c2410_gpio_pullup(S3C2410_GPH5, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_INP); // page up
|
|
s3c2410_gpio_pullup(S3C2410_GPF7, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_INP); // Page down
|
|
s3c2410_gpio_pullup(S3C2410_GPG7, 2);
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_QISDA_QD090B00
|
|
|
|
/*Qisda , wenny cheng , 20091224 , board id info {*/
|
|
// hw_version_for_keypad = readl(S3C2416_GPKDAT) & (0x3<<3);
|
|
printk("\nhw_version_for_keypad: %d\n", board_id);
|
|
|
|
//if(hw_version_for_keypad){
|
|
if(board_id != QD090B00_S02){
|
|
s3c2410_gpio_cfgpin(S3C2410_GPC3, S3C2410_GPC3_OUTP); // Tilt_EN
|
|
s3c2410_gpio_setpin(S3C2410_GPC3, 1);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_EINT10); // Search
|
|
s3c2410_gpio_pullup(S3C2410_GPG2, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11); // Return
|
|
s3c2410_gpio_pullup(S3C2410_GPG3, 2);
|
|
|
|
|
|
}
|
|
else{
|
|
//old
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_INP); // Search
|
|
s3c2410_gpio_pullup(S3C2410_GPD14, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD15, S3C2410_GPD15_INP); // Return
|
|
s3c2410_gpio_pullup(S3C2410_GPD15, 2);
|
|
}
|
|
/*Qisda , wenny cheng , 20091224 , board id info }*/
|
|
|
|
//Set gpio as input and pull-up enable
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD10, S3C2410_GPD10_INP); //T_SENSOR2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_INP); //T_SENSOR1
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); // power
|
|
s3c2410_gpio_pullup(S3C2410_GPF0, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_INP); // page down
|
|
s3c2410_gpio_pullup(S3C2410_GPF7, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_INP); // Refresh
|
|
s3c2410_gpio_pullup(S3C2410_GPG4, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_INP); // Menu
|
|
s3c2410_gpio_pullup(S3C2410_GPG6, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_INP); // Page up
|
|
s3c2410_gpio_pullup(S3C2410_GPG7, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // VOL+
|
|
s3c2410_gpio_pullup(S3C2410_GPH4, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_INP); // VOL-
|
|
s3c2410_gpio_pullup(S3C2410_GPH5, 2);
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_QISDA_QD060B00
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPC3, S3C2410_GPC3_OUTP); // Tilt_EN
|
|
s3c2410_gpio_setpin(S3C2410_GPC3, 1);
|
|
|
|
#ifdef CONFIG_QISDA_BK060B00
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_INP); //T_SENSOR2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_INP); //T_SENSOR1
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_INP); // Menu / Plato: Menu
|
|
s3c2410_gpio_pullup(S3C2410_GPG6, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG0, S3C2410_GPG0_INP); // VOL-/LEFT
|
|
s3c2410_gpio_pullup(S3C2410_GPG0, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_INP); // VOL+/RIGHT
|
|
s3c2410_gpio_pullup(S3C2410_GPG2, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_OUTP); // USB_SEL: DEVICE ONLY
|
|
s3c2410_gpio_setpin(S3C2410_GPH5, 0);
|
|
#else
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD10, S3C2410_GPD10_INP); //T_SENSOR2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_INP); //T_SENSOR1
|
|
|
|
//Set gpio as input and pull-up enable
|
|
// Qisda Jonas disable for keypad rework 20100104
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_INP); // Menu / Plato: Menu
|
|
s3c2410_gpio_pullup(S3C2410_GPD14, 2);
|
|
// Qisda Jonas disable for keypad rework
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); // power
|
|
s3c2410_gpio_pullup(S3C2410_GPF0, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_INP); // Search / UP / Plato: Vol up
|
|
s3c2410_gpio_pullup(S3C2410_GPH5, 2);
|
|
|
|
// Qisda Jonas modify for keypad rework 20100104
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11); // Menu key
|
|
s3c2410_gpio_pullup(S3C2410_GPG3, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_EINT12); // Page up, Plato: Back
|
|
s3c2410_gpio_pullup(S3C2410_GPG4, 2);
|
|
// Qisda Jonas modify for keypad rework
|
|
#endif
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD15, S3C2410_GPD15_INP); // Page down / Back / Plato: Back
|
|
s3c2410_gpio_pullup(S3C2410_GPD15, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_EINT7); // Back / Right / Plato: Page down
|
|
s3c2410_gpio_pullup(S3C2410_GPF7, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_EINT14); // VOL / Down / Plato: Search
|
|
s3c2410_gpio_pullup(S3C2410_GPG6, 2);
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_EINT15); // Refresh / Left / Plato: Page up
|
|
s3c2410_gpio_pullup(S3C2410_GPG7, 2);
|
|
|
|
#ifdef QISDA_L600
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // OK
|
|
s3c2410_gpio_pullup(S3C2410_GPH4, 2);
|
|
#endif
|
|
|
|
#ifdef CONFIG_QISDA_BQ060B00_DVT
|
|
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // Plato: Vol down
|
|
s3c2410_gpio_pullup(S3C2410_GPH4, 2);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
// CHG_STA, GPF6, Both edge triggered /*shiyong joey for asus 2009/12/15*/
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_EINT6);
|
|
s3c2410_gpio_pullup(S3C2410_GPF6, 0); /*joey modify 2->0 20100127*/
|
|
writel((readl(S3C2410_EXTINT0) & ~(1<<27)), S3C2410_EXTINT0);
|
|
writel(((readl(S3C2410_EXTINT0) & ~(7<<24))|(4<<24)), S3C2410_EXTINT0); /*joey modify (6<<24) to (4<<24)) 20100127*/ /*1:high 4:rise 6:both*/
|
|
|
|
// VBUS_IN_STA, GPG1, Both edge triggered /*shiyong joey for asus 2009/12/15*/
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9);
|
|
s3c2410_gpio_pullup(S3C2410_GPG1, 0);
|
|
writel((readl(S3C2410_EXTINT1) & ~(1<<7)), S3C2410_EXTINT1); /* EINT9 filter enable */
|
|
writel(((readl(S3C2410_EXTINT1) & ~(7<<4))|(6<<4)), S3C2410_EXTINT1);
|
|
|
|
// Power_Fail, GPG5, Both edge triggered /*shiyong joey for asus 2009/12/15*/
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG5, S3C2410_GPG5_EINT13);
|
|
s3c2410_gpio_pullup(S3C2410_GPG5, 2);
|
|
writel((readl(S3C2410_EXTINT1) & ~(1<<23)), S3C2410_EXTINT1);
|
|
writel(((readl(S3C2410_EXTINT1) & ~(7<<20))|(6<<20)), S3C2410_EXTINT1);
|
|
}
|
|
|
|
struct s3c_keypad_qisda *pdata;
|
|
/*
|
|
static s3c_keypad_qisda_workqueue(struct work_struct *work)
|
|
{
|
|
struct input_dev *dev = pdata->dev;
|
|
DPRINTK("s3c_keypad_qisda_workqueue 1\n");
|
|
input_report_key(dev,pdata->keycodes[0],1);
|
|
input_sync(dev);
|
|
|
|
msleep(200);
|
|
|
|
input_report_key(dev,pdata->keycodes[0],0);
|
|
input_sync(dev);
|
|
|
|
}
|
|
*/
|
|
|
|
/* Qisda, ShiYong Lin, 2009/09/10, Detect insertion source {*/
|
|
/*Leo*/
|
|
int IsWallCharger(void)
|
|
{
|
|
u32 i=0;
|
|
u32 read_pin=99, test_pin = 99;
|
|
udelay(1000);
|
|
|
|
if((readl(S3C2410_GPGDAT)&0x2)==0x2){
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 1); /* usb power enbale */
|
|
// s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPD13_OUTP);
|
|
// s3c2410_gpio_setpin(S3C2410_GPD13,1); /* usb power enbale */
|
|
|
|
/* if reset by sleep wakeup, control the retention I/O cell */
|
|
if (__raw_readl(S3C_RSTSTAT) & 0x8)
|
|
__raw_writel(__raw_readl(S3C_RSTCON)|(1<<16), S3C_RSTCON);
|
|
|
|
__raw_writel(__raw_readl(S3C2410_MISCCR)&~(1<<12), S3C2410_MISCCR);
|
|
__raw_writel(__raw_readl(S3C_PWRCFG)|(1<<4), S3C_PWRCFG);
|
|
__raw_writel((0<<2)|(1<<0), S3C_URSTCON);
|
|
|
|
udelay(1000);
|
|
__raw_writel((1<<2)|(0<<0), S3C_URSTCON);
|
|
__raw_writel((0<<2)|(0<<0), S3C_URSTCON);
|
|
__raw_writel((0<<3)|(0<<2)|(1<<1)|(0<<0), S3C_PHYCTRL);
|
|
__raw_writel((1<<31)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0), S3C_PHYPWR);
|
|
__raw_writel((0<<31)|(1<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
|
|
__raw_writel((1<<31)|(1<<4)|(1<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
|
|
}
|
|
|
|
for(i=0;i<10;i++) {
|
|
read_pin = __raw_readl(S3C_UDC_SYS_STATUS_REG)&0x60;
|
|
udelay(1000);
|
|
}
|
|
//Benq,Andy modify for wall charger recognize bugfix
|
|
//if( (read_pin != 0x60) ){
|
|
if( (read_pin != 0x60) && (read_pin != 0x0)){ //Benq, Andy add (read_pin != 0x0)
|
|
|
|
printk("usb\n");
|
|
#if defined(CONFIG_QISDA_E600_EVT2)|| defined(CONFIG_QISDA_QD060N00_DVT1_1)
|
|
if((readl(S3C2410_GPGDAT) &(1<<1))==0)
|
|
{
|
|
if((readl(S3C2410_GPHDAT) &&(1<<11))==0)
|
|
{
|
|
printk("3G Module off\n");
|
|
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0);
|
|
}
|
|
__raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
|
|
}
|
|
#endif
|
|
#if defined(CONFIG_QISDA_AS090B00_EVT1)||defined(CONFIG_QISDA_AS090B00_EVT1_1)||defined(CONFIG_QISDA_QD090B00_EVT1)
|
|
if((readl(S3C2410_GPGDAT) &(1<<1))==0)
|
|
{
|
|
if((readl(S3C2410_GPHDAT) &(1<<11))==0)
|
|
{
|
|
// printk("3G Module off\n");
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0);
|
|
}
|
|
__raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_PM_PLATFORM_POWER_SAVING
|
|
//{Benq,Andy add for USB power disable
|
|
printk("\nUSB_UDC_DEVICE_POWER_DOWN\n");
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb all power disable (USB_EN20)*/
|
|
//}Benq,Andy add for USB power disable
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
printk("wall charger\n");
|
|
#if defined(CONFIG_QISDA_E600_EVT2)||defined(CONFIG_QISDA_QD060N00_DVT1_1)
|
|
if((readl(S3C2410_GPGDAT) &(1<<1))==0)
|
|
{
|
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0);
|
|
|
|
__raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
|
|
}
|
|
#endif
|
|
#if defined(CONFIG_QISDA_AS090B00_EVT1)||defined(CONFIG_QISDA_AS090B00_EVT1_1)||defined(CONFIG_QISDA_QD090B00_EVT1)
|
|
if((readl(S3C2410_GPGDAT) &(1<<1))==0)
|
|
{
|
|
|
|
if((readl(S3C2410_GPHDAT) &(1<<11))==0)
|
|
{
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0);
|
|
}
|
|
__raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_PM_PLATFORM_POWER_SAVING
|
|
//{Benq,Andy add for USB power disable
|
|
printk("\nUSB_UDC_DEVICE_POWER_DOWN\n");
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb all power disable (USB_EN20)*/
|
|
//}Benq,Andy add for USB power disable
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
/*Leo*/
|
|
/* } Qisda, ShiYong Lin, 2009/09/10, Detect insertion source */
|
|
|
|
static void s3c_keypad_deal(struct input_dev *dev, u32 read_pin, int key)
|
|
{
|
|
if(read_pin){ //should be released
|
|
if(pdata->pressed[key]){
|
|
input_report_key(dev, pdata->keycodes[key], 0);
|
|
input_sync(dev);
|
|
pdata->pressed[key] = 0;
|
|
printk(" release: %d\n", pdata->keycodes[key]);
|
|
}
|
|
}
|
|
else{ //should be pressed
|
|
if(!pdata->pressed[key]){
|
|
input_report_key(dev, pdata->keycodes[key], 1);
|
|
input_sync(dev);
|
|
pdata->pressed[key] = 1;
|
|
printk(" press: %d\n", pdata->keycodes[key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static irqreturn_t s3c_pwrbtn_close_irq(int irq, void *id)
|
|
{
|
|
/* Qisda, ShiYong Lin, 2009/08/27, Implementing power btn behavior {*/
|
|
struct input_dev *dev = id;
|
|
u32 read_pin;
|
|
|
|
read_pin = readl(S3C2410_GPFDAT) & (1<<0);
|
|
#if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
|
|
s3c_keypad_deal(dev, read_pin, 8);
|
|
#elif defined(CONFIG_QISDA_QD090B00) || defined(CONFIG_QISDA_QD060N00_DVT1_1)
|
|
s3c_keypad_deal(dev, read_pin, 7);
|
|
#else
|
|
s3c_keypad_deal(dev, read_pin, 7);
|
|
#endif
|
|
|
|
#ifdef POWER_KEY_FOR_SYS_SHUTDOWN
|
|
//close system by letting P_KEEP low
|
|
#ifdef CONFIG_QISDA_BK060B00
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPD14, 0);
|
|
|
|
#else
|
|
s3c2410_gpio_setpin(S3C2410_GPG0, 0);
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG0, S3C2410_GPG0_OUTP);
|
|
#endif
|
|
#endif
|
|
/* } Qisda, ShiYong Lin, 2009/08/27, Implementing power btn behavior */
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
static void battery_status_handler(unsigned long data)
|
|
{
|
|
//struct input_dev *dev = id;
|
|
u32 read_pin;
|
|
u32 i, j;
|
|
|
|
printk("battery_status_handler\n");
|
|
|
|
read_pin = readl(S3C2410_GPGDAT) & (1<<1); /*joey add condition with usb/charger 20100128*/
|
|
if(read_pin!=0)
|
|
{
|
|
read_pin = readl(S3C2410_GPFDAT) & (0x01<<6);
|
|
|
|
#ifdef CONFIG_QISDA_QD090B00
|
|
if(read_pin)
|
|
{
|
|
//s3c_keypad_deal(dev, 0 , 25);
|
|
input_report_key(Message_dev,KEY_BATTERY,1);
|
|
input_sync(Message_dev);
|
|
printk("s3c_battery_status_irq, keypad_message_to_ap\n");
|
|
}
|
|
else
|
|
{
|
|
//s3c_keypad_deal(dev, 1 , 25);
|
|
input_report_key(Message_dev,KEY_BATTERY,0);
|
|
input_sync(Message_dev);
|
|
}
|
|
#else
|
|
if(read_pin)
|
|
{
|
|
//s3c_keypad_deal(dev, 0 , 27);
|
|
input_report_key(Message_dev,KEY_BATTERY,1);
|
|
input_sync(Message_dev);
|
|
printk("s3c_battery_status_irq, keypad_message_to_ap\n");
|
|
}
|
|
else
|
|
{
|
|
//s3c_keypad_deal(dev, 1 , 27);
|
|
input_report_key(Message_dev,KEY_BATTERY,0);
|
|
input_sync(Message_dev);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
enable_irq(IRQ_EINT6); /*joey add timer to avoid bouncing with usb in/out 20100127*/
|
|
}
|
|
|
|
static irqreturn_t s3c_battery_status_irq(int irq, void *id) /*joey add timer to avoid bouncing with usb in/out 20100127*/
|
|
{
|
|
printk("s3c_battery_status_irq, detecting\n");
|
|
disable_irq(IRQ_EINT6);
|
|
battery_status_timer.expires = jiffies + (HZ);
|
|
add_timer(&battery_status_timer);
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
|
|
static irqreturn_t s3c_cha_sta_irq(int irq, void *id)
|
|
{
|
|
/* Qisda , howard hsu, 2010/01/16 , op_mode-delay key event {*/
|
|
op_mode_delay_message_to_ap(0);//0:usb,1:sd
|
|
/* } Qisda , howard hsu, 2010/01/16 , op_mode-delay key event */
|
|
// Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event {
|
|
sleeping_cha_event = 1;
|
|
// Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event }
|
|
printk("s3c_cha_sta_irq\n");
|
|
disable_irq(IRQ_EINT9);
|
|
charger_source_timer.expires = jiffies + (HZ);
|
|
add_timer(&charger_source_timer);
|
|
return IRQ_HANDLED;
|
|
}
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
|
|
static irqreturn_t s3c_pwr_fail_irq(int irq, void *id)
|
|
{
|
|
printk("s3c_pwr_fail_irq, detecting\n");
|
|
disable_irq(IRQ_EINT13);
|
|
power_fail_timer.expires = jiffies + (HZ*3);
|
|
if(is_pwr_fail_timer_on == 0){
|
|
// printk("add_timer, detected\n");
|
|
add_timer(&power_fail_timer);
|
|
is_pwr_fail_timer_on = 1;
|
|
}
|
|
else{
|
|
// printk("mod_timer, detected\n");
|
|
mod_timer(&power_fail_timer, keypad_timer_qisda.expires);
|
|
}
|
|
return IRQ_HANDLED;
|
|
}
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
|
|
|
|
/* Qisda, ShiYong Lin, 2009/07/22, Implement function for RTC tick service {*/
|
|
void rtc_tick_keypad_message_to_ap (void)
|
|
{
|
|
input_report_key(Message_dev,KEY_TIMER_TICK,1);
|
|
input_sync(Message_dev);
|
|
input_report_key(Message_dev,KEY_TIMER_TICK,0);
|
|
input_sync(Message_dev);
|
|
printk("rtc_tick_keypad_message_to_ap, keypad_message_to_ap\n");
|
|
}
|
|
/*} Qisda, ShiYong Lin, 2009/07/22, Implement function for RTC tick service */
|
|
|
|
/* Qisda, Leo SJ Yang, 2009/10/26*/
|
|
/*send key code F6 1 when USB plugin*/
|
|
/*send key code F6 0 when USB unplug*/
|
|
/*send key code F6 0 when safely remove usb{*/
|
|
void USB_SaftRemove_keypad_message_to_ap(uint uiSleep)
|
|
{
|
|
if(uiSleep==1)
|
|
{
|
|
input_report_key(Message_dev,KEY_F6,1);
|
|
input_sync(Message_dev);
|
|
printk("Key-USB_PlugIn\n");
|
|
}
|
|
else
|
|
{
|
|
input_report_key(Message_dev,KEY_F6,0);
|
|
input_sync(Message_dev);
|
|
printk("Key-USB_PlugOut\n");
|
|
//printk("USB_SaftRemove_keypad_message_to_ap, USB_SaftRemove_keypad_message_to_ap press\n");
|
|
}
|
|
}
|
|
/*} Qisda, Leo SJ Yang, 2009/10/26*/
|
|
|
|
/*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
|
|
/* OP_MODE_DELAY_REQUEST is KEY_F9 */
|
|
/* Qisda , howard hsu, 20100208 , add type, 0 for usb, 1 for sd */
|
|
void op_mode_delay_message_to_ap(uint type)
|
|
{
|
|
static uint last_type=0;
|
|
if (type == last_type)
|
|
{
|
|
if(pdata!=NULL)
|
|
{
|
|
change_bit(OP_MODE_DELAY_REQUEST,pdata->dev->key);
|
|
}
|
|
}
|
|
last_type = type;
|
|
input_report_key(Message_dev,OP_MODE_DELAY_REQUEST,type);
|
|
input_sync(Message_dev);
|
|
}
|
|
/*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
|
|
/* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
|
|
// disable it first, wait integration test
|
|
#ifdef CONFIG_SD_SW_DEBOUNCE
|
|
void SD_Detect_keypad_message_to_ap(uint sd_on)
|
|
{
|
|
static uint last_sd_on=0;
|
|
if (last_sd_on == sd_on)
|
|
{
|
|
printk("\nCC--Repeat SDKey(%d)\n",sd_on);
|
|
if(pdata!=NULL)
|
|
{
|
|
change_bit(KEY_F5,pdata->dev->key);
|
|
}
|
|
}
|
|
last_sd_on = sd_on;
|
|
input_report_key(Message_dev,KEY_F5,sd_on);
|
|
input_sync(Message_dev);
|
|
printk("\nCC--SendSD Key(%d)\n",sd_on);
|
|
}
|
|
#endif /* CONFIG_SD_SW_DEBOUNCE */
|
|
/* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
|
|
|
|
/* Qisda, ShiYong Lin, 2009/09/08, Implement sleep message to AP {*/
|
|
void s3c_keypad_pm_sleep_message_to_ap (uint uiSleep)
|
|
{
|
|
if(uiSleep){
|
|
input_report_key(Message_dev,KEY_SLEEP,1);
|
|
input_sync(Message_dev);
|
|
}
|
|
else{
|
|
input_report_key(Message_dev,KEY_SLEEP,0);
|
|
input_sync(Message_dev);
|
|
}
|
|
}
|
|
/* } Qisda, ShiYong Lin, 2009/09/08, Implement sleep message to AP */
|
|
|
|
static void s3c_keypad_set_irq(struct input_dev *dev)
|
|
{
|
|
set_irq_type(IRQ_EINT0, 0x3);
|
|
request_irq(IRQ_EINT0, s3c_pwrbtn_close_irq,
|
|
SA_INTERRUPT, DEVICE_NAME, dev);
|
|
|
|
set_irq_type(IRQ_EINT6, 0x3); /*shiyong joey for asus 2009/12/15*/
|
|
request_irq(IRQ_EINT6, s3c_battery_status_irq,
|
|
SA_INTERRUPT, "s3c2410-battery status", dev);
|
|
|
|
set_irq_type(IRQ_EINT9, 0x3);
|
|
request_irq(IRQ_EINT9, s3c_cha_sta_irq,
|
|
SA_INTERRUPT, "s3c2410-charging status", dev);
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
|
|
if((readl(S3C2410_GPGDAT) & (1<<5)) == 0){
|
|
set_irq_type(IRQ_EINT13, IRQT_HIGH);
|
|
}
|
|
else{
|
|
set_irq_type(IRQ_EINT13, IRQT_LOW);
|
|
}
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
|
|
request_irq(IRQ_EINT13, s3c_pwr_fail_irq,
|
|
SA_INTERRUPT, "s3c2410-power fail status", dev);
|
|
}
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
|
|
static void charger_source_handler(unsigned long data)
|
|
{
|
|
u32 read_pin = 99;
|
|
printk("charger_source_handler_qisda\n");
|
|
read_pin = readl(S3C2410_GPGDAT) & (1<<1);
|
|
printk("GPG1 = %d\n", read_pin);
|
|
if(read_pin != 0){
|
|
//s3c2410_gpio_pullup(S3C2410_GPF6, 0); /*joey add to put floating GPF6 with usb 20100201*/
|
|
average_adc_value_keep1=9999; /*joey add to keep ADC will always return lower one 2009/12/28*/
|
|
average_adc_value_keep2=9999; /*joey add to keep ADC will always return lower one 2009/12/28*/
|
|
input_report_key(Message_dev, KEY_CHA_STA_UNPLUG, 0);
|
|
input_sync(Message_dev);
|
|
printk("usb or wallchager\n");
|
|
if(IsWallCharger()==0){
|
|
charging_source = 0;
|
|
input_report_key(Message_dev, KEY_CHA_STA_USB, 1);
|
|
input_sync(Message_dev);
|
|
printk("USB, EN2 = 0, EN1 = 1\n");
|
|
//EN2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPB0, 0);
|
|
//EN1
|
|
s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPB4, 1);
|
|
}
|
|
else
|
|
{
|
|
charging_source = 1;
|
|
input_report_key(Message_dev, KEY_CHA_STA_WALL_CHARGER, 1);
|
|
input_sync(Message_dev);
|
|
printk("Charger, EN2 = 1, EN1 = 0\n");
|
|
//EN2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPB0, 1);
|
|
//EN1
|
|
s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPB4, 0);
|
|
}
|
|
}
|
|
else{
|
|
//s3c2410_gpio_pullup(S3C2410_GPF6, 1); /*joey add to pull low GPF6 without usb 20100201*/
|
|
printk("nothing\n");
|
|
input_report_key(Message_dev, KEY_CHA_STA_UNPLUG, 1);
|
|
input_sync(Message_dev);
|
|
if(charging_source==0){
|
|
input_report_key(Message_dev, KEY_CHA_STA_USB, 0);
|
|
input_sync(Message_dev);
|
|
}
|
|
else{
|
|
input_report_key(Message_dev, KEY_CHA_STA_WALL_CHARGER, 0);
|
|
input_sync(Message_dev);
|
|
}
|
|
charging_source = 2;
|
|
printk("EN2 = 0, EN1 = 1\n");
|
|
//EN2
|
|
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPB0, 0);
|
|
//EN1
|
|
s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
|
|
s3c2410_gpio_setpin(S3C2410_GPB4, 1);
|
|
|
|
#ifdef CONFIG_PM_PLATFORM_POWER_SAVING
|
|
//{Benq,Andy add for disable USB power
|
|
printk("\nUSB_UDC_DEVICE_POWER_DOWN\n");
|
|
s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
|
|
s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb all power disable (USB33 & USB12)*/
|
|
//}Benq,Andy add for disable USB power
|
|
#endif
|
|
}
|
|
enable_irq(IRQ_EINT9);
|
|
}
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
|
|
static void power_fail_handler(unsigned long data)
|
|
{
|
|
// printk("power_fail_handler\n");
|
|
schedule_work(&power_fail_workq);
|
|
}
|
|
|
|
static void power_fail_workqueue(struct work_struct *work)
|
|
{
|
|
u32 test_pin, i;
|
|
u32 read_pin = readl(S3C2410_GPGDAT) & (1<<5);
|
|
msleep(1);
|
|
// printk("power_fail_workqueue, read_pin = %d\n",read_pin);
|
|
for(i = 0; i <100; i++){
|
|
test_pin = readl(S3C2410_GPGDAT) & (1<<5);
|
|
msleep(1);
|
|
if(read_pin != test_pin){
|
|
printk("read_pin != test_pin\n");
|
|
is_pwr_fail_timer_on = 0;
|
|
enable_irq(IRQ_EINT13);
|
|
return;
|
|
}
|
|
msleep(1);
|
|
}
|
|
// printk("power_fail_workqueue test_pin = %d\n", read_pin);
|
|
if(read_pin == 0){
|
|
// printk("send KEY_BATTERY_FAIL trigger, 0\n");
|
|
set_irq_type(IRQ_EINT13, IRQT_HIGH);
|
|
#if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
|
|
s3c_keypad_deal(Message_dev, 0, 12);
|
|
#elif defined(CONFIG_QISDA_QD090B00)
|
|
s3c_keypad_deal(Message_dev, 0, 22);
|
|
#elif CONFIG_QISDA_QD060N00_DVT1_1
|
|
s3c_keypad_deal(Message_dev, 0, 24);
|
|
#else
|
|
s3c_keypad_deal(Message_dev, 0, 12);
|
|
#endif
|
|
}
|
|
else{
|
|
// printk("send KEY_BATTERY_FAIL trigger, 1\n");
|
|
set_irq_type(IRQ_EINT13, IRQT_LOW);
|
|
#if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
|
|
s3c_keypad_deal(Message_dev, 1, 12);
|
|
#elif defined(CONFIG_QISDA_QD090B00)
|
|
s3c_keypad_deal(Message_dev, 1, 22);
|
|
#elif CONFIG_QISDA_QD060N00_DVT1_1
|
|
s3c_keypad_deal(Message_dev, 1, 24);
|
|
#else
|
|
s3c_keypad_deal(Message_dev, 1, 12);
|
|
#endif
|
|
}
|
|
is_pwr_fail_timer_on = 0;
|
|
enable_irq(IRQ_EINT13);
|
|
return;
|
|
}
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
|
|
static void keypad_timer_handler_qisda(unsigned long data)
|
|
{
|
|
u32 read_pin;
|
|
static u32 headphonr_insert;
|
|
static int headphonr_insert_counter=2;
|
|
u32 read_tilt;
|
|
static u32 tilt_status_previous;
|
|
static int tilt_counter=3;
|
|
static u32 mmc_status_previous = 0xF;
|
|
static int mmc_counter=16;
|
|
|
|
//struct s3c_keypad_qisda *pdata = (struct s3c_keypad_qisda *)data;
|
|
pdata = (struct s3c_keypad_qisda *)data;
|
|
struct input_dev *dev = pdata->dev;
|
|
|
|
#ifdef CONFIG_QISDA_AS090B00
|
|
read_pin = readl(S3C2410_GPFDAT);
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 0); // Page down
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<1)), 21); // SD card
|
|
|
|
if(headphonr_insert != (read_pin & (1<<4))){ // Headphone
|
|
if(headphonr_insert_counter != 0){
|
|
headphonr_insert_counter --;
|
|
}
|
|
else{
|
|
if(read_pin & (1<<4)){
|
|
//printk("Earphone insert!!!!!!!!!!!!!!!!\n");
|
|
input_report_switch(dev, SW_HEADPHONE_INSERT, 1);
|
|
input_sync(dev);
|
|
}
|
|
else {
|
|
//printk("Earphone remove!!!!!!!!!!!!!!!!!!!!!\n");
|
|
input_report_switch(dev, SW_HEADPHONE_INSERT, 0);
|
|
input_sync(dev);
|
|
}
|
|
|
|
headphonr_insert = read_pin & (1<<4);
|
|
headphonr_insert_counter = 2;
|
|
}
|
|
}
|
|
else{
|
|
headphonr_insert_counter = 2;
|
|
}
|
|
|
|
read_pin = readl(S3C2410_GPGDAT);
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 6); // Function
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 1); // Page up
|
|
|
|
read_pin = readl(S3C2410_GPHDAT);
|
|
s3c_keypad_deal(dev, read_pin & 1<<5, 2); // Volume down
|
|
s3c_keypad_deal(dev, read_pin & 1<<4, 3); // Volume up
|
|
|
|
read_pin = readl(S3C2410_GPDDAT);
|
|
s3c_keypad_deal(dev, read_pin & 1<<14, 5); // Menu
|
|
s3c_keypad_deal(dev, read_pin & 1<<15, 7); // Return
|
|
read_tilt = (readl(S3C2410_GPDDAT) & (0x3<<10)) >> 10;
|
|
|
|
if(tilt_status_previous != read_tilt){
|
|
if(tilt_counter != 0){
|
|
tilt_counter--;
|
|
}
|
|
else{
|
|
if(read_tilt == QISDA_TILT_270){
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 18);
|
|
s3c_keypad_deal(dev, 0, 19);
|
|
}
|
|
else if(read_tilt == QISDA_TILT_90){
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 1, 18);
|
|
s3c_keypad_deal(dev, 1, 19);
|
|
s3c_keypad_deal(dev, 0, 17);
|
|
}
|
|
else if(read_tilt == QISDA_TILT_180){
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 19);
|
|
s3c_keypad_deal(dev, 0, 18);
|
|
}
|
|
else{ //QISDA_TILT_0
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 18);
|
|
s3c_keypad_deal(dev, 1, 19);
|
|
s3c_keypad_deal(dev, 0, 16);
|
|
}
|
|
|
|
tilt_status_previous = read_tilt;
|
|
tilt_counter = 3;
|
|
}
|
|
}
|
|
else{
|
|
tilt_counter = 3;
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 18);
|
|
s3c_keypad_deal(dev, 1, 19);
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_QISDA_QD090B00
|
|
read_pin = readl(S3C2410_GPFDAT);
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 2); // Page down
|
|
/* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
|
|
#ifndef CONFIG_SD_SW_DEBOUNCE
|
|
if(mmc_status_previous != (read_pin & (0x1<<1))){
|
|
if(mmc_counter != 0){
|
|
mmc_counter--;
|
|
}
|
|
else{
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<1)), 16); // SD card
|
|
mmc_status_previous = (read_pin & (0x1<<1));
|
|
mmc_counter=16;
|
|
}
|
|
|
|
}
|
|
else{
|
|
mmc_counter=16;
|
|
}
|
|
#endif /* CONFIG_SD_SW_DEBOUNCE */
|
|
/* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
|
|
|
|
if(headphonr_insert != (read_pin & (1<<4))){ // Headphone
|
|
if(headphonr_insert_counter != 0){
|
|
headphonr_insert_counter --;
|
|
}
|
|
else{
|
|
if(read_pin & (1<<4)){
|
|
//printk("Earphone insert!!!!!!!!!!!!!!!!\n");
|
|
input_report_switch(dev, SW_HEADPHONE_INSERT, 1);
|
|
input_sync(dev);
|
|
}
|
|
else {
|
|
//printk("Earphone remove!!!!!!!!!!!!!!!!!!!!!\n");
|
|
input_report_switch(dev, SW_HEADPHONE_INSERT, 0);
|
|
input_sync(dev);
|
|
}
|
|
|
|
headphonr_insert = read_pin & (1<<4);
|
|
headphonr_insert_counter = 2;
|
|
}
|
|
}
|
|
else{
|
|
headphonr_insert_counter = 2;
|
|
}
|
|
|
|
read_pin = readl(S3C2410_GPGDAT);
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 8); // Refresh
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 0); // Menu
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 3); // Page up
|
|
|
|
/*Qisda , wenny cheng , 20091224 , board id info {*/
|
|
//if(hw_version_for_keypad){
|
|
if(board_id !=QD090B00_S02)
|
|
{
|
|
//new
|
|
s3c_keypad_deal(dev, read_pin & 1<<2, 1); // Search
|
|
s3c_keypad_deal(dev, read_pin & 1<<3, 4); // Return
|
|
}
|
|
/*Qisda , wenny cheng , 20091224 , board id info }*/
|
|
|
|
read_pin = readl(S3C2410_GPHDAT);
|
|
s3c_keypad_deal(dev, read_pin & 1<<5, 5); // Volume down
|
|
s3c_keypad_deal(dev, read_pin & 1<<4, 6); // Volume up
|
|
|
|
read_pin = readl(S3C2410_GPDDAT);
|
|
|
|
/*Qisda , wenny cheng , 20091224 , board id info {*/
|
|
//if(!hw_version_for_keypad){
|
|
if(board_id ==QD090B00_S02)
|
|
{
|
|
//old
|
|
s3c_keypad_deal(dev, read_pin & 1<<14, 1); // Search
|
|
s3c_keypad_deal(dev, read_pin & 1<<15, 4); // Return
|
|
}
|
|
/*Qisda , wenny cheng , 20091224 , board id info }*/
|
|
|
|
read_tilt = (read_pin & (0x3<<10)) >> 10;
|
|
if(tilt_status_previous != read_tilt){
|
|
if(tilt_counter != 0){
|
|
tilt_counter--;
|
|
}
|
|
else{
|
|
if(read_tilt == QISDA_TILT_270){
|
|
s3c_keypad_deal(dev, 1, 12);
|
|
s3c_keypad_deal(dev, 1, 13);
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 0, 15);
|
|
}
|
|
else if(read_tilt == QISDA_TILT_90){
|
|
s3c_keypad_deal(dev, 1, 12);
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 0, 13);
|
|
}
|
|
else if(read_tilt == QISDA_TILT_180){
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 1, 12);
|
|
s3c_keypad_deal(dev, 1, 13);
|
|
s3c_keypad_deal(dev, 0, 14);
|
|
}
|
|
else{ //QISDA_TILT_0
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 1, 13);
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 0, 12);
|
|
}
|
|
tilt_status_previous = read_tilt;
|
|
tilt_counter = 3;
|
|
}
|
|
}
|
|
else{
|
|
tilt_counter = 3;
|
|
s3c_keypad_deal(dev, 1, 12);
|
|
s3c_keypad_deal(dev, 1, 13);
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_QISDA_QD060B00
|
|
read_pin = readl(S3C2410_GPFDAT);
|
|
#ifdef QISDA_E600
|
|
#ifdef CONFIG_QISDA_BQ060B00_DVT
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 2); // Page down
|
|
#else
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 4); // Back
|
|
#endif
|
|
#endif
|
|
#ifdef QISDA_L600
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 13); // Right
|
|
#endif
|
|
|
|
/* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
|
|
#ifndef CONFIG_SD_SW_DEBOUNCE
|
|
if(mmc_status_previous != (read_pin & (0x1<<1))){
|
|
if(mmc_counter != 0){
|
|
mmc_counter--;
|
|
}
|
|
else{
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<1)), 18); // SD card
|
|
mmc_status_previous = (read_pin & (0x1<<1));
|
|
printk("Key-SD_CHANGE(%d)\n",mmc_status_previous);
|
|
mmc_counter=16;
|
|
}
|
|
}
|
|
else{
|
|
mmc_counter=16;
|
|
}
|
|
#endif /* CONFIG_SD_SW_DEBOUNCE */
|
|
/* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
|
|
|
|
if(headphonr_insert != (read_pin & (1<<4))){ // Headphone
|
|
if(headphonr_insert_counter != 0){
|
|
headphonr_insert_counter --;
|
|
}
|
|
else{
|
|
if(read_pin & (1<<4)){
|
|
//printk("Earphone removed\n");
|
|
input_report_switch(dev, SW_HEADPHONE_INSERT, 0);
|
|
input_sync(dev);
|
|
}
|
|
else {
|
|
//printk("Earphone inserted\n");
|
|
input_report_switch(dev, SW_HEADPHONE_INSERT, 1);
|
|
input_sync(dev);
|
|
}
|
|
|
|
headphonr_insert = read_pin & (1<<4);
|
|
headphonr_insert_counter = 2;
|
|
}
|
|
}
|
|
else{
|
|
headphonr_insert_counter = 2;
|
|
}
|
|
|
|
read_pin = readl(S3C2410_GPGDAT);
|
|
#ifdef QISDA_E600
|
|
#ifdef CONFIG_QISDA_BQ060B00_DVT
|
|
//s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 8); // Refresh
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 1); // Search
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 3); // Page up
|
|
if(board_id ==BQ060B00_A02)
|
|
{
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<3)), 0); // Menu
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 4); // Back
|
|
}
|
|
#else
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 3); // Page up
|
|
if(board_id ==QD060B00_A02) {
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<3)), 0); // Menu
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 2); // Page down
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 1); // Search
|
|
|
|
} else if(board_id == QD060B00_A01_And_Before){
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 6); // Volume
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 8); // Refresh
|
|
|
|
}
|
|
#endif
|
|
#endif
|
|
#ifdef QISDA_L600
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 11); // Down
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 12); // Left
|
|
#endif
|
|
|
|
#ifdef CONFIG_QISDA_BK060B00
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<0)), 12); // LEFT
|
|
s3c_keypad_deal(dev, (read_pin & (0x1<<2)), 13); // RIGHT
|
|
#endif
|
|
|
|
read_pin = readl(S3C2410_GPHDAT);
|
|
#ifdef QISDA_E600
|
|
#ifdef CONFIG_QISDA_BQ060B00_DVT
|
|
s3c_keypad_deal(dev, read_pin & 1<<4, 5); // Volume down
|
|
s3c_keypad_deal(dev, read_pin & 1<<5, 6); // Volume up
|
|
#else
|
|
// Qisda Jonas modify for keypad rework 20100104
|
|
if(board_id ==QD060B00_A02) {
|
|
s3c_keypad_deal(dev, read_pin & 1<<5, 8); // Refresh
|
|
} else if (board_id == QD060B00_A01_And_Before){
|
|
s3c_keypad_deal(dev, read_pin & 1<<5, 1); // Search
|
|
}
|
|
// Qisda Jonas modify for keypad rework
|
|
#endif
|
|
#endif
|
|
#ifdef QISDA_L600
|
|
s3c_keypad_deal(dev, read_pin & 1<<4, 9); // OK
|
|
s3c_keypad_deal(dev, read_pin & 1<<5, 10); // Up
|
|
#endif
|
|
|
|
|
|
read_pin = readl(S3C2410_GPDDAT);
|
|
#ifdef QISDA_E600
|
|
#ifdef CONFIG_QISDA_BQ060B00_DVT
|
|
// Qisda Jonas modify for keypad rework 20100103
|
|
if(board_id ==BQ060B00_A01_And_Before)
|
|
{
|
|
s3c_keypad_deal(dev, read_pin & 1<<14, 0); // Menu
|
|
s3c_keypad_deal(dev, read_pin & 1<<15, 4); // Back
|
|
}
|
|
#else
|
|
// Qisda Jonas modify for keypad rework
|
|
if(board_id == QD060B00_A02) {
|
|
s3c_keypad_deal(dev, read_pin & 1<<15, 6); // Volumn
|
|
} else if(board_id == QD060B00_A01_And_Before){
|
|
s3c_keypad_deal(dev, read_pin & 1<<14, 0); // Menu
|
|
s3c_keypad_deal(dev, read_pin & 1<<15, 2); // Page down
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
#ifdef QISDA_L600
|
|
s3c_keypad_deal(dev, read_pin & 1<<15, 4); // Back
|
|
#endif
|
|
|
|
//Benq,Aaron: no tilt sensor in Plato
|
|
#ifndef CONFIG_QISDA_BQ060B00_DVT
|
|
|
|
#ifdef CONFIG_QISDA_BK060B00
|
|
|
|
read_pin = readl(S3C2410_GPGDAT);
|
|
read_tilt = (read_pin & (0x3<<3)) >> 3;
|
|
#else
|
|
read_tilt = (read_pin & (0x3<<10)) >> 10;
|
|
#endif
|
|
|
|
if(tilt_status_previous != read_tilt){
|
|
if(tilt_counter != 0){
|
|
tilt_counter--;
|
|
}
|
|
else{
|
|
if(read_tilt == QISDA_TILT_270){
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 0, 17);
|
|
}
|
|
else if(read_tilt == QISDA_TILT_90){
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 0, 15);
|
|
}
|
|
else if(read_tilt == QISDA_TILT_180){
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 0, 16);
|
|
}
|
|
else{ //QISDA_TILT_0
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 0, 14);
|
|
}
|
|
tilt_status_previous = read_tilt;
|
|
tilt_counter = 3;
|
|
}
|
|
}
|
|
else{
|
|
tilt_counter = 3;
|
|
s3c_keypad_deal(dev, 1, 14);
|
|
s3c_keypad_deal(dev, 1, 15);
|
|
s3c_keypad_deal(dev, 1, 16);
|
|
s3c_keypad_deal(dev, 1, 17);
|
|
}
|
|
#endif // #ifndef CONFIG_QISDA_BQ060B00_DVT
|
|
#endif
|
|
|
|
if (is_timer_on_qisda == FALSE) {
|
|
add_timer(&keypad_timer_qisda);
|
|
is_timer_on_qisda = TRUE;
|
|
} else {
|
|
keypad_timer_qisda.expires = jiffies + (HZ/8);
|
|
mod_timer(&keypad_timer_qisda,keypad_timer_qisda.expires);
|
|
}
|
|
|
|
if(!keypad_set_irq){
|
|
s3c_keypad_set_irq(pdata->dev);
|
|
keypad_set_irq = TRUE;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int __init s3c_keypad_qisda_probe(struct platform_device *pdev)
|
|
{
|
|
int ret=0;
|
|
int i;
|
|
struct input_dev *input_dev;
|
|
struct s3c_keypad_qisda *s3c_keypad_qisda;
|
|
|
|
DPRINTK("s3c_keypad_qisda_probe for Qisda eBook\n");
|
|
|
|
keypad_port_initialize();
|
|
|
|
s3c_keypad_qisda = kzalloc(sizeof(struct s3c_keypad_qisda), GFP_KERNEL);
|
|
input_dev = input_allocate_device();
|
|
|
|
if (!s3c_keypad_qisda || !input_dev) {
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
platform_set_drvdata(pdev, s3c_keypad_qisda);
|
|
s3c_keypad_qisda->dev = input_dev;
|
|
|
|
/* create and register the input driver */
|
|
set_bit(EV_KEY, input_dev->evbit);
|
|
//set_bit(EV_REP, input_dev->evbit);
|
|
set_bit(EV_SW, input_dev->evbit);
|
|
set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
|
|
|
|
for(i=0; i<MAX_KEYPAD_QISDA; i++){
|
|
s3c_keypad_qisda->keycodes[i] = keypad_keycode_qisda[i];
|
|
s3c_keypad_qisda->pressed[i] = 0;
|
|
set_bit(s3c_keypad_qisda->keycodes[i] & KEY_MAX, input_dev->keybit);
|
|
}
|
|
|
|
input_dev->name = DEVICE_NAME;
|
|
input_dev->phys = "s3c-keypad-qisda/input0";
|
|
input_dev->cdev.dev = &pdev->dev;
|
|
input_dev->private = s3c_keypad_qisda;
|
|
|
|
input_dev->id.bustype = BUS_HOST;
|
|
input_dev->id.vendor = 0x0001;
|
|
input_dev->id.product = 0x0001;
|
|
input_dev->id.version = 0x0001;
|
|
|
|
input_dev->keycode = keypad_keycode_qisda;
|
|
|
|
input_register_device(input_dev);
|
|
|
|
/* Scan timer init */
|
|
init_timer(&keypad_timer_qisda);
|
|
keypad_timer_qisda.function = keypad_timer_handler_qisda;
|
|
keypad_timer_qisda.data = (unsigned long)s3c_keypad_qisda;
|
|
keypad_timer_qisda.expires = jiffies + (HZ*10);
|
|
|
|
if (is_timer_on_qisda == FALSE) {
|
|
add_timer(&keypad_timer_qisda);
|
|
is_timer_on_qisda = TRUE;
|
|
} else {
|
|
mod_timer(&keypad_timer_qisda,keypad_timer_qisda.expires);
|
|
}
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
|
|
init_timer(&charger_source_timer);
|
|
charger_source_timer.function = charger_source_handler;
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
|
|
/*joey add timer to avoid bouncing with usb in/out 20100127*/
|
|
init_timer(&battery_status_timer);
|
|
battery_status_timer.function = battery_status_handler;
|
|
|
|
/* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
|
|
init_timer(&power_fail_timer);
|
|
power_fail_timer.function = power_fail_handler;
|
|
INIT_WORK(&power_fail_workq, power_fail_workqueue);
|
|
/* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
|
|
|
|
//initial work queue
|
|
//INIT_WORK(&wqReadData,s3c_keypad_qisda_workqueue);
|
|
|
|
//{Benq,Andy add for USB cable unplug bugfix
|
|
//If boot up with USB cable, s3c_adc_init will set charging_source to 0, without sending input_report_key,
|
|
//so recheck is needed when initializing keypad, setting KEY_CHA_STA_USB to 1
|
|
if( charging_source == 0 ){
|
|
if ( ((readl(S3C2410_GPGDAT) & (1<<1)) != 0) && (IsWallCharger() == 0) )
|
|
input_report_key(s3c_keypad_qisda->dev, KEY_CHA_STA_USB, 1);
|
|
}
|
|
//}Benq,Andy add for USB cable unplug bugfix
|
|
|
|
DPRINTK("s3c_keypad_qisda_probe finished\n");
|
|
|
|
/* Qisda, ShiYong Lin, 2009/08/27, Implement for message for AP {*/
|
|
Message_dev = input_dev;
|
|
/* } Qisda, ShiYong Lin, 2009/08/27, Implement for message for AP */
|
|
return 0;
|
|
out:
|
|
input_unregister_device(input_dev);
|
|
kfree(s3c_keypad_qisda);
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
static int s3c_keypad_qisda_remove(struct platform_device *pdev)
|
|
{
|
|
struct input_dev *input_dev = platform_get_drvdata(pdev);
|
|
del_timer(&keypad_timer_qisda);
|
|
input_unregister_device(input_dev);
|
|
kfree(pdev->dev.platform_data);
|
|
DPRINTK("Removed");
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_PM
|
|
static int s3c_keypad_qisda_suspend(struct platform_device *dev, pm_message_t state)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int s3c_keypad_qisda_resume(struct platform_device *dev)
|
|
{
|
|
keypad_port_initialize();
|
|
return 0;
|
|
}
|
|
#else
|
|
#define s3c_keypad_suspend_qisda NULL
|
|
#define s3c_keypad_resume_qisda NULL
|
|
#endif /* CONFIG_PM */
|
|
|
|
static struct platform_driver s3c_keypad_qisda_driver = {
|
|
.probe = s3c_keypad_qisda_probe,
|
|
.remove = s3c_keypad_qisda_remove,
|
|
.suspend = s3c_keypad_qisda_suspend,
|
|
.resume = s3c_keypad_qisda_resume,
|
|
.driver = {
|
|
.owner = THIS_MODULE,
|
|
.name = DEVICE_NAME,
|
|
},
|
|
};
|
|
|
|
static int __init s3c_keypad_qisda_init(void) { return platform_driver_register(&s3c_keypad_qisda_driver); }
|
|
static void __exit s3c_keypad_qisda_exit(void) { platform_driver_unregister(&s3c_keypad_qisda_driver); }
|
|
module_init(s3c_keypad_qisda_init);
|
|
module_exit(s3c_keypad_qisda_exit);
|
|
MODULE_AUTHOR("Tony YC Huang");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("KeyPad interface for Samsung S3C 2416,Qisda eBook");
|
|
|
|
// Qisda Tony 090324, add keypad ]
|