···796796 Defaults to the default architecture's huge page size797797 if not specified.798798799799+ i8042.debug [HW] Toggle i8042 debug mode799800 i8042.direct [HW] Put keyboard port into non-translated mode800801 i8042.dumbkbd [HW] Pretend that controller can only read data from801802 keyboard and cannot control its state
···834834}835835836836/*837837- * Most special keys (Fn+F?) on Dell Latitudes do not generate release837837+ * Most special keys (Fn+F?) on Dell laptops do not generate release838838 * events so we have to do it ourselves.839839 */840840-static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)840840+static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)841841{842842 const unsigned int forced_release_keys[] = {843843 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,···12071207{12081208 struct input_dev *old_dev, *new_dev;12091209 unsigned long value;12101210- char *rest;12111210 int err;12121211 unsigned char old_extra, old_set;1213121212141213 if (!atkbd->write)12151214 return -EIO;1216121512171217- value = simple_strtoul(buf, &rest, 10);12181218- if (*rest || value > 1)12161216+ if (strict_strtoul(buf, 10, &value) || value > 1)12191217 return -EINVAL;1220121812211219 if (atkbd->extra != value) {···12621264{12631265 struct input_dev *old_dev, *new_dev;12641266 unsigned long value;12651265- char *rest;12661267 int err;12671268 unsigned char old_scroll;1268126912691269- value = simple_strtoul(buf, &rest, 10);12701270- if (*rest || value > 1)12701270+ if (strict_strtoul(buf, 10, &value) || value > 1)12711271 return -EINVAL;1272127212731273 if (atkbd->scroll != value) {···13061310{13071311 struct input_dev *old_dev, *new_dev;13081312 unsigned long value;13091309- char *rest;13101313 int err;13111314 unsigned char old_set, old_extra;1312131513131316 if (!atkbd->write)13141317 return -EIO;1315131813161316- value = simple_strtoul(buf, &rest, 10);13171317- if (*rest || (value != 2 && value != 3))13191319+ if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))13181320 return -EINVAL;1319132113201322 if (atkbd->set != value) {···13551361{13561362 struct input_dev *old_dev, *new_dev;13571363 unsigned long value;13581358- char *rest;13591364 int err;13601365 unsigned char old_softrepeat, old_softraw;1361136613621367 if (!atkbd->write)13631368 return -EIO;1364136913651365- value = simple_strtoul(buf, &rest, 10);13661366- if (*rest || value > 1)13701370+ if (strict_strtoul(buf, 10, &value) || value > 1)13671371 return -EINVAL;1368137213691373 if (atkbd->softrepeat != value) {···14051413{14061414 struct input_dev *old_dev, *new_dev;14071415 unsigned long value;14081408- char *rest;14091416 int err;14101417 unsigned char old_softraw;1411141814121412- value = simple_strtoul(buf, &rest, 10);14131413- if (*rest || value > 1)14191419+ if (strict_strtoul(buf, 10, &value) || value > 1)14141420 return -EINVAL;1415142114161422 if (atkbd->softraw != value) {···1451146114521462static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {14531463 {14541454- .ident = "Dell Latitude series",14641464+ .ident = "Dell Laptop",14551465 .matches = {14561466 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),14571457- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),14671467+ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */14581468 },14591469 .callback = atkbd_setup_fixup,14601460- .driver_data = atkbd_latitude_keymap_fixup,14701470+ .driver_data = atkbd_dell_laptop_keymap_fixup,14611471 },14621472 {14631473 .ident = "HP 2133",
+12-1
drivers/input/keyboard/bf54x-keys.c
···88 *99 *1010 * Modified:1111- * Copyright 2007 Analog Devices Inc.1111+ * Copyright 2007-2008 Analog Devices Inc.1212 *1313 * Bugs: Enter bugs at http://blackfin.uclinux.org/1414 *···8181 unsigned short *keycode;8282 struct timer_list timer;8383 unsigned int keyup_test_jiffies;8484+ unsigned short kpad_msel;8585+ unsigned short kpad_prescale;8686+ unsigned short kpad_ctl;8487};85888689static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,···363360{364361 struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);365362363363+ bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL();364364+ bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE();365365+ bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL();366366+366367 if (device_may_wakeup(&pdev->dev))367368 enable_irq_wake(bf54x_kpad->irq);368369···376369static int bfin_kpad_resume(struct platform_device *pdev)377370{378371 struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);372372+373373+ bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel);374374+ bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale);375375+ bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl);379376380377 if (device_may_wakeup(&pdev->dev))381378 disable_irq_wake(bf54x_kpad->irq);
+16-26
drivers/input/keyboard/gpio_keys.c
···3636 struct gpio_button_data data[0];3737};38383939-static void gpio_keys_report_event(struct gpio_keys_button *button,4040- struct input_dev *input)3939+static void gpio_keys_report_event(struct gpio_button_data *bdata)4140{4141+ struct gpio_keys_button *button = bdata->button;4242+ struct input_dev *input = bdata->input;4243 unsigned int type = button->type ?: EV_KEY;4344 int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;4445···5150{5251 struct gpio_button_data *data = (struct gpio_button_data *)_data;53525454- gpio_keys_report_event(data->button, data->input);5353+ gpio_keys_report_event(data);5554}56555756static irqreturn_t gpio_keys_isr(int irq, void *dev_id)5857{5959- struct platform_device *pdev = dev_id;6060- struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;6161- struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);6262- int i;5858+ struct gpio_button_data *bdata = dev_id;5959+ struct gpio_keys_button *button = bdata->button;63606464- for (i = 0; i < pdata->nbuttons; i++) {6565- struct gpio_keys_button *button = &pdata->buttons[i];6161+ BUG_ON(irq != gpio_to_irq(button->gpio));66626767- if (irq == gpio_to_irq(button->gpio)) {6868- struct gpio_button_data *bdata = &ddata->data[i];6363+ if (button->debounce_interval)6464+ mod_timer(&bdata->timer,6565+ jiffies + msecs_to_jiffies(button->debounce_interval));6666+ else6767+ gpio_keys_report_event(bdata);69687070- if (button->debounce_interval)7171- mod_timer(&bdata->timer,7272- jiffies +7373- msecs_to_jiffies(button->debounce_interval));7474- else7575- gpio_keys_report_event(button, bdata->input);7676-7777- return IRQ_HANDLED;7878- }7979- }8080-8181- return IRQ_NONE;6969+ return IRQ_HANDLED;8270}83718472static int __devinit gpio_keys_probe(struct platform_device *pdev)···141151 IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |142152 IRQF_TRIGGER_FALLING,143153 button->desc ? button->desc : "gpio_keys",144144- pdev);154154+ bdata);145155 if (error) {146156 pr_err("gpio-keys: Unable to claim irq %d; error %d\n",147157 irq, error);···168178169179 fail2:170180 while (--i >= 0) {171171- free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);181181+ free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);172182 if (pdata->buttons[i].debounce_interval)173183 del_timer_sync(&ddata->data[i].timer);174184 gpio_free(pdata->buttons[i].gpio);···193203194204 for (i = 0; i < pdata->nbuttons; i++) {195205 int irq = gpio_to_irq(pdata->buttons[i].gpio);196196- free_irq(irq, pdev);206206+ free_irq(irq, &ddata->data[i]);197207 if (pdata->buttons[i].debounce_interval)198208 del_timer_sync(&ddata->data[i].timer);199209 gpio_free(pdata->buttons[i].gpio);
+13
drivers/input/misc/Kconfig
···180180 To compile this driver as a module, choose M here: the module will be181181 called yealink.182182183183+config INPUT_CM109184184+ tristate "C-Media CM109 USB I/O Controller"185185+ depends on EXPERIMENTAL186186+ depends on USB_ARCH_HAS_HCD187187+ select USB188188+ help189189+ Say Y here if you want to enable keyboard and buzzer functions of the190190+ C-Media CM109 usb phones. The audio part is enabled by the generic191191+ usb sound driver, so you might want to enable that as well.192192+193193+ To compile this driver as a module, choose M here: the module will be194194+ called cm109.195195+183196config INPUT_UINPUT184197 tristate "User level driver support"185198 help
···11/*22- * drivers/usb/input/map_to_7segment.h33- *42 * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>53 *64 * This program is free software; you can redistribute it and/or···3436 * Usage:3537 *3638 * Register a map variable, and fill it with a character set:3737- * static SEG7_DEFAULT_MAP(map_seg7);3939+ * static SEG7_DEFAULT_MAP(map_seg7);3840 *3941 *4042 * Then use for conversion:
···96969797 If unsure, say N.98989999+config MOUSE_PS2_OLPC100100+ bool "OLPC PS/2 mouse protocol extension"101101+ depends on MOUSE_PS2 && OLPC102102+ help103103+ Say Y here if you have an OLPC XO-1 laptop (with built-in104104+ PS/2 touchpad/tablet device). The manufacturer calls the105105+ touchpad an HGPK.106106+107107+ If unsure, say N.108108+99109config MOUSE_SERIAL100110 tristate "Serial mouse"101111 select SERIO
···136136#define ATP_GEYSER_MODE_REQUEST_INDEX 0137137#define ATP_GEYSER_MODE_VENDOR_VALUE 0x04138138139139+/**140140+ * enum atp_status_bits - status bit meanings141141+ *142142+ * These constants represent the meaning of the status bits.143143+ * (only Geyser 3/4)144144+ *145145+ * @ATP_STATUS_BUTTON: The button was pressed146146+ * @ATP_STATUS_BASE_UPDATE: Update of the base values (untouched pad)147147+ * @ATP_STATUS_FROM_RESET: Reset previously performed148148+ */149149+enum atp_status_bits {150150+ ATP_STATUS_BUTTON = BIT(0),151151+ ATP_STATUS_BASE_UPDATE = BIT(2),152152+ ATP_STATUS_FROM_RESET = BIT(4),153153+};154154+139155/* Structure to hold all of our device specific stuff */140156struct atp {141157 char phys[64];142158 struct usb_device *udev; /* usb device */143159 struct urb *urb; /* usb request block */144144- signed char *data; /* transferred data */160160+ u8 *data; /* transferred data */145161 struct input_dev *input; /* input dev */146162 enum atp_touchpad_type type; /* type of touchpad */147163 bool open;···267251 int retval;268252269253 dprintk("appletouch: putting appletouch to sleep (reinit)\n");270270- dev->idlecount = 0;271271-272254 atp_geyser_init(udev);273255274256 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);···341327 input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);342328}343329344344-static void atp_complete(struct urb *urb)330330+/* Check URB status and for correct length of data package */331331+332332+#define ATP_URB_STATUS_SUCCESS 0333333+#define ATP_URB_STATUS_ERROR 1334334+#define ATP_URB_STATUS_ERROR_FATAL 2335335+336336+static int atp_status_check(struct urb *urb)345337{346346- int x, y, x_z, y_z, x_f, y_f;347347- int retval, i, j;348348- int key;349338 struct atp *dev = urb->context;350339351340 switch (urb->status) {···368351 /* This urb is terminated, clean up */369352 dbg("atp_complete: urb shutting down with status: %d",370353 urb->status);371371- return;354354+ return ATP_URB_STATUS_ERROR_FATAL;355355+372356 default:373357 dbg("atp_complete: nonzero urb status received: %d",374358 urb->status);375375- goto exit;359359+ return ATP_URB_STATUS_ERROR;376360 }377361378362 /* drop incomplete datasets */···381363 dprintk("appletouch: incomplete data package"382364 " (first byte: %d, length: %d).\n",383365 dev->data[0], dev->urb->actual_length);384384- goto exit;366366+ return ATP_URB_STATUS_ERROR;385367 }386368369369+ return ATP_URB_STATUS_SUCCESS;370370+}371371+372372+/*373373+ * USB interrupt callback functions374374+ */375375+376376+/* Interrupt function for older touchpads: FOUNTAIN/GEYSER1/GEYSER2 */377377+378378+static void atp_complete_geyser_1_2(struct urb *urb)379379+{380380+ int x, y, x_z, y_z, x_f, y_f;381381+ int retval, i, j;382382+ int key;383383+ struct atp *dev = urb->context;384384+ int status = atp_status_check(urb);385385+386386+ if (status == ATP_URB_STATUS_ERROR_FATAL)387387+ return;388388+ else if (status == ATP_URB_STATUS_ERROR)389389+ goto exit;390390+387391 /* reorder the sensors values */388388- if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {389389- memset(dev->xy_cur, 0, sizeof(dev->xy_cur));390390-391391- /*392392- * The values are laid out like this:393393- * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...394394- * '-' is an unused value.395395- */396396-397397- /* read X values */398398- for (i = 0, j = 19; i < 20; i += 2, j += 3) {399399- dev->xy_cur[i] = dev->data[j + 1];400400- dev->xy_cur[i + 1] = dev->data[j + 2];401401- }402402- /* read Y values */403403- for (i = 0, j = 1; i < 9; i += 2, j += 3) {404404- dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];405405- dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];406406- }407407- } else if (dev->type == ATP_GEYSER2) {392392+ if (dev->type == ATP_GEYSER2) {408393 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));409394410395 /*···448427 /* first sample */449428 dev->valid = true;450429 dev->x_old = dev->y_old = -1;430430+431431+ /* Store first sample */451432 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));452433453453- if (dev->size_detect_done ||454454- dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */434434+ /* Perform size detection, if not done already */435435+ if (!dev->size_detect_done) {436436+437437+ /* 17" Powerbooks have extra X sensors */438438+ for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);439439+ i < ATP_XSENSORS; i++) {440440+ if (!dev->xy_cur[i])441441+ continue;442442+443443+ printk(KERN_INFO444444+ "appletouch: 17\" model detected.\n");445445+446446+ if (dev->type == ATP_GEYSER2)447447+ input_set_abs_params(dev->input, ABS_X,448448+ 0,449449+ (20 - 1) *450450+ ATP_XFACT - 1,451451+ ATP_FUZZ, 0);452452+ else453453+ input_set_abs_params(dev->input, ABS_X,454454+ 0,455455+ (26 - 1) *456456+ ATP_XFACT - 1,457457+ ATP_FUZZ, 0);458458+ break;459459+ }460460+461461+ dev->size_detect_done = 1;455462 goto exit;456456-457457- /* 17" Powerbooks have extra X sensors */458458- for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);459459- i < ATP_XSENSORS; i++) {460460- if (!dev->xy_cur[i])461461- continue;462462-463463- printk(KERN_INFO "appletouch: 17\" model detected.\n");464464- if (dev->type == ATP_GEYSER2)465465- input_set_abs_params(dev->input, ABS_X, 0,466466- (20 - 1) *467467- ATP_XFACT - 1,468468- ATP_FUZZ, 0);469469- else470470- input_set_abs_params(dev->input, ABS_X, 0,471471- (ATP_XSENSORS - 1) *472472- ATP_XFACT - 1,473473- ATP_FUZZ, 0);474474- break;475463 }476476-477477- dev->size_detect_done = 1;478478- goto exit;479464 }480465481466 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {···502475 ATP_XFACT, &x_z, &x_f);503476 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,504477 ATP_YFACT, &y_z, &y_f);505505- key = dev->data[dev->datalen - 1] & 1;478478+ key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;479479+480480+ if (x && y) {481481+ if (dev->x_old != -1) {482482+ x = (dev->x_old * 3 + x) >> 2;483483+ y = (dev->y_old * 3 + y) >> 2;484484+ dev->x_old = x;485485+ dev->y_old = y;486486+487487+ if (debug > 1)488488+ printk(KERN_DEBUG "appletouch: "489489+ "X: %3d Y: %3d Xz: %3d Yz: %3d\n",490490+ x, y, x_z, y_z);491491+492492+ input_report_key(dev->input, BTN_TOUCH, 1);493493+ input_report_abs(dev->input, ABS_X, x);494494+ input_report_abs(dev->input, ABS_Y, y);495495+ input_report_abs(dev->input, ABS_PRESSURE,496496+ min(ATP_PRESSURE, x_z + y_z));497497+ atp_report_fingers(dev->input, max(x_f, y_f));498498+ }499499+ dev->x_old = x;500500+ dev->y_old = y;501501+502502+ } else if (!x && !y) {503503+504504+ dev->x_old = dev->y_old = -1;505505+ input_report_key(dev->input, BTN_TOUCH, 0);506506+ input_report_abs(dev->input, ABS_PRESSURE, 0);507507+ atp_report_fingers(dev->input, 0);508508+509509+ /* reset the accumulator on release */510510+ memset(dev->xy_acc, 0, sizeof(dev->xy_acc));511511+ }512512+513513+ input_report_key(dev->input, BTN_LEFT, key);514514+ input_sync(dev->input);515515+516516+ exit:517517+ retval = usb_submit_urb(dev->urb, GFP_ATOMIC);518518+ if (retval)519519+ err("atp_complete: usb_submit_urb failed with result %d",520520+ retval);521521+}522522+523523+/* Interrupt function for older touchpads: GEYSER3/GEYSER4 */524524+525525+static void atp_complete_geyser_3_4(struct urb *urb)526526+{527527+ int x, y, x_z, y_z, x_f, y_f;528528+ int retval, i, j;529529+ int key;530530+ struct atp *dev = urb->context;531531+ int status = atp_status_check(urb);532532+533533+ if (status == ATP_URB_STATUS_ERROR_FATAL)534534+ return;535535+ else if (status == ATP_URB_STATUS_ERROR)536536+ goto exit;537537+538538+ /* Reorder the sensors values:539539+ *540540+ * The values are laid out like this:541541+ * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...542542+ * '-' is an unused value.543543+ */544544+545545+ /* read X values */546546+ for (i = 0, j = 19; i < 20; i += 2, j += 3) {547547+ dev->xy_cur[i] = dev->data[j + 1];548548+ dev->xy_cur[i + 1] = dev->data[j + 2];549549+ }550550+ /* read Y values */551551+ for (i = 0, j = 1; i < 9; i += 2, j += 3) {552552+ dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];553553+ dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];554554+ }555555+556556+ dbg_dump("sample", dev->xy_cur);557557+558558+ /* Just update the base values (i.e. touchpad in untouched state) */559559+ if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) {560560+561561+ dprintk(KERN_DEBUG "appletouch: updated base values\n");562562+563563+ memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));564564+ goto exit;565565+ }566566+567567+ for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {568568+ /* calculate the change */569569+ dev->xy_acc[i] = dev->xy_cur[i] - dev->xy_old[i];570570+571571+ /* this is a round-robin value, so couple with that */572572+ if (dev->xy_acc[i] > 127)573573+ dev->xy_acc[i] -= 256;574574+575575+ if (dev->xy_acc[i] < -127)576576+ dev->xy_acc[i] += 256;577577+578578+ /* prevent down drifting */579579+ if (dev->xy_acc[i] < 0)580580+ dev->xy_acc[i] = 0;581581+ }582582+583583+ dbg_dump("accumulator", dev->xy_acc);584584+585585+ x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,586586+ ATP_XFACT, &x_z, &x_f);587587+ y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,588588+ ATP_YFACT, &y_z, &y_f);589589+ key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;506590507591 if (x && y) {508592 if (dev->x_old != -1) {···652514 input_sync(dev->input);653515654516 /*655655- * Many Geysers will continue to send packets continually after517517+ * Geysers 3/4 will continue to send packets continually after656518 * the first touch unless reinitialised. Do so if it's been657519 * idle for a while in order to avoid waking the kernel up658658- * several hundred times a second. Re-initialization does not659659- * work on Fountain touchpads.520520+ * several hundred times a second.660521 */661661- if (dev->type != ATP_FOUNTAIN) {662662- /*663663- * Button must not be pressed when entering suspend,664664- * otherwise we will never release the button.665665- */666666- if (!x && !y && !key) {667667- dev->idlecount++;668668- if (dev->idlecount == 10) {669669- dev->valid = false;670670- schedule_work(&dev->work);671671- /* Don't resubmit urb here, wait for reinit */672672- return;673673- }674674- } else522522+523523+ /*524524+ * Button must not be pressed when entering suspend,525525+ * otherwise we will never release the button.526526+ */527527+ if (!x && !y && !key) {528528+ dev->idlecount++;529529+ if (dev->idlecount == 10) {530530+ dev->x_old = dev->y_old = -1;675531 dev->idlecount = 0;676676- }532532+ schedule_work(&dev->work);533533+ /* Don't resubmit urb here, wait for reinit */534534+ return;535535+ }536536+ } else537537+ dev->idlecount = 0;677538678539 exit:679540 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);···769632 if (!dev->data)770633 goto err_free_urb;771634772772- usb_fill_int_urb(dev->urb, udev,773773- usb_rcvintpipe(udev, int_in_endpointAddr),774774- dev->data, dev->datalen, atp_complete, dev, 1);635635+ /* Select the USB complete (callback) function */636636+ if (dev->type == ATP_FOUNTAIN ||637637+ dev->type == ATP_GEYSER1 ||638638+ dev->type == ATP_GEYSER2)639639+ usb_fill_int_urb(dev->urb, udev,640640+ usb_rcvintpipe(udev, int_in_endpointAddr),641641+ dev->data, dev->datalen,642642+ atp_complete_geyser_1_2, dev, 1);643643+ else644644+ usb_fill_int_urb(dev->urb, udev,645645+ usb_rcvintpipe(udev, int_in_endpointAddr),646646+ dev->data, dev->datalen,647647+ atp_complete_geyser_3_4, dev, 1);775648776649 error = atp_handle_geyser(dev);777650 if (error)···898751 struct atp *dev = usb_get_intfdata(iface);899752900753 usb_kill_urb(dev->urb);901901- dev->valid = false;902902-903754 return 0;904755}905756
+477
drivers/input/mouse/hgpk.c
···11+/*22+ * OLPC HGPK (XO-1) touchpad PS/2 mouse driver33+ *44+ * Copyright (c) 2006-2008 One Laptop Per Child55+ * Authors:66+ * Zephaniah E. Hull77+ * Andres Salomon <dilinger@debian.org>88+ *99+ * This driver is partly based on the ALPS driver, which is:1010+ *1111+ * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>1212+ * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>1313+ * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>1414+ * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>1515+ *1616+ * This program is free software; you can redistribute it and/or modify1717+ * it under the terms of the GNU General Public License version 2 as1818+ * published by the Free Software Foundation.1919+ */2020+2121+/*2222+ * The spec from ALPS is available from2323+ * <http://wiki.laptop.org/go/Touch_Pad/Tablet>. It refers to this2424+ * device as HGPK (Hybrid GS, PT, and Keymatrix).2525+ *2626+ * The earliest versions of the device had simultaneous reporting; that2727+ * was removed. After that, the device used the Advanced Mode GS/PT streaming2828+ * stuff. That turned out to be too buggy to support, so we've finally2929+ * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad).3030+ */3131+3232+#define DEBUG3333+#include <linux/input.h>3434+#include <linux/serio.h>3535+#include <linux/libps2.h>3636+#include <linux/delay.h>3737+#include <asm/olpc.h>3838+3939+#include "psmouse.h"4040+#include "hgpk.h"4141+4242+static int tpdebug;4343+module_param(tpdebug, int, 0644);4444+MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");4545+4646+static int recalib_delta = 100;4747+module_param(recalib_delta, int, 0644);4848+MODULE_PARM_DESC(recalib_delta,4949+ "packets containing a delta this large will cause a recalibration.");5050+5151+/*5252+ * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"5353+ * above the pad and still have it send packets. This causes a jump cursor5454+ * when one places their finger on the pad. We can probably detect the5555+ * jump as we see a large deltas (>= 100px). In mouse mode, I've been5656+ * unable to even come close to 100px deltas during normal usage, so I think5757+ * this threshold is safe. If a large delta occurs, trigger a recalibration.5858+ */5959+static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)6060+{6161+ struct hgpk_data *priv = psmouse->private;6262+6363+ if (abs(x) > recalib_delta || abs(y) > recalib_delta) {6464+ hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n",6565+ recalib_delta, x, y);6666+ /* My car gets forty rods to the hogshead and that's the6767+ * way I likes it! */6868+ psmouse_queue_work(psmouse, &priv->recalib_wq,6969+ msecs_to_jiffies(1000));7070+ }7171+}7272+7373+/*7474+ * We have no idea why this particular hardware bug occurs. The touchpad7575+ * will randomly start spewing packets without anything touching the7676+ * pad. This wouldn't necessarily be bad, but it's indicative of a7777+ * severely miscalibrated pad; attempting to use the touchpad while it's7878+ * spewing means the cursor will jump all over the place, and act "drunk".7979+ *8080+ * The packets that are spewed tend to all have deltas between -2 and 2, and8181+ * the cursor will move around without really going very far. It will8282+ * tend to end up in the same location; if we tally up the changes over8383+ * 100 packets, we end up w/ a final delta of close to 0. This happens8484+ * pretty regularly when the touchpad is spewing, and is pretty hard to8585+ * manually trigger (at least for *my* fingers). So, it makes a perfect8686+ * scheme for detecting spews.8787+ */8888+static void hgpk_spewing_hack(struct psmouse *psmouse,8989+ int l, int r, int x, int y)9090+{9191+ struct hgpk_data *priv = psmouse->private;9292+9393+ /* ignore button press packets; many in a row could trigger9494+ * a false-positive! */9595+ if (l || r)9696+ return;9797+9898+ priv->x_tally += x;9999+ priv->y_tally += y;100100+101101+ if (++priv->count > 100) {102102+ if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {103103+ hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",104104+ priv->x_tally, priv->y_tally);105105+ psmouse_queue_work(psmouse, &priv->recalib_wq,106106+ msecs_to_jiffies(1000));107107+ }108108+ /* reset every 100 packets */109109+ priv->count = 0;110110+ priv->x_tally = 0;111111+ priv->y_tally = 0;112112+ }113113+}114114+115115+/*116116+ * HGPK Mouse Mode format (standard mouse format, sans middle button)117117+ *118118+ * byte 0: y-over x-over y-neg x-neg 1 0 swr swl119119+ * byte 1: x7 x6 x5 x4 x3 x2 x1 x0120120+ * byte 2: y7 y6 y5 y4 y3 y2 y1 y0121121+ *122122+ * swr/swl are the left/right buttons.123123+ * x-neg/y-neg are the x and y delta negative bits124124+ * x-over/y-over are the x and y overflow bits125125+ */126126+static int hgpk_validate_byte(unsigned char *packet)127127+{128128+ return (packet[0] & 0x0C) == 0x08;129129+}130130+131131+static void hgpk_process_packet(struct psmouse *psmouse)132132+{133133+ struct input_dev *dev = psmouse->dev;134134+ unsigned char *packet = psmouse->packet;135135+ int x, y, left, right;136136+137137+ left = packet[0] & 1;138138+ right = (packet[0] >> 1) & 1;139139+140140+ x = packet[1] - ((packet[0] << 4) & 0x100);141141+ y = ((packet[0] << 3) & 0x100) - packet[2];142142+143143+ hgpk_jumpy_hack(psmouse, x, y);144144+ hgpk_spewing_hack(psmouse, left, right, x, y);145145+146146+ if (tpdebug)147147+ hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);148148+149149+ input_report_key(dev, BTN_LEFT, left);150150+ input_report_key(dev, BTN_RIGHT, right);151151+152152+ input_report_rel(dev, REL_X, x);153153+ input_report_rel(dev, REL_Y, y);154154+155155+ input_sync(dev);156156+}157157+158158+static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)159159+{160160+ struct hgpk_data *priv = psmouse->private;161161+162162+ if (hgpk_validate_byte(psmouse->packet)) {163163+ hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",164164+ __func__, psmouse->pktcnt, psmouse->packet[0],165165+ psmouse->packet[1], psmouse->packet[2]);166166+ return PSMOUSE_BAD_DATA;167167+ }168168+169169+ if (psmouse->pktcnt >= psmouse->pktsize) {170170+ hgpk_process_packet(psmouse);171171+ return PSMOUSE_FULL_PACKET;172172+ }173173+174174+ if (priv->recalib_window) {175175+ if (time_before(jiffies, priv->recalib_window)) {176176+ /*177177+ * ugh, got a packet inside our recalibration178178+ * window, schedule another recalibration.179179+ */180180+ hgpk_dbg(psmouse,181181+ "packet inside calibration window, "182182+ "queueing another recalibration\n");183183+ psmouse_queue_work(psmouse, &priv->recalib_wq,184184+ msecs_to_jiffies(1000));185185+ }186186+ priv->recalib_window = 0;187187+ }188188+189189+ return PSMOUSE_GOOD_DATA;190190+}191191+192192+static int hgpk_force_recalibrate(struct psmouse *psmouse)193193+{194194+ struct ps2dev *ps2dev = &psmouse->ps2dev;195195+ struct hgpk_data *priv = psmouse->private;196196+197197+ /* C-series touchpads added the recalibrate command */198198+ if (psmouse->model < HGPK_MODEL_C)199199+ return 0;200200+201201+ /* we don't want to race with the irq handler, nor with resyncs */202202+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);203203+204204+ /* start by resetting the device */205205+ psmouse_reset(psmouse);206206+207207+ /* send the recalibrate request */208208+ if (ps2_command(ps2dev, NULL, 0xf5) ||209209+ ps2_command(ps2dev, NULL, 0xf5) ||210210+ ps2_command(ps2dev, NULL, 0xe6) ||211211+ ps2_command(ps2dev, NULL, 0xf5)) {212212+ return -1;213213+ }214214+215215+ /* according to ALPS, 150mS is required for recalibration */216216+ msleep(150);217217+218218+ /* XXX: If a finger is down during this delay, recalibration will219219+ * detect capacitance incorrectly. This is a hardware bug, and220220+ * we don't have a good way to deal with it. The 2s window stuff221221+ * (below) is our best option for now.222222+ */223223+224224+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))225225+ return -1;226226+227227+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);228228+229229+ /* After we recalibrate, we shouldn't get any packets for 2s. If230230+ * we do, it's likely that someone's finger was on the touchpad.231231+ * If someone's finger *was* on the touchpad, it's probably232232+ * miscalibrated. So, we should schedule another recalibration233233+ */234234+ priv->recalib_window = jiffies + msecs_to_jiffies(2000);235235+236236+ return 0;237237+}238238+239239+/*240240+ * This kills power to the touchpad; according to ALPS, current consumption241241+ * goes down to 50uA after running this. To turn power back on, we drive242242+ * MS-DAT low.243243+ */244244+static int hgpk_toggle_power(struct psmouse *psmouse, int enable)245245+{246246+ struct ps2dev *ps2dev = &psmouse->ps2dev;247247+ int timeo;248248+249249+ /* Added on D-series touchpads */250250+ if (psmouse->model < HGPK_MODEL_D)251251+ return 0;252252+253253+ if (enable) {254254+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);255255+256256+ /*257257+ * Sending a byte will drive MS-DAT low; this will wake up258258+ * the controller. Once we get an ACK back from it, it259259+ * means we can continue with the touchpad re-init. ALPS260260+ * tells us that 1s should be long enough, so set that as261261+ * the upper bound.262262+ */263263+ for (timeo = 20; timeo > 0; timeo--) {264264+ if (!ps2_sendbyte(&psmouse->ps2dev,265265+ PSMOUSE_CMD_DISABLE, 20))266266+ break;267267+ msleep(50);268268+ }269269+270270+ psmouse_reset(psmouse);271271+272272+ /* should be all set, enable the touchpad */273273+ ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);274274+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);275275+276276+ } else {277277+ hgpk_dbg(psmouse, "Powering off touchpad.\n");278278+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);279279+280280+ if (ps2_command(ps2dev, NULL, 0xec) ||281281+ ps2_command(ps2dev, NULL, 0xec) ||282282+ ps2_command(ps2dev, NULL, 0xea)) {283283+ return -1;284284+ }285285+286286+ /* probably won't see an ACK, the touchpad will be off */287287+ ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);288288+ }289289+290290+ return 0;291291+}292292+293293+static int hgpk_poll(struct psmouse *psmouse)294294+{295295+ /* We can't poll, so always return failure. */296296+ return -1;297297+}298298+299299+static int hgpk_reconnect(struct psmouse *psmouse)300300+{301301+ /* During suspend/resume the ps2 rails remain powered. We don't want302302+ * to do a reset because it's flush data out of buffers; however,303303+ * earlier prototypes (B1) had some brokenness that required a reset. */304304+ if (olpc_board_at_least(olpc_board(0xb2)))305305+ if (psmouse->ps2dev.serio->dev.power.power_state.event !=306306+ PM_EVENT_ON)307307+ return 0;308308+309309+ psmouse_reset(psmouse);310310+311311+ return 0;312312+}313313+314314+static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)315315+{316316+ struct hgpk_data *priv = psmouse->private;317317+318318+ return sprintf(buf, "%d\n", priv->powered);319319+}320320+321321+static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,322322+ const char *buf, size_t count)323323+{324324+ struct hgpk_data *priv = psmouse->private;325325+ unsigned long value;326326+ int err;327327+328328+ err = strict_strtoul(buf, 10, &value);329329+ if (err || value > 1)330330+ return -EINVAL;331331+332332+ if (value != priv->powered) {333333+ /*334334+ * hgpk_toggle_power will deal w/ state so335335+ * we're not racing w/ irq336336+ */337337+ err = hgpk_toggle_power(psmouse, value);338338+ if (!err)339339+ priv->powered = value;340340+ }341341+342342+ return err ? err : count;343343+}344344+345345+__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,346346+ hgpk_show_powered, hgpk_set_powered, 0);347347+348348+static void hgpk_disconnect(struct psmouse *psmouse)349349+{350350+ struct hgpk_data *priv = psmouse->private;351351+352352+ device_remove_file(&psmouse->ps2dev.serio->dev,353353+ &psmouse_attr_powered.dattr);354354+ psmouse_reset(psmouse);355355+ kfree(priv);356356+}357357+358358+static void hgpk_recalib_work(struct work_struct *work)359359+{360360+ struct delayed_work *w = container_of(work, struct delayed_work, work);361361+ struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);362362+ struct psmouse *psmouse = priv->psmouse;363363+364364+ hgpk_dbg(psmouse, "recalibrating touchpad..\n");365365+366366+ if (hgpk_force_recalibrate(psmouse))367367+ hgpk_err(psmouse, "recalibration failed!\n");368368+}369369+370370+static int hgpk_register(struct psmouse *psmouse)371371+{372372+ struct input_dev *dev = psmouse->dev;373373+ int err;374374+375375+ /* unset the things that psmouse-base sets which we don't have */376376+ __clear_bit(BTN_MIDDLE, dev->keybit);377377+378378+ /* set the things we do have */379379+ __set_bit(EV_KEY, dev->evbit);380380+ __set_bit(EV_REL, dev->evbit);381381+382382+ __set_bit(REL_X, dev->relbit);383383+ __set_bit(REL_Y, dev->relbit);384384+385385+ __set_bit(BTN_LEFT, dev->keybit);386386+ __set_bit(BTN_RIGHT, dev->keybit);387387+388388+ /* register handlers */389389+ psmouse->protocol_handler = hgpk_process_byte;390390+ psmouse->poll = hgpk_poll;391391+ psmouse->disconnect = hgpk_disconnect;392392+ psmouse->reconnect = hgpk_reconnect;393393+ psmouse->pktsize = 3;394394+395395+ /* Disable the idle resync. */396396+ psmouse->resync_time = 0;397397+ /* Reset after a lot of bad bytes. */398398+ psmouse->resetafter = 1024;399399+400400+ err = device_create_file(&psmouse->ps2dev.serio->dev,401401+ &psmouse_attr_powered.dattr);402402+ if (err)403403+ hgpk_err(psmouse, "Failed to create sysfs attribute\n");404404+405405+ return err;406406+}407407+408408+int hgpk_init(struct psmouse *psmouse)409409+{410410+ struct hgpk_data *priv;411411+ int err = -ENOMEM;412412+413413+ priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);414414+ if (!priv)415415+ goto alloc_fail;416416+417417+ psmouse->private = priv;418418+ priv->psmouse = psmouse;419419+ priv->powered = 1;420420+ INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);421421+422422+ err = psmouse_reset(psmouse);423423+ if (err)424424+ goto init_fail;425425+426426+ err = hgpk_register(psmouse);427427+ if (err)428428+ goto init_fail;429429+430430+ return 0;431431+432432+init_fail:433433+ kfree(priv);434434+alloc_fail:435435+ return err;436436+}437437+438438+static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)439439+{440440+ struct ps2dev *ps2dev = &psmouse->ps2dev;441441+ unsigned char param[3];442442+443443+ /* E7, E7, E7, E9 gets us a 3 byte identifier */444444+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||445445+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||446446+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||447447+ ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {448448+ return -EIO;449449+ }450450+451451+ hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);452452+453453+ /* HGPK signature: 0x67, 0x00, 0x<model> */454454+ if (param[0] != 0x67 || param[1] != 0x00)455455+ return -ENODEV;456456+457457+ hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);458458+459459+ return param[2];460460+}461461+462462+int hgpk_detect(struct psmouse *psmouse, int set_properties)463463+{464464+ int version;465465+466466+ version = hgpk_get_model(psmouse);467467+ if (version < 0)468468+ return version;469469+470470+ if (set_properties) {471471+ psmouse->vendor = "ALPS";472472+ psmouse->name = "HGPK";473473+ psmouse->model = version;474474+ }475475+476476+ return 0;477477+}
+49
drivers/input/mouse/hgpk.h
···11+/*22+ * OLPC HGPK (XO-1) touchpad PS/2 mouse driver33+ */44+55+#ifndef _HGPK_H66+#define _HGPK_H77+88+enum hgpk_model_t {99+ HGPK_MODEL_PREA = 0x0a, /* pre-B1s */1010+ HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */1111+ HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */1212+ HGPK_MODEL_C = 0x3c,1313+ HGPK_MODEL_D = 0x50, /* C1, mass production */1414+};1515+1616+struct hgpk_data {1717+ struct psmouse *psmouse;1818+ int powered;1919+ int count, x_tally, y_tally; /* hardware workaround stuff */2020+ unsigned long recalib_window;2121+ struct delayed_work recalib_wq;2222+};2323+2424+#define hgpk_dbg(psmouse, format, arg...) \2525+ dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)2626+#define hgpk_err(psmouse, format, arg...) \2727+ dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)2828+#define hgpk_info(psmouse, format, arg...) \2929+ dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)3030+#define hgpk_warn(psmouse, format, arg...) \3131+ dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)3232+#define hgpk_notice(psmouse, format, arg...) \3333+ dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)3434+3535+#ifdef CONFIG_MOUSE_PS2_OLPC3636+int hgpk_detect(struct psmouse *psmouse, int set_properties);3737+int hgpk_init(struct psmouse *psmouse);3838+#else3939+static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)4040+{4141+ return -ENODEV;4242+}4343+static inline int hgpk_init(struct psmouse *psmouse)4444+{4545+ return -ENODEV;4646+}4747+#endif4848+4949+#endif
+1-3
drivers/input/mouse/logips2pp.c
···157157static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)158158{159159 unsigned long value;160160- char *rest;161160162162- value = simple_strtoul(buf, &rest, 10);163163- if (*rest || value > 1)161161+ if (strict_strtoul(buf, 10, &value) || value > 1)164162 return -EINVAL;165163166164 ps2pp_set_smartscroll(psmouse, value);
···4343 u16 debounce_tol; /* tolerance used for filtering */4444 u16 debounce_rep; /* additional consecutive good readings4545 * required after the first two */4646+ int gpio_pendown; /* the GPIO used to decide the pendown4747+ * state if get_pendown_state == NULL4848+ */4649 int (*get_pendown_state)(void);4750 int (*filter_init) (struct ads7846_platform_data *pdata,4851 void **filter_data);