sunkbd
schedule_work(&sunkbd->tq);
sunkbd->reset = -1;
sunkbd->layout = -1;
if (!sunkbd->enabled)
if (sunkbd->keycode[data & SUNKBD_KEY]) {
input_report_key(sunkbd->dev,
sunkbd->keycode[data & SUNKBD_KEY],
input_sync(sunkbd->dev);
struct sunkbd *sunkbd = input_get_drvdata(dev);
serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
serio_write(sunkbd->serio,
serio_write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
serio_write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
static int sunkbd_initialize(struct sunkbd *sunkbd)
sunkbd->reset = -2;
serio_write(sunkbd->serio, SUNKBD_CMD_RESET);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
if (sunkbd->reset < 0)
sunkbd->type = sunkbd->reset;
if (sunkbd->type == 4) { /* Type 4 keyboard */
sunkbd->layout = -2;
serio_write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
wait_event_interruptible_timeout(sunkbd->wait,
sunkbd->layout >= 0, HZ / 4);
if (sunkbd->layout < 0)
if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK)
sunkbd->type = 5;
static void sunkbd_set_leds_beeps(struct sunkbd *sunkbd)
serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
serio_write(sunkbd->serio,
(!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) |
(!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) |
!!test_bit(LED_NUML, sunkbd->dev->led));
serio_write(sunkbd->serio,
SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
serio_write(sunkbd->serio,
SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq);
wait_event_interruptible_timeout(sunkbd->wait,
sunkbd->reset >= 0 || !sunkbd->enabled,
if (sunkbd->reset >= 0 && sunkbd->enabled)
sunkbd_set_leds_beeps(sunkbd);
static void sunkbd_enable(struct sunkbd *sunkbd, bool enable)
scoped_guard(serio_pause_rx, sunkbd->serio)
sunkbd->enabled = enable;
wake_up_interruptible(&sunkbd->wait);
cancel_work_sync(&sunkbd->tq);
struct sunkbd *sunkbd;
sunkbd = kzalloc_obj(*sunkbd);
if (!sunkbd || !input_dev)
sunkbd->serio = serio;
sunkbd->dev = input_dev;
init_waitqueue_head(&sunkbd->wait);
INIT_WORK(&sunkbd->tq, sunkbd_reinit);
snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
serio_set_drvdata(serio, sunkbd);
if (sunkbd_initialize(sunkbd) < 0) {
snprintf(sunkbd->name, sizeof(sunkbd->name),
"Sun Type %d keyboard", sunkbd->type);
memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
input_dev->name = sunkbd->name;
input_dev->phys = sunkbd->phys;
input_dev->id.product = sunkbd->type;
input_set_drvdata(input_dev, sunkbd);
input_dev->keycode = sunkbd->keycode;
__set_bit(sunkbd->keycode[i], input_dev->keybit);
sunkbd_enable(sunkbd, true);
err = input_register_device(sunkbd->dev);
fail4: sunkbd_enable(sunkbd, false);
kfree(sunkbd);
struct sunkbd *sunkbd = serio_get_drvdata(serio);
sunkbd_enable(sunkbd, false);
input_unregister_device(sunkbd->dev);
kfree(sunkbd);
struct sunkbd *sunkbd = serio_get_drvdata(serio);
if (sunkbd->reset <= -1) {
sunkbd->reset = data;
wake_up_interruptible(&sunkbd->wait);
if (sunkbd->layout == -1) {
sunkbd->layout = data;
wake_up_interruptible(&sunkbd->wait);
if (sunkbd->enabled)