aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Gay <ogay@logitech.com>2015-02-17 08:00:03 -0500
committerJiri Kosina <jkosina@suse.cz>2015-02-23 10:17:32 -0500
commita877417ed4368b51f57e879b52793260981ddcaa (patch)
treee08d875df128ba23fc9c1d3bd81ca0df75a724a8
parent870fd0f5df4e131467612cc46db46fc3b69fd706 (diff)
HID: expose country code in sysfs
This commit exposes in sysfs the HID country code that is stored in the country member of hid_device structure. It identifies the country code of localized hardware. For example some keyboards use it to exhibit the language of the key layout. It helps the upper layer to identify the localized hardware and setup the correct language to use. For USB HID devices the country code comes for the HID descriptor and for Bluetooth HID devices it is the HIDCountryCode attribute from the SDP database. Signed-off-by: Olivier Gay <ogay@logitech.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid10
-rw-r--r--drivers/hid/hid-core.c20
2 files changed, 30 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid b/Documentation/ABI/testing/sysfs-driver-hid
index b6490e14fe83..48942cacb0bf 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid
+++ b/Documentation/ABI/testing/sysfs-driver-hid
@@ -8,3 +8,13 @@ Description: When read, this file returns the device's raw binary HID
8 report descriptor. 8 report descriptor.
9 This file cannot be written. 9 This file cannot be written.
10Users: HIDAPI library (http://www.signal11.us/oss/hidapi) 10Users: HIDAPI library (http://www.signal11.us/oss/hidapi)
11
12What: For USB devices : /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/country
13 For BT devices : /sys/class/bluetooth/hci<addr>/<hid-bus>:<vendor-id>:<product-id>.<num>/country
14 Symlink : /sys/class/hidraw/hidraw<num>/device/country
15Date: February 2015
16KernelVersion: 3.19
17Contact: Olivier Gay <ogay@logitech.com>
18Description: When read, this file returns the hex integer value in ASCII
19 of the device's HID country code (e.g. 21 for US).
20 This file cannot be written.
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index db4fb6e1cc5b..4bae0f598ff8 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1562,12 +1562,26 @@ read_report_descriptor(struct file *filp, struct kobject *kobj,
1562 return count; 1562 return count;
1563} 1563}
1564 1564
1565static ssize_t
1566show_country(struct device *dev, struct device_attribute *attr,
1567 char *buf)
1568{
1569 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1570
1571 return sprintf(buf, "%02x\n", hdev->country & 0xff);
1572}
1573
1565static struct bin_attribute dev_bin_attr_report_desc = { 1574static struct bin_attribute dev_bin_attr_report_desc = {
1566 .attr = { .name = "report_descriptor", .mode = 0444 }, 1575 .attr = { .name = "report_descriptor", .mode = 0444 },
1567 .read = read_report_descriptor, 1576 .read = read_report_descriptor,
1568 .size = HID_MAX_DESCRIPTOR_SIZE, 1577 .size = HID_MAX_DESCRIPTOR_SIZE,
1569}; 1578};
1570 1579
1580static struct device_attribute dev_attr_country = {
1581 .attr = { .name = "country", .mode = 0444 },
1582 .show = show_country,
1583};
1584
1571int hid_connect(struct hid_device *hdev, unsigned int connect_mask) 1585int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1572{ 1586{
1573 static const char *types[] = { "Device", "Pointer", "Mouse", "Device", 1587 static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
@@ -1646,6 +1660,11 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1646 bus = "<UNKNOWN>"; 1660 bus = "<UNKNOWN>";
1647 } 1661 }
1648 1662
1663 ret = device_create_file(&hdev->dev, &dev_attr_country);
1664 if (ret)
1665 hid_warn(hdev,
1666 "can't create sysfs country code attribute err: %d\n", ret);
1667
1649 ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc); 1668 ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
1650 if (ret) 1669 if (ret)
1651 hid_warn(hdev, 1670 hid_warn(hdev,
@@ -1661,6 +1680,7 @@ EXPORT_SYMBOL_GPL(hid_connect);
1661 1680
1662void hid_disconnect(struct hid_device *hdev) 1681void hid_disconnect(struct hid_device *hdev)
1663{ 1682{
1683 device_remove_file(&hdev->dev, &dev_attr_country);
1664 device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc); 1684 device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
1665 if (hdev->claimed & HID_CLAIMED_INPUT) 1685 if (hdev->claimed & HID_CLAIMED_INPUT)
1666 hidinput_disconnect(hdev); 1686 hidinput_disconnect(hdev);