From: "Paul A. Tessier" <phern...@gmail.com> corrects led control message to include timers adds support for wireless timers in un/registering interfaces adds new sysfs group wacom_wireless adds new sysfs rw attribute wacom_wireless/sleep_timer adds new sysfs rw attribute wacom_wireless/powersave_timer
Signed-off-by: Paul A. Tessier <phern...@gmail.com> --- 3.7/wacom.h | 4 ++ 3.7/wacom_sys.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/3.7/wacom.h b/3.7/wacom.h index 19ab360..b62c608 100644 --- a/3.7/wacom.h +++ b/3.7/wacom.h @@ -124,6 +124,10 @@ struct wacom { u8 crop_lum; /* crop marks led brightness (1..127) */ } led; struct power_supply battery; + struct wacom_wireless { + u8 sleep_timer; + u8 powersave_timer; + } wireless; }; static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c index 58e8bc6..6c28e78 100644 --- a/3.7/wacom_sys.c +++ b/3.7/wacom_sys.c @@ -61,6 +61,14 @@ struct hid_descriptor { #define WAC_CMD_ICON_XFER 0x23 #define WAC_CMD_RETRIES 10 +/* Wacom Wireless Kit */ +#define WWK_SLEEP_MIN 5 +#define WWK_SLEEP_MAX 60 +#define WWK_SLEEP_DEFAULT 0 +#define WWK_POWERSAVE_MIN 1 +#define WWK_POWERSAVE_MAX 60 +#define WWK_POWERSAVE_DEFAULT 0 + #define DEV_ATTR_RW_PERM (S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH) #define DEV_ATTR_RO_PERM (S_IRUSR | S_IRGRP | S_IROTH) #define DEV_ATTR_WO_PERM (S_IWUSR | S_IWGRP) @@ -747,6 +755,8 @@ static int wacom_led_control(struct wacom *wacom) int bits = (crop_lum << 4) | (ring_lum << 2) | (ring_led); if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_WIRELESS_KIT) { + buf[1] = wacom->wireless.sleep_timer; + buf[2] = wacom->wireless.powersave_timer; buf[3] = 0x04; buf[4] = 0x40 | bits; } else { @@ -777,6 +787,12 @@ static int wacom_led_control(struct wacom *wacom) return retval; } +static int wacom_wireless_control(struct wacom *wacom) +{ + /* currently the wireless timers ride along with the led controls */ + return wacom_led_control(wacom); +} + static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *img) { unsigned char *buf; @@ -938,6 +954,62 @@ DEVICE_BTNIMG_ATTR(5); DEVICE_BTNIMG_ATTR(6); DEVICE_BTNIMG_ATTR(7); +#define DEVICE_WIRELESS_TIMER_ATTR(name, def) \ +static ssize_t wacom_wireless_##name##_timer_store(struct device *dev, \ + struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + struct wacom *wacom = dev_get_drvdata(dev); \ + int time, err; \ + err = kstrtoint(buf, 10, &time); \ + if (err) \ + return err; \ + if (time > WWK_##def##_MAX) \ + return -ERANGE; \ + else if (time < WWK_##def##_MIN) { \ + switch (time) { \ + case -1: \ + time = WWK_##def##_DEFAULT; \ + case 0: \ + time = WWK_##def##_MAX + 1; \ + default: \ + return -ERANGE; \ + } \ + } \ + mutex_lock(&wacom->lock); \ + wacom->wireless.name##_timer = time; \ + err = wacom_wireless_control(wacom); \ + mutex_unlock(&wacom->lock); \ + return err < 0 ? err : count; \ +} \ +static ssize_t wacom_wireless_##name##_timer_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct wacom *wacom = dev_get_drvdata(dev); \ + int time = wacom->wireless.name##_timer; \ + if (time > WWK_##def##_MAX) \ + time = 0; \ + else if (time == WWK_##def##_DEFAULT) \ + time = -1; \ + return scnprintf(buf, PAGE_SIZE, "%d\n",time); \ +} \ +static DEVICE_ATTR(name##_timer, DEV_ATTR_RW_PERM, \ + wacom_wireless_##name##_timer_show, \ + wacom_wireless_##name##_timer_store) + +DEVICE_WIRELESS_TIMER_ATTR(sleep, SLEEP); +DEVICE_WIRELESS_TIMER_ATTR(powersave, POWERSAVE); + +static struct attribute *wireless_attrs[] = { + &dev_attr_sleep_timer.attr, + &dev_attr_powersave_timer.attr, + NULL +}; + +static struct attribute_group wireless_attr_group = { + .name = "wacom_wireless", + .attrs = wireless_attrs, +}; + static struct attribute *cintiq_led_attrs[] = { &dev_attr_status_led0_select.attr, &dev_attr_status_led1_select.attr, @@ -1170,12 +1242,52 @@ fail1: return error; } +static void wacom_unregister_wireless(struct wacom *wacom) +{ + struct wacom_features *wacom_features = &wacom->wacom_wac.features; + + if (!(wacom_features->quirks & WACOM_QUIRK_WIRELESS_KIT) || + wacom_features->device_type != BTN_TOOL_PEN) + return; + + sysfs_remove_group(&wacom->intf->dev.kobj, + &wireless_attr_group); +} + +static int wacom_register_wireless(struct wacom *wacom) +{ + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct wacom_features *wacom_features = &wacom_wac->features; + int error; + + if (!(wacom_features->quirks & WACOM_QUIRK_WIRELESS_KIT) || + wacom_features->device_type != BTN_TOOL_PEN) + return 0; + + wacom->wireless.sleep_timer = WWK_SLEEP_DEFAULT; + wacom->wireless.powersave_timer = WWK_POWERSAVE_DEFAULT; + + error = sysfs_create_group(&wacom->intf->dev.kobj, + &wireless_attr_group); + if (error) { + dev_err(&wacom->intf->dev, + "cannot create 'wacom_wireless' sysfs group: err %d\n", + error); + return error; + } + + wacom_wireless_control(wacom); + + return 0; +} + static void wacom_unregister(struct wacom *wacom) { struct wacom_wac *wacom_wac = &wacom->wacom_wac; if (wacom_wac->input) { input_unregister_device(wacom_wac->input); + wacom_unregister_wireless(wacom); wacom_destroy_leds(wacom); } @@ -1190,12 +1302,17 @@ static int wacom_register(struct wacom *wacom) if (error) goto fail1; - error = wacom_register_input(wacom); + error = wacom_register_wireless(wacom); if (error) goto fail2; + + error = wacom_register_input(wacom); + if (error) + goto fail3; return 0; +fail3: wacom_unregister_wireless(wacom); fail2: wacom_destroy_leds(wacom); fail1: return error; -- 1.8.3.2 ------------------------------------------------------------------------------ _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel