diff options
| -rw-r--r-- | Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus | 41 | ||||
| -rw-r--r-- | Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus | 40 | ||||
| -rw-r--r-- | drivers/hid/hid-roccat-kovaplus.c | 235 | ||||
| -rw-r--r-- | drivers/hid/hid-roccat-kovaplus.h | 14 |
4 files changed, 167 insertions, 163 deletions
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus new file mode 100644 index 000000000000..4d9fb26292a2 --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi | ||
| 2 | Date: January 2011 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: The integer value of this attribute ranges from 1-4. | ||
| 5 | When read, this attribute returns the number of the active | ||
| 6 | cpi level. | ||
| 7 | This file is readonly. | ||
| 8 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 9 | Users: http://roccat.sourceforge.net | ||
| 10 | |||
| 11 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x | ||
| 12 | Date: January 2011 | ||
| 13 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 14 | Description: The integer value of this attribute ranges from 1-10. | ||
| 15 | When read, this attribute returns the number of the actual | ||
| 16 | sensitivity in x direction. | ||
| 17 | This file is readonly. | ||
| 18 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 19 | Users: http://roccat.sourceforge.net | ||
| 20 | |||
| 21 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y | ||
| 22 | Date: January 2011 | ||
| 23 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 24 | Description: The integer value of this attribute ranges from 1-10. | ||
| 25 | When read, this attribute returns the number of the actual | ||
| 26 | sensitivity in y direction. | ||
| 27 | This file is readonly. | ||
| 28 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 29 | Users: http://roccat.sourceforge.net | ||
| 30 | |||
| 31 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version | ||
| 32 | Date: January 2011 | ||
| 33 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 34 | Description: When read, this file returns the raw integer version number of the | ||
| 35 | firmware reported by the mouse. Using the integer value eases | ||
| 36 | further usage in other programs. To receive the real version | ||
| 37 | number the decimal point has to be shifted 2 positions to the | ||
| 38 | left. E.g. a returned value of 121 means 1.21 | ||
| 39 | This file is readonly. | ||
| 40 | Obsoleted by binary sysfs attribute "info". | ||
| 41 | Users: http://roccat.sourceforge.net | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus index 20f937c9d84f..507f2c7321d5 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus | |||
| @@ -1,12 +1,3 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi | ||
| 2 | Date: January 2011 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: The integer value of this attribute ranges from 1-4. | ||
| 5 | When read, this attribute returns the number of the active | ||
| 6 | cpi level. | ||
| 7 | This file is readonly. | ||
| 8 | Users: http://roccat.sourceforge.net | ||
| 9 | |||
| 10 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile | 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile |
| 11 | Date: January 2011 | 2 | Date: January 2011 |
| 12 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| @@ -18,33 +9,12 @@ Description: The integer value of this attribute ranges from 0-4. | |||
| 18 | active when the mouse is powered on. | 9 | active when the mouse is powered on. |
| 19 | Users: http://roccat.sourceforge.net | 10 | Users: http://roccat.sourceforge.net |
| 20 | 11 | ||
| 21 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x | 12 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/info |
| 22 | Date: January 2011 | 13 | Date: November 2012 |
| 23 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 24 | Description: The integer value of this attribute ranges from 1-10. | ||
| 25 | When read, this attribute returns the number of the actual | ||
| 26 | sensitivity in x direction. | ||
| 27 | This file is readonly. | ||
| 28 | Users: http://roccat.sourceforge.net | ||
| 29 | |||
| 30 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y | ||
| 31 | Date: January 2011 | ||
| 32 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 14 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 33 | Description: The integer value of this attribute ranges from 1-10. | 15 | Description: When read, this file returns general data like firmware version. |
| 34 | When read, this attribute returns the number of the actual | 16 | When written, the device can be reset. |
| 35 | sensitivity in y direction. | 17 | The data is 6 bytes long. |
| 36 | This file is readonly. | ||
| 37 | Users: http://roccat.sourceforge.net | ||
| 38 | |||
| 39 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version | ||
| 40 | Date: January 2011 | ||
| 41 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 42 | Description: When read, this file returns the raw integer version number of the | ||
| 43 | firmware reported by the mouse. Using the integer value eases | ||
| 44 | further usage in other programs. To receive the real version | ||
| 45 | number the decimal point has to be shifted 2 positions to the | ||
| 46 | left. E.g. a returned value of 121 means 1.21 | ||
| 47 | This file is readonly. | ||
| 48 | Users: http://roccat.sourceforge.net | 18 | Users: http://roccat.sourceforge.net |
| 49 | 19 | ||
| 50 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons | 20 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons |
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index ca6527ac655d..1589fd3bcf0f 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c | |||
| @@ -70,13 +70,6 @@ static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, | |||
| 70 | return kovaplus_send_control(usb_dev, number, request); | 70 | return kovaplus_send_control(usb_dev, number, request); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static int kovaplus_get_info(struct usb_device *usb_dev, | ||
| 74 | struct kovaplus_info *buf) | ||
| 75 | { | ||
| 76 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO, | ||
| 77 | buf, sizeof(struct kovaplus_info)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static int kovaplus_get_profile_settings(struct usb_device *usb_dev, | 73 | static int kovaplus_get_profile_settings(struct usb_device *usb_dev, |
| 81 | struct kovaplus_profile_settings *buf, uint number) | 74 | struct kovaplus_profile_settings *buf, uint number) |
| 82 | { | 75 | { |
| @@ -88,15 +81,7 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev, | |||
| 88 | return retval; | 81 | return retval; |
| 89 | 82 | ||
| 90 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, | 83 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, |
| 91 | buf, sizeof(struct kovaplus_profile_settings)); | 84 | buf, KOVAPLUS_SIZE_PROFILE_SETTINGS); |
| 92 | } | ||
| 93 | |||
| 94 | static int kovaplus_set_profile_settings(struct usb_device *usb_dev, | ||
| 95 | struct kovaplus_profile_settings const *settings) | ||
| 96 | { | ||
| 97 | return roccat_common2_send_with_status(usb_dev, | ||
| 98 | KOVAPLUS_COMMAND_PROFILE_SETTINGS, | ||
| 99 | settings, sizeof(struct kovaplus_profile_settings)); | ||
| 100 | } | 85 | } |
| 101 | 86 | ||
| 102 | static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, | 87 | static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, |
| @@ -110,15 +95,7 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, | |||
| 110 | return retval; | 95 | return retval; |
| 111 | 96 | ||
| 112 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, | 97 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, |
| 113 | buf, sizeof(struct kovaplus_profile_buttons)); | 98 | buf, KOVAPLUS_SIZE_PROFILE_BUTTONS); |
| 114 | } | ||
| 115 | |||
| 116 | static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, | ||
| 117 | struct kovaplus_profile_buttons const *buttons) | ||
| 118 | { | ||
| 119 | return roccat_common2_send_with_status(usb_dev, | ||
| 120 | KOVAPLUS_COMMAND_PROFILE_BUTTONS, | ||
| 121 | buttons, sizeof(struct kovaplus_profile_buttons)); | ||
| 122 | } | 99 | } |
| 123 | 100 | ||
| 124 | /* retval is 0-4 on success, < 0 on error */ | 101 | /* retval is 0-4 on success, < 0 on error */ |
| @@ -147,122 +124,140 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev, | |||
| 147 | &buf, sizeof(struct kovaplus_actual_profile)); | 124 | &buf, sizeof(struct kovaplus_actual_profile)); |
| 148 | } | 125 | } |
| 149 | 126 | ||
| 150 | static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, | 127 | static ssize_t kovaplus_sysfs_read(struct file *fp, struct kobject *kobj, |
| 151 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 128 | char *buf, loff_t off, size_t count, |
| 152 | loff_t off, size_t count) | 129 | size_t real_size, uint command) |
| 153 | { | 130 | { |
| 154 | struct device *dev = | 131 | struct device *dev = |
| 155 | container_of(kobj, struct device, kobj)->parent->parent; | 132 | container_of(kobj, struct device, kobj)->parent->parent; |
| 156 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | 133 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); |
| 134 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 135 | int retval; | ||
| 157 | 136 | ||
| 158 | if (off >= sizeof(struct kovaplus_profile_settings)) | 137 | if (off >= real_size) |
| 159 | return 0; | 138 | return 0; |
| 160 | 139 | ||
| 161 | if (off + count > sizeof(struct kovaplus_profile_settings)) | 140 | if (off != 0 || count != real_size) |
| 162 | count = sizeof(struct kovaplus_profile_settings) - off; | 141 | return -EINVAL; |
| 163 | 142 | ||
| 164 | mutex_lock(&kovaplus->kovaplus_lock); | 143 | mutex_lock(&kovaplus->kovaplus_lock); |
| 165 | memcpy(buf, ((char const *)&kovaplus->profile_settings[*(uint *)(attr->private)]) + off, | 144 | retval = roccat_common2_receive(usb_dev, command, buf, real_size); |
| 166 | count); | ||
| 167 | mutex_unlock(&kovaplus->kovaplus_lock); | 145 | mutex_unlock(&kovaplus->kovaplus_lock); |
| 168 | 146 | ||
| 169 | return count; | 147 | if (retval) |
| 148 | return retval; | ||
| 149 | |||
| 150 | return real_size; | ||
| 170 | } | 151 | } |
| 171 | 152 | ||
| 172 | static ssize_t kovaplus_sysfs_write_profile_settings(struct file *fp, | 153 | static ssize_t kovaplus_sysfs_write(struct file *fp, struct kobject *kobj, |
| 173 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 154 | void const *buf, loff_t off, size_t count, |
| 174 | loff_t off, size_t count) | 155 | size_t real_size, uint command) |
| 175 | { | 156 | { |
| 176 | struct device *dev = | 157 | struct device *dev = |
| 177 | container_of(kobj, struct device, kobj)->parent->parent; | 158 | container_of(kobj, struct device, kobj)->parent->parent; |
| 178 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | 159 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); |
| 179 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 160 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 180 | int retval = 0; | 161 | int retval; |
| 181 | int difference; | ||
| 182 | int profile_index; | ||
| 183 | struct kovaplus_profile_settings *profile_settings; | ||
| 184 | 162 | ||
| 185 | if (off != 0 || count != sizeof(struct kovaplus_profile_settings)) | 163 | if (off != 0 || count != real_size) |
| 186 | return -EINVAL; | 164 | return -EINVAL; |
| 187 | 165 | ||
| 188 | profile_index = ((struct kovaplus_profile_settings const *)buf)->profile_index; | ||
| 189 | profile_settings = &kovaplus->profile_settings[profile_index]; | ||
| 190 | |||
| 191 | mutex_lock(&kovaplus->kovaplus_lock); | 166 | mutex_lock(&kovaplus->kovaplus_lock); |
| 192 | difference = memcmp(buf, profile_settings, | 167 | retval = roccat_common2_send_with_status(usb_dev, command, |
| 193 | sizeof(struct kovaplus_profile_settings)); | 168 | buf, real_size); |
| 194 | if (difference) { | ||
| 195 | retval = kovaplus_set_profile_settings(usb_dev, | ||
| 196 | (struct kovaplus_profile_settings const *)buf); | ||
| 197 | if (!retval) | ||
| 198 | memcpy(profile_settings, buf, | ||
| 199 | sizeof(struct kovaplus_profile_settings)); | ||
| 200 | } | ||
| 201 | mutex_unlock(&kovaplus->kovaplus_lock); | 169 | mutex_unlock(&kovaplus->kovaplus_lock); |
| 202 | 170 | ||
| 203 | if (retval) | 171 | if (retval) |
| 204 | return retval; | 172 | return retval; |
| 205 | 173 | ||
| 206 | return sizeof(struct kovaplus_profile_settings); | 174 | return real_size; |
| 207 | } | 175 | } |
| 208 | 176 | ||
| 209 | static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, | 177 | #define KOVAPLUS_SYSFS_W(thingy, THINGY) \ |
| 210 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 178 | static ssize_t kovaplus_sysfs_write_ ## thingy(struct file *fp, \ |
| 211 | loff_t off, size_t count) | 179 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 212 | { | 180 | loff_t off, size_t count) \ |
| 213 | struct device *dev = | 181 | { \ |
| 214 | container_of(kobj, struct device, kobj)->parent->parent; | 182 | return kovaplus_sysfs_write(fp, kobj, buf, off, count, \ |
| 215 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | 183 | KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \ |
| 184 | } | ||
| 216 | 185 | ||
| 217 | if (off >= sizeof(struct kovaplus_profile_buttons)) | 186 | #define KOVAPLUS_SYSFS_R(thingy, THINGY) \ |
| 218 | return 0; | 187 | static ssize_t kovaplus_sysfs_read_ ## thingy(struct file *fp, \ |
| 188 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ | ||
| 189 | loff_t off, size_t count) \ | ||
| 190 | { \ | ||
| 191 | return kovaplus_sysfs_read(fp, kobj, buf, off, count, \ | ||
| 192 | KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \ | ||
| 193 | } | ||
| 219 | 194 | ||
| 220 | if (off + count > sizeof(struct kovaplus_profile_buttons)) | 195 | #define KOVAPLUS_SYSFS_RW(thingy, THINGY) \ |
| 221 | count = sizeof(struct kovaplus_profile_buttons) - off; | 196 | KOVAPLUS_SYSFS_W(thingy, THINGY) \ |
| 197 | KOVAPLUS_SYSFS_R(thingy, THINGY) | ||
| 222 | 198 | ||
| 223 | mutex_lock(&kovaplus->kovaplus_lock); | 199 | #define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
| 224 | memcpy(buf, ((char const *)&kovaplus->profile_buttons[*(uint *)(attr->private)]) + off, | 200 | { \ |
| 225 | count); | 201 | .attr = { .name = #thingy, .mode = 0660 }, \ |
| 226 | mutex_unlock(&kovaplus->kovaplus_lock); | 202 | .size = KOVAPLUS_SIZE_ ## THINGY, \ |
| 203 | .read = kovaplus_sysfs_read_ ## thingy, \ | ||
| 204 | .write = kovaplus_sysfs_write_ ## thingy \ | ||
| 205 | } | ||
| 206 | |||
| 207 | #define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ | ||
| 208 | { \ | ||
| 209 | .attr = { .name = #thingy, .mode = 0440 }, \ | ||
| 210 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | ||
| 211 | .read = kovaplus_sysfs_read_ ## thingy, \ | ||
| 212 | } | ||
| 227 | 213 | ||
| 228 | return count; | 214 | #define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
| 215 | { \ | ||
| 216 | .attr = { .name = #thingy, .mode = 0220 }, \ | ||
| 217 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | ||
| 218 | .write = kovaplus_sysfs_write_ ## thingy \ | ||
| 229 | } | 219 | } |
| 230 | 220 | ||
| 231 | static ssize_t kovaplus_sysfs_write_profile_buttons(struct file *fp, | 221 | KOVAPLUS_SYSFS_RW(info, INFO) |
| 222 | KOVAPLUS_SYSFS_W(profile_settings, PROFILE_SETTINGS) | ||
| 223 | KOVAPLUS_SYSFS_W(profile_buttons, PROFILE_BUTTONS) | ||
| 224 | |||
| 225 | static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, | ||
| 232 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 226 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 233 | loff_t off, size_t count) | 227 | loff_t off, size_t count) |
| 234 | { | 228 | { |
| 235 | struct device *dev = | 229 | struct device *dev = |
| 236 | container_of(kobj, struct device, kobj)->parent->parent; | 230 | container_of(kobj, struct device, kobj)->parent->parent; |
| 237 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 238 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 231 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 239 | int retval = 0; | 232 | ssize_t retval; |
| 240 | int difference; | ||
| 241 | uint profile_index; | ||
| 242 | struct kovaplus_profile_buttons *profile_buttons; | ||
| 243 | 233 | ||
| 244 | if (off != 0 || count != sizeof(struct kovaplus_profile_buttons)) | 234 | retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private), |
| 245 | return -EINVAL; | 235 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); |
| 236 | if (retval) | ||
| 237 | return retval; | ||
| 246 | 238 | ||
| 247 | profile_index = ((struct kovaplus_profile_buttons const *)buf)->profile_index; | 239 | return kovaplus_sysfs_read(fp, kobj, buf, off, count, |
| 248 | profile_buttons = &kovaplus->profile_buttons[profile_index]; | 240 | KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 241 | KOVAPLUS_COMMAND_PROFILE_SETTINGS); | ||
| 242 | } | ||
| 249 | 243 | ||
| 250 | mutex_lock(&kovaplus->kovaplus_lock); | 244 | static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, |
| 251 | difference = memcmp(buf, profile_buttons, | 245 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 252 | sizeof(struct kovaplus_profile_buttons)); | 246 | loff_t off, size_t count) |
| 253 | if (difference) { | 247 | { |
| 254 | retval = kovaplus_set_profile_buttons(usb_dev, | 248 | struct device *dev = |
| 255 | (struct kovaplus_profile_buttons const *)buf); | 249 | container_of(kobj, struct device, kobj)->parent->parent; |
| 256 | if (!retval) | 250 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 257 | memcpy(profile_buttons, buf, | 251 | ssize_t retval; |
| 258 | sizeof(struct kovaplus_profile_buttons)); | ||
| 259 | } | ||
| 260 | mutex_unlock(&kovaplus->kovaplus_lock); | ||
| 261 | 252 | ||
| 253 | retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private), | ||
| 254 | KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 262 | if (retval) | 255 | if (retval) |
| 263 | return retval; | 256 | return retval; |
| 264 | 257 | ||
| 265 | return sizeof(struct kovaplus_profile_buttons); | 258 | return kovaplus_sysfs_read(fp, kobj, buf, off, count, |
| 259 | KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
| 260 | KOVAPLUS_COMMAND_PROFILE_BUTTONS); | ||
| 266 | } | 261 | } |
| 267 | 262 | ||
| 268 | static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, | 263 | static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, |
| @@ -342,9 +337,20 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev, | |||
| 342 | static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, | 337 | static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, |
| 343 | struct device_attribute *attr, char *buf) | 338 | struct device_attribute *attr, char *buf) |
| 344 | { | 339 | { |
| 345 | struct kovaplus_device *kovaplus = | 340 | struct kovaplus_device *kovaplus; |
| 346 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 341 | struct usb_device *usb_dev; |
| 347 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->info.firmware_version); | 342 | struct kovaplus_info info; |
| 343 | |||
| 344 | dev = dev->parent->parent; | ||
| 345 | kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 346 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 347 | |||
| 348 | mutex_lock(&kovaplus->kovaplus_lock); | ||
| 349 | roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO, | ||
| 350 | &info, KOVAPLUS_SIZE_INFO); | ||
| 351 | mutex_unlock(&kovaplus->kovaplus_lock); | ||
| 352 | |||
| 353 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | ||
| 348 | } | 354 | } |
| 349 | 355 | ||
| 350 | static struct device_attribute kovaplus_attributes[] = { | 356 | static struct device_attribute kovaplus_attributes[] = { |
| @@ -363,73 +369,66 @@ static struct device_attribute kovaplus_attributes[] = { | |||
| 363 | }; | 369 | }; |
| 364 | 370 | ||
| 365 | static struct bin_attribute kovaplus_bin_attributes[] = { | 371 | static struct bin_attribute kovaplus_bin_attributes[] = { |
| 366 | { | 372 | KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO), |
| 367 | .attr = { .name = "profile_settings", .mode = 0220 }, | 373 | KOVAPLUS_BIN_ATTRIBUTE_W(profile_settings, PROFILE_SETTINGS), |
| 368 | .size = sizeof(struct kovaplus_profile_settings), | 374 | KOVAPLUS_BIN_ATTRIBUTE_W(profile_buttons, PROFILE_BUTTONS), |
| 369 | .write = kovaplus_sysfs_write_profile_settings | ||
| 370 | }, | ||
| 371 | { | 375 | { |
| 372 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 376 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
| 373 | .size = sizeof(struct kovaplus_profile_settings), | 377 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 374 | .read = kovaplus_sysfs_read_profilex_settings, | 378 | .read = kovaplus_sysfs_read_profilex_settings, |
| 375 | .private = &profile_numbers[0] | 379 | .private = &profile_numbers[0] |
| 376 | }, | 380 | }, |
| 377 | { | 381 | { |
| 378 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 382 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
| 379 | .size = sizeof(struct kovaplus_profile_settings), | 383 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 380 | .read = kovaplus_sysfs_read_profilex_settings, | 384 | .read = kovaplus_sysfs_read_profilex_settings, |
| 381 | .private = &profile_numbers[1] | 385 | .private = &profile_numbers[1] |
| 382 | }, | 386 | }, |
| 383 | { | 387 | { |
| 384 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 388 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
| 385 | .size = sizeof(struct kovaplus_profile_settings), | 389 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 386 | .read = kovaplus_sysfs_read_profilex_settings, | 390 | .read = kovaplus_sysfs_read_profilex_settings, |
| 387 | .private = &profile_numbers[2] | 391 | .private = &profile_numbers[2] |
| 388 | }, | 392 | }, |
| 389 | { | 393 | { |
| 390 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 394 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
| 391 | .size = sizeof(struct kovaplus_profile_settings), | 395 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 392 | .read = kovaplus_sysfs_read_profilex_settings, | 396 | .read = kovaplus_sysfs_read_profilex_settings, |
| 393 | .private = &profile_numbers[3] | 397 | .private = &profile_numbers[3] |
| 394 | }, | 398 | }, |
| 395 | { | 399 | { |
| 396 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 400 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
| 397 | .size = sizeof(struct kovaplus_profile_settings), | 401 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 398 | .read = kovaplus_sysfs_read_profilex_settings, | 402 | .read = kovaplus_sysfs_read_profilex_settings, |
| 399 | .private = &profile_numbers[4] | 403 | .private = &profile_numbers[4] |
| 400 | }, | 404 | }, |
| 401 | { | 405 | { |
| 402 | .attr = { .name = "profile_buttons", .mode = 0220 }, | ||
| 403 | .size = sizeof(struct kovaplus_profile_buttons), | ||
| 404 | .write = kovaplus_sysfs_write_profile_buttons | ||
| 405 | }, | ||
| 406 | { | ||
| 407 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 406 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
| 408 | .size = sizeof(struct kovaplus_profile_buttons), | 407 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 409 | .read = kovaplus_sysfs_read_profilex_buttons, | 408 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 410 | .private = &profile_numbers[0] | 409 | .private = &profile_numbers[0] |
| 411 | }, | 410 | }, |
| 412 | { | 411 | { |
| 413 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 412 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
| 414 | .size = sizeof(struct kovaplus_profile_buttons), | 413 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 415 | .read = kovaplus_sysfs_read_profilex_buttons, | 414 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 416 | .private = &profile_numbers[1] | 415 | .private = &profile_numbers[1] |
| 417 | }, | 416 | }, |
| 418 | { | 417 | { |
| 419 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 418 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
| 420 | .size = sizeof(struct kovaplus_profile_buttons), | 419 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 421 | .read = kovaplus_sysfs_read_profilex_buttons, | 420 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 422 | .private = &profile_numbers[2] | 421 | .private = &profile_numbers[2] |
| 423 | }, | 422 | }, |
| 424 | { | 423 | { |
| 425 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 424 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
| 426 | .size = sizeof(struct kovaplus_profile_buttons), | 425 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 427 | .read = kovaplus_sysfs_read_profilex_buttons, | 426 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 428 | .private = &profile_numbers[3] | 427 | .private = &profile_numbers[3] |
| 429 | }, | 428 | }, |
| 430 | { | 429 | { |
| 431 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 430 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
| 432 | .size = sizeof(struct kovaplus_profile_buttons), | 431 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 433 | .read = kovaplus_sysfs_read_profilex_buttons, | 432 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 434 | .private = &profile_numbers[4] | 433 | .private = &profile_numbers[4] |
| 435 | }, | 434 | }, |
| @@ -444,10 +443,6 @@ static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev, | |||
| 444 | 443 | ||
| 445 | mutex_init(&kovaplus->kovaplus_lock); | 444 | mutex_init(&kovaplus->kovaplus_lock); |
| 446 | 445 | ||
| 447 | retval = kovaplus_get_info(usb_dev, &kovaplus->info); | ||
| 448 | if (retval) | ||
| 449 | return retval; | ||
| 450 | |||
| 451 | for (i = 0; i < 5; ++i) { | 446 | for (i = 0; i < 5; ++i) { |
| 452 | msleep(wait); | 447 | msleep(wait); |
| 453 | retval = kovaplus_get_profile_settings(usb_dev, | 448 | retval = kovaplus_get_profile_settings(usb_dev, |
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h index f82daa1cdcb9..1189573daee2 100644 --- a/drivers/hid/hid-roccat-kovaplus.h +++ b/drivers/hid/hid-roccat-kovaplus.h | |||
| @@ -14,6 +14,12 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | enum { | ||
| 18 | KOVAPLUS_SIZE_INFO = 0x06, | ||
| 19 | KOVAPLUS_SIZE_PROFILE_SETTINGS = 0x10, | ||
| 20 | KOVAPLUS_SIZE_PROFILE_BUTTONS = 0x17, | ||
| 21 | }; | ||
| 22 | |||
| 17 | enum kovaplus_control_requests { | 23 | enum kovaplus_control_requests { |
| 18 | /* write; value = profile number range 0-4 */ | 24 | /* write; value = profile number range 0-4 */ |
| 19 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, | 25 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, |
| @@ -53,13 +59,6 @@ struct kovaplus_info { | |||
| 53 | uint8_t unknown[3]; | 59 | uint8_t unknown[3]; |
| 54 | } __packed; | 60 | } __packed; |
| 55 | 61 | ||
| 56 | /* writes 1 on plugin */ | ||
| 57 | struct kovaplus_a { | ||
| 58 | uint8_t command; /* KOVAPLUS_COMMAND_A */ | ||
| 59 | uint8_t size; /* 3 */ | ||
| 60 | uint8_t unknown; | ||
| 61 | } __packed; | ||
| 62 | |||
| 63 | enum kovaplus_commands { | 62 | enum kovaplus_commands { |
| 64 | KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, | 63 | KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
| 65 | KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 64 | KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
| @@ -125,7 +124,6 @@ struct kovaplus_device { | |||
| 125 | int roccat_claimed; | 124 | int roccat_claimed; |
| 126 | int chrdev_minor; | 125 | int chrdev_minor; |
| 127 | struct mutex kovaplus_lock; | 126 | struct mutex kovaplus_lock; |
| 128 | struct kovaplus_info info; | ||
| 129 | struct kovaplus_profile_settings profile_settings[5]; | 127 | struct kovaplus_profile_settings profile_settings[5]; |
| 130 | struct kovaplus_profile_buttons profile_buttons[5]; | 128 | struct kovaplus_profile_buttons profile_buttons[5]; |
| 131 | }; | 129 | }; |
