diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 14:39:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 14:39:00 -0400 |
commit | 3366dd9fa887ebbda4872e9554f853eaeda764be (patch) | |
tree | d1bb553325b276e9d2a1bce99f3e64834b46866b /drivers/hid/i2c-hid | |
parent | 697a067f1ec67f2f8dfafd0a1b95a46997a11f32 (diff) | |
parent | 21796b39c9e876a46a353a4a9ff9881766a7c176 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- HID battery handling cleanup by David Herrmann
- ELO 4000/4500 driver, which has been finally ported to be proper HID
driver by Jiri Slaby
- ps3remote driver functionality is now provided by generic sony
driver, by Jiri Kosina
- PS2/3 Buzz controllers support, by Colin Leitner
- rework of wiimote driver including full extensions hotpluggin
support, sub-device modularization and speaker support by David
Herrmann
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (55 commits)
HID: wacom: Intuos4 battery charging changes
HID: i2c-hid: support sending HID output reports using the output register
HID: kye: Add report fixup for Genius Gila Gaming mouse
HID: wiimote: support Nintendo Wii U Pro Controller
Input: make gamepad API keycodes more clear
input: document gamepad API and add extra keycodes
HID: explain out-of-range check better
HID: fix false positive out of range values
HID: wiimote: fix coccinelle warnings
HID: roccat: check cdev_add return value
HID: fold ps3remote driver into generic Sony driver
HID: hyperv: convert alloc+memcpy to memdup
HID: core: fix reporting of raw events
HID: wiimote: discard invalid EXT data reports
HID: wiimote: fix classic controller parsing
HID: wiimote: init EXT/MP during device detection
HID: wiimote: fix DRM debug-attr to correctly parse input
HID: wiimote: add MP quirks
HID: wiimote: remove old static extension support
HID: wiimote: add "bboard_calib" attribute
...
Diffstat (limited to 'drivers/hid/i2c-hid')
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 2b1799a3b212..879b0ed701a3 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -108,6 +108,7 @@ static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01), | |||
108 | static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; | 108 | static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; |
109 | static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; | 109 | static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; |
110 | static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; | 110 | static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; |
111 | static const struct i2c_hid_cmd hid_no_cmd = { .length = 0 }; | ||
111 | 112 | ||
112 | /* | 113 | /* |
113 | * These definitions are not used here, but are defined by the spec. | 114 | * These definitions are not used here, but are defined by the spec. |
@@ -259,8 +260,11 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
259 | { | 260 | { |
260 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 261 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
261 | u8 *args = ihid->argsbuf; | 262 | u8 *args = ihid->argsbuf; |
263 | const struct i2c_hid_cmd * hidcmd = &hid_set_report_cmd; | ||
262 | int ret; | 264 | int ret; |
263 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); | 265 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); |
266 | u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); | ||
267 | u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); | ||
264 | 268 | ||
265 | /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */ | 269 | /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */ |
266 | u16 size = 2 /* size */ + | 270 | u16 size = 2 /* size */ + |
@@ -278,8 +282,18 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
278 | reportID = 0x0F; | 282 | reportID = 0x0F; |
279 | } | 283 | } |
280 | 284 | ||
281 | args[index++] = dataRegister & 0xFF; | 285 | /* |
282 | args[index++] = dataRegister >> 8; | 286 | * use the data register for feature reports or if the device does not |
287 | * support the output register | ||
288 | */ | ||
289 | if (reportType == 0x03 || maxOutputLength == 0) { | ||
290 | args[index++] = dataRegister & 0xFF; | ||
291 | args[index++] = dataRegister >> 8; | ||
292 | } else { | ||
293 | args[index++] = outputRegister & 0xFF; | ||
294 | args[index++] = outputRegister >> 8; | ||
295 | hidcmd = &hid_no_cmd; | ||
296 | } | ||
283 | 297 | ||
284 | args[index++] = size & 0xFF; | 298 | args[index++] = size & 0xFF; |
285 | args[index++] = size >> 8; | 299 | args[index++] = size >> 8; |
@@ -289,7 +303,7 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
289 | 303 | ||
290 | memcpy(&args[index], buf, data_len); | 304 | memcpy(&args[index], buf, data_len); |
291 | 305 | ||
292 | ret = __i2c_hid_command(client, &hid_set_report_cmd, reportID, | 306 | ret = __i2c_hid_command(client, hidcmd, reportID, |
293 | reportType, args, args_len, NULL, 0); | 307 | reportType, args, args_len, NULL, 0); |
294 | if (ret) { | 308 | if (ret) { |
295 | dev_err(&client->dev, "failed to set a report to device.\n"); | 309 | dev_err(&client->dev, "failed to set a report to device.\n"); |