static void sunkbd_disconnect(struct serio *serio) { struct sunkbd *sunkbd = serio_get_drvdata(serio); sunkbd_enable(sunkbd, 0); input_unregister_device(sunkbd->dev); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(sunkbd); }
static void dock_keyboard_serio_disconnect(struct serio *serio) { struct dock_keyboard_data *data = serio_get_drvdata(serio); pr_debug("kbd: serio_disconnect\n"); data->serio = NULL; serio_close(serio); serio_set_drvdata(serio, NULL); }
static void vsxxxaa_disconnect (struct serio *serio) { struct vsxxxaa *mouse = serio_get_drvdata (serio); serio_close (serio); serio_set_drvdata (serio, NULL); input_unregister_device (mouse->dev); kfree (mouse); }
static void mtouch_disconnect(struct serio *serio) { struct mtouch* mtouch = serio_get_drvdata(serio); input_get_device(mtouch->dev); input_unregister_device(mtouch->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(mtouch->dev); kfree(mtouch); }
static void hampshire_disconnect(struct serio *serio) { struct hampshire *phampshire = serio_get_drvdata(serio); input_get_device(phampshire->dev); input_unregister_device(phampshire->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(phampshire->dev); kfree(phampshire); }
static void rain_disconnect(struct serio *serio) { struct rain *rain = serio_get_drvdata(serio); cancel_work_sync(&rain->work); cec_unregister_adapter(rain->adap); dev_info(&serio->dev, "disconnected\n"); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(rain); }
static void pm_disconnect(struct serio *serio) { struct pm *pm = serio_get_drvdata(serio); serio_close(serio); input_unregister_device(pm->dev); kfree(pm); serio_set_drvdata(serio, NULL); }
static void touchit213_disconnect(struct serio *serio) { struct touchit213 *touchit213 = serio_get_drvdata(serio); input_get_device(touchit213->dev); input_unregister_device(touchit213->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(touchit213->dev); kfree(touchit213); }
/* * fujitsu_disconnect() is the opposite of fujitsu_connect() */ static void fujitsu_disconnect(struct serio *serio) { struct fujitsu *fujitsu = serio_get_drvdata(serio); input_get_device(fujitsu->dev); input_unregister_device(fujitsu->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(fujitsu->dev); kfree(fujitsu); }
static void tsc_disconnect(struct serio *serio) { struct tsc_ser *ptsc = serio_get_drvdata(serio); serio_close(serio); input_unregister_device(ptsc->dev); kfree(ptsc); serio_set_drvdata(serio, NULL); }
static void inexio_disconnect(struct serio *serio) { struct inexio* pinexio = serio_get_drvdata(serio); input_get_device(pinexio->dev); input_unregister_device(pinexio->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(pinexio->dev); kfree(pinexio); }
static void gunze_disconnect(struct serio *serio) { struct gunze *gunze = serio_get_drvdata(serio); input_get_device(gunze->dev); input_unregister_device(gunze->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(gunze->dev); kfree(gunze); }
static void hil_dev_disconnect(struct serio *serio) { struct hil_dev *dev = serio_get_drvdata(serio); BUG_ON(dev == NULL); serio_close(serio); input_unregister_device(dev->dev); serio_set_drvdata(serio, NULL); kfree(dev); }
static void dynapro_disconnect(struct serio *serio) { struct dynapro *pdynapro = serio_get_drvdata(serio); input_get_device(pdynapro->dev); input_unregister_device(pdynapro->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(pdynapro->dev); kfree(pdynapro); }
/* * lkkbd_disconnect() unregisters and closes behind us. */ static void lkkbd_disconnect(struct serio *serio) { struct lkkbd *lk = serio_get_drvdata(serio); input_get_device(lk->dev); input_unregister_device(lk->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(lk->dev); kfree(lk); }
static void elo_disconnect(struct serio *serio) { struct elo *elo = serio_get_drvdata(serio); input_get_device(elo->dev); input_unregister_device(elo->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(elo->dev); kfree(elo); }
static void tw_disconnect(struct serio *serio) { struct tw *tw = serio_get_drvdata(serio); input_get_device(tw->dev); input_unregister_device(tw->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(tw->dev); kfree(tw); }
static void h3600ts_disconnect(struct serio *serio) { struct h3600_dev *ts = serio_get_drvdata(serio); free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); input_get_device(ts->dev); input_unregister_device(ts->dev); serio_close(serio); serio_set_drvdata(serio, NULL); input_put_device(ts->dev); kfree(ts); }
static int sec_keyboard_connect(struct serio *serio, struct serio_driver *drv) { struct sec_keyboard_drvdata *data = container_of(drv, struct sec_keyboard_drvdata, serio_driver); printk(KERN_DEBUG "[Keyboard] %s", __func__); data->serio = serio; serio_set_drvdata(serio, data); if (serio_open(serio, drv)) printk(KERN_ERR "[Keyboard] failed to open serial port\n"); else data->tx_ready = true; return 0; }
static void taos_disconnect(struct serio *serio) { struct taos_data *taos = serio_get_drvdata(serio); if (taos->client) i2c_unregister_device(taos->client); i2c_del_adapter(&taos->adapter); serio_close(serio); serio_set_drvdata(serio, NULL); kfree(taos); dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n"); }
/* * h3600ts_connect() is the routine that is called when someone adds a * new serio device that supports H3600 protocol and registers it as * an input device. */ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) { struct h3600_dev *ts; struct input_dev *input_dev; int err; ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL); input_dev = input_allocate_device(); if (!ts || !input_dev) { err = -ENOMEM; goto fail1; } ts->serio = serio; ts->dev = input_dev; snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys); input_dev->name = "H3600 TouchScreen"; input_dev->phys = ts->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_H3600; input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_set_drvdata(input_dev, ts); input_dev->event = h3600ts_event; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_LED) | BIT_MASK(EV_PWR); input_dev->ledbit[0] = BIT_MASK(LED_SLEEP); input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0); input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0); set_bit(KEY_RECORD, input_dev->keybit); set_bit(KEY_Q, input_dev->keybit); set_bit(KEY_PROG1, input_dev->keybit); set_bit(KEY_PROG2, input_dev->keybit); set_bit(KEY_PROG3, input_dev->keybit); set_bit(KEY_UP, input_dev->keybit); set_bit(KEY_RIGHT, input_dev->keybit); set_bit(KEY_LEFT, input_dev->keybit); set_bit(KEY_DOWN, input_dev->keybit); set_bit(KEY_ENTER, input_dev->keybit); set_bit(KEY_SUSPEND, input_dev->keybit); set_bit(BTN_TOUCH, input_dev->keybit); /* Device specific stuff */ set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES); set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); err = -EBUSY; goto fail2; } if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); err = -EBUSY; goto fail3; } serio_set_drvdata(serio, ts); err = serio_open(serio, drv); if (err) return err; //h3600_flite_control(1, 25); /* default brightness */ input_register_device(ts->dev); return 0; fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); fail1: serio_set_drvdata(serio, NULL); input_free_device(input_dev); kfree(ts); return err; }
static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) { struct sunkbd *sunkbd; struct input_dev *input_dev; int err = -ENOMEM; int i; sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!sunkbd || !input_dev) goto fail1; 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); err = serio_open(serio, drv); if (err) goto fail2; if (sunkbd_initialize(sunkbd) < 0) { err = -ENODEV; goto fail3; } 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.bustype = BUS_RS232; input_dev->id.vendor = SERIO_SUNKBD; input_dev->id.product = sunkbd->type; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_set_drvdata(input_dev, sunkbd); input_dev->event = sunkbd_event; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) | BIT_MASK(EV_SND) | BIT_MASK(EV_REP); input_dev->ledbit[0] = BIT_MASK(LED_CAPSL) | BIT_MASK(LED_COMPOSE) | BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML); input_dev->sndbit[0] = BIT_MASK(SND_CLICK) | BIT_MASK(SND_BELL); input_dev->keycode = sunkbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode); for (i = 0; i < 128; i++) set_bit(sunkbd->keycode[i], input_dev->keybit); clear_bit(0, input_dev->keybit); sunkbd_enable(sunkbd, 1); err = input_register_device(sunkbd->dev); if (err) goto fail4; return 0; fail4: sunkbd_enable(sunkbd, 0); fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(input_dev); kfree(sunkbd); return err; }
static int elo_connect(struct serio *serio, struct serio_driver *drv) { struct elo *elo; struct input_dev *input_dev; int err; elo = kzalloc(sizeof(struct elo), GFP_KERNEL); input_dev = input_allocate_device(); if (!elo || !input_dev) { err = -ENOMEM; goto fail1; } elo->serio = serio; elo->id = serio->id.id; elo->dev = input_dev; elo->expected_packet = ELO10_TOUCH_PACKET; mutex_init(&elo->cmd_mutex); init_completion(&elo->cmd_done); snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); input_dev->name = "Elo Serial TouchScreen"; input_dev->phys = elo->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_ELO; input_dev->id.product = elo->id; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); serio_set_drvdata(serio, elo); err = serio_open(serio, drv); if (err) goto fail2; switch (elo->id) { case 0: /* 10-byte protocol */ if (elo_setup_10(elo)) goto fail3; break; case 1: /* 6-byte protocol */ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); case 2: /* 4-byte protocol */ input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); break; case 3: /* 3-byte protocol */ input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); break; } err = input_register_device(elo->dev); if (err) goto fail3; return 0; fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(input_dev); kfree(elo); return err; }
static int taos_connect(struct serio *serio, struct serio_driver *drv) { struct taos_data *taos; struct i2c_adapter *adapter; char *name; int err; taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL); if (!taos) { err = -ENOMEM; goto exit; } taos->state = TAOS_STATE_INIT; serio_set_drvdata(serio, taos); err = serio_open(serio, drv); if (err) goto exit_kfree; adapter = &taos->adapter; adapter->owner = THIS_MODULE; adapter->algo = &taos_algorithm; adapter->algo_data = serio; adapter->dev.parent = &serio->dev; /* Reset the TAOS evaluation module to identify it */ serio_write(serio, TAOS_CMD_RESET); wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE, msecs_to_jiffies(2000)); if (taos->state != TAOS_STATE_IDLE) { err = -ENODEV; dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, " "pos=%d)\n", taos->state, taos->pos); goto exit_close; } name = taos_adapter_name(taos->buffer); if (!name) { err = -ENODEV; dev_err(&serio->dev, "TAOS EVM identification failed\n"); goto exit_close; } strlcpy(adapter->name, name, sizeof(adapter->name)); err = i2c_add_adapter(adapter); if (err) goto exit_close; dev_dbg(&serio->dev, "Connected to TAOS EVM\n"); taos->client = taos_instantiate_device(adapter); return 0; exit_close: serio_close(serio); exit_kfree: serio_set_drvdata(serio, NULL); kfree(taos); exit: return err; }
static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) { struct hil_dev *dev; struct input_dev *input_dev; uint8_t did, *idd; int error; dev = kzalloc(sizeof(*dev), GFP_KERNEL); input_dev = input_allocate_device(); if (!dev || !input_dev) { error = -ENOMEM; goto bail0; } dev->serio = serio; dev->dev = input_dev; error = serio_open(serio, drv); if (error) goto bail0; serio_set_drvdata(serio, dev); /* Get device info. MLC driver supplies devid/status/etc. */ init_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); serio_write(serio, HIL_CMD_IDD); error = wait_for_completion_killable(&dev->cmd_done); if (error) goto bail1; init_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); serio_write(serio, HIL_CMD_RSC); error = wait_for_completion_killable(&dev->cmd_done); if (error) goto bail1; init_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); serio_write(serio, HIL_CMD_RNM); error = wait_for_completion_killable(&dev->cmd_done); if (error) goto bail1; init_completion(&dev->cmd_done); serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); serio_write(serio, HIL_CMD_EXD); error = wait_for_completion_killable(&dev->cmd_done); if (error) goto bail1; did = dev->idd[0]; idd = dev->idd + 1; switch (did & HIL_IDD_DID_TYPE_MASK) { case HIL_IDD_DID_TYPE_KB_INTEGRAL: case HIL_IDD_DID_TYPE_KB_ITF: case HIL_IDD_DID_TYPE_KB_RSVD: case HIL_IDD_DID_TYPE_CHAR: if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "combo devices are not supported.\n"); goto bail1; } dev->is_pointer = false; hil_dev_keyboard_setup(dev); break; case HIL_IDD_DID_TYPE_REL: case HIL_IDD_DID_TYPE_ABS: dev->is_pointer = true; hil_dev_pointer_setup(dev); break; default: goto bail1; } input_dev->id.bustype = BUS_HIL; input_dev->id.vendor = PCI_VENDOR_ID_HP; input_dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ input_dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ input_dev->dev.parent = &serio->dev; if (!dev->is_pointer) { serio_write(serio, 0); serio_write(serio, 0); serio_write(serio, HIL_PKT_CMD >> 8); /* Enable Keyswitch Autorepeat 1 */ serio_write(serio, HIL_CMD_EK1); /* No need to wait for completion */ }
static int pm_connect(struct serio *serio, struct serio_driver *drv) { struct pm *pm; struct input_dev *input_dev; int max_x, max_y; int err; pm = kzalloc(sizeof(struct pm), GFP_KERNEL); input_dev = input_allocate_device(); if (!pm || !input_dev) { err = -ENOMEM; goto fail1; } pm->serio = serio; pm->dev = input_dev; snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); pm->maxcontacts = 1; input_dev->name = "PenMount Serial TouchScreen"; input_dev->phys = pm->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_PENMOUNT; input_dev->id.product = 0; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); switch (serio->id.id) { default: case 0: pm->packetsize = 5; pm->parse_packet = pm_parse_9000; input_dev->id.product = 0x9000; max_x = max_y = 0x3ff; break; case 1: pm->packetsize = 6; pm->parse_packet = pm_parse_6000; input_dev->id.product = 0x6000; max_x = max_y = 0x3ff; break; case 2: pm->packetsize = 6; pm->parse_packet = pm_parse_3000; input_dev->id.product = 0x3000; max_x = max_y = 0x7ff; pm->maxcontacts = PM_3000_MTSLOT; break; case 3: pm->packetsize = 6; pm->parse_packet = pm_parse_6250; input_dev->id.product = 0x6250; max_x = max_y = 0x3ff; pm->maxcontacts = PM_6250_MTSLOT; break; } input_set_abs_params(pm->dev, ABS_X, 0, max_x, 0, 0); input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0); if (pm->maxcontacts > 1) { input_mt_init_slots(pm->dev, pm->maxcontacts); input_set_abs_params(pm->dev, ABS_MT_POSITION_X, 0, max_x, 0, 0); input_set_abs_params(pm->dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0); } serio_set_drvdata(serio, pm); err = serio_open(serio, drv); if (err) goto fail2; err = input_register_device(pm->dev); if (err) goto fail3; return 0; fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(input_dev); kfree(pm); return err; }
/* * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. */ static int lkkbd_connect (struct serio *serio, struct serio_driver *drv) { struct lkkbd *lk; struct input_dev *input_dev; int i; int err; lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL); input_dev = input_allocate_device (); if (!lk || !input_dev) { err = -ENOMEM; goto fail1; } lk->serio = serio; lk->dev = input_dev; INIT_WORK (&lk->tq, lkkbd_reinit); lk->bell_volume = bell_volume; lk->keyclick_volume = keyclick_volume; lk->ctrlclick_volume = ctrlclick_volume; memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES); strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name)); snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); input_dev->name = lk->name; input_dev->phys = lk->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_LKKBD; input_dev->id.product = 0; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_dev->event = lkkbd_event; input_set_drvdata (input_dev, lk); set_bit (EV_KEY, input_dev->evbit); set_bit (EV_LED, input_dev->evbit); set_bit (EV_SND, input_dev->evbit); set_bit (EV_REP, input_dev->evbit); set_bit (LED_CAPSL, input_dev->ledbit); set_bit (LED_SLEEP, input_dev->ledbit); set_bit (LED_COMPOSE, input_dev->ledbit); set_bit (LED_SCROLLL, input_dev->ledbit); set_bit (SND_BELL, input_dev->sndbit); set_bit (SND_CLICK, input_dev->sndbit); input_dev->keycode = lk->keycode; input_dev->keycodesize = sizeof (lk_keycode_t); input_dev->keycodemax = LK_NUM_KEYCODES; for (i = 0; i < LK_NUM_KEYCODES; i++) set_bit (lk->keycode[i], input_dev->keybit); serio_set_drvdata (serio, lk); err = serio_open (serio, drv); if (err) goto fail2; err = input_register_device (lk->dev); if (err) goto fail3; lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET); return 0; fail3: serio_close (serio); fail2: serio_set_drvdata (serio, NULL); fail1: input_free_device (input_dev); kfree (lk); return err; }
static int spaceball_connect(struct serio *serio, struct serio_driver *drv) { struct spaceball *spaceball; struct input_dev *input_dev; int err = -ENOMEM; int i, id; if ((id = serio->id.id) > SPACEBALL_MAX_ID) return -ENODEV; spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); input_dev = input_allocate_device(); if (!spaceball || !input_dev) goto fail1; spaceball->dev = input_dev; snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); input_dev->name = spaceball_names[id]; input_dev->phys = spaceball->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_SPACEBALL; input_dev->id.product = id; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); switch (id) { case SPACEBALL_4000FLX: case SPACEBALL_4000FLX_L: input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9); input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE); default: input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8); case SPACEBALL_3003C: input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8); } for (i = 0; i < 3; i++) { input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40); input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8); } serio_set_drvdata(serio, spaceball); err = serio_open(serio, drv); if (err) goto fail2; err = input_register_device(spaceball->dev); if (err) goto fail3; return 0; fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(input_dev); kfree(spaceball); return err; }