Input: add Uniwest EVI front panel driver
Subsystems (2)
RFC PATCH 1/2 Input: add Uniwest EVI front panel driver
This is my first input driver, and my first attempt to istart the process of upstreaming something, (other than a small patch).
I apologize in advance :)
The Uniwest EVI front panel has 9 usable buttons
which correspond to keyboard keys, as well as
horizontal and verical slidersr,
(the sliders are like touch based scroll bars)
and 9 indicator LEDs
This initial version of the driver just supports the buttons.
Signed-off-by Joshua Clayton <[email protected]>
--- drivers/input/misc/Kconfig | 10 ++ drivers/input/misc/Makefile | 1 + drivers/input/misc/evifpanel.c | 265 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 drivers/input/misc/evifpanel.c
drivers/input/misc/Kconfig +10 -0
@@ -222,6 +222,16 @@ config INPUT_APANEL To compile this driver as a module, choose M here: the module will be called apanel. +config INPUT_EVIFPANEL + tristate "Uniwest EVI Front panel" + select SERIO + help + Say Y if you have a Uniwest EVI and want to enable the + sliders and buttons on the front. + + To compile this driver as a module, choose M here: the + module will be called evifpanel. + config INPUT_GP2A tristate "Sharp GP2AP002A00F I2C Proximity/Opto sensor driver" depends on I2C
drivers/input/misc/Makefile +1 -0
@@ -28,6 +28,7 @@ obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o obj-$(CONFIG_INPUT_DRV2667_HAPTICS) += drv2667.o +obj-$(CONFIG_INPUT_EVIFPANEL) += evifpanel.o obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o obj-$(CONFIG_INPUT_GPIO_BEEPER) += gpio-beeper.o obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o
drivers/input/misc/evifpanel.c new file +265 -0
265 lines not on this page · raw message
Signature · 1 line
2.1.4
RFC PATCH 2/2 Input: evifpanel: show sliders through sysfs
sysfs file export the sliders in short int range
slider sysfs files will be superceded by input events when we figure out what that should look like.
Signed-off-by Joshua Clayton <[email protected]>
--- drivers/input/misc/evifpanel.c | 112 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+)
drivers/input/misc/evifpanel.c +112 -0
@@ -14,12 +14,18 @@#include <linux/init.h> #include <linux/serio.h> #include <linux/slab.h> +#include <linux/sysfs.h> #define DRIVER_DESC "Uniwest EVI Frontpanel input driver"MODULE_AUTHOR ("Joshua Clayton <[email protected]>" );MODULE_DESCRIPTION (DRIVER_DESC );MODULE_LICENSE ("GPL" ); +struct fp_slider { +s32 sum; +s32 count; +}; +struct evifpanel {struct input_dev *dev;struct serio *serio;
@@ -27,6 +33,8 @@ struct evifpanel {char name[64 ];char phys[32 ];unsigned char buf[8 ]; +s32 h_slider; +s32 v_slider; };struct key_map {
@@ -38,6 +46,30 @@ struct key_map { };static struct key_map btns[] = { + {EV_ABS ,ABS_X ,0 ,3 ,4 }, + {EV_ABS ,ABS_X ,1 ,3 ,0 }, + {EV_ABS ,ABS_X ,2 ,4 ,6 }, + {EV_ABS ,ABS_X ,3 ,4 ,5 }, + {EV_ABS ,ABS_X ,4 ,4 ,4 }, + {EV_ABS ,ABS_X ,5 ,4 ,3 }, + {EV_ABS ,ABS_X ,6 ,4 ,2 }, + {EV_ABS ,ABS_X ,7 ,4 ,1 }, + {EV_ABS ,ABS_X ,8 ,4 ,0 }, + {EV_ABS ,ABS_X ,9 ,5 ,6 }, + {EV_ABS ,ABS_X ,10 ,5 ,5 }, + {EV_ABS ,ABS_X ,11 ,3 ,3 }, + {EV_ABS ,ABS_Y ,0 ,3 ,2 }, + {EV_ABS ,ABS_Y ,1 ,6 ,2 }, + {EV_ABS ,ABS_Y ,2 ,6 ,3 }, + {EV_ABS ,ABS_Y ,3 ,6 ,4 }, + {EV_ABS ,ABS_Y ,4 ,6 ,5 }, + {EV_ABS ,ABS_Y ,5 ,6 ,6 }, + {EV_ABS ,ABS_Y ,6 ,5 ,0 }, + {EV_ABS ,ABS_Y ,7 ,5 ,1 }, + {EV_ABS ,ABS_Y ,8 ,5 ,2 }, + {EV_ABS ,ABS_Y ,9 ,5 ,3 }, + {EV_ABS ,ABS_Y ,10 ,5 ,4 }, + {EV_ABS ,ABS_Y ,11 ,3 ,1 }, {EV_KEY ,KEY_F1 ,1 ,6 ,0 }, {EV_KEY ,KEY_D ,1 ,6 ,1 }, {EV_KEY ,KEY_N ,1 ,7 ,0 },
@@ -57,22 +89,63 @@ static void fp_check_key(struct evifpanel *fp, struct key_map *key)input_report_key (fp->dev, key->code, value); } +static void fp_slider_accumulate (struct evifpanel *fp, +struct fp_slider *slider,struct key_map *key) +{ +s32 value = !!(fp->buf[key->byte] &BIT (key->offset)); + + slider->sum += value * key->value; + slider->count += value; +} + +static s32 fp_slider_value (struct evifpanel *fp,struct fp_slider *slider) +{ +s32 value; + +if (slider->count) + value = (slider->sum *0xffff / (11 * slider->count)) -0x8000 ; +else + value =0 ; + +if (value ==-1 ) + value =0 ; + +return value; +} +/* * Check buttons against array of key_map */ static void fp_check_btns (struct evifpanel *fp,struct key_map *key) { +struct fp_slider h_axis, v_axis; + + h_axis.sum =0 ; + h_axis.count =0 ; + v_axis.sum =0 ; + v_axis.count =0 ; +while (key->type) {switch (key->type) {case EV_KEY :fp_check_key (fp, key);break ; +case EV_ABS : +if (key->code ==ABS_X ) +fp_slider_accumulate (fp, &h_axis, key); +else +fp_slider_accumulate (fp, &v_axis, key); + +break ;default :break ;/* ignore unknown types */ } key++; } + fp->h_slider =fp_slider_value (fp, &h_axis); + fp->v_slider =fp_slider_value (fp, &v_axis); +input_sync (fp->dev); }
@@ -161,6 +234,37 @@ static irqreturn_t fp_interrupt(struct serio *serio, unsigned char data,return IRQ_HANDLED ; } +static ssize_t v_slider_show (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct serio *serio =to_serio_port (dev); +struct evifpanel *fp =serio_get_drvdata (serio); + +return scnprintf (buf,PAGE_SIZE ,"%d\n" , fp->v_slider); +} + +static ssize_t h_slider_show (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct serio *serio =to_serio_port (dev); +struct evifpanel *fp =serio_get_drvdata (serio); + +return scnprintf (buf,PAGE_SIZE ,"%d\n" , fp->h_slider); +} + +static DEVICE_ATTR_RO (v_slider); +static DEVICE_ATTR_RO (h_slider); + +static struct attribute *attrs[] = { + &dev_attr_v_slider.attr, + &dev_attr_h_slider.attr, +NULL , +}; + +struct attribute_group fp_attrs = { + .attrs = attrs, +}; +static void fp_set_device_attrs (struct evifpanel *fp) { snprintf(fp->name, sizeof(fp->name),
@@ -210,6 +314,11 @@ static int fp_connect(struct serio *serio, struct serio_driver *drv) goto fail2; }fp_request_fw_ver (fp); + error =sysfs_create_group (&serio->dev.kobj, &fp_attrs); +if (error) { +dev_err (&serio->dev,"failed to add sysfs group\n" ); + goto sysfs_fail; + } error =input_register_device (input_dev);if (error) {
@@ -221,6 +330,8 @@ static int fp_connect(struct serio *serio, struct serio_driver *drv) fail3:serio_close (serio); +sysfs_fail: +sysfs_remove_group (&serio->dev.kobj, &fp_attrs); fail2:serio_set_drvdata (serio,NULL ); fail1:
@@ -236,6 +347,7 @@ static void fp_disconnect(struct serio *serio)struct evifpanel *fp =serio_get_drvdata (serio);input_unregister_device (fp->dev); +sysfs_remove_group (&serio->dev.kobj, &fp_attrs);serio_close (serio);serio_set_drvdata (serio,NULL );kfree (fp);
Signature · 1 line
2.1.4