diff options
Diffstat (limited to 'drivers/accessory/sec_keyboard.c')
-rw-r--r-- | drivers/accessory/sec_keyboard.c | 46 |
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; |