···11+rotary-encoder - a generic driver for GPIO connected devices22+Daniel Mack <daniel@caiaq.de>, Feb 200933+44+0. Function55+-----------66+77+Rotary encoders are devices which are connected to the CPU or other88+peripherals with two wires. The outputs are phase-shifted by 90 degrees99+and by triggering on falling and rising edges, the turn direction can1010+be determined.1111+1212+The phase diagram of these two outputs look like this:1313+1414+ _____ _____ _____1515+ | | | | | |1616+ Channel A ____| |_____| |_____| |____1717+1818+ : : : : : : : : : : : :1919+ __ _____ _____ _____2020+ | | | | | | |2121+ Channel B |_____| |_____| |_____| |__2222+2323+ : : : : : : : : : : : :2424+ Event a b c d a b c d a b c d2525+2626+ |<-------->|2727+ one step2828+2929+3030+For more information, please see3131+ http://en.wikipedia.org/wiki/Rotary_encoder3232+3333+3434+1. Events / state machine3535+-------------------------3636+3737+a) Rising edge on channel A, channel B in low state3838+ This state is used to recognize a clockwise turn3939+4040+b) Rising edge on channel B, channel A in high state4141+ When entering this state, the encoder is put into 'armed' state,4242+ meaning that there it has seen half the way of a one-step transition.4343+4444+c) Falling edge on channel A, channel B in high state4545+ This state is used to recognize a counter-clockwise turn4646+4747+d) Falling edge on channel B, channel A in low state4848+ Parking position. If the encoder enters this state, a full transition4949+ should have happend, unless it flipped back on half the way. The5050+ 'armed' state tells us about that.5151+5252+2. Platform requirements5353+------------------------5454+5555+As there is no hardware dependent call in this driver, the platform it is5656+used with must support gpiolib. Another requirement is that IRQs must be5757+able to fire on both edges.5858+5959+6060+3. Board integration6161+--------------------6262+6363+To use this driver in your system, register a platform_device with the6464+name 'rotary-encoder' and associate the IRQs and some specific platform6565+data with it.6666+6767+struct rotary_encoder_platform_data is declared in6868+include/linux/rotary-encoder.h and needs to be filled with the number of6969+steps the encoder has and can carry information about externally inverted7070+signals (because of used invertig buffer or other reasons).7171+7272+Because GPIO to IRQ mapping is platform specific, this information must7373+be given in seperately to the driver. See the example below.7474+7575+---------<snip>---------7676+7777+/* board support file example */7878+7979+#include <linux/input.h>8080+#include <linux/rotary_encoder.h>8181+8282+#define GPIO_ROTARY_A 18383+#define GPIO_ROTARY_B 28484+8585+static struct rotary_encoder_platform_data my_rotary_encoder_info = {8686+ .steps = 24,8787+ .axis = ABS_X,8888+ .gpio_a = GPIO_ROTARY_A,8989+ .gpio_b = GPIO_ROTARY_B,9090+ .inverted_a = 0,9191+ .inverted_b = 0,9292+};9393+9494+static struct platform_device rotary_encoder_device = {9595+ .name = "rotary-encoder",9696+ .id = 0,9797+ .dev = {9898+ .platform_data = &my_rotary_encoder_info,9999+ }100100+};101101+
···132132 }133133}134134135135+static void input_stop_autorepeat(struct input_dev *dev)136136+{137137+ del_timer(&dev->timer);138138+}139139+135140#define INPUT_IGNORE_EVENT 0136141#define INPUT_PASS_TO_HANDLERS 1137142#define INPUT_PASS_TO_DEVICE 2···172167 __change_bit(code, dev->key);173168 if (value)174169 input_start_autorepeat(dev, code);170170+ else171171+ input_stop_autorepeat(dev);175172 }176173177174 disposition = INPUT_PASS_TO_HANDLERS;···744737745738static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)746739{747747- int state = input_devices_state;748748-749740 poll_wait(file, &input_devices_poll_wait, wait);750750- if (state != input_devices_state)741741+ if (file->f_version != input_devices_state) {742742+ file->f_version = input_devices_state;751743 return POLLIN | POLLRDNORM;744744+ }752745753746 return 0;754747}
+64-75
drivers/input/keyboard/atkbd.c
···229229/*230230 * System-specific ketymap fixup routine231231 */232232-static void (*atkbd_platform_fixup)(struct atkbd *);232232+static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);233233+static void *atkbd_platform_fixup_data;233234234235static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,235236 ssize_t (*handler)(struct atkbd *, char *));···835834}836835837836/*837837+ * generate release events for the keycodes given in data838838+ */839839+static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,840840+ const void *data)841841+{842842+ const unsigned int *keys = data;843843+ unsigned int i;844844+845845+ if (atkbd->set == 2)846846+ for (i = 0; keys[i] != -1U; i++)847847+ __set_bit(keys[i], atkbd->force_release_mask);848848+}849849+850850+/*838851 * Most special keys (Fn+F?) on Dell laptops do not generate release839852 * events so we have to do it ourselves.840853 */841841-static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)842842-{843843- static const unsigned int forced_release_keys[] = {844844- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,845845- };846846- int i;847847-848848- if (atkbd->set == 2)849849- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)850850- __set_bit(forced_release_keys[i],851851- atkbd->force_release_mask);852852-}854854+static unsigned int atkbd_dell_laptop_forced_release_keys[] = {855855+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U856856+};853857854858/*855859 * Perform fixup for HP system that doesn't generate release856860 * for its video switch857861 */858858-static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)859859-{860860- static const unsigned int forced_release_keys[] = {861861- 0x94,862862- };863863- int i;864864-865865- if (atkbd->set == 2)866866- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)867867- __set_bit(forced_release_keys[i],868868- atkbd->force_release_mask);869869-}862862+static unsigned int atkbd_hp_forced_release_keys[] = {863863+ 0x94, -1U864864+};870865871866/*872867 * Inventec system with broken key release on volume keys873868 */874874-static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)875875-{876876- const unsigned int forced_release_keys[] = {877877- 0xae, 0xb0,878878- };879879- int i;880880-881881- if (atkbd->set == 2)882882- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)883883- __set_bit(forced_release_keys[i],884884- atkbd->force_release_mask);885885-}869869+static unsigned int atkbd_inventec_forced_release_keys[] = {870870+ 0xae, 0xb0, -1U871871+};886872887873/*888874 * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release889875 * for its volume buttons890876 */891891-static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd)892892-{893893- const unsigned int forced_release_keys[] = {894894- 0xae, 0xb0,895895- };896896- int i;897897-898898- if (atkbd->set == 2)899899- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)900900- __set_bit(forced_release_keys[i],901901- atkbd->force_release_mask);902902-}877877+static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {878878+ 0xae, 0xb0, -1U879879+};903880904881/*905882 * Samsung NC10 with Fn+F? key release not working906883 */907907-static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd)908908-{909909- const unsigned int forced_release_keys[] = {910910- 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9,911911- };912912- int i;884884+static unsigned int atkbd_samsung_forced_release_keys[] = {885885+ 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U886886+};913887914914- if (atkbd->set == 2)915915- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)916916- __set_bit(forced_release_keys[i],917917- atkbd->force_release_mask);918918-}888888+/*889889+ * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop890890+ * do not generate release events so we have to do it ourselves.891891+ */892892+static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {893893+ 0xb0, 0xae, -1U894894+};919895920896/*921897 * atkbd_set_keycode_table() initializes keyboard's keycode table···945967 * Perform additional fixups946968 */947969 if (atkbd_platform_fixup)948948- atkbd_platform_fixup(atkbd);970970+ atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data);949971}950972951973/*···14701492 return sprintf(buf, "%lu\n", atkbd->err_count);14711493}1472149414731473-static int __init atkbd_setup_fixup(const struct dmi_system_id *id)14951495+static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)14741496{14751475- atkbd_platform_fixup = id->driver_data;14971497+ atkbd_platform_fixup = atkbd_apply_forced_release_keylist;14981498+ atkbd_platform_fixup_data = id->driver_data;14991499+14761500 return 0;14771501}14781502···14851505 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),14861506 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */14871507 },14881488- .callback = atkbd_setup_fixup,14891489- .driver_data = atkbd_dell_laptop_keymap_fixup,15081508+ .callback = atkbd_setup_forced_release,15091509+ .driver_data = atkbd_dell_laptop_forced_release_keys,14901510 },14911511 {14921512 .ident = "Dell Laptop",···14941514 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),14951515 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */14961516 },14971497- .callback = atkbd_setup_fixup,14981498- .driver_data = atkbd_dell_laptop_keymap_fixup,15171517+ .callback = atkbd_setup_forced_release,15181518+ .driver_data = atkbd_dell_laptop_forced_release_keys,14991519 },15001520 {15011521 .ident = "HP 2133",···15031523 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),15041524 DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),15051525 },15061506- .callback = atkbd_setup_fixup,15071507- .driver_data = atkbd_hp_keymap_fixup,15261526+ .callback = atkbd_setup_forced_release,15271527+ .driver_data = atkbd_hp_forced_release_keys,15081528 },15091529 {15101530 .ident = "HP Pavilion ZV6100",···15121532 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),15131533 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),15141534 },15151515- .callback = atkbd_setup_fixup,15161516- .driver_data = atkbd_hp_zv6100_keymap_fixup,15351535+ .callback = atkbd_setup_forced_release,15361536+ .driver_data = atkbd_hp_zv6100_forced_release_keys,15171537 },15181538 {15191539 .ident = "Inventec Symphony",···15211541 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),15221542 DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),15231543 },15241524- .callback = atkbd_setup_fixup,15251525- .driver_data = atkbd_inventec_keymap_fixup,15441544+ .callback = atkbd_setup_forced_release,15451545+ .driver_data = atkbd_inventec_forced_release_keys,15261546 },15271547 {15281548 .ident = "Samsung NC10",···15301550 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),15311551 DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),15321552 },15331533- .callback = atkbd_setup_fixup,15341534- .driver_data = atkbd_samsung_keymap_fixup,15531553+ .callback = atkbd_setup_forced_release,15541554+ .driver_data = atkbd_samsung_forced_release_keys,15551555+ },15561556+ {15571557+ .ident = "Fujitsu Amilo PA 1510",15581558+ .matches = {15591559+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),15601560+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),15611561+ },15621562+ .callback = atkbd_setup_forced_release,15631563+ .driver_data = atkbd_amilo_pa1510_forced_release_keys,15351564 },15361565 { }15371566};
+2-2
drivers/input/keyboard/bf54x-keys.c
···211211212212 if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||213213 !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {214214- printk(KERN_ERR DRV_NAME215215- ": Invalid Debounce/Columdrive Time from pdata\n");214214+ printk(KERN_WARNING DRV_NAME215215+ ": Invalid Debounce/Columndrive Time in platform data\n");216216 bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */217217 } else {218218 bfin_write_KPAD_MSEL(
+82-62
drivers/input/keyboard/hilkbd.c
···198198}199199200200201201-/* initialise HIL */202202-static int __init203203-hil_keyb_init(void)201201+/* initialize HIL */202202+static int __devinit hil_keyb_init(void)204203{205204 unsigned char c;206205 unsigned int i, kbid;207206 wait_queue_head_t hil_wait;208207 int err;209208210210- if (hil_dev.dev) {209209+ if (hil_dev.dev)211210 return -ENODEV; /* already initialized */212212- }213211212212+ init_waitqueue_head(&hil_wait);214213 spin_lock_init(&hil_dev.lock);214214+215215 hil_dev.dev = input_allocate_device();216216 if (!hil_dev.dev)217217 return -ENOMEM;218218219219-#if defined(CONFIG_HP300)220220- if (!MACH_IS_HP300) {221221- err = -ENODEV;222222- goto err1;223223- }224224- if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {225225- printk(KERN_ERR "HIL: hardware register was not found\n");226226- err = -ENODEV;227227- goto err1;228228- }229229- if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {230230- printk(KERN_ERR "HIL: IOPORT region already used\n");231231- err = -EIO;232232- goto err1;233233- }234234-#endif235235-236219 err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);237220 if (err) {238221 printk(KERN_ERR "HIL: Can't get IRQ\n");239239- goto err2;222222+ goto err1;240223 }241224242225 /* Turn on interrupts */···229246 hil_dev.valid = 0; /* clear any pending data */230247 hil_do(HIL_READKBDSADR, NULL, 0);231248232232- init_waitqueue_head(&hil_wait);233233- wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);234234- if (!hil_dev.valid) {249249+ wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ);250250+ if (!hil_dev.valid)235251 printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");236236- }237252238253 c = hil_dev.c;239254 hil_dev.valid = 0;···249268250269 for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)251270 if (hphilkeyb_keycode[i] != KEY_RESERVED)252252- set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);271271+ __set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);253272254273 hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);255274 hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |···268287 err = input_register_device(hil_dev.dev);269288 if (err) {270289 printk(KERN_ERR "HIL: Can't register device\n");271271- goto err3;290290+ goto err2;272291 }292292+273293 printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",274294 hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);275295276296 return 0;277297278278-err3:279279- hil_do(HIL_INTOFF, NULL, 0);280280- disable_irq(HIL_IRQ);281281- free_irq(HIL_IRQ, hil_dev.dev_id);282298err2:283283-#if defined(CONFIG_HP300)284284- release_region(HILBASE + HIL_DATA, 2);299299+ hil_do(HIL_INTOFF, NULL, 0);300300+ free_irq(HIL_IRQ, hil_dev.dev_id);285301err1:286286-#endif287302 input_free_device(hil_dev.dev);288303 hil_dev.dev = NULL;289304 return err;290305}291306307307+static void __devexit hil_keyb_exit(void)308308+{309309+ if (HIL_IRQ)310310+ free_irq(HIL_IRQ, hil_dev.dev_id);311311+312312+ /* Turn off interrupts */313313+ hil_do(HIL_INTOFF, NULL, 0);314314+315315+ input_unregister_device(hil_dev.dev);316316+ hil_dev.dev = NULL;317317+}292318293319#if defined(CONFIG_PARISC)294294-static int __init295295-hil_init_chip(struct parisc_device *dev)320320+static int __devinit hil_probe_chip(struct parisc_device *dev)296321{322322+ /* Only allow one HIL keyboard */323323+ if (hil_dev.dev)324324+ return -ENODEV;325325+297326 if (!dev->irq) {298298- printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);327327+ printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n",328328+ (void *)dev->hpa.start);299329 return -ENODEV;300330 }301331···319327 return hil_keyb_init();320328}321329330330+static int __devexit hil_remove_chip(struct parisc_device *dev)331331+{332332+ hil_keyb_exit();333333+334334+ return 0;335335+}336336+322337static struct parisc_device_id hil_tbl[] = {323338 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },324339 { 0, }325340};326341342342+#if 0343343+/* Disabled to avoid conflicts with the HP SDC HIL drivers */327344MODULE_DEVICE_TABLE(parisc, hil_tbl);345345+#endif328346329347static struct parisc_driver hil_driver = {330330- .name = "hil",331331- .id_table = hil_tbl,332332- .probe = hil_init_chip,348348+ .name = "hil",349349+ .id_table = hil_tbl,350350+ .probe = hil_probe_chip,351351+ .remove = __devexit_p(hil_remove_chip),333352};334334-#endif /* CONFIG_PARISC */335335-336353337354static int __init hil_init(void)338355{339339-#if defined(CONFIG_PARISC)340356 return register_parisc_driver(&hil_driver);341341-#else342342- return hil_keyb_init();343343-#endif344357}345345-346358347359static void __exit hil_exit(void)348360{349349- if (HIL_IRQ) {350350- disable_irq(HIL_IRQ);351351- free_irq(HIL_IRQ, hil_dev.dev_id);361361+ unregister_parisc_driver(&hil_driver);362362+}363363+364364+#else /* !CONFIG_PARISC */365365+366366+static int __init hil_init(void)367367+{368368+ int error;369369+370370+ /* Only allow one HIL keyboard */371371+ if (hil_dev.dev)372372+ return -EBUSY;373373+374374+ if (!MACH_IS_HP300)375375+ return -ENODEV;376376+377377+ if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {378378+ printk(KERN_ERR "HIL: hardware register was not found\n");379379+ return -ENODEV;352380 }353381354354- /* Turn off interrupts */355355- hil_do(HIL_INTOFF, NULL, 0);382382+ if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {383383+ printk(KERN_ERR "HIL: IOPORT region already used\n");384384+ return -EIO;385385+ }356386357357- input_unregister_device(hil_dev.dev);387387+ error = hil_keyb_init();388388+ if (error) {389389+ release_region(HILBASE + HIL_DATA, 2);390390+ return error;391391+ }358392359359- hil_dev.dev = NULL;360360-361361-#if defined(CONFIG_PARISC)362362- unregister_parisc_driver(&hil_driver);363363-#else364364- release_region(HILBASE+HIL_DATA, 2);365365-#endif393393+ return 0;366394}395395+396396+static void __exit hil_exit(void)397397+{398398+ hil_keyb_exit();399399+ release_region(HILBASE + HIL_DATA, 2);400400+}401401+402402+#endif /* CONFIG_PARISC */367403368404module_init(hil_init);369405module_exit(hil_exit);
+23
drivers/input/misc/Kconfig
···227227 Say Y to include support for delivering PMU events via input228228 layer on NXP PCF50633.229229230230+config INPUT_GPIO_ROTARY_ENCODER231231+ tristate "Rotary encoders connected to GPIO pins"232232+ depends on GPIOLIB && GENERIC_GPIO233233+ help234234+ Say Y here to add support for rotary encoders connected to GPIO lines.235235+ Check file:Documentation/incput/rotary_encoder.txt for more236236+ information.237237+238238+ To compile this driver as a module, choose M here: the239239+ module will be called rotary_encoder.240240+241241+config INPUT_RB532_BUTTON242242+ tristate "Mikrotik Routerboard 532 button interface"243243+ depends on MIKROTIK_RB532244244+ depends on GPIOLIB && GENERIC_GPIO245245+ select INPUT_POLLDEV246246+ help247247+ Say Y here if you want support for the S1 button built into248248+ Mikrotik's Routerboard 532.249249+250250+ To compile this driver as a module, choose M here: the251251+ module will be called rb532_button.252252+230253endif
···3131 * newly configured "channel".3232 */33333434-static unsigned int channel_mask = 0xFFFF;3535-module_param(channel_mask, uint, 0644);3434+enum {3535+ ATI_REMOTE2_MAX_CHANNEL_MASK = 0xFFFF,3636+ ATI_REMOTE2_MAX_MODE_MASK = 0x1F,3737+};3838+3939+static int ati_remote2_set_mask(const char *val,4040+ struct kernel_param *kp, unsigned int max)4141+{4242+ unsigned long mask;4343+ int ret;4444+4545+ if (!val)4646+ return -EINVAL;4747+4848+ ret = strict_strtoul(val, 0, &mask);4949+ if (ret)5050+ return ret;5151+5252+ if (mask & ~max)5353+ return -EINVAL;5454+5555+ *(unsigned int *)kp->arg = mask;5656+5757+ return 0;5858+}5959+6060+static int ati_remote2_set_channel_mask(const char *val,6161+ struct kernel_param *kp)6262+{6363+ pr_debug("%s()\n", __func__);6464+6565+ return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);6666+}6767+6868+static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp)6969+{7070+ pr_debug("%s()\n", __func__);7171+7272+ return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);7373+}7474+7575+static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp)7676+{7777+ pr_debug("%s()\n", __func__);7878+7979+ return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);8080+}8181+8282+static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)8383+{8484+ pr_debug("%s()\n", __func__);8585+8686+ return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg);8787+}8888+8989+static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;9090+#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)9191+#define param_set_channel_mask ati_remote2_set_channel_mask9292+#define param_get_channel_mask ati_remote2_get_channel_mask9393+module_param(channel_mask, channel_mask, 0644);3694MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");37953838-static unsigned int mode_mask = 0x1F;3939-module_param(mode_mask, uint, 0644);9696+static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;9797+#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)9898+#define param_set_mode_mask ati_remote2_set_mode_mask9999+#define param_get_mode_mask ati_remote2_get_mode_mask100100+module_param(mode_mask, mode_mask, 0644);40101MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");4110242103static struct usb_device_id ati_remote2_id_table[] = {···194133 u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];195134196135 unsigned int flags;136136+137137+ unsigned int channel_mask;138138+ unsigned int mode_mask;197139};198140199141static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);200142static void ati_remote2_disconnect(struct usb_interface *interface);201143static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);202144static int ati_remote2_resume(struct usb_interface *interface);145145+static int ati_remote2_reset_resume(struct usb_interface *interface);146146+static int ati_remote2_pre_reset(struct usb_interface *interface);147147+static int ati_remote2_post_reset(struct usb_interface *interface);203148204149static struct usb_driver ati_remote2_driver = {205150 .name = "ati_remote2",···214147 .id_table = ati_remote2_id_table,215148 .suspend = ati_remote2_suspend,216149 .resume = ati_remote2_resume,150150+ .reset_resume = ati_remote2_reset_resume,151151+ .pre_reset = ati_remote2_pre_reset,152152+ .post_reset = ati_remote2_post_reset,217153 .supports_autosuspend = 1,218154};219155···308238309239 channel = data[0] >> 4;310240311311- if (!((1 << channel) & channel_mask))241241+ if (!((1 << channel) & ar2->channel_mask))312242 return;313243314244 mode = data[0] & 0x0F;···320250 return;321251 }322252323323- if (!((1 << mode) & mode_mask))253253+ if (!((1 << mode) & ar2->mode_mask))324254 return;325255326256 input_event(idev, EV_REL, REL_X, (s8) data[1]);···347277348278 channel = data[0] >> 4;349279350350- if (!((1 << channel) & channel_mask))280280+ if (!((1 << channel) & ar2->channel_mask))351281 return;352282353283 mode = data[0] & 0x0F;···375305 ar2->mode = mode;376306 }377307378378- if (!((1 << mode) & mode_mask))308308+ if (!((1 << mode) & ar2->mode_mask))379309 return;380310381311 index = ati_remote2_lookup(hw_code);···480410 int index, mode;481411482412 mode = scancode >> 8;483483- if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))413413+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))484414 return -EINVAL;485415486416 index = ati_remote2_lookup(scancode & 0xFF);···497427 int index, mode, old_keycode;498428499429 mode = scancode >> 8;500500- if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))430430+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))501431 return -EINVAL;502432503433 index = ati_remote2_lookup(scancode & 0xFF);···620550 }621551}622552623623-static int ati_remote2_setup(struct ati_remote2 *ar2)553553+static int ati_remote2_setup(struct ati_remote2 *ar2, unsigned int ch_mask)624554{625555 int r, i, channel;626556···635565636566 channel = 0;637567 for (i = 0; i < 16; i++) {638638- if ((1 << i) & channel_mask) {639639- if (!(~(1 << i) & 0xFFFF & channel_mask))568568+ if ((1 << i) & ch_mask) {569569+ if (!(~(1 << i) & ch_mask))640570 channel = i + 1;641571 break;642572 }···654584655585 return 0;656586}587587+588588+static ssize_t ati_remote2_show_channel_mask(struct device *dev,589589+ struct device_attribute *attr,590590+ char *buf)591591+{592592+ struct usb_device *udev = to_usb_device(dev);593593+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);594594+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);595595+596596+ return sprintf(buf, "0x%04x\n", ar2->channel_mask);597597+}598598+599599+static ssize_t ati_remote2_store_channel_mask(struct device *dev,600600+ struct device_attribute *attr,601601+ const char *buf, size_t count)602602+{603603+ struct usb_device *udev = to_usb_device(dev);604604+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);605605+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);606606+ unsigned long mask;607607+ int r;608608+609609+ if (strict_strtoul(buf, 0, &mask))610610+ return -EINVAL;611611+612612+ if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK)613613+ return -EINVAL;614614+615615+ r = usb_autopm_get_interface(ar2->intf[0]);616616+ if (r) {617617+ dev_err(&ar2->intf[0]->dev,618618+ "%s(): usb_autopm_get_interface() = %d\n", __func__, r);619619+ return r;620620+ }621621+622622+ mutex_lock(&ati_remote2_mutex);623623+624624+ if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask))625625+ ar2->channel_mask = mask;626626+627627+ mutex_unlock(&ati_remote2_mutex);628628+629629+ usb_autopm_put_interface(ar2->intf[0]);630630+631631+ return count;632632+}633633+634634+static ssize_t ati_remote2_show_mode_mask(struct device *dev,635635+ struct device_attribute *attr,636636+ char *buf)637637+{638638+ struct usb_device *udev = to_usb_device(dev);639639+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);640640+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);641641+642642+ return sprintf(buf, "0x%02x\n", ar2->mode_mask);643643+}644644+645645+static ssize_t ati_remote2_store_mode_mask(struct device *dev,646646+ struct device_attribute *attr,647647+ const char *buf, size_t count)648648+{649649+ struct usb_device *udev = to_usb_device(dev);650650+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);651651+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);652652+ unsigned long mask;653653+654654+ if (strict_strtoul(buf, 0, &mask))655655+ return -EINVAL;656656+657657+ if (mask & ~ATI_REMOTE2_MAX_MODE_MASK)658658+ return -EINVAL;659659+660660+ ar2->mode_mask = mask;661661+662662+ return count;663663+}664664+665665+static DEVICE_ATTR(channel_mask, 0644, ati_remote2_show_channel_mask,666666+ ati_remote2_store_channel_mask);667667+668668+static DEVICE_ATTR(mode_mask, 0644, ati_remote2_show_mode_mask,669669+ ati_remote2_store_mode_mask);670670+671671+static struct attribute *ati_remote2_attrs[] = {672672+ &dev_attr_channel_mask.attr,673673+ &dev_attr_mode_mask.attr,674674+ NULL,675675+};676676+677677+static struct attribute_group ati_remote2_attr_group = {678678+ .attrs = ati_remote2_attrs,679679+};657680658681static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)659682{···778615 if (r)779616 goto fail2;780617781781- r = ati_remote2_setup(ar2);618618+ ar2->channel_mask = channel_mask;619619+ ar2->mode_mask = mode_mask;620620+621621+ r = ati_remote2_setup(ar2, ar2->channel_mask);782622 if (r)783623 goto fail2;784624···790624791625 strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));792626793793- r = ati_remote2_input_init(ar2);627627+ r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);794628 if (r)795629 goto fail2;630630+631631+ r = ati_remote2_input_init(ar2);632632+ if (r)633633+ goto fail3;796634797635 usb_set_intfdata(interface, ar2);798636···804634805635 return 0;806636637637+ fail3:638638+ sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);807639 fail2:808640 ati_remote2_urb_cleanup(ar2);809809-810641 usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);811642 fail1:812643 kfree(ar2);···827656 usb_set_intfdata(interface, NULL);828657829658 input_unregister_device(ar2->idev);659659+660660+ sysfs_remove_group(&ar2->udev->dev.kobj, &ati_remote2_attr_group);830661831662 ati_remote2_urb_cleanup(ar2);832663···882709883710 if (!r)884711 ar2->flags &= ~ATI_REMOTE2_SUSPENDED;712712+713713+ mutex_unlock(&ati_remote2_mutex);714714+715715+ return r;716716+}717717+718718+static int ati_remote2_reset_resume(struct usb_interface *interface)719719+{720720+ struct ati_remote2 *ar2;721721+ struct usb_host_interface *alt = interface->cur_altsetting;722722+ int r = 0;723723+724724+ if (alt->desc.bInterfaceNumber)725725+ return 0;726726+727727+ ar2 = usb_get_intfdata(interface);728728+729729+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);730730+731731+ mutex_lock(&ati_remote2_mutex);732732+733733+ r = ati_remote2_setup(ar2, ar2->channel_mask);734734+ if (r)735735+ goto out;736736+737737+ if (ar2->flags & ATI_REMOTE2_OPENED)738738+ r = ati_remote2_submit_urbs(ar2);739739+740740+ if (!r)741741+ ar2->flags &= ~ATI_REMOTE2_SUSPENDED;742742+743743+ out:744744+ mutex_unlock(&ati_remote2_mutex);745745+746746+ return r;747747+}748748+749749+static int ati_remote2_pre_reset(struct usb_interface *interface)750750+{751751+ struct ati_remote2 *ar2;752752+ struct usb_host_interface *alt = interface->cur_altsetting;753753+754754+ if (alt->desc.bInterfaceNumber)755755+ return 0;756756+757757+ ar2 = usb_get_intfdata(interface);758758+759759+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);760760+761761+ mutex_lock(&ati_remote2_mutex);762762+763763+ if (ar2->flags == ATI_REMOTE2_OPENED)764764+ ati_remote2_kill_urbs(ar2);765765+766766+ return 0;767767+}768768+769769+static int ati_remote2_post_reset(struct usb_interface *interface)770770+{771771+ struct ati_remote2 *ar2;772772+ struct usb_host_interface *alt = interface->cur_altsetting;773773+ int r = 0;774774+775775+ if (alt->desc.bInterfaceNumber)776776+ return 0;777777+778778+ ar2 = usb_get_intfdata(interface);779779+780780+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);781781+782782+ if (ar2->flags == ATI_REMOTE2_OPENED)783783+ r = ati_remote2_submit_urbs(ar2);885784886785 mutex_unlock(&ati_remote2_mutex);887786
+120
drivers/input/misc/rb532_button.c
···11+/*22+ * Support for the S1 button on Routerboard 53233+ *44+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>55+ */66+77+#include <linux/input-polldev.h>88+#include <linux/module.h>99+#include <linux/platform_device.h>1010+1111+#include <asm/mach-rc32434/gpio.h>1212+#include <asm/mach-rc32434/rb.h>1313+1414+#define DRV_NAME "rb532-button"1515+1616+#define RB532_BTN_RATE 100 /* msec */1717+#define RB532_BTN_KSYM BTN_01818+1919+/* The S1 button state is provided by GPIO pin 1. But as this2020+ * pin is also used for uart input as alternate function, the2121+ * operational modes must be switched first:2222+ * 1) disable uart using set_latch_u5()2323+ * 2) turn off alternate function implicitly through2424+ * gpio_direction_input()2525+ * 3) read the GPIO's current value2626+ * 4) undo step 2 by enabling alternate function (in this2727+ * mode the GPIO direction is fixed, so no change needed)2828+ * 5) turn on uart again2929+ * The GPIO value occurs to be inverted, so pin high means3030+ * button is not pressed.3131+ */3232+static bool rb532_button_pressed(void)3333+{3434+ int val;3535+3636+ set_latch_u5(0, LO_FOFF);3737+ gpio_direction_input(GPIO_BTN_S1);3838+3939+ val = gpio_get_value(GPIO_BTN_S1);4040+4141+ rb532_gpio_set_func(GPIO_BTN_S1);4242+ set_latch_u5(LO_FOFF, 0);4343+4444+ return !val;4545+}4646+4747+static void rb532_button_poll(struct input_polled_dev *poll_dev)4848+{4949+ input_report_key(poll_dev->input, RB532_BTN_KSYM,5050+ rb532_button_pressed());5151+ input_sync(poll_dev->input);5252+}5353+5454+static int __devinit rb532_button_probe(struct platform_device *pdev)5555+{5656+ struct input_polled_dev *poll_dev;5757+ int error;5858+5959+ poll_dev = input_allocate_polled_device();6060+ if (!poll_dev)6161+ return -ENOMEM;6262+6363+ poll_dev->poll = rb532_button_poll;6464+ poll_dev->poll_interval = RB532_BTN_RATE;6565+6666+ poll_dev->input->name = "rb532 button";6767+ poll_dev->input->phys = "rb532/button0";6868+ poll_dev->input->id.bustype = BUS_HOST;6969+ poll_dev->input->dev.parent = &pdev->dev;7070+7171+ dev_set_drvdata(&pdev->dev, poll_dev);7272+7373+ input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM);7474+7575+ error = input_register_polled_device(poll_dev);7676+ if (error) {7777+ input_free_polled_device(poll_dev);7878+ return error;7979+ }8080+8181+ return 0;8282+}8383+8484+static int __devexit rb532_button_remove(struct platform_device *pdev)8585+{8686+ struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev);8787+8888+ input_unregister_polled_device(poll_dev);8989+ input_free_polled_device(poll_dev);9090+ dev_set_drvdata(&pdev->dev, NULL);9191+9292+ return 0;9393+}9494+9595+static struct platform_driver rb532_button_driver = {9696+ .probe = rb532_button_probe,9797+ .remove = __devexit_p(rb532_button_remove),9898+ .driver = {9999+ .name = DRV_NAME,100100+ .owner = THIS_MODULE,101101+ },102102+};103103+104104+static int __init rb532_button_init(void)105105+{106106+ return platform_driver_register(&rb532_button_driver);107107+}108108+109109+static void __exit rb532_button_exit(void)110110+{111111+ platform_driver_unregister(&rb532_button_driver);112112+}113113+114114+module_init(rb532_button_init);115115+module_exit(rb532_button_exit);116116+117117+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");118118+MODULE_LICENSE("GPL");119119+MODULE_DESCRIPTION("Support for S1 button on Routerboard 532");120120+MODULE_ALIAS("platform:" DRV_NAME);
+221
drivers/input/misc/rotary_encoder.c
···11+/*22+ * rotary_encoder.c33+ *44+ * (c) 2009 Daniel Mack <daniel@caiaq.de>55+ *66+ * state machine code inspired by code from Tim Ruetz77+ *88+ * A generic driver for rotary encoders connected to GPIO lines.99+ * See file:Documentation/input/rotary_encoder.txt for more information1010+ *1111+ * This program is free software; you can redistribute it and/or modify1212+ * it under the terms of the GNU General Public License version 2 as1313+ * published by the Free Software Foundation.1414+ */1515+1616+#include <linux/kernel.h>1717+#include <linux/module.h>1818+#include <linux/init.h>1919+#include <linux/interrupt.h>2020+#include <linux/input.h>2121+#include <linux/device.h>2222+#include <linux/platform_device.h>2323+#include <linux/gpio.h>2424+#include <linux/rotary_encoder.h>2525+2626+#define DRV_NAME "rotary-encoder"2727+2828+struct rotary_encoder {2929+ unsigned int irq_a;3030+ unsigned int irq_b;3131+ unsigned int pos;3232+ unsigned int armed;3333+ unsigned int dir;3434+ struct input_dev *input;3535+ struct rotary_encoder_platform_data *pdata;3636+};3737+3838+static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)3939+{4040+ struct rotary_encoder *encoder = dev_id;4141+ struct rotary_encoder_platform_data *pdata = encoder->pdata;4242+ int a = !!gpio_get_value(pdata->gpio_a);4343+ int b = !!gpio_get_value(pdata->gpio_b);4444+ int state;4545+4646+ a ^= pdata->inverted_a;4747+ b ^= pdata->inverted_b;4848+ state = (a << 1) | b;4949+5050+ switch (state) {5151+5252+ case 0x0:5353+ if (!encoder->armed)5454+ break;5555+5656+ if (encoder->dir) {5757+ /* turning counter-clockwise */5858+ encoder->pos += pdata->steps;5959+ encoder->pos--;6060+ encoder->pos %= pdata->steps;6161+ } else {6262+ /* turning clockwise */6363+ encoder->pos++;6464+ encoder->pos %= pdata->steps;6565+ }6666+6767+ input_report_abs(encoder->input, pdata->axis, encoder->pos);6868+ input_sync(encoder->input);6969+7070+ encoder->armed = 0;7171+ break;7272+7373+ case 0x1:7474+ case 0x2:7575+ if (encoder->armed)7676+ encoder->dir = state - 1;7777+ break;7878+7979+ case 0x3:8080+ encoder->armed = 1;8181+ break;8282+ }8383+8484+ return IRQ_HANDLED;8585+}8686+8787+static int __devinit rotary_encoder_probe(struct platform_device *pdev)8888+{8989+ struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;9090+ struct rotary_encoder *encoder;9191+ struct input_dev *input;9292+ int err;9393+9494+ if (!pdata || !pdata->steps) {9595+ dev_err(&pdev->dev, "invalid platform data\n");9696+ return -ENOENT;9797+ }9898+9999+ encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);100100+ input = input_allocate_device();101101+ if (!encoder || !input) {102102+ dev_err(&pdev->dev, "failed to allocate memory for device\n");103103+ err = -ENOMEM;104104+ goto exit_free_mem;105105+ }106106+107107+ encoder->input = input;108108+ encoder->pdata = pdata;109109+ encoder->irq_a = gpio_to_irq(pdata->gpio_a);110110+ encoder->irq_b = gpio_to_irq(pdata->gpio_b);111111+112112+ /* create and register the input driver */113113+ input->name = pdev->name;114114+ input->id.bustype = BUS_HOST;115115+ input->dev.parent = &pdev->dev;116116+ input->evbit[0] = BIT_MASK(EV_ABS);117117+ input_set_abs_params(encoder->input,118118+ pdata->axis, 0, pdata->steps, 0, 1);119119+120120+ err = input_register_device(input);121121+ if (err) {122122+ dev_err(&pdev->dev, "failed to register input device\n");123123+ goto exit_free_mem;124124+ }125125+126126+ /* request the GPIOs */127127+ err = gpio_request(pdata->gpio_a, DRV_NAME);128128+ if (err) {129129+ dev_err(&pdev->dev, "unable to request GPIO %d\n",130130+ pdata->gpio_a);131131+ goto exit_unregister_input;132132+ }133133+134134+ err = gpio_request(pdata->gpio_b, DRV_NAME);135135+ if (err) {136136+ dev_err(&pdev->dev, "unable to request GPIO %d\n",137137+ pdata->gpio_b);138138+ goto exit_free_gpio_a;139139+ }140140+141141+ /* request the IRQs */142142+ err = request_irq(encoder->irq_a, &rotary_encoder_irq,143143+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,144144+ DRV_NAME, encoder);145145+ if (err) {146146+ dev_err(&pdev->dev, "unable to request IRQ %d\n",147147+ encoder->irq_a);148148+ goto exit_free_gpio_b;149149+ }150150+151151+ err = request_irq(encoder->irq_b, &rotary_encoder_irq,152152+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,153153+ DRV_NAME, encoder);154154+ if (err) {155155+ dev_err(&pdev->dev, "unable to request IRQ %d\n",156156+ encoder->irq_b);157157+ goto exit_free_irq_a;158158+ }159159+160160+ platform_set_drvdata(pdev, encoder);161161+162162+ return 0;163163+164164+exit_free_irq_a:165165+ free_irq(encoder->irq_a, encoder);166166+exit_free_gpio_b:167167+ gpio_free(pdata->gpio_b);168168+exit_free_gpio_a:169169+ gpio_free(pdata->gpio_a);170170+exit_unregister_input:171171+ input_unregister_device(input);172172+ input = NULL; /* so we don't try to free it */173173+exit_free_mem:174174+ input_free_device(input);175175+ kfree(encoder);176176+ return err;177177+}178178+179179+static int __devexit rotary_encoder_remove(struct platform_device *pdev)180180+{181181+ struct rotary_encoder *encoder = platform_get_drvdata(pdev);182182+ struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;183183+184184+ free_irq(encoder->irq_a, encoder);185185+ free_irq(encoder->irq_b, encoder);186186+ gpio_free(pdata->gpio_a);187187+ gpio_free(pdata->gpio_b);188188+ input_unregister_device(encoder->input);189189+ platform_set_drvdata(pdev, NULL);190190+ kfree(encoder);191191+192192+ return 0;193193+}194194+195195+static struct platform_driver rotary_encoder_driver = {196196+ .probe = rotary_encoder_probe,197197+ .remove = __devexit_p(rotary_encoder_remove),198198+ .driver = {199199+ .name = DRV_NAME,200200+ .owner = THIS_MODULE,201201+ }202202+};203203+204204+static int __init rotary_encoder_init(void)205205+{206206+ return platform_driver_register(&rotary_encoder_driver);207207+}208208+209209+static void __exit rotary_encoder_exit(void)210210+{211211+ platform_driver_unregister(&rotary_encoder_driver);212212+}213213+214214+module_init(rotary_encoder_init);215215+module_exit(rotary_encoder_exit);216216+217217+MODULE_ALIAS("platform:" DRV_NAME);218218+MODULE_DESCRIPTION("GPIO rotary encoder driver");219219+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");220220+MODULE_LICENSE("GPL v2");221221+
+11
drivers/input/mouse/Kconfig
···292292 help293293 Say Y here to support PXA930 Trackball mouse.294294295295+config MOUSE_MAPLE296296+ tristate "Maple mouse (for the Dreamcast)"297297+ depends on MAPLE298298+ help299299+ This driver supports the Maple mouse on the SEGA Dreamcast.300300+301301+ Most Dreamcast users, who have a mouse, will say Y here.302302+303303+ To compile this driver as a module choose M here: the module will be304304+ called maplemouse.305305+295306endif
···111111 struct pci_dev *dev;112112 int err;113113114114- dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);115115- if (dev) {116116- pci_dev_put(dev);114114+ if (!no_pci_devices())117115 return -ENODEV;118118- }119116120117 if (!request_region(pc110pad_io, 4, "pc110pad")) {121118 printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n",
···2929 To compile this driver as a module, choose M here: the3030 module will be called ads7846.31313232+config TOUCHSCREEN_AD78773333+ tristate "AD7877 based touchscreens"3434+ depends on SPI_MASTER3535+ help3636+ Say Y here if you have a touchscreen interface using the3737+ AD7877 controller, and your board-specific initialization3838+ code includes that in its table of SPI devices.3939+4040+ If unsure, say N (but it's safe to say "Y").4141+4242+ To compile this driver as a module, choose M here: the4343+ module will be called ad7877.4444+4545+config TOUCHSCREEN_AD7879_I2C4646+ tristate "AD7879 based touchscreens: AD7879-1 I2C Interface"4747+ depends on I2C4848+ select TOUCHSCREEN_AD78794949+ help5050+ Say Y here if you have a touchscreen interface using the5151+ AD7879-1 controller, and your board-specific initialization5252+ code includes that in its table of I2C devices.5353+5454+ If unsure, say N (but it's safe to say "Y").5555+5656+ To compile this driver as a module, choose M here: the5757+ module will be called ad7879.5858+5959+config TOUCHSCREEN_AD7879_SPI6060+ tristate "AD7879 based touchscreens: AD7879 SPI Interface"6161+ depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n6262+ select TOUCHSCREEN_AD78796363+ help6464+ Say Y here if you have a touchscreen interface using the6565+ AD7879 controller, and your board-specific initialization6666+ code includes that in its table of SPI devices.6767+6868+ If unsure, say N (but it's safe to say "Y").6969+7070+ To compile this driver as a module, choose M here: the7171+ module will be called ad7879.7272+7373+config TOUCHSCREEN_AD78797474+ tristate7575+ default n7676+3277config TOUCHSCREEN_BITSY3378 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"3479 depends on SA1100_BITSY···352307353308 To compile this driver as a module, choose M here: the354309 module will be called mainstone-wm97xx.310310+311311+config TOUCHSCREEN_WM97XX_ZYLONITE312312+ tristate "Zylonite accelerated touch"313313+ depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE314314+ select TOUCHSCREEN_WM9713315315+ help316316+ Say Y here for support for streaming mode with the touchscreen317317+ on Zylonite systems.318318+319319+ If unsure, say N.320320+321321+ To compile this driver as a module, choose M here: the322322+ module will be called zylonite-wm97xx.355323356324config TOUCHSCREEN_USB_COMPOSITE357325 tristate "USB Touchscreen Driver"
···11+/*22+ * zylonite-wm97xx.c -- Zylonite Continuous Touch screen driver33+ *44+ * Copyright 2004, 2007, 2008 Wolfson Microelectronics PLC.55+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>66+ * Parts Copyright : Ian Molton <spyro@f2s.com>77+ * Andrew Zabolotny <zap@homelink.ru>88+ *99+ * This program is free software; you can redistribute it and/or modify it1010+ * under the terms of the GNU General Public License as published by the1111+ * Free Software Foundation; either version 2 of the License, or (at your1212+ * option) any later version.1313+ *1414+ * Notes:1515+ * This is a wm97xx extended touch driver supporting interrupt driven1616+ * and continuous operation on Marvell Zylonite development systems1717+ * (which have a WM9713 on board).1818+ */1919+2020+#include <linux/module.h>2121+#include <linux/moduleparam.h>2222+#include <linux/kernel.h>2323+#include <linux/init.h>2424+#include <linux/delay.h>2525+#include <linux/irq.h>2626+#include <linux/interrupt.h>2727+#include <linux/io.h>2828+#include <linux/wm97xx.h>2929+3030+#include <mach/hardware.h>3131+#include <mach/mfp.h>3232+#include <mach/regs-ac97.h>3333+3434+struct continuous {3535+ u16 id; /* codec id */3636+ u8 code; /* continuous code */3737+ u8 reads; /* number of coord reads per read cycle */3838+ u32 speed; /* number of coords per second */3939+};4040+4141+#define WM_READS(sp) ((sp / HZ) + 1)4242+4343+static const struct continuous cinfo[] = {4444+ { WM9713_ID2, 0, WM_READS(94), 94 },4545+ { WM9713_ID2, 1, WM_READS(120), 120 },4646+ { WM9713_ID2, 2, WM_READS(154), 154 },4747+ { WM9713_ID2, 3, WM_READS(188), 188 },4848+};4949+5050+/* continuous speed index */5151+static int sp_idx;5252+5353+/*5454+ * Pen sampling frequency (Hz) in continuous mode.5555+ */5656+static int cont_rate = 200;5757+module_param(cont_rate, int, 0);5858+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");5959+6060+/*6161+ * Pressure readback.6262+ *6363+ * Set to 1 to read back pen down pressure6464+ */6565+static int pressure;6666+module_param(pressure, int, 0);6767+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");6868+6969+/*7070+ * AC97 touch data slot.7171+ *7272+ * Touch screen readback data ac97 slot7373+ */7474+static int ac97_touch_slot = 5;7575+module_param(ac97_touch_slot, int, 0);7676+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");7777+7878+7979+/* flush AC97 slot 5 FIFO machines */8080+static void wm97xx_acc_pen_up(struct wm97xx *wm)8181+{8282+ int i;8383+8484+ msleep(1);8585+8686+ for (i = 0; i < 16; i++)8787+ MODR;8888+}8989+9090+static int wm97xx_acc_pen_down(struct wm97xx *wm)9191+{9292+ u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;9393+ int reads = 0;9494+ static u16 last, tries;9595+9696+ /* When the AC97 queue has been drained we need to allow time9797+ * to buffer up samples otherwise we end up spinning polling9898+ * for samples. The controller can't have a suitably low9999+ * threashold set to use the notifications it gives.100100+ */101101+ msleep(1);102102+103103+ if (tries > 5) {104104+ tries = 0;105105+ return RC_PENUP;106106+ }107107+108108+ x = MODR;109109+ if (x == last) {110110+ tries++;111111+ return RC_AGAIN;112112+ }113113+ last = x;114114+ do {115115+ if (reads)116116+ x = MODR;117117+ y = MODR;118118+ if (pressure)119119+ p = MODR;120120+121121+ /* are samples valid */122122+ if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||123123+ (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||124124+ (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES)125125+ goto up;126126+127127+ /* coordinate is good */128128+ tries = 0;129129+ input_report_abs(wm->input_dev, ABS_X, x & 0xfff);130130+ input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);131131+ input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);132132+ input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));133133+ input_sync(wm->input_dev);134134+ reads++;135135+ } while (reads < cinfo[sp_idx].reads);136136+up:137137+ return RC_PENDOWN | RC_AGAIN;138138+}139139+140140+static int wm97xx_acc_startup(struct wm97xx *wm)141141+{142142+ int idx;143143+144144+ /* check we have a codec */145145+ if (wm->ac97 == NULL)146146+ return -ENODEV;147147+148148+ /* Go you big red fire engine */149149+ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {150150+ if (wm->id != cinfo[idx].id)151151+ continue;152152+ sp_idx = idx;153153+ if (cont_rate <= cinfo[idx].speed)154154+ break;155155+ }156156+ wm->acc_rate = cinfo[sp_idx].code;157157+ wm->acc_slot = ac97_touch_slot;158158+ dev_info(wm->dev,159159+ "zylonite accelerated touchscreen driver, %d samples/sec\n",160160+ cinfo[sp_idx].speed);161161+162162+ return 0;163163+}164164+165165+static void wm97xx_irq_enable(struct wm97xx *wm, int enable)166166+{167167+ if (enable)168168+ enable_irq(wm->pen_irq);169169+ else170170+ disable_irq_nosync(wm->pen_irq);171171+}172172+173173+static struct wm97xx_mach_ops zylonite_mach_ops = {174174+ .acc_enabled = 1,175175+ .acc_pen_up = wm97xx_acc_pen_up,176176+ .acc_pen_down = wm97xx_acc_pen_down,177177+ .acc_startup = wm97xx_acc_startup,178178+ .irq_enable = wm97xx_irq_enable,179179+ .irq_gpio = WM97XX_GPIO_2,180180+};181181+182182+static int zylonite_wm97xx_probe(struct platform_device *pdev)183183+{184184+ struct wm97xx *wm = platform_get_drvdata(pdev);185185+ int gpio_touch_irq;186186+187187+ if (cpu_is_pxa320())188188+ gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO15);189189+ else190190+ gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26);191191+192192+ wm->pen_irq = IRQ_GPIO(gpio_touch_irq);193193+ set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH);194194+195195+ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,196196+ WM97XX_GPIO_POL_HIGH,197197+ WM97XX_GPIO_STICKY,198198+ WM97XX_GPIO_WAKE);199199+ wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,200200+ WM97XX_GPIO_POL_HIGH,201201+ WM97XX_GPIO_NOTSTICKY,202202+ WM97XX_GPIO_NOWAKE);203203+204204+ return wm97xx_register_mach_ops(wm, &zylonite_mach_ops);205205+}206206+207207+static int zylonite_wm97xx_remove(struct platform_device *pdev)208208+{209209+ struct wm97xx *wm = platform_get_drvdata(pdev);210210+211211+ wm97xx_unregister_mach_ops(wm);212212+213213+ return 0;214214+}215215+216216+static struct platform_driver zylonite_wm97xx_driver = {217217+ .probe = zylonite_wm97xx_probe,218218+ .remove = zylonite_wm97xx_remove,219219+ .driver = {220220+ .name = "wm97xx-touch",221221+ },222222+};223223+224224+static int __init zylonite_wm97xx_init(void)225225+{226226+ return platform_driver_register(&zylonite_wm97xx_driver);227227+}228228+229229+static void __exit zylonite_wm97xx_exit(void)230230+{231231+ platform_driver_unregister(&zylonite_wm97xx_driver);232232+}233233+234234+module_init(zylonite_wm97xx_init);235235+module_exit(zylonite_wm97xx_exit);236236+237237+/* Module information */238238+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");239239+MODULE_DESCRIPTION("wm97xx continuous touch driver for Zylonite");240240+MODULE_LICENSE("GPL");
+13
include/linux/rotary_encoder.h
···11+#ifndef __ROTARY_ENCODER_H__22+#define __ROTARY_ENCODER_H__33+44+struct rotary_encoder_platform_data {55+ unsigned int steps;66+ unsigned int axis;77+ unsigned int gpio_a;88+ unsigned int gpio_b;99+ unsigned int inverted_a;1010+ unsigned int inverted_b;1111+};1212+1313+#endif /* __ROTARY_ENCODER_H__ */
+35
include/linux/spi/ad7879.h
···11+/* linux/spi/ad7879.h */22+33+/* Touchscreen characteristics vary between boards and models. The44+ * platform_data for the device's "struct device" holds this information.55+ *66+ * It's OK if the min/max values are zero.77+ */88+struct ad7879_platform_data {99+ u16 model; /* 7879 */1010+ u16 x_plate_ohms;1111+ u16 x_min, x_max;1212+ u16 y_min, y_max;1313+ u16 pressure_min, pressure_max;1414+1515+ /* [0..255] 0=OFF Starts at 1=550us and goes1616+ * all the way to 9.440ms in steps of 35us.1717+ */1818+ u8 pen_down_acc_interval;1919+ /* [0..15] Starts at 0=128us and goes all the2020+ * way to 4.096ms in steps of 128us.2121+ */2222+ u8 first_conversion_delay;2323+ /* [0..3] 0 = 2us, 1 = 4us, 2 = 8us, 3 = 16us */2424+ u8 acquisition_time;2525+ /* [0..3] Average X middle samples 0 = 2, 1 = 4, 2 = 8, 3 = 16 */2626+ u8 averaging;2727+ /* [0..3] Perform X measurements 0 = OFF,2828+ * 1 = 4, 2 = 8, 3 = 16 (median > averaging)2929+ */3030+ u8 median;3131+ /* 1 = AUX/VBAT/GPIO set to GPIO Output */3232+ u8 gpio_output;3333+ /* Initial GPIO pin state (valid if gpio_output = 1) */3434+ u8 gpio_default;3535+};