Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jikos/hid

Pull HID updates from Jiri Kosina:
 "Some highlights:

   - hid-sony improvements of Sixaxis device support by Antonio Ospite
   - hid-hyperv driven devices can now be used as wakeup source, by
     Dexuan Cui
   - hid-lenovo driver is now more generic and supports more devices, by
     Jamie Lentin
   - hid-huion now supports wider range of tablets, by Nikolai
     Kondrashov
   - other various unsorted fixes and device ID additions"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (30 commits)
  HID: hyperv: register as a wakeup source
  HID: sony: Default initialize all elements of the LED max_brightness array to 1
  HID: huion: Fix sparse warnings
  HID: usbhid: Use flag HID_DISCONNECTED when a usb device is removed
  HID: ignore jabra gn9350e
  HID: cp2112: add I2C mode
  HID: use multi input quirk for 22b9:2968
  HID: rmi: only bind the hid-rmi driver to the mouse interface of composite USB devices
  HID: rmi: check that report ids exist in the report_id_hash before accessing their size
  HID: lenovo: Add support for Compact (BT|USB) keyboard
  HID: lenovo: Don't call function in condition, show error codes
  HID: lenovo: Prepare support for adding other devices
  HID: lenovo: Rename hid-lenovo-tpkbd to hid-lenovo
  HID: huion: Handle tablets with UC-Logic vendor ID
  HID: huion: Switch to generating report descriptor
  HID: huion: Don't ignore other interfaces
  HID: huion: Use "tablet" instead of specific model
  HID: add quirk for 0x04d9:0xa096 device
  HID: i2c-hid: call the hid driver's suspend and resume callbacks
  HID: rmi: change logging level of log messages related to unexpected reports
  ...
  • Loading branch information
torvalds committed Aug 7, 2014
2 parents a1b0a00 + cf6f397 commit 172bfe0
Show file tree
Hide file tree
Showing 18 changed files with 1,194 additions and 642 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,47 @@ Contact: linux-input@vger.kernel.org
Description: This controls if mouse clicks should be generated if the trackpoint is quickly pressed. How fast this press has to be
is being controlled by press_speed.
Values are 0 or 1.
Applies to Thinkpad USB Keyboard with TrackPoint.

What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/dragging
Date: July 2011
Contact: linux-input@vger.kernel.org
Description: If this setting is enabled, it is possible to do dragging by pressing the trackpoint. This requires press_to_select to be enabled.
Values are 0 or 1.
Applies to Thinkpad USB Keyboard with TrackPoint.

What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/release_to_select
Date: July 2011
Contact: linux-input@vger.kernel.org
Description: For details regarding this setting please refer to http://www.pc.ibm.com/ww/healthycomputing/trkpntb.html
Values are 0 or 1.
Applies to Thinkpad USB Keyboard with TrackPoint.

What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/select_right
Date: July 2011
Contact: linux-input@vger.kernel.org
Description: This setting controls if the mouse click events generated by pressing the trackpoint (if press_to_select is enabled) generate
a left or right mouse button click.
Values are 0 or 1.
Applies to Thinkpad USB Keyboard with TrackPoint.

What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/sensitivity
Date: July 2011
Contact: linux-input@vger.kernel.org
Description: This file contains the trackpoint sensitivity.
Values are decimal integers from 1 (lowest sensitivity) to 255 (highest sensitivity).
Applies to Thinkpad USB Keyboard with TrackPoint.

What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/press_speed
Date: July 2011
Contact: linux-input@vger.kernel.org
Description: This setting controls how fast the trackpoint needs to be pressed to generate a mouse click if press_to_select is enabled.
Values are decimal integers from 1 (slowest) to 255 (fastest).
Applies to Thinkpad USB Keyboard with TrackPoint.

What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fn_lock
Date: July 2014
Contact: linux-input@vger.kernel.org
Description: This setting controls whether Fn Lock is enabled on the keyboard (i.e. if F1 is Mute or F1)
Values are 0 or 1
Applies to ThinkPad Compact (USB|Bluetooth) Keyboard with TrackPoint.
18 changes: 10 additions & 8 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -331,18 +331,20 @@ config HID_LCPOWER
---help---
Support for LC-Power RC1000MCE RF remote control.

config HID_LENOVO_TPKBD
tristate "Lenovo ThinkPad USB Keyboard with TrackPoint"
config HID_LENOVO
tristate "Lenovo / Thinkpad devices"
depends on HID
select NEW_LEDS
select LEDS_CLASS
---help---
Support for the Lenovo ThinkPad USB Keyboard with TrackPoint.
Support for Lenovo devices that are not fully compliant with HID standard.

Say Y here if you have a Lenovo ThinkPad USB Keyboard with TrackPoint
and would like to use device-specific features like changing the
sensitivity of the trackpoint, using the microphone mute button or
controlling the mute and microphone mute LEDs.
Say Y if you want support for the non-compliant features of the Lenovo
Thinkpad standalone keyboards, e.g:
- ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint
configuration)
- ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys)
- ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys)

config HID_LOGITECH
tristate "Logitech devices" if EXPERT
Expand Down Expand Up @@ -785,7 +787,7 @@ config HID_XINMO
depends on HID
---help---
Support for Xin-Mo devices that are not fully compliant with the HID
standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
if you have a Xin-Mo Dual Arcade controller.

config HID_ZEROPLUS
Expand Down
2 changes: 1 addition & 1 deletion drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
obj-$(CONFIG_HID_LENOVO_TPKBD) += hid-lenovo-tpkbd.o
obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
Expand Down
11 changes: 8 additions & 3 deletions drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,9 @@ static int hid_scan_report(struct hid_device *hid)
* Vendor specific handlings
*/
if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) &&
(hid->group == HID_GROUP_GENERIC))
(hid->group == HID_GROUP_GENERIC) &&
/* only bind to the mouse interface of composite USB devices */
(hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
/* hid-rmi should take care of them, not hid-generic */
hid->group = HID_GROUP_RMI;

Expand Down Expand Up @@ -1782,7 +1784,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
Expand All @@ -1796,8 +1798,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
#if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD)
#if IS_ENABLED(CONFIG_HID_LENOVO)
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
#endif
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
Expand Down Expand Up @@ -2266,6 +2270,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_GN9350E) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
Expand Down
111 changes: 108 additions & 3 deletions drivers/hid/hid-cp2112.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,6 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
u8 buf[5];
int ret;

cp2112_gpio_set(chip, offset, value);

ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
sizeof(buf), HID_FEATURE_REPORT,
HID_REQ_GET_REPORT);
Expand All @@ -260,6 +258,12 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
return ret;
}

/*
* Set gpio value when output direction is already set,
* as specified in AN495, Rev. 0.2, cpt. 4.4
*/
cp2112_gpio_set(chip, offset, value);

return 0;
}

Expand Down Expand Up @@ -425,6 +429,105 @@ static int cp2112_write_req(void *buf, u8 slave_address, u8 command, u8 *data,
return data_length + 4;
}

static int cp2112_i2c_write_req(void *buf, u8 slave_address, u8 *data,
u8 data_length)
{
struct cp2112_write_req_report *report = buf;

if (data_length > sizeof(report->data))
return -EINVAL;

report->report = CP2112_DATA_WRITE_REQUEST;
report->slave_address = slave_address << 1;
report->length = data_length;
memcpy(report->data, data, data_length);
return data_length + 3;
}

static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num)
{
struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data;
struct hid_device *hdev = dev->hdev;
u8 buf[64];
ssize_t count;
unsigned int retries;
int ret;

hid_dbg(hdev, "I2C %d messages\n", num);

if (num != 1) {
hid_err(hdev,
"Multi-message I2C transactions not supported\n");
return -EOPNOTSUPP;
}

if (msgs->flags & I2C_M_RD)
count = cp2112_read_req(buf, msgs->addr, msgs->len);
else
count = cp2112_i2c_write_req(buf, msgs->addr, msgs->buf,
msgs->len);

if (count < 0)
return count;

ret = hid_hw_power(hdev, PM_HINT_FULLON);
if (ret < 0) {
hid_err(hdev, "power management error: %d\n", ret);
return ret;
}

ret = cp2112_hid_output(hdev, buf, count, HID_OUTPUT_REPORT);
if (ret < 0) {
hid_warn(hdev, "Error starting transaction: %d\n", ret);
goto power_normal;
}

for (retries = 0; retries < XFER_STATUS_RETRIES; ++retries) {
ret = cp2112_xfer_status(dev);
if (-EBUSY == ret)
continue;
if (ret < 0)
goto power_normal;
break;
}

if (XFER_STATUS_RETRIES <= retries) {
hid_warn(hdev, "Transfer timed out, cancelling.\n");
buf[0] = CP2112_CANCEL_TRANSFER;
buf[1] = 0x01;

ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
if (ret < 0)
hid_warn(hdev, "Error cancelling transaction: %d\n",
ret);

ret = -ETIMEDOUT;
goto power_normal;
}

if (!(msgs->flags & I2C_M_RD))
goto finish;

ret = cp2112_read(dev, msgs->buf, msgs->len);
if (ret < 0)
goto power_normal;
if (ret != msgs->len) {
hid_warn(hdev, "short read: %d < %d\n", ret, msgs->len);
ret = -EIO;
goto power_normal;
}

finish:
/* return the number of transferred messages */
ret = 1;

power_normal:
hid_hw_power(hdev, PM_HINT_NORMAL);
hid_dbg(hdev, "I2C transfer finished: %d\n", ret);
return ret;
}

static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data)
Expand Down Expand Up @@ -591,7 +694,8 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,

static u32 cp2112_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_BYTE |
return I2C_FUNC_I2C |
I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA |
Expand All @@ -601,6 +705,7 @@ static u32 cp2112_functionality(struct i2c_adapter *adap)
}

static const struct i2c_algorithm smbus_algorithm = {
.master_xfer = cp2112_i2c_xfer,
.smbus_xfer = cp2112_xfer,
.functionality = cp2112_functionality,
};
Expand Down
Loading

0 comments on commit 172bfe0

Please sign in to comment.