aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/accessory/sec_keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/accessory/sec_keyboard.c')
-rw-r--r--drivers/accessory/sec_keyboard.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/accessory/sec_keyboard.c b/drivers/accessory/sec_keyboard.c
index cc89c0c..3e7556f 100644
--- a/drivers/accessory/sec_keyboard.c
+++ b/drivers/accessory/sec_keyboard.c
@@ -44,6 +44,26 @@ static void sec_keyboard_remapkey(struct work_struct *work)
data->remap_key = 0;
}
+static void sec_keyboard_ack(struct work_struct *work)
+{
+ unsigned int ackcode = 0;
+ char *envp[3];
+ struct sec_keyboard_drvdata *data = container_of(work,
+ struct sec_keyboard_drvdata, ack_dwork.work);
+
+ if (data->ack_code) {
+ ackcode = data->ack_code;
+ sec_keyboard_tx(data, ackcode);
+ }
+
+ if (ackcode == 0x68)
+ data->univ_kbd_dock = true;
+
+ printk(KERN_DEBUG "[Keyboard] Ack code to KBD 0x%x\n", ackcode);
+
+ data->noti_univ_kbd_dock(data->ack_code);
+}
+
static void release_all_keys(struct sec_keyboard_drvdata *data)
{
int i;
@@ -105,7 +125,16 @@ static void sec_keyboard_process_data(
data->pressed[scan_code] = true;
schedule_delayed_work(&data->remap_dwork, HZ/3);
break;
-
+ case 0x68:
+ case 0x69:
+ case 0x6a:
+ case 0x6b:
+ case 0x6c:
+ data->ack_code = scan_code;
+ schedule_delayed_work(&data->ack_dwork, HZ/200);
+ printk(KERN_DEBUG "[Keyboard] scan_code %d Received.\n",
+ scan_code);
+ break;
case 0xc5:
case 0xc8:
keycode = (scan_code & 0x7f);
@@ -163,11 +192,15 @@ static int check_keyboard_dock(struct sec_keyboard_callbacks *cb, bool val)
return 0;
}
}
+ /* To block acc_power enable in LPM mode */
+ if ((data->tx_ready != true) && (val == true))
+ return 0 ;
}
- if (!val)
+ if (!val) {
data->dockconnected = false;
- else {
+ data->univ_kbd_dock = false;
+ } else {
cancel_delayed_work_sync(&data->power_dwork);
/* wakeup by keyboard dock */
if (data->pre_connected) {
@@ -304,7 +337,8 @@ static void keyboard_early_suspend(struct early_suspend *early_sus)
msleep(20);
*/
release_all_keys(data);
- sec_keyboard_tx(data, 0x10); /* the idle mode */
+ if (data->univ_kbd_dock == false)
+ sec_keyboard_tx(data, 0x10); /* the idle mode */
}
}
@@ -350,16 +384,19 @@ static int __devinit sec_keyboard_probe(struct platform_device *pdev)
ddata->led_on = false;
ddata->dockconnected = false;
ddata->pre_connected = false;
+ ddata->univ_kbd_dock = false;
ddata->remap_key = 0;
ddata->kl = UNKOWN_KEYLAYOUT;
ddata->callbacks.check_keyboard_dock = check_keyboard_dock;
if (pdata->register_cb)
pdata->register_cb(&ddata->callbacks);
+ ddata->noti_univ_kbd_dock = pdata->noti_univ_kbd_dock;
memcpy(ddata->keycode, sec_keycodes, sizeof(sec_keycodes));
INIT_DELAYED_WORK(&ddata->remap_dwork, sec_keyboard_remapkey);
INIT_DELAYED_WORK(&ddata->power_dwork, sec_keyboard_power);
+ INIT_DELAYED_WORK(&ddata->ack_dwork, sec_keyboard_ack);
platform_set_drvdata(pdev, ddata);
input_set_drvdata(input, ddata);
@@ -443,6 +480,7 @@ err_input_allocate_device:
input_free_device(input);
del_timer_sync(&ddata->remap_dwork.timer);
del_timer_sync(&ddata->power_dwork.timer);
+ del_timer_sync(&ddata->ack_dwork.timer);
err_free_mem:
kfree(ddata);
return error;