Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH 3/3] video: fbdev: don't print error message on framebuffer_alloc() failure
From: Bartlomiej Zolnierkiewicz @ 2019-06-28 10:27 UTC (permalink / raw)
  To: linux-fbdev, dri-devel, linux-kernel, linux-input
  Cc: Bruno Prémont, Jiri Kosina, Benjamin Tissoires
In-Reply-To: <3da197ed-a701-2aa7-d775-2bdbe9deab4a@samsung.com>


On 6/14/19 4:51 PM, Bartlomiej Zolnierkiewicz wrote:
> framebuffer_alloc() can fail only on kzalloc() memory allocation
> failure and since kzalloc() will print error message in such case
> we can omit printing extra error message in drivers (which BTW is
> what the majority of framebuffer_alloc() users is doing already).
> 
> Cc: "Bruno Prémont" <bonbons@linux-vserver.org>
> Cc: Jiri Kosina <jikos@kernel.org>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

I queued the patch for v5.3.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

^ permalink raw reply

* [PATCH 03/43] docs: hid: convert to ReST
From: Mauro Carvalho Chehab @ 2019-06-28 12:19 UTC (permalink / raw)
  To: Linux Doc Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, linux-kernel,
	Jonathan Corbet, Jiri Kosina, Jonathan Cameron,
	Srinivas Pandruvada, Benjamin Tissoires, Dmitry Torokhov,
	linux-input, linux-iio, linux-usb
In-Reply-To: <cover.1561723979.git.mchehab+samsung@kernel.org>

Rename the HID documentation files to ReST, add an
index for them and adjust in order to produce a nice html
output via the Sphinx build system.

While here, fix the sysfs example from hid-sensor.txt, that
has a lot of "?" instead of the proper UTF-8 characters that
are produced by the tree command.

At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 .../hid/{hid-alps.txt => hid-alps.rst}        |  85 ++-
 .../hid/{hid-sensor.txt => hid-sensor.rst}    | 192 +++----
 .../{hid-transport.txt => hid-transport.rst}  |  82 ++-
 Documentation/hid/{hiddev.txt => hiddev.rst}  | 154 ++++--
 Documentation/hid/{hidraw.txt => hidraw.rst}  |  53 +-
 Documentation/hid/index.rst                   |  18 +
 Documentation/hid/intel-ish-hid.rst           | 485 ++++++++++++++++++
 Documentation/hid/intel-ish-hid.txt           | 454 ----------------
 Documentation/hid/{uhid.txt => uhid.rst}      |  46 +-
 Documentation/input/input.rst                 |   2 +-
 MAINTAINERS                                   |   2 +-
 11 files changed, 897 insertions(+), 676 deletions(-)
 rename Documentation/hid/{hid-alps.txt => hid-alps.rst} (64%)
 rename Documentation/hid/{hid-sensor.txt => hid-sensor.rst} (61%)
 rename Documentation/hid/{hid-transport.txt => hid-transport.rst} (93%)
 rename Documentation/hid/{hiddev.txt => hiddev.rst} (77%)
 rename Documentation/hid/{hidraw.txt => hidraw.rst} (89%)
 create mode 100644 Documentation/hid/index.rst
 create mode 100644 Documentation/hid/intel-ish-hid.rst
 delete mode 100644 Documentation/hid/intel-ish-hid.txt
 rename Documentation/hid/{uhid.txt => uhid.rst} (94%)

diff --git a/Documentation/hid/hid-alps.txt b/Documentation/hid/hid-alps.rst
similarity index 64%
rename from Documentation/hid/hid-alps.txt
rename to Documentation/hid/hid-alps.rst
index 6b02a2447c77..e2f4c4c11e3f 100644
--- a/Documentation/hid/hid-alps.txt
+++ b/Documentation/hid/hid-alps.rst
@@ -1,19 +1,26 @@
+==========================
 ALPS HID Touchpad Protocol
-----------------------
+==========================
 
 Introduction
 ------------
 Currently ALPS HID driver supports U1 Touchpad device.
 
-U1 devuce basic information.
+U1 device basic information.
+
+==========	======
 Vender ID	0x044E
 Product ID	0x120B
 Version ID	0x0121
+==========	======
 
 
 HID Descriptor
-------------
+--------------
+
+=======	====================	=====	=======================================
 Byte	Field			Value	Notes
+=======	====================	=====	=======================================
 0	wHIDDescLength		001E	Length of HID Descriptor : 30 bytes
 2	bcdVersion		0100	Compliant with Version 1.00
 4	wReportDescLength	00B2	Report Descriptor is 178 Bytes (0x00B2)
@@ -28,32 +35,42 @@ Byte	Field			Value	Notes
 22	wProductID		120B	Product ID 0x120B
 24	wVersionID		0121	Version 01.21
 26	RESERVED		0000	RESERVED
+=======	====================	=====	=======================================
 
 
 Report ID
-------------
-ReportID-1	(Input Reports)	(HIDUsage-Mouse) for TP&SP
-ReportID-2	(Input Reports)	(HIDUsage-keyboard) for TP
-ReportID-3	(Input Reports)	(Vendor Usage: Max 10 finger data) for TP
-ReportID-4	(Input Reports)	(Vendor Usage: ON bit data) for GP
-ReportID-5	(Feature Reports)	Feature Reports
-ReportID-6	(Input Reports)	(Vendor Usage: StickPointer data) for SP
-ReportID-7	(Feature Reports)	Flash update (Bootloader)
+---------
+
+==========	=================  =========================================
+ReportID-1	(Input Reports)	   (HIDUsage-Mouse) for TP&SP
+ReportID-2	(Input Reports)	   (HIDUsage-keyboard) for TP
+ReportID-3	(Input Reports)	   (Vendor Usage: Max 10 finger data) for TP
+ReportID-4	(Input Reports)	   (Vendor Usage: ON bit data) for GP
+ReportID-5	(Feature Reports)  Feature Reports
+ReportID-6	(Input Reports)	   (Vendor Usage: StickPointer data) for SP
+ReportID-7	(Feature Reports)  Flash update (Bootloader)
+==========	=================  =========================================
 
 
 Data pattern
 ------------
+
+=====	==========	=====	=================
 Case1	ReportID_1	TP/SP	Relative/Relative
 Case2	ReportID_3	TP	Absolute
 	ReportID_6	SP	Absolute
+=====	==========	=====	=================
 
 
 Command Read/Write
 ------------------
 To read/write to RAM, need to send a commands to the device.
+
 The command format is as below.
 
 DataByte(SET_REPORT)
+
+=====	======================
 Byte1	Command Byte
 Byte2	Address - Byte 0 (LSB)
 Byte3	Address - Byte 1
@@ -61,13 +78,19 @@ Byte4	Address - Byte 2
 Byte5	Address - Byte 3 (MSB)
 Byte6	Value Byte
 Byte7	Checksum
+=====	======================
 
 Command Byte is read=0xD1/write=0xD2 .
+
 Address is read/write RAM address.
+
 Value Byte is writing data when you send the write commands.
+
 When you read RAM, there is no meaning.
 
 DataByte(GET_REPORT)
+
+=====	======================
 Byte1	Response Byte
 Byte2	Address - Byte 0 (LSB)
 Byte3	Address - Byte 1
@@ -75,6 +98,7 @@ Byte4	Address - Byte 2
 Byte5	Address - Byte 3 (MSB)
 Byte6	Value Byte
 Byte7	Checksum
+=====	======================
 
 Read value is stored in Value Byte.
 
@@ -82,7 +106,11 @@ Read value is stored in Value Byte.
 Packet Format
 Touchpad data byte
 ------------------
-	b7	b6	b5	b4	b3	b2	b1	b0
+
+
+======= ======= ======= ======= ======= ======= ======= ======= =====
+-	b7	b6	b5	b4	b3	b2	b1	b0
+======= ======= ======= ======= ======= ======= ======= ======= =====
 1	0	0	SW6	SW5	SW4	SW3	SW2	SW1
 2	0	0	0	Fcv	Fn3	Fn2	Fn1	Fn0
 3	Xa0_7	Xa0_6	Xa0_5	Xa0_4	Xa0_3	Xa0_2	Xa0_1	Xa0_0
@@ -114,17 +142,25 @@ Touchpad data byte
 25	Ya4_7	Ya4_6	Ya4_5	Ya4_4	Ya4_3	Ya4_2	Ya4_1	Ya4_0
 26	Ya4_15	Ya4_14	Ya4_13	Ya4_12	Ya4_11	Ya4_10	Ya4_9	Ya4_8
 27	LFB4	Zs4_6	Zs4_5	Zs4_4	Zs4_3	Zs4_2	Zs4_1	Zs4_0
+======= ======= ======= ======= ======= ======= ======= ======= =====
 
 
-SW1-SW6:	SW ON/OFF status
-Xan_15-0(16bit):X Absolute data of the "n"th finger
-Yan_15-0(16bit):Y Absolute data of the "n"th finger
-Zsn_6-0(7bit):	Operation area of the "n"th finger
+SW1-SW6:
+	SW ON/OFF status
+Xan_15-0(16bit):
+	X Absolute data of the "n"th finger
+Yan_15-0(16bit):
+	Y Absolute data of the "n"th finger
+Zsn_6-0(7bit):
+	Operation area of the "n"th finger
 
 
 StickPointer data byte
-------------------
-	b7	b6	b5	b4	b3	b2	b1	b0
+----------------------
+
+======= ======= ======= ======= ======= ======= ======= ======= =====
+-	b7	b6	b5	b4	b3	b2	b1	b0
+======= ======= ======= ======= ======= ======= ======= ======= =====
 Byte1	1	1	1	0	1	SW3	SW2	SW1
 Byte2	X7	X6	X5	X4	X3	X2	X1	X0
 Byte3	X15	X14	X13	X12	X11	X10	X9	X8
@@ -132,8 +168,13 @@ Byte4	Y7	Y6	Y5	Y4	Y3	Y2	Y1	Y0
 Byte5	Y15	Y14	Y13	Y12	Y11	Y10	Y9	Y8
 Byte6	Z7	Z6	Z5	Z4	Z3	Z2	Z1	Z0
 Byte7	T&P	Z14	Z13	Z12	Z11	Z10	Z9	Z8
+======= ======= ======= ======= ======= ======= ======= ======= =====
 
-SW1-SW3:	SW ON/OFF status
-Xn_15-0(16bit):X Absolute data
-Yn_15-0(16bit):Y Absolute data
-Zn_14-0(15bit):Z
+SW1-SW3:
+	SW ON/OFF status
+Xn_15-0(16bit):
+	X Absolute data
+Yn_15-0(16bit):
+	Y Absolute data
+Zn_14-0(15bit):
+	Z
diff --git a/Documentation/hid/hid-sensor.txt b/Documentation/hid/hid-sensor.rst
similarity index 61%
rename from Documentation/hid/hid-sensor.txt
rename to Documentation/hid/hid-sensor.rst
index b287752a31cd..758972e34971 100644
--- a/Documentation/hid/hid-sensor.txt
+++ b/Documentation/hid/hid-sensor.rst
@@ -1,6 +1,6 @@
-
+=====================
 HID Sensors Framework
-======================
+=====================
 HID sensor framework provides necessary interfaces to implement sensor drivers,
 which are connected to a sensor hub. The sensor hub is a HID device and it provides
 a report descriptor conforming to HID 1.12 sensor usage tables.
@@ -15,22 +15,22 @@ the drivers themselves."
 This specification describes many usage IDs, which describe the type of sensor
 and also the individual data fields. Each sensor can have variable number of
 data fields. The length and order is specified in the report descriptor. For
-example a part of report descriptor can look like:
+example a part of report descriptor can look like::
 
-   INPUT(1)[INPUT]
- ..
-    Field(2)
-      Physical(0020.0073)
-      Usage(1)
-        0020.045f
-      Logical Minimum(-32767)
-      Logical Maximum(32767)
-      Report Size(8)
-      Report Count(1)
-      Report Offset(16)
-      Flags(Variable Absolute)
-..
-..
+     INPUT(1)[INPUT]
+   ..
+      Field(2)
+        Physical(0020.0073)
+        Usage(1)
+          0020.045f
+        Logical Minimum(-32767)
+        Logical Maximum(32767)
+        Report Size(8)
+        Report Count(1)
+        Report Offset(16)
+        Flags(Variable Absolute)
+  ..
+  ..
 
 The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73).
 This accelerometer-3D has some fields. Here for example field 2 is motion intensity
@@ -40,13 +40,14 @@ data will use this format.
 
 
 Implementation
-=================
+==============
 
 This specification defines many different types of sensors with different sets of
 data fields. It is difficult to have a common input event to user space applications,
 for different sensors. For example an accelerometer can send X,Y and Z data, whereas
 an ambient light sensor can send illumination data.
 So the implementation has two parts:
+
 - Core hid driver
 - Individual sensor processing part (sensor drivers)
 
@@ -55,8 +56,11 @@ Core driver
 The core driver registers (hid-sensor-hub) registers as a HID driver. It parses
 report descriptors and identifies all the sensors present. It adds an MFD device
 with name HID-SENSOR-xxxx (where xxxx is usage id from the specification).
-For example
+
+For example:
+
 HID-SENSOR-200073 is registered for an Accelerometer 3D driver.
+
 So if any driver with this name is inserted, then the probe routine for that
 function will be called. So an accelerometer processing driver can register
 with this name and will be probed if there is an accelerometer-3D detected.
@@ -66,7 +70,8 @@ drivers to register and get events for that usage id. Also it provides parsing
 functions, which get and set each input/feature/output report.
 
 Individual sensor processing part (sensor drivers)
------------
+--------------------------------------------------
+
 The processing driver will use an interface provided by the core driver to parse
 the report and get the indexes of the fields and also can get events. This driver
 can use IIO interface to use the standard ABI defined for a type of sensor.
@@ -75,31 +80,34 @@ can use IIO interface to use the standard ABI defined for a type of sensor.
 Core driver Interface
 =====================
 
-Callback structure:
-Each processing driver can use this structure to set some callbacks.
+Callback structure::
+
+  Each processing driver can use this structure to set some callbacks.
 	int (*suspend)(..): Callback when HID suspend is received
 	int (*resume)(..): Callback when HID resume is received
 	int (*capture_sample)(..): Capture a sample for one of its data fields
 	int (*send_event)(..): One complete event is received which can have
                                multiple data fields.
 
-Registration functions:
-int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
+Registration functions::
+
+  int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
 			u32 usage_id,
 			struct hid_sensor_hub_callbacks *usage_callback):
 
 Registers callbacks for an usage id. The callback functions are not allowed
-to sleep.
+to sleep::
 
 
-int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
+  int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
 			u32 usage_id):
 
 Removes callbacks for an usage id.
 
 
-Parsing function:
-int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
+Parsing function::
+
+  int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
 			u8 type,
 			u32 usage_id, u32 attr_usage_id,
 			struct hid_sensor_hub_attribute_info *info);
@@ -110,26 +118,27 @@ so that fields can be set or get individually.
 These indexes avoid searching every time and getting field index to get or set.
 
 
-Set Feature report
-int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
+Set Feature report::
+
+  int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
 			u32 field_index, s32 value);
 
 This interface is used to set a value for a field in feature report. For example
 if there is a field report_interval, which is parsed by a call to
-sensor_hub_input_get_attribute_info before, then it can directly set that individual
-field.
+sensor_hub_input_get_attribute_info before, then it can directly set that
+individual field::
 
 
-int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
+  int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
 			u32 field_index, s32 *value);
 
 This interface is used to get a value for a field in input report. For example
 if there is a field report_interval, which is parsed by a call to
-sensor_hub_input_get_attribute_info before, then it can directly get that individual
-field value.
+sensor_hub_input_get_attribute_info before, then it can directly get that
+individual field value::
 
 
-int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
+  int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
 			u32 usage_id,
 			u32 attr_usage_id, u32 report_id);
 
@@ -143,6 +152,8 @@ registered callback function to process the sample.
 ----------
 
 HID Custom and generic Sensors
+------------------------------
+
 
 HID Sensor specification defines two special sensor usage types. Since they
 don't represent a standard sensor, it is not possible to define using Linux IIO
@@ -158,66 +169,73 @@ keyboard attached/detached or lid open/close.
 To allow application to utilize these sensors, here they are exported uses sysfs
 attribute groups, attributes and misc device interface.
 
-An example of this representation on sysfs:
-/sys/devices/pci0000:00/INT33C2:00/i2c-0/i2c-INT33D1:00/0018:8086:09FA.0001/HID-SENSOR-2000e1.6.auto$ tree -R
-.
-????????? enable_sensor
-????????? feature-0-200316
-??????? ????????? feature-0-200316-maximum
-??????? ????????? feature-0-200316-minimum
-??????? ????????? feature-0-200316-name
-??????? ????????? feature-0-200316-size
-??????? ????????? feature-0-200316-unit-expo
-??????? ????????? feature-0-200316-units
-??????? ????????? feature-0-200316-value
-????????? feature-1-200201
-??????? ????????? feature-1-200201-maximum
-??????? ????????? feature-1-200201-minimum
-??????? ????????? feature-1-200201-name
-??????? ????????? feature-1-200201-size
-??????? ????????? feature-1-200201-unit-expo
-??????? ????????? feature-1-200201-units
-??????? ????????? feature-1-200201-value
-????????? input-0-200201
-??????? ????????? input-0-200201-maximum
-??????? ????????? input-0-200201-minimum
-??????? ????????? input-0-200201-name
-??????? ????????? input-0-200201-size
-??????? ????????? input-0-200201-unit-expo
-??????? ????????? input-0-200201-units
-??????? ????????? input-0-200201-value
-????????? input-1-200202
-??????? ????????? input-1-200202-maximum
-??????? ????????? input-1-200202-minimum
-??????? ????????? input-1-200202-name
-??????? ????????? input-1-200202-size
-??????? ????????? input-1-200202-unit-expo
-??????? ????????? input-1-200202-units
-??????? ????????? input-1-200202-value
+An example of this representation on sysfs::
+
+  /sys/devices/pci0000:00/INT33C2:00/i2c-0/i2c-INT33D1:00/0018:8086:09FA.0001/HID-SENSOR-2000e1.6.auto$ tree -R
+  .
+  │   ├──  enable_sensor
+  │   │   ├── feature-0-200316
+  │   │   │   ├── feature-0-200316-maximum
+  │   │   │   ├── feature-0-200316-minimum
+  │   │   │   ├── feature-0-200316-name
+  │   │   │   ├── feature-0-200316-size
+  │   │   │   ├── feature-0-200316-unit-expo
+  │   │   │   ├── feature-0-200316-units
+  │   │   │   ├── feature-0-200316-value
+  │   │   ├── feature-1-200201
+  │   │   │   ├── feature-1-200201-maximum
+  │   │   │   ├── feature-1-200201-minimum
+  │   │   │   ├── feature-1-200201-name
+  │   │   │   ├── feature-1-200201-size
+  │   │   │   ├── feature-1-200201-unit-expo
+  │   │   │   ├── feature-1-200201-units
+  │   │   │   ├── feature-1-200201-value
+  │   │   ├── input-0-200201
+  │   │   │   ├── input-0-200201-maximum
+  │   │   │   ├── input-0-200201-minimum
+  │   │   │   ├── input-0-200201-name
+  │   │   │   ├── input-0-200201-size
+  │   │   │   ├── input-0-200201-unit-expo
+  │   │   │   ├── input-0-200201-units
+  │   │   │   ├── input-0-200201-value
+  │   │   ├── input-1-200202
+  │   │   │   ├── input-1-200202-maximum
+  │   │   │   ├── input-1-200202-minimum
+  │   │   │   ├── input-1-200202-name
+  │   │   │   ├── input-1-200202-size
+  │   │   │   ├── input-1-200202-unit-expo
+  │   │   │   ├── input-1-200202-units
+  │   │   │   ├── input-1-200202-value
 
 Here there is a custom sensors with four fields, two feature and two inputs.
 Each field is represented by a set of attributes. All fields except the "value"
 are read only. The value field is a RW field.
-Example
-/sys/bus/platform/devices/HID-SENSOR-2000e1.6.auto/feature-0-200316$ grep -r . *
-feature-0-200316-maximum:6
-feature-0-200316-minimum:0
-feature-0-200316-name:property-reporting-state
-feature-0-200316-size:1
-feature-0-200316-unit-expo:0
-feature-0-200316-units:25
-feature-0-200316-value:1
+
+Example::
+
+  /sys/bus/platform/devices/HID-SENSOR-2000e1.6.auto/feature-0-200316$ grep -r . *
+  feature-0-200316-maximum:6
+  feature-0-200316-minimum:0
+  feature-0-200316-name:property-reporting-state
+  feature-0-200316-size:1
+  feature-0-200316-unit-expo:0
+  feature-0-200316-units:25
+  feature-0-200316-value:1
 
 How to enable such sensor?
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 By default sensor can be power gated. To enable sysfs attribute "enable" can be
-used.
-$ echo 1 > enable_sensor
+used::
+
+	$ echo 1 > enable_sensor
 
 Once enabled and powered on, sensor can report value using HID reports.
-These reports are pushed using misc device interface in a FIFO order.
-/dev$ tree | grep HID-SENSOR-2000e1.6.auto
-??????? ????????? 10:53 -> ../HID-SENSOR-2000e1.6.auto
-????????? HID-SENSOR-2000e1.6.auto
+These reports are pushed using misc device interface in a FIFO order::
+
+	/dev$ tree | grep HID-SENSOR-2000e1.6.auto
+	│   │   │   ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto
+	│   ├──  HID-SENSOR-2000e1.6.auto
 
 Each reports can be of variable length preceded by a header. This header
 consist of a 32 bit usage id, 64 bit time stamp and 32 bit length field of raw
diff --git a/Documentation/hid/hid-transport.txt b/Documentation/hid/hid-transport.rst
similarity index 93%
rename from Documentation/hid/hid-transport.txt
rename to Documentation/hid/hid-transport.rst
index 4f41d67f1b4b..0fe526f36db6 100644
--- a/Documentation/hid/hid-transport.txt
+++ b/Documentation/hid/hid-transport.rst
@@ -1,5 +1,6 @@
-                          HID I/O Transport Drivers
-                         ===========================
+=========================
+HID I/O Transport Drivers
+=========================
 
 The HID subsystem is independent of the underlying transport driver. Initially,
 only USB was supported, but other specifications adopted the HID design and
@@ -16,6 +17,8 @@ transport and device setup/management. HID core is responsible of
 report-parsing, report interpretation and the user-space API. Device specifics
 and quirks are handled by all layers depending on the quirk.
 
+::
+
  +-----------+  +-----------+            +-----------+  +-----------+
  | Device #1 |  | Device #i |            | Device #j |  | Device #k |
  +-----------+  +-----------+            +-----------+  +-----------+
@@ -42,8 +45,9 @@ and quirks are handled by all layers depending on the quirk.
  +----------------+  +-----------+  +------------------+  +------------------+
 
 Example Drivers:
-  I/O: USB, I2C, Bluetooth-l2cap
-  Transport: USB-HID, I2C-HID, BT-HIDP
+
+  - I/O: USB, I2C, Bluetooth-l2cap
+  - Transport: USB-HID, I2C-HID, BT-HIDP
 
 Everything below "HID Core" is simplified in this graph as it is only of
 interest to HID device drivers. Transport drivers do not need to know the
@@ -183,7 +187,7 @@ Other ctrl-channel requests are supported by USB-HID but are not available
 -------------------
 
 Transport drivers normally use the following procedure to register a new device
-with HID core:
+with HID core::
 
 	struct hid_device *hid;
 	int ret;
@@ -215,7 +219,7 @@ Once hid_add_device() is entered, HID core might use the callbacks provided in
 "custom_ll_driver". Note that fields like "country" can be ignored by underlying
 transport-drivers if not supported.
 
-To unregister a device, use:
+To unregister a device, use::
 
 	hid_destroy_device(hid);
 
@@ -226,73 +230,110 @@ driver callbacks.
 -----------------------------
 
 The available HID callbacks are:
- - int (*start) (struct hid_device *hdev)
+
+   ::
+
+      int (*start) (struct hid_device *hdev)
+
    Called from HID device drivers once they want to use the device. Transport
    drivers can choose to setup their device in this callback. However, normally
    devices are already set up before transport drivers register them to HID core
    so this is mostly only used by USB-HID.
 
- - void (*stop) (struct hid_device *hdev)
+   ::
+
+      void (*stop) (struct hid_device *hdev)
+
    Called from HID device drivers once they are done with a device. Transport
    drivers can free any buffers and deinitialize the device. But note that
    ->start() might be called again if another HID device driver is loaded on the
    device.
+
    Transport drivers are free to ignore it and deinitialize devices after they
    destroyed them via hid_destroy_device().
 
- - int (*open) (struct hid_device *hdev)
+   ::
+
+      int (*open) (struct hid_device *hdev)
+
    Called from HID device drivers once they are interested in data reports.
    Usually, while user-space didn't open any input API/etc., device drivers are
    not interested in device data and transport drivers can put devices asleep.
    However, once ->open() is called, transport drivers must be ready for I/O.
    ->open() calls are nested for each client that opens the HID device.
 
- - void (*close) (struct hid_device *hdev)
+   ::
+
+      void (*close) (struct hid_device *hdev)
+
    Called from HID device drivers after ->open() was called but they are no
    longer interested in device reports. (Usually if user-space closed any input
    devices of the driver).
+
    Transport drivers can put devices asleep and terminate any I/O of all
    ->open() calls have been followed by a ->close() call. However, ->start() may
    be called again if the device driver is interested in input reports again.
 
- - int (*parse) (struct hid_device *hdev)
+   ::
+
+      int (*parse) (struct hid_device *hdev)
+
    Called once during device setup after ->start() has been called. Transport
    drivers must read the HID report-descriptor from the device and tell HID core
    about it via hid_parse_report().
 
- - int (*power) (struct hid_device *hdev, int level)
+   ::
+
+      int (*power) (struct hid_device *hdev, int level)
+
    Called by HID core to give PM hints to transport drivers. Usually this is
    analogical to the ->open() and ->close() hints and redundant.
 
- - void (*request) (struct hid_device *hdev, struct hid_report *report,
-                    int reqtype)
+   ::
+
+      void (*request) (struct hid_device *hdev, struct hid_report *report,
+		       int reqtype)
+
    Send an HID request on the ctrl channel. "report" contains the report that
    should be sent and "reqtype" the request type. Request-type can be
    HID_REQ_SET_REPORT or HID_REQ_GET_REPORT.
+
    This callback is optional. If not provided, HID core will assemble a raw
    report following the HID specs and send it via the ->raw_request() callback.
    The transport driver is free to implement this asynchronously.
 
- - int (*wait) (struct hid_device *hdev)
+   ::
+
+      int (*wait) (struct hid_device *hdev)
+
    Used by HID core before calling ->request() again. A transport driver can use
    it to wait for any pending requests to complete if only one request is
    allowed at a time.
 
- - int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
-                       __u8 *buf, size_t count, unsigned char rtype,
-                       int reqtype)
+   ::
+
+      int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
+                          __u8 *buf, size_t count, unsigned char rtype,
+                          int reqtype)
+
    Same as ->request() but provides the report as raw buffer. This request shall
    be synchronous. A transport driver must not use ->wait() to complete such
    requests. This request is mandatory and hid core will reject the device if
    it is missing.
 
- - int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
+   ::
+
+      int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
+
    Send raw output report via intr channel. Used by some HID device drivers
    which require high throughput for outgoing requests on the intr channel. This
    must not cause SET_REPORT calls! This must be implemented as asynchronous
    output report on the intr channel!
 
- - int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype)
+   ::
+
+      int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype)
+
    Perform SET/GET_IDLE request. Only used by USB-HID, do not implement!
 
 2.3) Data Path
@@ -314,4 +355,5 @@ transport driver and not passed to hid_input_report().
 Acknowledgements to SET_REPORT requests are not of interest to HID core.
 
 ----------------------------------------------------
+
 Written 2013, David Herrmann <dh.herrmann@gmail.com>
diff --git a/Documentation/hid/hiddev.txt b/Documentation/hid/hiddev.rst
similarity index 77%
rename from Documentation/hid/hiddev.txt
rename to Documentation/hid/hiddev.rst
index 638448707aa2..209e6ba4e019 100644
--- a/Documentation/hid/hiddev.txt
+++ b/Documentation/hid/hiddev.rst
@@ -1,6 +1,9 @@
+================================================
 Care and feeding of your Human Interface Devices
+================================================
 
-INTRODUCTION
+Introduction
+============
 
 In addition to the normal input type HID devices, USB also uses the
 human interface device protocols for things that are not really human
@@ -16,38 +19,40 @@ normalised event interface - see Documentation/input/input.rst
 * the hiddev interface, which provides fairly raw HID events
 
 The data flow for a HID event produced by a device is something like
-the following :
+the following::
 
  usb.c ---> hid-core.c  ----> hid-input.c ----> [keyboard/mouse/joystick/event]
                          |
                          |
-                          --> hiddev.c ----> POWER / MONITOR CONTROL 
+                          --> hiddev.c ----> POWER / MONITOR CONTROL
 
 In addition, other subsystems (apart from USB) can potentially feed
 events into the input subsystem, but these have no effect on the hid
 device interface.
 
-USING THE HID DEVICE INTERFACE
+Using the HID Device Interface
+==============================
 
 The hiddev interface is a char interface using the normal USB major,
 with the minor numbers starting at 96 and finishing at 111. Therefore,
-you need the following commands:
-mknod /dev/usb/hiddev0 c 180 96
-mknod /dev/usb/hiddev1 c 180 97
-mknod /dev/usb/hiddev2 c 180 98
-mknod /dev/usb/hiddev3 c 180 99
-mknod /dev/usb/hiddev4 c 180 100
-mknod /dev/usb/hiddev5 c 180 101
-mknod /dev/usb/hiddev6 c 180 102
-mknod /dev/usb/hiddev7 c 180 103
-mknod /dev/usb/hiddev8 c 180 104
-mknod /dev/usb/hiddev9 c 180 105
-mknod /dev/usb/hiddev10 c 180 106
-mknod /dev/usb/hiddev11 c 180 107
-mknod /dev/usb/hiddev12 c 180 108
-mknod /dev/usb/hiddev13 c 180 109
-mknod /dev/usb/hiddev14 c 180 110
-mknod /dev/usb/hiddev15 c 180 111
+you need the following commands::
+
+	mknod /dev/usb/hiddev0 c 180 96
+	mknod /dev/usb/hiddev1 c 180 97
+	mknod /dev/usb/hiddev2 c 180 98
+	mknod /dev/usb/hiddev3 c 180 99
+	mknod /dev/usb/hiddev4 c 180 100
+	mknod /dev/usb/hiddev5 c 180 101
+	mknod /dev/usb/hiddev6 c 180 102
+	mknod /dev/usb/hiddev7 c 180 103
+	mknod /dev/usb/hiddev8 c 180 104
+	mknod /dev/usb/hiddev9 c 180 105
+	mknod /dev/usb/hiddev10 c 180 106
+	mknod /dev/usb/hiddev11 c 180 107
+	mknod /dev/usb/hiddev12 c 180 108
+	mknod /dev/usb/hiddev13 c 180 109
+	mknod /dev/usb/hiddev14 c 180 110
+	mknod /dev/usb/hiddev15 c 180 111
 
 So you point your hiddev compliant user-space program at the correct
 interface for your device, and it all just works.
@@ -56,7 +61,9 @@ Assuming that you have a hiddev compliant user-space program, of
 course. If you need to write one, read on.
 
 
-THE HIDDEV API
+The HIDDEV API
+==============
+
 This description should be read in conjunction with the HID
 specification, freely available from http://www.usb.org, and
 conveniently linked of http://www.linux-usb.org.
@@ -69,12 +76,14 @@ each of which can have one or more "usages".  In the hid-core,
 each one of these usages has a single signed 32 bit value.
 
 read():
+-------
+
 This is the event interface.  When the HID device's state changes,
 it performs an interrupt transfer containing a report which contains
 the changed value.  The hid-core.c module parses the report, and
 returns to hiddev.c the individual usages that have changed within
 the report.  In its basic mode, the hiddev will make these individual
-usage changes available to the reader using a struct hiddev_event:
+usage changes available to the reader using a struct hiddev_event::
 
        struct hiddev_event {
            unsigned hid;
@@ -90,13 +99,19 @@ behavior of the read() function can be modified using the HIDIOCSFLAG
 ioctl() described below.
 
 
-ioctl(): 
-This is the control interface. There are a number of controls: 
+ioctl():
+--------
 
-HIDIOCGVERSION - int (read)
-Gets the version code out of the hiddev driver.
+This is the control interface. There are a number of controls:
+
+HIDIOCGVERSION
+  - int (read)
+
+ Gets the version code out of the hiddev driver.
+
+HIDIOCAPPLICATION
+  - (none)
 
-HIDIOCAPPLICATION - (none)
 This ioctl call returns the HID application usage associated with the
 hid device. The third argument to ioctl() specifies which application
 index to get. This is useful when the device has more than one
@@ -104,25 +119,33 @@ application collection. If the index is invalid (greater or equal to
 the number of application collections this device has) the ioctl
 returns -1. You can find out beforehand how many application
 collections the device has from the num_applications field from the
-hiddev_devinfo structure. 
+hiddev_devinfo structure.
+
+HIDIOCGCOLLECTIONINFO
+  - struct hiddev_collection_info (read/write)
 
-HIDIOCGCOLLECTIONINFO - struct hiddev_collection_info (read/write)
 This returns a superset of the information above, providing not only
 application collections, but all the collections the device has.  It
 also returns the level the collection lives in the hierarchy.
-The user passes in a hiddev_collection_info struct with the index 
-field set to the index that should be returned.  The ioctl fills in 
-the other fields.  If the index is larger than the last collection 
+The user passes in a hiddev_collection_info struct with the index
+field set to the index that should be returned.  The ioctl fills in
+the other fields.  If the index is larger than the last collection
 index, the ioctl returns -1 and sets errno to -EINVAL.
 
-HIDIOCGDEVINFO - struct hiddev_devinfo (read)
+HIDIOCGDEVINFO
+  - struct hiddev_devinfo (read)
+
 Gets a hiddev_devinfo structure which describes the device.
 
-HIDIOCGSTRING - struct hiddev_string_descriptor (read/write)
+HIDIOCGSTRING
+  - struct hiddev_string_descriptor (read/write)
+
 Gets a string descriptor from the device. The caller must fill in the
 "index" field to indicate which descriptor should be returned.
 
-HIDIOCINITREPORT - (none)
+HIDIOCINITREPORT
+  - (none)
+
 Instructs the kernel to retrieve all input and feature report values
 from the device. At this point, all the usage structures will contain
 current values for the device, and will maintain it as the device
@@ -130,21 +153,29 @@ changes.  Note that the use of this ioctl is unnecessary in general,
 since later kernels automatically initialize the reports from the
 device at attach time.
 
-HIDIOCGNAME - string (variable length)
+HIDIOCGNAME
+  - string (variable length)
+
 Gets the device name
 
-HIDIOCGREPORT - struct hiddev_report_info (write)
+HIDIOCGREPORT
+  - struct hiddev_report_info (write)
+
 Instructs the kernel to get a feature or input report from the device,
 in order to selectively update the usage structures (in contrast to
 INITREPORT).
 
-HIDIOCSREPORT - struct hiddev_report_info (write)
+HIDIOCSREPORT
+  - struct hiddev_report_info (write)
+
 Instructs the kernel to send a report to the device. This report can
 be filled in by the user through HIDIOCSUSAGE calls (below) to fill in
 individual usage values in the report before sending the report in full
-to the device. 
+to the device.
+
+HIDIOCGREPORTINFO
+  - struct hiddev_report_info (read/write)
 
-HIDIOCGREPORTINFO - struct hiddev_report_info (read/write)
 Fills in a hiddev_report_info structure for the user. The report is
 looked up by type (input, output or feature) and id, so these fields
 must be filled in by the user. The ID can be absolute -- the actual
@@ -154,52 +185,67 @@ report_id) for the next report after report_id. Without a-priori
 information about report ids, the right way to use this ioctl is to
 use the relative IDs above to enumerate the valid IDs. The ioctl
 returns non-zero when there is no more next ID. The real report ID is
-filled into the returned hiddev_report_info structure. 
+filled into the returned hiddev_report_info structure.
+
+HIDIOCGFIELDINFO
+  - struct hiddev_field_info (read/write)
 
-HIDIOCGFIELDINFO - struct hiddev_field_info (read/write)
 Returns the field information associated with a report in a
 hiddev_field_info structure. The user must fill in report_id and
 report_type in this structure, as above. The field_index should also
 be filled in, which should be a number from 0 and maxfield-1, as
-returned from a previous HIDIOCGREPORTINFO call. 
+returned from a previous HIDIOCGREPORTINFO call.
+
+HIDIOCGUCODE
+  - struct hiddev_usage_ref (read/write)
 
-HIDIOCGUCODE - struct hiddev_usage_ref (read/write)
 Returns the usage_code in a hiddev_usage_ref structure, given that
 given its report type, report id, field index, and index within the
 field have already been filled into the structure.
 
-HIDIOCGUSAGE - struct hiddev_usage_ref (read/write)
+HIDIOCGUSAGE
+  - struct hiddev_usage_ref (read/write)
+
 Returns the value of a usage in a hiddev_usage_ref structure. The
 usage to be retrieved can be specified as above, or the user can
 choose to fill in the report_type field and specify the report_id as
 HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be
 filled in with the report and field information associated with this
-usage if it is found. 
+usage if it is found.
+
+HIDIOCSUSAGE
+  - struct hiddev_usage_ref (write)
 
-HIDIOCSUSAGE - struct hiddev_usage_ref (write)
 Sets the value of a usage in an output report.  The user fills in
 the hiddev_usage_ref structure as above, but additionally fills in
 the value field.
 
-HIDIOGCOLLECTIONINDEX - struct hiddev_usage_ref (write)
+HIDIOGCOLLECTIONINDEX
+  - struct hiddev_usage_ref (write)
+
 Returns the collection index associated with this usage.  This
 indicates where in the collection hierarchy this usage sits.
 
-HIDIOCGFLAG - int (read)
-HIDIOCSFLAG - int (write)
+HIDIOCGFLAG
+  - int (read)
+HIDIOCSFLAG
+  - int (write)
+
 These operations respectively inspect and replace the mode flags
 that influence the read() call above.  The flags are as follows:
 
-    HIDDEV_FLAG_UREF - read() calls will now return 
+    HIDDEV_FLAG_UREF
+      - read() calls will now return
         struct hiddev_usage_ref instead of struct hiddev_event.
         This is a larger structure, but in situations where the
         device has more than one usage in its reports with the
         same usage code, this mode serves to resolve such
         ambiguity.
 
-    HIDDEV_FLAG_REPORT - This flag can only be used in conjunction
+    HIDDEV_FLAG_REPORT
+      - This flag can only be used in conjunction
         with HIDDEV_FLAG_UREF.  With this flag set, when the device
         sends a report, a struct hiddev_usage_ref will be returned
-        to read() filled in with the report_type and report_id, but 
+        to read() filled in with the report_type and report_id, but
         with field_index set to FIELD_INDEX_NONE.  This serves as
         additional notification when the device has sent a report.
diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.rst
similarity index 89%
rename from Documentation/hid/hidraw.txt
rename to Documentation/hid/hidraw.rst
index c8436e354f44..4a4a0ba1f362 100644
--- a/Documentation/hid/hidraw.txt
+++ b/Documentation/hid/hidraw.rst
@@ -1,5 +1,6 @@
-      HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices
-     ==================================================================
+================================================================
+HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices
+================================================================
 
 The hidraw driver provides a raw interface to USB and Bluetooth Human
 Interface Devices (HIDs).  It differs from hiddev in that reports sent and
@@ -31,6 +32,7 @@ directly under /dev (eg: /dev/hidraw0).  As this location is distribution-
 and udev rule-dependent, applications should use libudev to locate hidraw
 devices attached to the system.  There is a tutorial on libudev with a
 working example at:
+
 	http://www.signal11.us/oss/udev/
 
 The HIDRAW API
@@ -51,7 +53,7 @@ byte.  For devices which do not use numbered reports, the report data
 will begin at the first byte.
 
 write()
---------
+-------
 The write() function will write a report to the device. For USB devices, if
 the device has an INTERRUPT OUT endpoint, the report will be sent on that
 endpoint. If it does not, the report will be sent over the control endpoint,
@@ -62,38 +64,52 @@ number.  If the device does not use numbered reports, the first byte should
 be set to 0. The report data itself should begin at the second byte.
 
 ioctl()
---------
+-------
 Hidraw supports the following ioctls:
 
-HIDIOCGRDESCSIZE: Get Report Descriptor Size
+HIDIOCGRDESCSIZE:
+	Get Report Descriptor Size
+
 This ioctl will get the size of the device's report descriptor.
 
-HIDIOCGRDESC: Get Report Descriptor
+HIDIOCGRDESC:
+	Get Report Descriptor
+
 This ioctl returns the device's report descriptor using a
 hidraw_report_descriptor struct.  Make sure to set the size field of the
 hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE.
 
-HIDIOCGRAWINFO: Get Raw Info
+HIDIOCGRAWINFO:
+	Get Raw Info
+
 This ioctl will return a hidraw_devinfo struct containing the bus type, the
 vendor ID (VID), and product ID (PID) of the device. The bus type can be one
-of:
-	BUS_USB
-	BUS_HIL
-	BUS_BLUETOOTH
-	BUS_VIRTUAL
+of::
+
+	- BUS_USB
+	- BUS_HIL
+	- BUS_BLUETOOTH
+	- BUS_VIRTUAL
+
 which are defined in uapi/linux/input.h.
 
-HIDIOCGRAWNAME(len): Get Raw Name
+HIDIOCGRAWNAME(len):
+	Get Raw Name
+
 This ioctl returns a string containing the vendor and product strings of
 the device.  The returned string is Unicode, UTF-8 encoded.
 
-HIDIOCGRAWPHYS(len): Get Physical Address
+HIDIOCGRAWPHYS(len):
+	Get Physical Address
+
 This ioctl returns a string representing the physical address of the device.
 For USB devices, the string contains the physical path to the device (the
 USB controller, hubs, ports, etc).  For Bluetooth devices, the string
 contains the hardware (MAC) address of the device.
 
-HIDIOCSFEATURE(len): Send a Feature Report
+HIDIOCSFEATURE(len):
+	Send a Feature Report
+
 This ioctl will send a feature report to the device.  Per the HID
 specification, feature reports are always sent using the control endpoint.
 Set the first byte of the supplied buffer to the report number.  For devices
@@ -101,7 +117,9 @@ which do not use numbered reports, set the first byte to 0. The report data
 begins in the second byte. Make sure to set len accordingly, to one more
 than the length of the report (to account for the report number).
 
-HIDIOCGFEATURE(len): Get a Feature Report
+HIDIOCGFEATURE(len):
+	Get a Feature Report
+
 This ioctl will request a feature report from the device using the control
 endpoint.  The first byte of the supplied buffer should be set to the report
 number of the requested report.  For devices which do not use numbered
@@ -109,11 +127,12 @@ reports, set the first byte to 0.  The report will be returned starting at
 the first byte of the buffer (ie: the report number is not returned).
 
 Example
----------
+-------
 In samples/, find hid-example.c, which shows examples of read(), write(),
 and all the ioctls for hidraw.  The code may be used by anyone for any
 purpose, and can serve as a starting point for developing applications using
 hidraw.
 
 Document by:
+
 	Alan Ott <alan@signal11.us>, Signal 11 Software
diff --git a/Documentation/hid/index.rst b/Documentation/hid/index.rst
new file mode 100644
index 000000000000..af4324902622
--- /dev/null
+++ b/Documentation/hid/index.rst
@@ -0,0 +1,18 @@
+:orphan:
+
+=============================
+Human Interface Devices (HID)
+=============================
+
+.. toctree::
+   :maxdepth: 1
+
+   hiddev
+   hidraw
+   hid-sensor
+   hid-transport
+
+   uhid
+
+   hid-alps
+   intel-ish-hid
diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst
new file mode 100644
index 000000000000..cccbf4be17d7
--- /dev/null
+++ b/Documentation/hid/intel-ish-hid.rst
@@ -0,0 +1,485 @@
+=================================
+Intel Integrated Sensor Hub (ISH)
+=================================
+
+A sensor hub enables the ability to offload sensor polling and algorithm
+processing to a dedicated low power co-processor. This allows the core
+processor to go into low power modes more often, resulting in the increased
+battery life.
+
+There are many vendors providing external sensor hubs confirming to HID
+Sensor usage tables, and used in several tablets, 2 in 1 convertible laptops
+and embedded products. Linux had this support since Linux 3.9.
+
+Intel® introduced integrated sensor hubs as a part of the SoC starting from
+Cherry Trail and now supported on multiple generations of CPU packages. There
+are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
+These ISH also comply to HID sensor specification, but the  difference is the
+transport protocol used for communication. The current external sensor hubs
+mainly use HID over i2C or USB. But ISH doesn't use either i2c or USB.
+
+1. Overview
+===========
+
+Using a analogy with a usbhid implementation, the ISH follows a similar model
+for a very high speed communication::
+
+	-----------------		----------------------
+	|    USB HID	|	-->	|    ISH HID	     |
+	-----------------		----------------------
+	-----------------		----------------------
+	|  USB protocol	|	-->	|    ISH Transport   |
+	-----------------		----------------------
+	-----------------		----------------------
+	|  EHCI/XHCI	|	-->	|    ISH IPC	     |
+	-----------------		----------------------
+	      PCI				 PCI
+	-----------------		----------------------
+        |Host controller|	-->	|    ISH processor   |
+	-----------------		----------------------
+	     USB Link
+	-----------------		----------------------
+	| USB End points|	-->	|    ISH Clients     |
+	-----------------		----------------------
+
+Like USB protocol provides a method for device enumeration, link management
+and user data encapsulation, the ISH also provides similar services. But it is
+very light weight tailored to manage and communicate with ISH client
+applications implemented in the firmware.
+
+The ISH allows multiple sensor management applications executing in the
+firmware. Like USB endpoints the messaging can be to/from a client. As part of
+enumeration process, these clients are identified. These clients can be simple
+HID sensor applications, sensor calibration application or senor firmware
+update application.
+
+The implementation model is similar, like USB bus, ISH transport is also
+implemented as a bus. Each client application executing in the ISH processor
+is registered as a device on this bus. The driver, which binds each device
+(ISH HID driver) identifies the device type and registers with the hid core.
+
+2. ISH Implementation: Block Diagram
+====================================
+
+::
+
+	 ---------------------------
+	|  User Space Applications  |
+	 ---------------------------
+
+  ----------------IIO ABI----------------
+	 --------------------------
+	|  IIO Sensor Drivers	  |
+	 --------------------------
+	 --------------------------
+	|	 IIO core	  |
+	 --------------------------
+	 --------------------------
+	|   HID Sensor Hub MFD	  |
+	 --------------------------
+	 --------------------------
+	|       HID Core	  |
+	 --------------------------
+	 --------------------------
+	|   HID over ISH Client   |
+	 --------------------------
+	 --------------------------
+	|   ISH Transport (ISHTP) |
+	 --------------------------
+	 --------------------------
+	|      IPC Drivers	  |
+	 --------------------------
+  OS
+  ---------------- PCI -----------------
+  Hardware + Firmware
+	 ----------------------------
+	| ISH Hardware/Firmware(FW) |
+	 ----------------------------
+
+3. High level processing in above blocks
+========================================
+
+3.1 Hardware Interface
+----------------------
+
+The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
+product and vendor IDs are changed from different generations of processors. So
+the source code which enumerate drivers needs to update from generation to
+generation.
+
+3.2 Inter Processor Communication (IPC) driver
+----------------------------------------------
+
+Location: drivers/hid/intel-ish-hid/ipc
+
+The IPC message used memory mapped I/O. The registers are defined in
+hw-ish-regs.h.
+
+3.2.1 IPC/FW message types
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are two types of messages, one for management of link and other messages
+are to and from transport layers.
+
+TX and RX of Transport messages
+...............................
+
+A set of memory mapped register offers support of multi byte messages TX and
+RX (E.g.IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
+internal queues to sequence messages and send them in order to the FW.
+Optionally the caller can register handler to get notification of completion.
+A door bell mechanism is used in messaging to trigger processing in host and
+client firmware side. When ISH interrupt handler is called, the ISH2HOST
+doorbell register is used by host drivers to determine that the interrupt
+is for ISH.
+
+Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
+register has the following format:
+Bits 0..6: fragment length (7 bits are used)
+Bits 10..13: encapsulated protocol
+Bits 16..19: management command (for IPC management protocol)
+Bit 31: doorbell trigger (signal H/W interrupt to the other side)
+Other bits are reserved, should be 0.
+
+3.2.2 Transport layer interface
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To abstract HW level IPC communication, a set of callbacks are registered.
+The transport layer uses them to send and receive messages.
+Refer to  struct ishtp_hw_ops for callbacks.
+
+3.3 ISH Transport layer
+-----------------------
+
+Location: drivers/hid/intel-ish-hid/ishtp/
+
+3.3.1 A Generic Transport Layer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The transport layer is a bi-directional protocol, which defines:
+- Set of commands to start, stop, connect, disconnect and flow control
+(ishtp/hbm.h) for details
+- A flow control mechanism to avoid buffer overflows
+
+This protocol resembles bus messages described in the following document:
+http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
+specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
+
+3.3.2 Connection and Flow Control Mechanism
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each FW client and a protocol is identified by an UUID. In order to communicate
+to a FW client, a connection must be established using connect request and
+response bus messages. If successful, a pair (host_client_id and fw_client_id)
+will identify the connection.
+
+Once connection is established, peers send each other flow control bus messages
+independently. Every peer may send a message only if it has received a
+flow-control credit before. Once it sent a message, it may not send another one
+before receiving the next flow control credit.
+Either side can send disconnect request bus message to end communication. Also
+the link will be dropped if major FW reset occurs.
+
+3.3.3 Peer to Peer data transfer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Peer to Peer data transfer can happen with or without using DMA. Depending on
+the sensor bandwidth requirement DMA can be enabled by using module parameter
+ishtp_use_dma under intel_ishtp.
+
+Each side (host and FW) manages its DMA transfer memory independently. When an
+ISHTP client from either host or FW side wants to send something, it decides
+whether to send over IPC or over DMA; for each transfer the decision is
+independent. The sending side sends DMA_XFER message when the message is in
+the respective host buffer (TX when host client sends, RX when FW client
+sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
+the sender that the memory region for that message may be reused.
+
+DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
+(that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
+Additionally to DMA address communication, this sequence checks capabilities:
+if thw host doesn't support DMA, then it won't send DMA allocation, so FW can't
+send DMA; if FW doesn't support DMA then it won't respond with
+DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
+Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
+it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
+that it already did DMA and the message resides at host. Thus, DMA_XFER
+and DMA_XFER_ACK act as ownership indicators.
+
+At initial state all outgoing memory belongs to the sender (TX to host, RX to
+FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
+the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
+needs not wait for previous DMA_XFER to be ack'ed, and may send another message
+as long as remaining continuous memory in its ownership is enough.
+In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
+(up to IPC MTU), thus allowing for interrupt throttling.
+Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
+fragments and via IPC otherwise.
+
+3.3.4 Ring Buffers
+^^^^^^^^^^^^^^^^^^
+
+When a client initiate a connection, a ring or RX and TX buffers are allocated.
+The size of ring can be specified by the client. HID client set 16 and 32 for
+TX and RX buffers respectively. On send request from client, the data to be
+sent is copied to one of the send ring buffer and scheduled to be sent using
+bus message protocol. These buffers are required because the FW may have not
+have processed the last message and may not have enough flow control credits
+to send. Same thing holds true on receive side and flow control is required.
+
+3.3.5 Host Enumeration
+^^^^^^^^^^^^^^^^^^^^^^
+
+The host enumeration bus command allow discovery of clients present in the FW.
+There can be multiple sensor clients and clients for calibration function.
+
+To ease in implantation and allow independent driver handle each client
+this transport layer takes advantage of Linux Bus driver model. Each
+client is registered as device on the the transport bus (ishtp bus).
+
+Enumeration sequence of messages:
+
+- Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
+- FW responds with HOST_START_RES_CMD
+- Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
+- FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
+  client IDs
+- For each FW ID found in that bitmap host sends
+  HOST_CLIENT_PROPERTIES_REQ_CMD
+- FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
+  max ISHTP message size, etc.
+- Once host received properties for that last discovered client, it considers
+  ISHTP device fully functional (and allocates DMA buffers)
+
+3.4 HID over ISH Client
+-----------------------
+
+Location: drivers/hid/intel-ish-hid
+
+The ISHTP client driver is responsible for:
+
+- enumerate HID devices under FW ISH client
+- Get Report descriptor
+- Register with HID core as a LL driver
+- Process Get/Set feature request
+- Get input reports
+
+3.5 HID Sensor Hub MFD and IIO sensor drivers
+---------------------------------------------
+
+The functionality in these drivers is the same as an external sensor hub.
+Refer to
+Documentation/hid/hid-sensor.rst for HID sensor
+Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space
+
+3.6 End to End HID transport Sequence Diagram
+---------------------------------------------
+
+::
+
+  HID-ISH-CLN                    ISHTP                    IPC                             HW
+          |                        |                       |                               |
+          |                        |                       |-----WAKE UP------------------>|
+          |                        |                       |                               |
+          |                        |                       |-----HOST READY--------------->|
+          |                        |                       |                               |
+          |                        |                       |<----MNG_RESET_NOTIFY_ACK----- |
+          |                        |                       |                               |
+          |                        |<----ISHTP_START------ |                               |
+          |                        |                       |                               |
+          |                        |<-----------------HOST_START_RES_CMD-------------------|
+          |                        |                       |                               |
+          |                        |------------------QUERY_SUBSCRIBER-------------------->|
+          |                        |                       |                               |
+          |                        |------------------HOST_ENUM_REQ_CMD------------------->|
+          |                        |                       |                               |
+          |                        |<-----------------HOST_ENUM_RES_CMD--------------------|
+          |                        |                       |                               |
+          |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
+          |                        |                       |                               |
+          |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
+          |       Create new device on in ishtp bus        |                               |
+          |                        |                       |                               |
+          |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
+          |                        |                       |                               |
+          |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
+          |       Create new device on in ishtp bus        |                               |
+          |                        |                       |                               |
+          |                        |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
+          |                        |                       |                               |
+       probed()
+          |----ishtp_cl_connect--->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
+          |                        |                       |                               |
+          |                        |<----------------CLIENT_CONNECT_RES_CMD----------------|
+          |                        |                       |                               |
+          |register event callback |                       |                               |
+          |                        |                       |                               |
+          |ishtp_cl_send(
+          HOSTIF_DM_ENUM_DEVICES)  |----------fill ishtp_msg_hdr struct write to HW-----  >|
+          |                        |                       |                               |
+          |                        |                       |<-----IRQ(IPC_PROTOCOL_ISHTP---|
+          |                        |                       |                               |
+          |<--ENUM_DEVICE RSP------|                       |                               |
+          |                        |                       |                               |
+  for each enumerated device
+          |ishtp_cl_send(
+          HOSTIF_GET_HID_DESCRIPTOR|----------fill ishtp_msg_hdr struct write to HW-----  >|
+          |                        |                       |                               |
+          ...Response
+          |                        |                       |                               |
+  for each enumerated device
+          |ishtp_cl_send(
+       HOSTIF_GET_REPORT_DESCRIPTOR|--------------fill ishtp_msg_hdr struct write to HW-- >|
+          |                        |                       |                               |
+          |                        |                       |                               |
+   hid_allocate_device
+          |                        |                       |                               |
+   hid_add_device                  |                       |                               |
+          |                        |                       |                               |
+
+
+3.7 ISH Debugging
+-----------------
+
+To debug ISH, event tracing mechanism is used. To enable debug logs
+echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable
+cat sys/kernel/debug/tracing/trace
+
+3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
+-----------------------------------------------------
+
+::
+
+  root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
+  /sys/bus/iio/devices/
+  ├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
+  │   ├── buffer
+  │   │   ├── enable
+  │   │   ├── length
+  │   │   └── watermark
+  ...
+  │   ├── in_accel_hysteresis
+  │   ├── in_accel_offset
+  │   ├── in_accel_sampling_frequency
+  │   ├── in_accel_scale
+  │   ├── in_accel_x_raw
+  │   ├── in_accel_y_raw
+  │   ├── in_accel_z_raw
+  │   ├── name
+  │   ├── scan_elements
+  │   │   ├── in_accel_x_en
+  │   │   ├── in_accel_x_index
+  │   │   ├── in_accel_x_type
+  │   │   ├── in_accel_y_en
+  │   │   ├── in_accel_y_index
+  │   │   ├── in_accel_y_type
+  │   │   ├── in_accel_z_en
+  │   │   ├── in_accel_z_index
+  │   │   └── in_accel_z_type
+  ...
+  │   │   ├── devices
+  │   │   │   │   ├── buffer
+  │   │   │   │   │   ├── enable
+  │   │   │   │   │   ├── length
+  │   │   │   │   │   └── watermark
+  │   │   │   │   ├── dev
+  │   │   │   │   ├── in_intensity_both_raw
+  │   │   │   │   ├── in_intensity_hysteresis
+  │   │   │   │   ├── in_intensity_offset
+  │   │   │   │   ├── in_intensity_sampling_frequency
+  │   │   │   │   ├── in_intensity_scale
+  │   │   │   │   ├── name
+  │   │   │   │   ├── scan_elements
+  │   │   │   │   │   ├── in_intensity_both_en
+  │   │   │   │   │   ├── in_intensity_both_index
+  │   │   │   │   │   └── in_intensity_both_type
+  │   │   │   │   ├── trigger
+  │   │   │   │   │   └── current_trigger
+  ...
+  │   │   │   │   ├── buffer
+  │   │   │   │   │   ├── enable
+  │   │   │   │   │   ├── length
+  │   │   │   │   │   └── watermark
+  │   │   │   │   ├── dev
+  │   │   │   │   ├── in_magn_hysteresis
+  │   │   │   │   ├── in_magn_offset
+  │   │   │   │   ├── in_magn_sampling_frequency
+  │   │   │   │   ├── in_magn_scale
+  │   │   │   │   ├── in_magn_x_raw
+  │   │   │   │   ├── in_magn_y_raw
+  │   │   │   │   ├── in_magn_z_raw
+  │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
+  │   │   │   │   ├── in_rot_hysteresis
+  │   │   │   │   ├── in_rot_offset
+  │   │   │   │   ├── in_rot_sampling_frequency
+  │   │   │   │   ├── in_rot_scale
+  │   │   │   │   ├── name
+  ...
+  │   │   │   │   ├── scan_elements
+  │   │   │   │   │   ├── in_magn_x_en
+  │   │   │   │   │   ├── in_magn_x_index
+  │   │   │   │   │   ├── in_magn_x_type
+  │   │   │   │   │   ├── in_magn_y_en
+  │   │   │   │   │   ├── in_magn_y_index
+  │   │   │   │   │   ├── in_magn_y_type
+  │   │   │   │   │   ├── in_magn_z_en
+  │   │   │   │   │   ├── in_magn_z_index
+  │   │   │   │   │   ├── in_magn_z_type
+  │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
+  │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
+  │   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
+  │   │   │   │   ├── trigger
+  │   │   │   │   │   └── current_trigger
+  ...
+  │   │   │   │   ├── buffer
+  │   │   │   │   │   ├── enable
+  │   │   │   │   │   ├── length
+  │   │   │   │   │   └── watermark
+  │   │   │   │   ├── dev
+  │   │   │   │   ├── in_anglvel_hysteresis
+  │   │   │   │   ├── in_anglvel_offset
+  │   │   │   │   ├── in_anglvel_sampling_frequency
+  │   │   │   │   ├── in_anglvel_scale
+  │   │   │   │   ├── in_anglvel_x_raw
+  │   │   │   │   ├── in_anglvel_y_raw
+  │   │   │   │   ├── in_anglvel_z_raw
+  │   │   │   │   ├── name
+  │   │   │   │   ├── scan_elements
+  │   │   │   │   │   ├── in_anglvel_x_en
+  │   │   │   │   │   ├── in_anglvel_x_index
+  │   │   │   │   │   ├── in_anglvel_x_type
+  │   │   │   │   │   ├── in_anglvel_y_en
+  │   │   │   │   │   ├── in_anglvel_y_index
+  │   │   │   │   │   ├── in_anglvel_y_type
+  │   │   │   │   │   ├── in_anglvel_z_en
+  │   │   │   │   │   ├── in_anglvel_z_index
+  │   │   │   │   │   └── in_anglvel_z_type
+  │   │   │   │   ├── trigger
+  │   │   │   │   │   └── current_trigger
+  ...
+  │   │   │   │   ├── buffer
+  │   │   │   │   │   ├── enable
+  │   │   │   │   │   ├── length
+  │   │   │   │   │   └── watermark
+  │   │   │   │   ├── dev
+  │   │   │   │   ├── in_anglvel_hysteresis
+  │   │   │   │   ├── in_anglvel_offset
+  │   │   │   │   ├── in_anglvel_sampling_frequency
+  │   │   │   │   ├── in_anglvel_scale
+  │   │   │   │   ├── in_anglvel_x_raw
+  │   │   │   │   ├── in_anglvel_y_raw
+  │   │   │   │   ├── in_anglvel_z_raw
+  │   │   │   │   ├── name
+  │   │   │   │   ├── scan_elements
+  │   │   │   │   │   ├── in_anglvel_x_en
+  │   │   │   │   │   ├── in_anglvel_x_index
+  │   │   │   │   │   ├── in_anglvel_x_type
+  │   │   │   │   │   ├── in_anglvel_y_en
+  │   │   │   │   │   ├── in_anglvel_y_index
+  │   │   │   │   │   ├── in_anglvel_y_type
+  │   │   │   │   │   ├── in_anglvel_z_en
+  │   │   │   │   │   ├── in_anglvel_z_index
+  │   │   │   │   │   └── in_anglvel_z_type
+  │   │   │   │   ├── trigger
+  │   │   │   │   │   └── current_trigger
+  ...
diff --git a/Documentation/hid/intel-ish-hid.txt b/Documentation/hid/intel-ish-hid.txt
deleted file mode 100644
index d48b21c71ddd..000000000000
--- a/Documentation/hid/intel-ish-hid.txt
+++ /dev/null
@@ -1,454 +0,0 @@
-Intel Integrated Sensor Hub (ISH)
-===============================
-
-A sensor hub enables the ability to offload sensor polling and algorithm
-processing to a dedicated low power co-processor. This allows the core
-processor to go into low power modes more often, resulting in the increased
-battery life.
-
-There are many vendors providing external sensor hubs confirming to HID
-Sensor usage tables, and used in several tablets, 2 in 1 convertible laptops
-and embedded products. Linux had this support since Linux 3.9.
-
-Intel® introduced integrated sensor hubs as a part of the SoC starting from
-Cherry Trail and now supported on multiple generations of CPU packages. There
-are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
-These ISH also comply to HID sensor specification, but the  difference is the
-transport protocol used for communication. The current external sensor hubs
-mainly use HID over i2C or USB. But ISH doesn't use either i2c or USB.
-
-1. Overview
-
-Using a analogy with a usbhid implementation, the ISH follows a similar model
-for a very high speed communication:
-
-	-----------------		----------------------
-	|    USB HID	|	-->	|    ISH HID	     |
-	-----------------		----------------------
-	-----------------		----------------------
-	|  USB protocol	|	-->	|    ISH Transport   |
-	-----------------		----------------------
-	-----------------		----------------------
-	|  EHCI/XHCI	|	-->	|    ISH IPC	     |
-	-----------------		----------------------
-	      PCI				 PCI
-	-----------------		----------------------
-        |Host controller|	-->	|    ISH processor   |
-	-----------------		----------------------
-	     USB Link
-	-----------------		----------------------
-	| USB End points|	-->	|    ISH Clients     |
-	-----------------		----------------------
-
-Like USB protocol provides a method for device enumeration, link management
-and user data encapsulation, the ISH also provides similar services. But it is
-very light weight tailored to manage and communicate with ISH client
-applications implemented in the firmware.
-
-The ISH allows multiple sensor management applications executing in the
-firmware. Like USB endpoints the messaging can be to/from a client. As part of
-enumeration process, these clients are identified. These clients can be simple
-HID sensor applications, sensor calibration application or senor firmware
-update application.
-
-The implementation model is similar, like USB bus, ISH transport is also
-implemented as a bus. Each client application executing in the ISH processor
-is registered as a device on this bus. The driver, which binds each device
-(ISH HID driver) identifies the device type and registers with the hid core.
-
-2. ISH Implementation: Block Diagram
-
-	 ---------------------------
-	|  User Space Applications  |
-	 ---------------------------
-
-----------------IIO ABI----------------
-	 --------------------------
-	|  IIO Sensor Drivers	  |
-	 --------------------------
-	 --------------------------
-	|	 IIO core	  |
-	 --------------------------
-	 --------------------------
-	|   HID Sensor Hub MFD	  |
-	 --------------------------
-	 --------------------------
-	|       HID Core	  |
-	 --------------------------
-	 --------------------------
-	|   HID over ISH Client   |
-	 --------------------------
-	 --------------------------
-	|   ISH Transport (ISHTP) |
-	 --------------------------
-	 --------------------------
-	|      IPC Drivers	  |
-	 --------------------------
-OS
-----------------   PCI -----------------
-Hardware + Firmware
-	 ----------------------------
-	| ISH Hardware/Firmware(FW) |
-	 ----------------------------
-
-3. High level processing in above blocks
-
-3.1 Hardware Interface
-
-The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
-product and vendor IDs are changed from different generations of processors. So
-the source code which enumerate drivers needs to update from generation to
-generation.
-
-3.2 Inter Processor Communication (IPC) driver
-Location: drivers/hid/intel-ish-hid/ipc
-
-The IPC message used memory mapped I/O. The registers are defined in
-hw-ish-regs.h.
-
-3.2.1 IPC/FW message types
-
-There are two types of messages, one for management of link and other messages
-are to and from transport layers.
-
-TX and RX of Transport messages
-
-A set of memory mapped register offers support of multi byte messages TX and
-RX (E.g.IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
-internal queues to sequence messages and send them in order to the FW.
-Optionally the caller can register handler to get notification of completion.
-A door bell mechanism is used in messaging to trigger processing in host and
-client firmware side. When ISH interrupt handler is called, the ISH2HOST
-doorbell register is used by host drivers to determine that the interrupt
-is for ISH.
-
-Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
-register has the following format:
-Bits 0..6: fragment length (7 bits are used)
-Bits 10..13: encapsulated protocol
-Bits 16..19: management command (for IPC management protocol)
-Bit 31: doorbell trigger (signal H/W interrupt to the other side)
-Other bits are reserved, should be 0.
-
-3.2.2 Transport layer interface
-
-To abstract HW level IPC communication, a set of callbacks are registered.
-The transport layer uses them to send and receive messages.
-Refer to  struct ishtp_hw_ops for callbacks.
-
-3.3 ISH Transport layer
-Location: drivers/hid/intel-ish-hid/ishtp/
-
-3.3.1 A Generic Transport Layer
-
-The transport layer is a bi-directional protocol, which defines:
-- Set of commands to start, stop, connect, disconnect and flow control
-(ishtp/hbm.h) for details
-- A flow control mechanism to avoid buffer overflows
-
-This protocol resembles bus messages described in the following document:
-http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
-specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
-
-3.3.2 Connection and Flow Control Mechanism
-
-Each FW client and a protocol is identified by an UUID. In order to communicate
-to a FW client, a connection must be established using connect request and
-response bus messages. If successful, a pair (host_client_id and fw_client_id)
-will identify the connection.
-
-Once connection is established, peers send each other flow control bus messages
-independently. Every peer may send a message only if it has received a
-flow-control credit before. Once it sent a message, it may not send another one
-before receiving the next flow control credit.
-Either side can send disconnect request bus message to end communication. Also
-the link will be dropped if major FW reset occurs.
-
-3.3.3 Peer to Peer data transfer
-
-Peer to Peer data transfer can happen with or without using DMA. Depending on
-the sensor bandwidth requirement DMA can be enabled by using module parameter
-ishtp_use_dma under intel_ishtp.
-
-Each side (host and FW) manages its DMA transfer memory independently. When an
-ISHTP client from either host or FW side wants to send something, it decides
-whether to send over IPC or over DMA; for each transfer the decision is
-independent. The sending side sends DMA_XFER message when the message is in
-the respective host buffer (TX when host client sends, RX when FW client
-sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
-the sender that the memory region for that message may be reused.
-
-DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
-(that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
-Additionally to DMA address communication, this sequence checks capabilities:
-if thw host doesn't support DMA, then it won't send DMA allocation, so FW can't
-send DMA; if FW doesn't support DMA then it won't respond with
-DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
-Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
-it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
-that it already did DMA and the message resides at host. Thus, DMA_XFER
-and DMA_XFER_ACK act as ownership indicators.
-
-At initial state all outgoing memory belongs to the sender (TX to host, RX to
-FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
-the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
-needs not wait for previous DMA_XFER to be ack'ed, and may send another message
-as long as remaining continuous memory in its ownership is enough.
-In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
-(up to IPC MTU), thus allowing for interrupt throttling.
-Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
-fragments and via IPC otherwise.
-
-3.3.4 Ring Buffers
-
-When a client initiate a connection, a ring or RX and TX buffers are allocated.
-The size of ring can be specified by the client. HID client set 16 and 32 for
-TX and RX buffers respectively. On send request from client, the data to be
-sent is copied to one of the send ring buffer and scheduled to be sent using
-bus message protocol. These buffers are required because the FW may have not
-have processed the last message and may not have enough flow control credits
-to send. Same thing holds true on receive side and flow control is required.
-
-3.3.5 Host Enumeration
-
-The host enumeration bus command allow discovery of clients present in the FW.
-There can be multiple sensor clients and clients for calibration function.
-
-To ease in implantation and allow independent driver handle each client
-this transport layer takes advantage of Linux Bus driver model. Each
-client is registered as device on the the transport bus (ishtp bus).
-
-Enumeration sequence of messages:
-- Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
-- FW responds with HOST_START_RES_CMD
-- Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
-- FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
-client IDs
-- For each FW ID found in that bitmap host sends
-HOST_CLIENT_PROPERTIES_REQ_CMD
-- FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
-max ISHTP message size, etc.
-- Once host received properties for that last discovered client, it considers
-ISHTP device fully functional (and allocates DMA buffers)
-
-3.4 HID over ISH Client
-Location: drivers/hid/intel-ish-hid
-
-The ISHTP client driver is responsible for:
-- enumerate HID devices under FW ISH client
-- Get Report descriptor
-- Register with HID core as a LL driver
-- Process Get/Set feature request
-- Get input reports
-
-3.5 HID Sensor Hub MFD and IIO sensor drivers
-
-The functionality in these drivers is the same as an external sensor hub.
-Refer to
-Documentation/hid/hid-sensor.txt for HID sensor
-Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space
-
-3.6 End to End HID transport Sequence Diagram
-
-HID-ISH-CLN			ISHTP			IPC				HW
-	|			|			|				|
-	|			|			|-----WAKE UP------------------>|
-	|			|			|				|
-	|			|			|-----HOST READY--------------->|
-	|			|			|				|
-	|			|			|<----MNG_RESET_NOTIFY_ACK----- |
-	|			|			|				|
-	|			|<----ISHTP_START------ |				|
-	|			|			|				|
-	|			|<-----------------HOST_START_RES_CMD-------------------|
-	|			|			|				|
-	|			|------------------QUERY_SUBSCRIBER-------------------->|
-	|			|			|				|
-	|			|------------------HOST_ENUM_REQ_CMD------------------->|
-	|			|			|				|
-	|			|<-----------------HOST_ENUM_RES_CMD--------------------|
-	|			|			|				|
-	|			|------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
-	|			|			|				|
-	|			|<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
-	|	Create new device on in ishtp bus	|				|
-	|			|			|				|
-	|			|------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
-	|			|			|				|
-	|			|<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
-	|	Create new device on in ishtp bus	|				|
-	|			|			|				|
-	|			|--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
-	|			|			|				|
-     probed()
-	|----ishtp_cl_connect-->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
-	|			|			|				|
-	|			|<----------------CLIENT_CONNECT_RES_CMD----------------|
-	|			|			|				|
-	|register event callback|			|				|
-	|			|			|				|
-	|ishtp_cl_send(
-	HOSTIF_DM_ENUM_DEVICES) |----------fill ishtp_msg_hdr struct write to HW-----  >|
-	|			|			|				|
-	|			|			|<-----IRQ(IPC_PROTOCOL_ISHTP---|
-	|			|			|				|
-	|<--ENUM_DEVICE RSP-----|			|				|
-	|			|			|				|
-for each enumerated device
-	|ishtp_cl_send(
-	HOSTIF_GET_HID_DESCRIPTOR |----------fill ishtp_msg_hdr struct write to HW---  >|
-	|			|			|				|
-	...Response
-	|			|			|				|
-for each enumerated device
-	|ishtp_cl_send(
-	HOSTIF_GET_REPORT_DESCRIPTOR |----------fill ishtp_msg_hdr struct write to HW- >|
-	|			|			|				|
-	|			|			|				|
- hid_allocate_device
-	|			|			|				|
- hid_add_device			|			|				|
-	|			|			|				|
-
-
-3.7 ISH Debugging
-
-To debug ISH, event tracing mechanism is used. To enable debug logs
-echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable
-cat sys/kernel/debug/tracing/trace
-
-3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
-
-root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
-/sys/bus/iio/devices/
-├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
-│   ├── buffer
-│   │   ├── enable
-│   │   ├── length
-│   │   └── watermark
-...
-│   ├── in_accel_hysteresis
-│   ├── in_accel_offset
-│   ├── in_accel_sampling_frequency
-│   ├── in_accel_scale
-│   ├── in_accel_x_raw
-│   ├── in_accel_y_raw
-│   ├── in_accel_z_raw
-│   ├── name
-│   ├── scan_elements
-│   │   ├── in_accel_x_en
-│   │   ├── in_accel_x_index
-│   │   ├── in_accel_x_type
-│   │   ├── in_accel_y_en
-│   │   ├── in_accel_y_index
-│   │   ├── in_accel_y_type
-│   │   ├── in_accel_z_en
-│   │   ├── in_accel_z_index
-│   │   └── in_accel_z_type
-...
-│   │   ├── devices
-│   │   │   │   ├── buffer
-│   │   │   │   │   ├── enable
-│   │   │   │   │   ├── length
-│   │   │   │   │   └── watermark
-│   │   │   │   ├── dev
-│   │   │   │   ├── in_intensity_both_raw
-│   │   │   │   ├── in_intensity_hysteresis
-│   │   │   │   ├── in_intensity_offset
-│   │   │   │   ├── in_intensity_sampling_frequency
-│   │   │   │   ├── in_intensity_scale
-│   │   │   │   ├── name
-│   │   │   │   ├── scan_elements
-│   │   │   │   │   ├── in_intensity_both_en
-│   │   │   │   │   ├── in_intensity_both_index
-│   │   │   │   │   └── in_intensity_both_type
-│   │   │   │   ├── trigger
-│   │   │   │   │   └── current_trigger
-...
-│   │   │   │   ├── buffer
-│   │   │   │   │   ├── enable
-│   │   │   │   │   ├── length
-│   │   │   │   │   └── watermark
-│   │   │   │   ├── dev
-│   │   │   │   ├── in_magn_hysteresis
-│   │   │   │   ├── in_magn_offset
-│   │   │   │   ├── in_magn_sampling_frequency
-│   │   │   │   ├── in_magn_scale
-│   │   │   │   ├── in_magn_x_raw
-│   │   │   │   ├── in_magn_y_raw
-│   │   │   │   ├── in_magn_z_raw
-│   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
-│   │   │   │   ├── in_rot_hysteresis
-│   │   │   │   ├── in_rot_offset
-│   │   │   │   ├── in_rot_sampling_frequency
-│   │   │   │   ├── in_rot_scale
-│   │   │   │   ├── name
-...
-│   │   │   │   ├── scan_elements
-│   │   │   │   │   ├── in_magn_x_en
-│   │   │   │   │   ├── in_magn_x_index
-│   │   │   │   │   ├── in_magn_x_type
-│   │   │   │   │   ├── in_magn_y_en
-│   │   │   │   │   ├── in_magn_y_index
-│   │   │   │   │   ├── in_magn_y_type
-│   │   │   │   │   ├── in_magn_z_en
-│   │   │   │   │   ├── in_magn_z_index
-│   │   │   │   │   ├── in_magn_z_type
-│   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
-│   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
-│   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
-│   │   │   │   ├── trigger
-│   │   │   │   │   └── current_trigger
-...
-│   │   │   │   ├── buffer
-│   │   │   │   │   ├── enable
-│   │   │   │   │   ├── length
-│   │   │   │   │   └── watermark
-│   │   │   │   ├── dev
-│   │   │   │   ├── in_anglvel_hysteresis
-│   │   │   │   ├── in_anglvel_offset
-│   │   │   │   ├── in_anglvel_sampling_frequency
-│   │   │   │   ├── in_anglvel_scale
-│   │   │   │   ├── in_anglvel_x_raw
-│   │   │   │   ├── in_anglvel_y_raw
-│   │   │   │   ├── in_anglvel_z_raw
-│   │   │   │   ├── name
-│   │   │   │   ├── scan_elements
-│   │   │   │   │   ├── in_anglvel_x_en
-│   │   │   │   │   ├── in_anglvel_x_index
-│   │   │   │   │   ├── in_anglvel_x_type
-│   │   │   │   │   ├── in_anglvel_y_en
-│   │   │   │   │   ├── in_anglvel_y_index
-│   │   │   │   │   ├── in_anglvel_y_type
-│   │   │   │   │   ├── in_anglvel_z_en
-│   │   │   │   │   ├── in_anglvel_z_index
-│   │   │   │   │   └── in_anglvel_z_type
-│   │   │   │   ├── trigger
-│   │   │   │   │   └── current_trigger
-...
-│   │   │   │   ├── buffer
-│   │   │   │   │   ├── enable
-│   │   │   │   │   ├── length
-│   │   │   │   │   └── watermark
-│   │   │   │   ├── dev
-│   │   │   │   ├── in_anglvel_hysteresis
-│   │   │   │   ├── in_anglvel_offset
-│   │   │   │   ├── in_anglvel_sampling_frequency
-│   │   │   │   ├── in_anglvel_scale
-│   │   │   │   ├── in_anglvel_x_raw
-│   │   │   │   ├── in_anglvel_y_raw
-│   │   │   │   ├── in_anglvel_z_raw
-│   │   │   │   ├── name
-│   │   │   │   ├── scan_elements
-│   │   │   │   │   ├── in_anglvel_x_en
-│   │   │   │   │   ├── in_anglvel_x_index
-│   │   │   │   │   ├── in_anglvel_x_type
-│   │   │   │   │   ├── in_anglvel_y_en
-│   │   │   │   │   ├── in_anglvel_y_index
-│   │   │   │   │   ├── in_anglvel_y_type
-│   │   │   │   │   ├── in_anglvel_z_en
-│   │   │   │   │   ├── in_anglvel_z_index
-│   │   │   │   │   └── in_anglvel_z_type
-│   │   │   │   ├── trigger
-│   │   │   │   │   └── current_trigger
-...
diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.rst
similarity index 94%
rename from Documentation/hid/uhid.txt
rename to Documentation/hid/uhid.rst
index 958fff945304..b18cb96c885f 100644
--- a/Documentation/hid/uhid.txt
+++ b/Documentation/hid/uhid.rst
@@ -1,5 +1,6 @@
-      UHID - User-space I/O driver support for HID subsystem
-     ========================================================
+======================================================
+UHID - User-space I/O driver support for HID subsystem
+======================================================
 
 UHID allows user-space to implement HID transport drivers. Please see
 hid-transport.txt for an introduction into HID transport drivers. This document
@@ -22,9 +23,9 @@ If a new device is detected by your HID I/O Driver and you want to register this
 device with the HID subsystem, then you need to open /dev/uhid once for each
 device you want to register. All further communication is done by read()'ing or
 write()'ing "struct uhid_event" objects. Non-blocking operations are supported
-by setting O_NONBLOCK.
+by setting O_NONBLOCK::
 
-struct uhid_event {
+  struct uhid_event {
         __u32 type;
         union {
                 struct uhid_create2_req create2;
@@ -32,7 +33,7 @@ struct uhid_event {
                 struct uhid_input2_req input2;
                 ...
         } u;
-};
+  };
 
 The "type" field contains the ID of the event. Depending on the ID different
 payloads are sent. You must not split a single event across multiple read()'s or
@@ -86,31 +87,31 @@ the request was handled successfully. O_NONBLOCK does not affect write() as
 writes are always handled immediately in a non-blocking fashion. Future requests
 might make use of O_NONBLOCK, though.
 
-  UHID_CREATE2:
+UHID_CREATE2:
   This creates the internal HID device. No I/O is possible until you send this
   event to the kernel. The payload is of type struct uhid_create2_req and
   contains information about your device. You can start I/O now.
 
-  UHID_DESTROY:
+UHID_DESTROY:
   This destroys the internal HID device. No further I/O will be accepted. There
   may still be pending messages that you can receive with read() but no further
   UHID_INPUT events can be sent to the kernel.
   You can create a new device by sending UHID_CREATE2 again. There is no need to
   reopen the character device.
 
-  UHID_INPUT2:
+UHID_INPUT2:
   You must send UHID_CREATE2 before sending input to the kernel! This event
   contains a data-payload. This is the raw data that you read from your device
   on the interrupt channel. The kernel will parse the HID reports.
 
-  UHID_GET_REPORT_REPLY:
+UHID_GET_REPORT_REPLY:
   If you receive a UHID_GET_REPORT request you must answer with this request.
   You  must copy the "id" field from the request into the answer. Set the "err"
   field to 0 if no error occurred or to EIO if an I/O error occurred.
   If "err" is 0 then you should fill the buffer of the answer with the results
   of the GET_REPORT request and set "size" correspondingly.
 
-  UHID_SET_REPORT_REPLY:
+UHID_SET_REPORT_REPLY:
   This is the SET_REPORT equivalent of UHID_GET_REPORT_REPLY. Unlike GET_REPORT,
   SET_REPORT never returns a data buffer, therefore, it's sufficient to set the
   "id" and "err" fields correctly.
@@ -120,16 +121,18 @@ read()
 read() will return a queued output report. No reaction is required to any of
 them but you should handle them according to your needs.
 
-  UHID_START:
+UHID_START:
   This is sent when the HID device is started. Consider this as an answer to
   UHID_CREATE2. This is always the first event that is sent. Note that this
   event might not be available immediately after write(UHID_CREATE2) returns.
   Device drivers might required delayed setups.
   This event contains a payload of type uhid_start_req. The "dev_flags" field
   describes special behaviors of a device. The following flags are defined:
-      UHID_DEV_NUMBERED_FEATURE_REPORTS:
-      UHID_DEV_NUMBERED_OUTPUT_REPORTS:
-      UHID_DEV_NUMBERED_INPUT_REPORTS:
+
+      - UHID_DEV_NUMBERED_FEATURE_REPORTS
+      - UHID_DEV_NUMBERED_OUTPUT_REPORTS
+      - UHID_DEV_NUMBERED_INPUT_REPORTS
+
           Each of these flags defines whether a given report-type uses numbered
           reports. If numbered reports are used for a type, all messages from
           the kernel already have the report-number as prefix. Otherwise, no
@@ -137,33 +140,35 @@ them but you should handle them according to your needs.
           For messages sent by user-space to the kernel, you must adjust the
           prefixes according to these flags.
 
-  UHID_STOP:
+UHID_STOP:
   This is sent when the HID device is stopped. Consider this as an answer to
   UHID_DESTROY.
+
   If you didn't destroy your device via UHID_DESTROY, but the kernel sends an
   UHID_STOP event, this should usually be ignored. It means that the kernel
   reloaded/changed the device driver loaded on your HID device (or some other
   maintenance actions happened).
+
   You can usually ignored any UHID_STOP events safely.
 
-  UHID_OPEN:
+UHID_OPEN:
   This is sent when the HID device is opened. That is, the data that the HID
   device provides is read by some other process. You may ignore this event but
   it is useful for power-management. As long as you haven't received this event
   there is actually no other process that reads your data so there is no need to
   send UHID_INPUT2 events to the kernel.
 
-  UHID_CLOSE:
+UHID_CLOSE:
   This is sent when there are no more processes which read the HID data. It is
   the counterpart of UHID_OPEN and you may as well ignore this event.
 
-  UHID_OUTPUT:
+UHID_OUTPUT:
   This is sent if the HID device driver wants to send raw data to the I/O
   device on the interrupt channel. You should read the payload and forward it to
   the device. The payload is of type "struct uhid_output_req".
   This may be received even though you haven't received UHID_OPEN, yet.
 
-  UHID_GET_REPORT:
+UHID_GET_REPORT:
   This event is sent if the kernel driver wants to perform a GET_REPORT request
   on the control channeld as described in the HID specs. The report-type and
   report-number are available in the payload.
@@ -177,11 +182,12 @@ them but you should handle them according to your needs.
   timed out, the kernel will ignore the response silently. The "id" field is
   never re-used, so conflicts cannot happen.
 
-  UHID_SET_REPORT:
+UHID_SET_REPORT:
   This is the SET_REPORT equivalent of UHID_GET_REPORT. On receipt, you shall
   send a SET_REPORT request to your hid device. Once it replies, you must tell
   the kernel about it via UHID_SET_REPORT_REPLY.
   The same restrictions as for UHID_GET_REPORT apply.
 
 ----------------------------------------------------
+
 Written 2012, David Herrmann <dh.herrmann@gmail.com>
diff --git a/Documentation/input/input.rst b/Documentation/input/input.rst
index 47f86a4bf16c..0eb61e67a7b7 100644
--- a/Documentation/input/input.rst
+++ b/Documentation/input/input.rst
@@ -188,7 +188,7 @@ LCDs and many other purposes.
 
 The monitor and speaker controls should be easy to add to the hid/input
 interface, but for the UPSs and LCDs it doesn't make much sense. For this,
-the hiddev interface was designed. See Documentation/hid/hiddev.txt
+the hiddev interface was designed. See Documentation/hid/hiddev.rst
 for more information about it.
 
 The usage of the usbhid module is very simple, it takes no parameters,
diff --git a/MAINTAINERS b/MAINTAINERS
index 3e3b9738f2e6..9458cdaa5b4b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16461,7 +16461,7 @@ M:	Benjamin Tissoires <benjamin.tissoires@redhat.com>
 L:	linux-usb@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
 S:	Maintained
-F:	Documentation/hid/hiddev.txt
+F:	Documentation/hid/hiddev.rst
 F:	drivers/hid/usbhid/
 
 USB INTEL XHCI ROLE MUX DRIVER
-- 
2.21.0

^ permalink raw reply related

* Re: [PATCH 1/2] Input: edt-ft5x06 - use get_unaligned_be16()
From: Benoit Parrot @ 2019-06-28 17:36 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, Andy Shevchenko, Marco Felsch, linux-kernel
In-Reply-To: <20190623063153.261546-1-dmitry.torokhov@gmail.com>

Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote on Sat [2019-Jun-22 23:31:52 -0700]:
> Instead of doing conversion by hand, let's use the proper accessors.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/touchscreen/edt-ft5x06.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index c639ebce914c..ec770226e119 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
> @@ -27,6 +27,7 @@
>  #include <linux/gpio/consumer.h>
>  #include <linux/input/mt.h>
>  #include <linux/input/touchscreen.h>
> +#include <asm/unaligned.h>
>  
>  #define WORK_REGISTER_THRESHOLD		0x00
>  #define WORK_REGISTER_REPORT_RATE	0x08
> @@ -239,8 +240,8 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
>  		if (tsdata->version == EDT_M06 && type == TOUCH_EVENT_DOWN)
>  			continue;
>  
> -		x = ((buf[0] << 8) | buf[1]) & 0x0fff;
> -		y = ((buf[2] << 8) | buf[3]) & 0x0fff;
> +		x = get_unaligned_be16(buf) & 0x0fff;
> +		y = get_unaligned_be16(buf + 2) & 0x0fff;

Appears to work fine in my test:

Tested-by: Benoit Parrot <bparrot@ti.com>

>  		/* The FT5x26 send the y coordinate first */
>  		if (tsdata->version == EV_FT)
>  			swap(x, y);
> -- 
> 2.22.0.410.gd8fdbe21b5-goog
> 

^ permalink raw reply

* Re: [PATCH 2/2] Input: edt-ft5x06 - simplify event reporting code
From: Benoit Parrot @ 2019-06-28 17:37 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, Andy Shevchenko, Marco Felsch, linux-kernel
In-Reply-To: <20190623063153.261546-2-dmitry.torokhov@gmail.com>

Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote on Sat [2019-Jun-22 23:31:53 -0700]:
> Now that input_mt_report_slot_state() returns true if slot is active we no
> longer need a temporary for the slot state.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Appears to work fine in my test:

Tested-by: Benoit Parrot <bparrot@ti.com>

> ---
>  drivers/input/touchscreen/edt-ft5x06.c | 13 ++++---------
>  1 file changed, 4 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index ec770226e119..3cc4341bbdff 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
> @@ -229,7 +229,6 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
>  
>  	for (i = 0; i < tsdata->max_support_points; i++) {
>  		u8 *buf = &rdbuf[i * tplen + offset];
> -		bool down;
>  
>  		type = buf[0] >> 6;
>  		/* ignore Reserved events */
> @@ -247,16 +246,12 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
>  			swap(x, y);
>  
>  		id = (buf[2] >> 4) & 0x0f;
> -		down = type != TOUCH_EVENT_UP;
>  
>  		input_mt_slot(tsdata->input, id);
> -		input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, down);
> -
> -		if (!down)
> -			continue;
> -
> -		touchscreen_report_pos(tsdata->input, &tsdata->prop, x, y,
> -				       true);
> +		if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
> +					       type != TOUCH_EVENT_UP))
> +			touchscreen_report_pos(tsdata->input, &tsdata->prop,
> +					       x, y, true);
>  	}
>  
>  	input_mt_report_pointer_emulation(tsdata->input, true);
> -- 
> 2.22.0.410.gd8fdbe21b5-goog
> 

^ permalink raw reply

* Re: [PATCH] platform/x86: touchscreen_dmi: Update Hi10 Air filter
From: Andy Shevchenko @ 2019-06-29 13:20 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Christian Oder, Darren Hart, Andy Shevchenko, linux-input,
	Platform Driver, Linux Kernel Mailing List
In-Reply-To: <736848fd-1c45-0bd9-bfd1-747c716bd953@redhat.com>

On Wed, Jun 12, 2019 at 3:55 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 12-06-19 14:40, Christian Oder wrote:
> > Turns out the Hi10 Air is built by multiple companies so using Hampoo
> > as a filter is not enough to cover all variants.
> >
> > This has been verified as working on the Hampoo and Morshow version.
> >
> > Signed-off-by: Christian Oder <me@myself5.de>
>
> Patch looks good to me:
>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
>

I have pushed it, though I forget about this issue, it went without
this tag, sorry.

> Regards,
>
> Hans
>
>
> > ---
> >   drivers/platform/x86/touchscreen_dmi.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
> > index b662cb2d7cd5..61e7c4987d0d 100644
> > --- a/drivers/platform/x86/touchscreen_dmi.c
> > +++ b/drivers/platform/x86/touchscreen_dmi.c
> > @@ -597,7 +597,8 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
> >               /* Chuwi Hi10 Air */
> >               .driver_data = (void *)&chuwi_hi10_air_data,
> >               .matches = {
> > -                     DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
> > +                     DMI_MATCH(DMI_SYS_VENDOR, "CHUWI INNOVATION AND TECHNOLOGY(SHENZHEN)CO.LTD"),
> > +                     DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
> >                       DMI_MATCH(DMI_PRODUCT_SKU, "P1W6_C109D_B"),
> >               },
> >       },
> >



-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH 0/2] Support for buttons on newer MS Surface devices
From: Andy Shevchenko @ 2019-06-29 14:18 UTC (permalink / raw)
  To: Maximilian Luz
  Cc: Linux Kernel Mailing List, linux-input, Platform Driver,
	Dmitry Torokhov, Hans de Goede, Chen Yu, Darren Hart,
	Andy Shevchenko, Benjamin Tissoires
In-Reply-To: <20190620115056.4169-1-luzmaximilian@gmail.com>

On Thu, Jun 20, 2019 at 2:51 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> This series adds suport for power and volume buttons on 5th and 6th
> generation Microsoft Surface devices. Specifically, it adds support for
> the power-button on the Surface Laptop 1 and Laptop 2, as well as
> support for power- and (on-device) volume-buttons on the Surface Pro 5
> (2017), Pro 6, and Book 2.
>
> These devices use the same MSHW0040 device as on the Surface Pro 4,
> however, whereas the Pro 4 uses an ACPI notify handler, the newer
> devices use GPIO interrupts to signal these events.
>
> The first patch of this series ensures that the surfacepro3_button
> driver, used for MSHW0040 on the Pro 4, does not probe for the newer
> devices. The second patch adapts soc_button_array to implement the
> actual button support.
>
> I think the changes to soc_button_array in the second patch warrant a
> thorough review. I've tried to make things a bit more generic to be able
> to integrate arbitrary ACPI GPIO power-/volume-button devices more
> easily, I'm not sure if there may be reasons against this.
>
> These patches have also been tested on various Surface devices via the
> github.com/jakeday/linux-surface patchset.
>

Pushed to my review and testing queue, thanks!

> Maximilian Luz (2):
>   platform: Fix device check for surfacepro3_button
>   input: soc_button_array for newer surface devices
>
>  drivers/input/misc/soc_button_array.c     | 134 ++++++++++++++++++++--
>  drivers/platform/x86/surfacepro3_button.c |  38 ++++++
>  2 files changed, 160 insertions(+), 12 deletions(-)
>
> --
> 2.22.0
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH 2/2] input: soc_button_array for newer surface devices
From: Andy Shevchenko @ 2019-06-29 14:22 UTC (permalink / raw)
  To: Maximilian Luz
  Cc: Linux Kernel Mailing List, linux-input, Platform Driver,
	Dmitry Torokhov, Hans de Goede, Chen Yu, Darren Hart,
	Andy Shevchenko, Benjamin Tissoires
In-Reply-To: <20190620115056.4169-3-luzmaximilian@gmail.com>

On Thu, Jun 20, 2019 at 2:51 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> Power and volume button support for 5th and 6th genration Microsoft
> Surface devices via soc_button_array.
>
> Note that these devices use the same MSHW0040 device as on the Surface
> Pro 4, however the implementation is different (GPIOs vs. ACPI
> notifications). Thus some checking is required to ensure we only load
> this driver on the correct devices.
>

Either I need an Ack from Dmitry, or it should go via his tree.

> Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
> ---
>  drivers/input/misc/soc_button_array.c | 134 +++++++++++++++++++++++---
>  1 file changed, 122 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
> index 5e59f8e57f8e..157f53a2bd51 100644
> --- a/drivers/input/misc/soc_button_array.c
> +++ b/drivers/input/misc/soc_button_array.c
> @@ -25,6 +25,17 @@ struct soc_button_info {
>         bool wakeup;
>  };
>
> +/**
> + * struct soc_device_data - driver data for different device types
> + * @button_info: specifications of buttons, if NULL specification is assumed to
> + *               be present in _DSD
> + * @check: device-specific check (NULL means all will be accepted)
> + */
> +struct soc_device_data {
> +       struct soc_button_info *button_info;
> +       int (*check)(struct device *dev);
> +};
> +
>  /*
>   * Some of the buttons like volume up/down are auto repeat, while others
>   * are not. To support both, we register two platform devices, and put
> @@ -310,6 +321,7 @@ static int soc_button_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
>         const struct acpi_device_id *id;
> +       struct soc_device_data *device_data;
>         struct soc_button_info *button_info;
>         struct soc_button_data *priv;
>         struct platform_device *pd;
> @@ -320,18 +332,20 @@ static int soc_button_probe(struct platform_device *pdev)
>         if (!id)
>                 return -ENODEV;
>
> -       if (!id->driver_data) {
> +       device_data = (struct soc_device_data *)id->driver_data;
> +       if (device_data && device_data->check) {
> +               error = device_data->check(dev);
> +               if (error)
> +                       return error;
> +       }
> +
> +       if (device_data && device_data->button_info) {
> +               button_info = (struct soc_button_info *)
> +                               device_data->button_info;
> +       } else {
>                 button_info = soc_button_get_button_info(dev);
>                 if (IS_ERR(button_info))
>                         return PTR_ERR(button_info);
> -       } else {
> -               button_info = (struct soc_button_info *)id->driver_data;
> -       }
> -
> -       error = gpiod_count(dev, NULL);
> -       if (error < 0) {
> -               dev_dbg(dev, "no GPIO attached, ignoring...\n");
> -               return -ENODEV;
>         }
>
>         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> @@ -357,12 +371,32 @@ static int soc_button_probe(struct platform_device *pdev)
>         if (!priv->children[0] && !priv->children[1])
>                 return -ENODEV;
>
> -       if (!id->driver_data)
> +       if (!device_data || !device_data->button_info)
>                 devm_kfree(dev, button_info);
>
>         return 0;
>  }
>
> +
> +static int soc_device_check_generic(struct device *dev)
> +{
> +       int gpios;
> +
> +       gpios = gpiod_count(dev, NULL);
> +       if (gpios < 0) {
> +               dev_dbg(dev, "no GPIO attached, ignoring...\n");
> +               return -ENODEV;
> +       }
> +
> +       return 0;
> +}
> +
> +static struct soc_device_data soc_device_ACPI0011 = {
> +       .button_info = NULL,
> +       .check = soc_device_check_generic,
> +};
> +
> +
>  /*
>   * Definition of buttons on the tablet. The ACPI index of each button
>   * is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
> @@ -377,9 +411,85 @@ static struct soc_button_info soc_button_PNP0C40[] = {
>         { }
>  };
>
> +static struct soc_device_data soc_device_PNP0C40 = {
> +       .button_info = soc_button_PNP0C40,
> +       .check = soc_device_check_generic,
> +};
> +
> +
> +/*
> + * Special device check for Surface Book 2 and Surface Pro (2017).
> + * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned
> + * devices use MSHW0040 for power and volume buttons, however the way they
> + * have to be addressed differs. Make sure that we only load this drivers
> + * for the correct devices by checking the OEM Platform Revision provided by
> + * the _DSM method.
> + */
> +#define MSHW0040_DSM_REVISION          0x01
> +#define MSHW0040_DSM_GET_OMPR          0x02    // get OEM Platform Revision
> +static const guid_t MSHW0040_DSM_UUID =
> +       GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
> +                 0x49, 0x80, 0x35);
> +
> +static int soc_device_check_MSHW0040(struct device *dev)
> +{
> +       acpi_handle handle = ACPI_HANDLE(dev);
> +       union acpi_object *result;
> +       u64 oem_platform_rev = 0;
> +       int gpios;
> +
> +       // get OEM platform revision
> +       result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
> +                                        MSHW0040_DSM_REVISION,
> +                                        MSHW0040_DSM_GET_OMPR, NULL,
> +                                        ACPI_TYPE_INTEGER);
> +
> +       if (result) {
> +               oem_platform_rev = result->integer.value;
> +               ACPI_FREE(result);
> +       }
> +
> +       if (oem_platform_rev == 0)
> +               return -ENODEV;
> +
> +       dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
> +
> +       /*
> +        * We are _really_ expecting GPIOs here. If we do not get any, this
> +        * means the GPIO driver has not been loaded yet (which can happen).
> +        * Try again later.
> +        */
> +       gpios = gpiod_count(dev, NULL);
> +       if (gpios < 0)
> +               return -EAGAIN;
> +
> +       return 0;
> +}
> +
> +/*
> + * Button infos for Microsoft Surface Book 2 and Surface Pro (2017).
> + * Obtained from DSDT/testing.
> + */
> +static struct soc_button_info soc_button_MSHW0040[] = {
> +       { "power", 0, EV_KEY, KEY_POWER, false, true },
> +       { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
> +       { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false },
> +       { }
> +};
> +
> +static struct soc_device_data soc_device_MSHW0040 = {
> +       .button_info = soc_button_MSHW0040,
> +       .check = soc_device_check_MSHW0040,
> +};
> +
> +
>  static const struct acpi_device_id soc_button_acpi_match[] = {
> -       { "PNP0C40", (unsigned long)soc_button_PNP0C40 },
> -       { "ACPI0011", 0 },
> +       { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
> +       { "ACPI0011", (unsigned long)&soc_device_ACPI0011 },
> +
> +       /* Microsoft Surface Devices (5th and 6th generation) */
> +       { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
> +
>         { }
>  };
>
> --
> 2.22.0
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH 2/2] Input: edt-ft5x06 - simplify event reporting code
From: Dmitry Torokhov @ 2019-06-30  7:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-input, Marco Felsch, Benoit Parrot,
	Linux Kernel Mailing List
In-Reply-To: <CAHp75VfgR4d7aOG6XPBXisrfa=30pYfCJZ1Yhh2E44bs8vWmVw@mail.gmail.com>

On Sun, Jun 23, 2019 at 10:59:18AM +0300, Andy Shevchenko wrote:
> On Sun, Jun 23, 2019 at 9:31 AM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > Now that input_mt_report_slot_state() returns true if slot is active we no
> > longer need a temporary for the slot state.
> 
> 
> > -               down = type != TOUCH_EVENT_UP;
> >
> >                 input_mt_slot(tsdata->input, id);
> > -               input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, down);
> 
> > +               if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
> > +                                              type != TOUCH_EVENT_UP))
> 
> Can't we simple do somethink like
> -               down = type != TOUCH_EVENT_UP;
> +               down = input_mt_report_slot_state(tsdata->input,
> MT_TOOL_FINGER, type != TOUCH_EVENT_UP);

Why though? The temporary was needed so we did not have to repeat the
expression for "contact down" condition, and now we do not need it. The
whole change was done so that we cab remove the temporary...

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v8 1/5] Input: elan_i2c: Export the device id whitelist
From: Dmitry Torokhov @ 2019-06-30  7:18 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Jeffrey Hugo, Jiri Kosina, Hans de Goede, Bjorn Andersson,
	Andy Gross, Lee Jones, xnox, Rob Herring, Mark Rutland,
	open list:HID CORE LAYER, DTML, MSM, lkml
In-Reply-To: <CAO-hwJLEDCbMud6dCfvXzwDfauAgfOZmQwkmELEF2e6-4Oe6=g@mail.gmail.com>

On Thu, Jun 27, 2019 at 04:29:29PM +0200, Benjamin Tissoires wrote:
> On Thu, Jun 27, 2019 at 4:02 PM Jeffrey Hugo <jeffrey.l.hugo@gmail.com> wrote:
> >
> > On Sun, Jun 23, 2019 at 12:20 AM Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> > >
> > > On Fri, Jun 21, 2019 at 07:50:42AM -0700, Jeffrey Hugo wrote:
> > > > Elan_i2c and hid-quirks work in conjunction to decide which devices each
> > > > driver will handle.  Elan_i2c has a whitelist of devices that should be
> > > > consumed by hid-quirks so that there is one master list of devices to
> > > > handoff between the drivers.  Put the ids in a header file so that
> > > > hid-quirks can consume it instead of duplicating the list.
> > > >
> > > > Signed-off-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
> > >
> > > Benjamin, are you happy with this version?
> >
> > Benjamin, ping?
> > Sorry to be a bother, but I'm still anxious to get this queued for 5.3.
> 
> Ooops, yeah, sorry I missed Dmitry's email.
> 
> Fine by me:
> Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v8 2/5] HID: quirks: Refactor ELAN 400 and 401 handling
From: Dmitry Torokhov @ 2019-06-30  7:18 UTC (permalink / raw)
  To: Jeffrey Hugo
  Cc: benjamin.tissoires, jikos, hdegoede, bjorn.andersson, agross,
	lee.jones, xnox, robh+dt, mark.rutland, linux-input, devicetree,
	linux-arm-msm, linux-kernel
In-Reply-To: <20190621145312.38688-1-jeffrey.l.hugo@gmail.com>

On Fri, Jun 21, 2019 at 07:53:12AM -0700, Jeffrey Hugo wrote:
> There needs to be coordination between hid-quirks and the elan_i2c driver
> about which devices are handled by what drivers.  Currently, both use
> whitelists, which results in valid devices being unhandled by default,
> when they should not be rejected by hid-quirks.  This is quickly becoming
> an issue.
> 
> Since elan_i2c has a maintained whitelist of what devices it will handle,
> which is now in a header file that hid-quirks can access, use that to
> implement a blacklist in hid-quirks so that only the devices that need to
> be handled by elan_i2c get rejected by hid-quirks, and everything else is
> handled by default.
> 
> Suggested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Signed-off-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
> Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Applied, thank you.

> ---
>  drivers/hid/hid-quirks.c | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
> index e5ca6fe2ca57..48ed4caf0ebc 100644
> --- a/drivers/hid/hid-quirks.c
> +++ b/drivers/hid/hid-quirks.c
> @@ -16,6 +16,7 @@
>  #include <linux/export.h>
>  #include <linux/slab.h>
>  #include <linux/mutex.h>
> +#include <linux/input/elan-i2c-ids.h>
>  
>  #include "hid-ids.h"
>  
> @@ -914,6 +915,8 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
>  
>  bool hid_ignore(struct hid_device *hdev)
>  {
> +	int i;
> +
>  	if (hdev->quirks & HID_QUIRK_NO_IGNORE)
>  		return false;
>  	if (hdev->quirks & HID_QUIRK_IGNORE)
> @@ -978,18 +981,15 @@ bool hid_ignore(struct hid_device *hdev)
>  		break;
>  	case USB_VENDOR_ID_ELAN:
>  		/*
> -		 * Many Elan devices have a product id of 0x0401 and are handled
> -		 * by the elan_i2c input driver. But the ACPI HID ELAN0800 dev
> -		 * is not (and cannot be) handled by that driver ->
> -		 * Ignore all 0x0401 devs except for the ELAN0800 dev.
> +		 * Blacklist of everything that gets handled by the elan_i2c
> +		 * input driver.  This avoids disabling valid touchpads and
> +		 * other ELAN devices.
>  		 */
> -		if (hdev->product == 0x0401 &&
> -		    strncmp(hdev->name, "ELAN0800", 8) != 0)
> -			return true;
> -		/* Same with product id 0x0400 */
> -		if (hdev->product == 0x0400 &&
> -		    strncmp(hdev->name, "QTEC0001", 8) != 0)
> -			return true;
> +		if ((hdev->product == 0x0401 || hdev->product == 0x0400))
> +			for (i = 0; strlen(elan_acpi_id[i].id); ++i)
> +				if (!strncmp(hdev->name, elan_acpi_id[i].id,
> +					     strlen(elan_acpi_id[i].id)))
> +					return true;
>  		break;
>  	}
>  
> -- 
> 2.17.1
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Input: joydev - extend absolute mouse detection
From: Dmitry Torokhov @ 2019-06-30  7:32 UTC (permalink / raw)
  To: Alexander Tsoy; +Cc: linux-input, Thomas Hellstrom, linux-kernel
In-Reply-To: <20190623234456.4074-1-alexander@tsoy.me>

On Mon, Jun 24, 2019 at 02:44:56AM +0300, Alexander Tsoy wrote:
> Extend event signature matching to catch more input devices emulated by
> BMC firmwares, QEMU and VMware.
> 
> Signed-off-by: Alexander Tsoy <alexander@tsoy.me>

Applied, thank you.

> ---
>  drivers/input/joydev.c | 24 ++++++++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
> index ac21c050fdb0..a2b5fbba2d3b 100644
> --- a/drivers/input/joydev.c
> +++ b/drivers/input/joydev.c
> @@ -808,6 +808,7 @@ static bool joydev_dev_is_blacklisted(struct input_dev *dev)
>  static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
>  {
>  	DECLARE_BITMAP(jd_scratch, KEY_CNT);
> +	bool ev_match = false;
>  
>  	BUILD_BUG_ON(ABS_CNT > KEY_CNT || EV_CNT > KEY_CNT);
>  
> @@ -826,17 +827,36 @@ static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
>  	 * considered to be an absolute mouse if the following is
>  	 * true:
>  	 *
> -	 * 1) Event types are exactly EV_ABS, EV_KEY and EV_SYN.
> +	 * 1) Event types are exactly
> +	 *      EV_ABS, EV_KEY and EV_SYN
> +	 *    or
> +	 *      EV_ABS, EV_KEY, EV_SYN and EV_MSC
> +	 *    or
> +	 *      EV_ABS, EV_KEY, EV_SYN, EV_MSC and EV_REL.
>  	 * 2) Absolute events are exactly ABS_X and ABS_Y.
>  	 * 3) Keys are exactly BTN_LEFT, BTN_RIGHT and BTN_MIDDLE.
>  	 * 4) Device is not on "Amiga" bus.
>  	 */
>  
>  	bitmap_zero(jd_scratch, EV_CNT);
> +	/* VMware VMMouse, HP ILO2 */
>  	__set_bit(EV_ABS, jd_scratch);
>  	__set_bit(EV_KEY, jd_scratch);
>  	__set_bit(EV_SYN, jd_scratch);
> -	if (!bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
> +	if (bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
> +		ev_match = true;
> +
> +	/* HP ILO2, AMI BMC firmware */
> +	__set_bit(EV_MSC, jd_scratch);
> +	if (bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
> +		ev_match = true;
> +
> +	/* VMware Virtual USB Mouse, QEMU USB Tablet, ATEN BMC firmware */
> +	__set_bit(EV_REL, jd_scratch);
> +	if (bitmap_equal(jd_scratch, dev->evbit, EV_CNT))
> +		ev_match = true;
> +
> +	if (!ev_match)
>  		return false;
>  
>  	bitmap_zero(jd_scratch, ABS_CNT);
> -- 
> 2.21.0
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] HID: apple: Fix stuck function keys when using FN
From: João Moreno @ 2019-06-30 20:15 UTC (permalink / raw)
  Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20190610213106.19342-1-mail@joaomoreno.com>

Hi Jiri & Benjamin,

Let me know if you need something else to get this patch moving forward. This
fixes an issue I hit daily, it would be great to get it fixed.

Thanks.

On Mon, 10 Jun 2019 at 23:31, Joao Moreno <mail@joaomoreno.com> wrote:
>
> This fixes an issue in which key down events for function keys would be
> repeatedly emitted even after the user has raised the physical key. For
> example, the driver fails to emit the F5 key up event when going through
> the following steps:
> - fnmode=1: hold FN, hold F5, release FN, release F5
> - fnmode=2: hold F5, hold FN, release F5, release FN
>
> The repeated F5 key down events can be easily verified using xev.
>
> Signed-off-by: Joao Moreno <mail@joaomoreno.com>
> ---
>  drivers/hid/hid-apple.c | 21 +++++++++++----------
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
> index 1cb41992aaa1..81867a6fa047 100644
> --- a/drivers/hid/hid-apple.c
> +++ b/drivers/hid/hid-apple.c
> @@ -205,20 +205,21 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
>                 trans = apple_find_translation (table, usage->code);
>
>                 if (trans) {
> -                       if (test_bit(usage->code, asc->pressed_fn))
> -                               do_translate = 1;
> -                       else if (trans->flags & APPLE_FLAG_FKEY)
> -                               do_translate = (fnmode == 2 && asc->fn_on) ||
> -                                       (fnmode == 1 && !asc->fn_on);
> +                       int fn_on = value ? asc->fn_on :
> +                               test_bit(usage->code, asc->pressed_fn);
> +
> +                       if (!value)
> +                               clear_bit(usage->code, asc->pressed_fn);
> +                       else if (asc->fn_on)
> +                               set_bit(usage->code, asc->pressed_fn);
> +
> +                       if (trans->flags & APPLE_FLAG_FKEY)
> +                               do_translate = (fnmode == 2 && fn_on) ||
> +                                       (fnmode == 1 && !fn_on);
>                         else
>                                 do_translate = asc->fn_on;
>
>                         if (do_translate) {
> -                               if (value)
> -                                       set_bit(usage->code, asc->pressed_fn);
> -                               else
> -                                       clear_bit(usage->code, asc->pressed_fn);
> -
>                                 input_event(input, usage->type, trans->to,
>                                                 value);
>
> --
> 2.19.1
>

^ permalink raw reply

* [PATCH 2/4] input: keyboard/mouse/touchscreen/misc: Use dev_get_drvdata()
From: Fuqian Huang @ 2019-07-01  3:23 UTC (permalink / raw)
  Cc: Fuqian Huang, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
	Vladimir Zapolskiy, Sylvain Lemieux, Laxman Dewangan,
	Thierry Reding, Jonathan Hunter, Olof Johansson,
	H Hartley Sweeten, Arnd Bergmann, Enrico Weigelt, Thomas Gleixner,
	Andy Shevchenko, Kate Stewart

Using dev_get_drvdata directly.

Signed-off-by: Fuqian Huang <huangfq.daxian@gmail.com>
---
 drivers/input/keyboard/ep93xx_keypad.c   | 10 ++++------
 drivers/input/keyboard/gpio_keys.c       |  3 +--
 drivers/input/keyboard/imx_keypad.c      | 10 ++++------
 drivers/input/keyboard/lpc32xx-keys.c    |  6 ++----
 drivers/input/keyboard/matrix_keypad.c   | 10 ++++------
 drivers/input/keyboard/omap4-keypad.c    | 10 ++++------
 drivers/input/keyboard/pmic8xxx-keypad.c |  6 ++----
 drivers/input/keyboard/pxa27x_keypad.c   | 10 ++++------
 drivers/input/keyboard/samsung-keypad.c  | 12 ++++--------
 drivers/input/keyboard/spear-keyboard.c  | 10 ++++------
 drivers/input/keyboard/st-keyscan.c      |  6 ++----
 drivers/input/keyboard/tegra-kbc.c       | 10 ++++------
 drivers/input/misc/gpio-vibra.c          |  6 ++----
 drivers/input/misc/max77693-haptic.c     |  6 ++----
 drivers/input/misc/max8925_onkey.c       | 10 ++++------
 drivers/input/misc/max8997_haptic.c      |  3 +--
 drivers/input/misc/msm-vibrator.c        |  6 ++----
 drivers/input/misc/palmas-pwrbutton.c    |  6 ++----
 drivers/input/misc/regulator-haptic.c    |  6 ++----
 drivers/input/misc/stpmic1_onkey.c       |  6 ++----
 drivers/input/misc/twl4030-vibra.c       |  3 +--
 drivers/input/misc/twl6040-vibra.c       |  3 +--
 drivers/input/mouse/navpoint.c           |  6 ++----
 drivers/input/touchscreen/imx6ul_tsc.c   |  6 ++----
 24 files changed, 62 insertions(+), 108 deletions(-)

diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index 7c70492d9d6b..bcc8a17f9a01 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -178,8 +178,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int ep93xx_keypad_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
+	struct ep93xx_keypad *keypad = dev_get_drvdata(dev);
 	struct input_dev *input_dev = keypad->input_dev;
 
 	mutex_lock(&input_dev->mutex);
@@ -191,7 +190,7 @@ static int ep93xx_keypad_suspend(struct device *dev)
 
 	mutex_unlock(&input_dev->mutex);
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(dev))
 		enable_irq_wake(keypad->irq);
 
 	return 0;
@@ -199,11 +198,10 @@ static int ep93xx_keypad_suspend(struct device *dev)
 
 static int ep93xx_keypad_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
+	struct ep93xx_keypad *keypad = dev_get_drvdata(dev);
 	struct input_dev *input_dev = keypad->input_dev;
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(dev))
 		disable_irq_wake(keypad->irq);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index a23c23979a2e..83d66155ce74 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -290,8 +290,7 @@ static ssize_t gpio_keys_show_##name(struct device *dev,		\
 				     struct device_attribute *attr,	\
 				     char *buf)				\
 {									\
-	struct platform_device *pdev = to_platform_device(dev);		\
-	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);	\
+	struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);	\
 									\
 	return gpio_keys_attr_show_helper(ddata, buf,			\
 					  type, only_disabled);		\
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index ae9c51cc85f9..d820de0908db 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -528,8 +528,7 @@ static int imx_keypad_probe(struct platform_device *pdev)
 
 static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct imx_keypad *kbd = platform_get_drvdata(pdev);
+	struct imx_keypad *kbd = dev_get_drvdata(dev);
 	struct input_dev *input_dev = kbd->input_dev;
 	unsigned short reg_val = readw(kbd->mmio_base + KPSR);
 
@@ -541,7 +540,7 @@ static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
 
 	mutex_unlock(&input_dev->mutex);
 
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		if (reg_val & KBD_STAT_KPKD)
 			reg_val |= KBD_STAT_KRIE;
 		if (reg_val & KBD_STAT_KPKR)
@@ -556,12 +555,11 @@ static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
 
 static int __maybe_unused imx_kbd_noirq_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct imx_keypad *kbd = platform_get_drvdata(pdev);
+	struct imx_keypad *kbd = dev_get_drvdata(dev);
 	struct input_dev *input_dev = kbd->input_dev;
 	int ret = 0;
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(dev))
 		disable_irq_wake(kbd->irq);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c
index a34e3271b0c9..cc15da57cfec 100644
--- a/drivers/input/keyboard/lpc32xx-keys.c
+++ b/drivers/input/keyboard/lpc32xx-keys.c
@@ -269,8 +269,7 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int lpc32xx_kscan_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev);
+	struct lpc32xx_kscan_drv *kscandat = dev_get_drvdata(dev);
 	struct input_dev *input = kscandat->input;
 
 	mutex_lock(&input->mutex);
@@ -287,8 +286,7 @@ static int lpc32xx_kscan_suspend(struct device *dev)
 
 static int lpc32xx_kscan_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev);
+	struct lpc32xx_kscan_drv *kscandat = dev_get_drvdata(dev);
 	struct input_dev *input = kscandat->input;
 	int retval = 0;
 
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 30924b57058f..c5a294e1de95 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -272,12 +272,11 @@ static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
 
 static int matrix_keypad_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+	struct matrix_keypad *keypad = dev_get_drvdata(dev);
 
 	matrix_keypad_stop(keypad->input_dev);
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(dev))
 		matrix_keypad_enable_wakeup(keypad);
 
 	return 0;
@@ -285,10 +284,9 @@ static int matrix_keypad_suspend(struct device *dev)
 
 static int matrix_keypad_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+	struct matrix_keypad *keypad = dev_get_drvdata(dev);
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(dev))
 		matrix_keypad_disable_wakeup(keypad);
 
 	matrix_keypad_start(keypad->input_dev);
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
index 94c94d7f5155..a6db5494c742 100644
--- a/drivers/input/keyboard/omap4-keypad.c
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -412,11 +412,10 @@ MODULE_DEVICE_TABLE(of, omap_keypad_dt_match);
 #ifdef CONFIG_PM_SLEEP
 static int omap4_keypad_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap4_keypad *keypad_data = platform_get_drvdata(pdev);
+	struct omap4_keypad *keypad_data = dev_get_drvdata(dev);
 	int error;
 
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		error = enable_irq_wake(keypad_data->irq);
 		if (!error)
 			keypad_data->irq_wake_enabled = true;
@@ -427,10 +426,9 @@ static int omap4_keypad_suspend(struct device *dev)
 
 static int omap4_keypad_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap4_keypad *keypad_data = platform_get_drvdata(pdev);
+	struct omap4_keypad *keypad_data = dev_get_drvdata(dev);
 
-	if (device_may_wakeup(&pdev->dev) && keypad_data->irq_wake_enabled) {
+	if (device_may_wakeup(dev) && keypad_data->irq_wake_enabled) {
 		disable_irq_wake(keypad_data->irq);
 		keypad_data->irq_wake_enabled = false;
 	}
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index d529768a1d06..1e22d276e3e9 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -628,8 +628,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int pmic8xxx_kp_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
+	struct pmic8xxx_kp *kp = dev_get_drvdata(dev);
 	struct input_dev *input_dev = kp->input;
 
 	if (device_may_wakeup(dev)) {
@@ -648,8 +647,7 @@ static int pmic8xxx_kp_suspend(struct device *dev)
 
 static int pmic8xxx_kp_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
+	struct pmic8xxx_kp *kp = dev_get_drvdata(dev);
 	struct input_dev *input_dev = kp->input;
 
 	if (device_may_wakeup(dev)) {
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 39023664d2f2..654e178ff39e 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -663,14 +663,13 @@ static void pxa27x_keypad_close(struct input_dev *dev)
 #ifdef CONFIG_PM_SLEEP
 static int pxa27x_keypad_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
+	struct pxa27x_keypad *keypad = dev_get_drvdata(dev);
 
 	/*
 	 * If the keypad is used a wake up source, clock can not be disabled.
 	 * Or it can not detect the key pressing.
 	 */
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(dev))
 		enable_irq_wake(keypad->irq);
 	else
 		clk_disable_unprepare(keypad->clk);
@@ -680,8 +679,7 @@ static int pxa27x_keypad_suspend(struct device *dev)
 
 static int pxa27x_keypad_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
+	struct pxa27x_keypad *keypad = dev_get_drvdata(dev);
 	struct input_dev *input_dev = keypad->input_dev;
 	int ret = 0;
 
@@ -689,7 +687,7 @@ static int pxa27x_keypad_resume(struct device *dev)
 	 * If the keypad is used as wake up source, the clock is not turned
 	 * off. So do not need configure it again.
 	 */
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		disable_irq_wake(keypad->irq);
 	} else {
 		mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index 70c1d086bdd2..286432c4a28a 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -462,8 +462,7 @@ static int samsung_keypad_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int samsung_keypad_runtime_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct samsung_keypad *keypad = platform_get_drvdata(pdev);
+	struct samsung_keypad *keypad = dev_get_drvdata(dev);
 	unsigned int val;
 	int error;
 
@@ -486,8 +485,7 @@ static int samsung_keypad_runtime_suspend(struct device *dev)
 
 static int samsung_keypad_runtime_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct samsung_keypad *keypad = platform_get_drvdata(pdev);
+	struct samsung_keypad *keypad = dev_get_drvdata(dev);
 	unsigned int val;
 
 	if (keypad->stopped)
@@ -531,8 +529,7 @@ static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
 
 static int samsung_keypad_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct samsung_keypad *keypad = platform_get_drvdata(pdev);
+	struct samsung_keypad *keypad = dev_get_drvdata(dev);
 	struct input_dev *input_dev = keypad->input_dev;
 
 	mutex_lock(&input_dev->mutex);
@@ -549,8 +546,7 @@ static int samsung_keypad_suspend(struct device *dev)
 
 static int samsung_keypad_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct samsung_keypad *keypad = platform_get_drvdata(pdev);
+	struct samsung_keypad *keypad = dev_get_drvdata(dev);
 	struct input_dev *input_dev = keypad->input_dev;
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 7d25fa338ab4..a0276a3376d2 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -288,8 +288,7 @@ static int spear_kbd_remove(struct platform_device *pdev)
 
 static int __maybe_unused spear_kbd_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	struct spear_kbd *kbd = dev_get_drvdata(dev);
 	struct input_dev *input_dev = kbd->input;
 	unsigned int rate = 0, mode_ctl_reg, val;
 
@@ -300,7 +299,7 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
 
 	mode_ctl_reg = readl_relaxed(kbd->io_base + MODE_CTL_REG);
 
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		if (!enable_irq_wake(kbd->irq))
 			kbd->irq_wake_enabled = true;
 
@@ -341,13 +340,12 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
 
 static int __maybe_unused spear_kbd_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct spear_kbd *kbd = platform_get_drvdata(pdev);
+	struct spear_kbd *kbd = dev_get_drvdata(dev);
 	struct input_dev *input_dev = kbd->input;
 
 	mutex_lock(&input_dev->mutex);
 
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		if (kbd->irq_wake_enabled) {
 			kbd->irq_wake_enabled = false;
 			disable_irq_wake(kbd->irq);
diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c
index f097128b93fe..b00554a41321 100644
--- a/drivers/input/keyboard/st-keyscan.c
+++ b/drivers/input/keyboard/st-keyscan.c
@@ -215,8 +215,7 @@ static int keyscan_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int keyscan_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct st_keyscan *keypad = platform_get_drvdata(pdev);
+	struct st_keyscan *keypad = dev_get_drvdata(dev);
 	struct input_dev *input = keypad->input_dev;
 
 	mutex_lock(&input->mutex);
@@ -232,8 +231,7 @@ static int keyscan_suspend(struct device *dev)
 
 static int keyscan_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct st_keyscan *keypad = platform_get_drvdata(pdev);
+	struct st_keyscan *keypad = dev_get_drvdata(dev);
 	struct input_dev *input = keypad->input_dev;
 	int retval = 0;
 
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index a37a7a9e9171..f33577944207 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -731,11 +731,10 @@ static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable)
 
 static int tegra_kbc_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct tegra_kbc *kbc = platform_get_drvdata(pdev);
+	struct tegra_kbc *kbc = dev_get_drvdata(dev);
 
 	mutex_lock(&kbc->idev->mutex);
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		disable_irq(kbc->irq);
 		del_timer_sync(&kbc->timer);
 		tegra_kbc_set_fifo_interrupt(kbc, false);
@@ -768,12 +767,11 @@ static int tegra_kbc_suspend(struct device *dev)
 
 static int tegra_kbc_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct tegra_kbc *kbc = platform_get_drvdata(pdev);
+	struct tegra_kbc *kbc = dev_get_drvdata(dev);
 	int err = 0;
 
 	mutex_lock(&kbc->idev->mutex);
-	if (device_may_wakeup(&pdev->dev)) {
+	if (device_may_wakeup(dev)) {
 		disable_irq_wake(kbc->irq);
 		tegra_kbc_setup_wakekeys(kbc, false);
 		/* We will use fifo interrupts for key detection. */
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c
index f79f75595dd7..ad30cb5b1523 100644
--- a/drivers/input/misc/gpio-vibra.c
+++ b/drivers/input/misc/gpio-vibra.c
@@ -159,8 +159,7 @@ static int gpio_vibrator_probe(struct platform_device *pdev)
 
 static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct gpio_vibrator *vibrator = platform_get_drvdata(pdev);
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
 
 	cancel_work_sync(&vibrator->play_work);
 	if (vibrator->running)
@@ -171,8 +170,7 @@ static int __maybe_unused gpio_vibrator_suspend(struct device *dev)
 
 static int __maybe_unused gpio_vibrator_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct gpio_vibrator *vibrator = platform_get_drvdata(pdev);
+	struct gpio_vibrator *vibrator = dev_get_drvdata(dev);
 
 	if (vibrator->running)
 		gpio_vibrator_start(vibrator);
diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c
index 0d09ffeafeea..86e1c72efda1 100644
--- a/drivers/input/misc/max77693-haptic.c
+++ b/drivers/input/misc/max77693-haptic.c
@@ -377,8 +377,7 @@ static int max77693_haptic_probe(struct platform_device *pdev)
 
 static int __maybe_unused max77693_haptic_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct max77693_haptic *haptic = platform_get_drvdata(pdev);
+	struct max77693_haptic *haptic = dev_get_drvdata(dev);
 
 	if (haptic->enabled) {
 		max77693_haptic_disable(haptic);
@@ -390,8 +389,7 @@ static int __maybe_unused max77693_haptic_suspend(struct device *dev)
 
 static int __maybe_unused max77693_haptic_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct max77693_haptic *haptic = platform_get_drvdata(pdev);
+	struct max77693_haptic *haptic = dev_get_drvdata(dev);
 
 	if (haptic->suspend_state) {
 		max77693_haptic_enable(haptic);
diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c
index 7c49b8d23894..af0ba592a0b3 100644
--- a/drivers/input/misc/max8925_onkey.c
+++ b/drivers/input/misc/max8925_onkey.c
@@ -135,9 +135,8 @@ static int max8925_onkey_probe(struct platform_device *pdev)
 
 static int __maybe_unused max8925_onkey_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct max8925_onkey_info *info = platform_get_drvdata(pdev);
-	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_onkey_info *info = dev_get_drvdata(dev);
+	struct max8925_chip *chip = dev_get_drvdata(dev->parent);
 
 	if (device_may_wakeup(dev)) {
 		chip->wakeup_flag |= 1 << info->irq[0];
@@ -149,9 +148,8 @@ static int __maybe_unused max8925_onkey_suspend(struct device *dev)
 
 static int __maybe_unused max8925_onkey_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct max8925_onkey_info *info = platform_get_drvdata(pdev);
-	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_onkey_info *info = dev_get_drvdata(dev);
+	struct max8925_chip *chip = dev_get_drvdata(dev->parent);
 
 	if (device_may_wakeup(dev)) {
 		chip->wakeup_flag &= ~(1 << info->irq[0]);
diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c
index 20ff087b8a44..e841b8e4b1d4 100644
--- a/drivers/input/misc/max8997_haptic.c
+++ b/drivers/input/misc/max8997_haptic.c
@@ -374,8 +374,7 @@ static int max8997_haptic_remove(struct platform_device *pdev)
 
 static int __maybe_unused max8997_haptic_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct max8997_haptic *chip = platform_get_drvdata(pdev);
+	struct max8997_haptic *chip = dev_get_drvdata(dev);
 
 	max8997_haptic_disable(chip);
 
diff --git a/drivers/input/misc/msm-vibrator.c b/drivers/input/misc/msm-vibrator.c
index b60f1aaee705..a28974bfb64e 100644
--- a/drivers/input/misc/msm-vibrator.c
+++ b/drivers/input/misc/msm-vibrator.c
@@ -234,8 +234,7 @@ static int msm_vibrator_probe(struct platform_device *pdev)
 
 static int __maybe_unused msm_vibrator_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
+	struct msm_vibrator *vibrator = dev_get_drvdata(dev);
 
 	cancel_work_sync(&vibrator->worker);
 
@@ -247,8 +246,7 @@ static int __maybe_unused msm_vibrator_suspend(struct device *dev)
 
 static int __maybe_unused msm_vibrator_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
+	struct msm_vibrator *vibrator = dev_get_drvdata(dev);
 
 	if (vibrator->enabled)
 		msm_vibrator_start(vibrator);
diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c
index 1e1baed63929..27617868b292 100644
--- a/drivers/input/misc/palmas-pwrbutton.c
+++ b/drivers/input/misc/palmas-pwrbutton.c
@@ -270,8 +270,7 @@ static int palmas_pwron_remove(struct platform_device *pdev)
  */
 static int __maybe_unused palmas_pwron_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct palmas_pwron *pwron = platform_get_drvdata(pdev);
+	struct palmas_pwron *pwron = dev_get_drvdata(dev);
 
 	cancel_delayed_work_sync(&pwron->input_work);
 
@@ -291,8 +290,7 @@ static int __maybe_unused palmas_pwron_suspend(struct device *dev)
  */
 static int __maybe_unused palmas_pwron_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct palmas_pwron *pwron = platform_get_drvdata(pdev);
+	struct palmas_pwron *pwron = dev_get_drvdata(dev);
 
 	if (device_may_wakeup(dev))
 		disable_irq_wake(pwron->irq);
diff --git a/drivers/input/misc/regulator-haptic.c b/drivers/input/misc/regulator-haptic.c
index a661e77545c5..9734374964f2 100644
--- a/drivers/input/misc/regulator-haptic.c
+++ b/drivers/input/misc/regulator-haptic.c
@@ -203,8 +203,7 @@ static int regulator_haptic_probe(struct platform_device *pdev)
 
 static int __maybe_unused regulator_haptic_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct regulator_haptic *haptic = platform_get_drvdata(pdev);
+	struct regulator_haptic *haptic = dev_get_drvdata(dev);
 	int error;
 
 	error = mutex_lock_interruptible(&haptic->mutex);
@@ -222,8 +221,7 @@ static int __maybe_unused regulator_haptic_suspend(struct device *dev)
 
 static int __maybe_unused regulator_haptic_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct regulator_haptic *haptic = platform_get_drvdata(pdev);
+	struct regulator_haptic *haptic = dev_get_drvdata(dev);
 	unsigned int magnitude;
 
 	mutex_lock(&haptic->mutex);
diff --git a/drivers/input/misc/stpmic1_onkey.c b/drivers/input/misc/stpmic1_onkey.c
index 7b49c9997df7..ff4761540539 100644
--- a/drivers/input/misc/stpmic1_onkey.c
+++ b/drivers/input/misc/stpmic1_onkey.c
@@ -150,8 +150,7 @@ static int stpmic1_onkey_probe(struct platform_device *pdev)
 
 static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
+	struct stpmic1_onkey *onkey = dev_get_drvdata(dev);
 
 	if (device_may_wakeup(dev)) {
 		enable_irq_wake(onkey->irq_falling);
@@ -162,8 +161,7 @@ static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
 
 static int __maybe_unused stpmic1_onkey_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
+	struct stpmic1_onkey *onkey = dev_get_drvdata(dev);
 
 	if (device_may_wakeup(dev)) {
 		disable_irq_wake(onkey->irq_falling);
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index e0ff616fb857..f7ef67997863 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -145,8 +145,7 @@ static void twl4030_vibra_close(struct input_dev *input)
 /*** Module ***/
 static int __maybe_unused twl4030_vibra_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct vibra_info *info = platform_get_drvdata(pdev);
+	struct vibra_info *info = dev_get_drvdata(dev);
 
 	if (info->enabled)
 		vibra_disable(info);
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
index 93235a007d07..900be3420967 100644
--- a/drivers/input/misc/twl6040-vibra.c
+++ b/drivers/input/misc/twl6040-vibra.c
@@ -212,8 +212,7 @@ static void twl6040_vibra_close(struct input_dev *input)
 
 static int __maybe_unused twl6040_vibra_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct vibra_info *info = platform_get_drvdata(pdev);
+	struct vibra_info *info = dev_get_drvdata(dev);
 
 	cancel_work_sync(&info->play_work);
 
diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c
index 0b75248c8380..f47d278c2657 100644
--- a/drivers/input/mouse/navpoint.c
+++ b/drivers/input/mouse/navpoint.c
@@ -317,8 +317,7 @@ static int navpoint_remove(struct platform_device *pdev)
 
 static int __maybe_unused navpoint_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct navpoint *navpoint = platform_get_drvdata(pdev);
+	struct navpoint *navpoint = dev_get_drvdata(dev);
 	struct input_dev *input = navpoint->input;
 
 	mutex_lock(&input->mutex);
@@ -331,8 +330,7 @@ static int __maybe_unused navpoint_suspend(struct device *dev)
 
 static int __maybe_unused navpoint_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct navpoint *navpoint = platform_get_drvdata(pdev);
+	struct navpoint *navpoint = dev_get_drvdata(dev);
 	struct input_dev *input = navpoint->input;
 
 	mutex_lock(&input->mutex);
diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
index c10fc594f94d..493322ed0e34 100644
--- a/drivers/input/touchscreen/imx6ul_tsc.c
+++ b/drivers/input/touchscreen/imx6ul_tsc.c
@@ -511,8 +511,7 @@ static int imx6ul_tsc_probe(struct platform_device *pdev)
 
 static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
+	struct imx6ul_tsc *tsc = dev_get_drvdata(dev);
 	struct input_dev *input_dev = tsc->input;
 
 	mutex_lock(&input_dev->mutex);
@@ -531,8 +530,7 @@ static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
 
 static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
+	struct imx6ul_tsc *tsc = dev_get_drvdata(dev);
 	struct input_dev *input_dev = tsc->input;
 	int retval = 0;
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH] HID: Add another Primax PIXART OEM mouse quirk
From: Sebastian Parschauer @ 2019-07-01  5:48 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires; +Cc: linux-input, Sebastian Parschauer, stable

The PixArt OEM mice are known for disconnecting every minute in
runlevel 1 or 3 if they are not always polled. So add quirk
ALWAYS_POLL for this Alienware branded Primax mouse as well.

Daniel Schepler (@dschepler) reported and tested the quirk.
Reference: https://github.com/sriemer/fix-linux-mouse/issues/15

Signed-off-by: Sebastian Parschauer <s.parschauer@gmx.de>
CC: stable@vger.kernel.org
---
 drivers/hid/hid-ids.h    | 1 +
 drivers/hid/hid-quirks.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index eac0c54c5970..ea04b37cdac2 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1238,6 +1238,7 @@
 #define USB_DEVICE_ID_PRIMAX_KEYBOARD	0x4e05
 #define USB_DEVICE_ID_PRIMAX_REZEL	0x4e72
 #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F	0x4d0f
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65	0x4d65
 #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22	0x4e22


diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index e5ca6fe2ca57..4aa321e35a8e 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -129,6 +129,7 @@ static const struct hid_device_id hid_quirks[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET },
--
2.16.4

^ permalink raw reply related

* Re: [Patch 1/1] Input: edt-ft5x06 - disable irq handling during suspend
From: Dmitry Torokhov @ 2019-07-01  7:32 UTC (permalink / raw)
  To: Benoit Parrot
  Cc: Andy Shevchenko, Henrik Rydberg, Marco Felsch, Andy Shevchenko,
	linux-input, Linux Kernel Mailing List
In-Reply-To: <20190624122457.seiezk4cla2gjh5u@ti.com>

On Mon, Jun 24, 2019 at 07:24:57AM -0500, Benoit Parrot wrote:
> Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote on Sat [2019-Jun-22 22:59:40 -0700]:
> > On Sat, Jun 22, 2019 at 01:37:10PM +0300, Andy Shevchenko wrote:
> > > On Fri, Jun 21, 2019 at 9:53 PM Benoit Parrot <bparrot@ti.com> wrote:
> > > >
> > > > As a wakeup source when the system is in suspend there is little point
> > > > trying to access a register across the i2c bus as it is probably still
> > > > inactive. We need to prevent the irq handler from being called during
> > > > suspend.
> > > >
> > > 
> > > Hmm... But how OS will know what the event to handle afterwards?
> > > I mean shouldn't we guarantee somehow the delivery of the event to the
> > > input, in this case, subsystem followed by corresponding user space?
> > 
> > If we are using level interrupts then it will work OK, however it is
> > really easy to lose edge here, as replaying disabled edge triggered
> > interrupts is not really reliable.
> > 
> > Benoit, what kind of interrupt do you use in your system?
> 
> Dmitry,
> 
> On our systems we currently used edge trigger. One example is available in
> mainline: arch/arm/boot/dts/am437x-sk-evm.dts
> 632:              interrupts = <31 IRQ_TYPE_EDGE_FALLING>;

Does your device still work if you switch to level-triggered interrupt?

Regarding your patch I am uncomfortable with disabling interrupts if
interrupt is edge-triggered, as replaying edge interrupts after enabling
is not very reliable. So we should either only disable interrupt if it
is level-triggered, or make sure we read and process data from the
device after re-enabling interrupt to rearm it. We'll need to make sure
suspend does not race with interrupt handler than and also make sure we
handle case when device does not actually has data to report.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 2/4] input: keyboard/mouse/touchscreen/misc: Use dev_get_drvdata()
From: Dmitry Torokhov @ 2019-07-01  7:52 UTC (permalink / raw)
  To: Fuqian Huang
  Cc: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	NXP Linux Team, Vladimir Zapolskiy, Sylvain Lemieux,
	Laxman Dewangan, Thierry Reding, Jonathan Hunter, Olof Johansson,
	H Hartley Sweeten, Arnd Bergmann, Enrico Weigelt, Thomas Gleixner,
	Andy Shevchenko, Kate Stewart, Florian Fainelli, Anson Huang
In-Reply-To: <20190701032342.25971-1-huangfq.daxian@gmail.com>

Hi Fuqian,

On Mon, Jul 01, 2019 at 11:23:12AM +0800, Fuqian Huang wrote:
> Using dev_get_drvdata directly.
> 

I prefer using proper bus accessors.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v3 7/7] Input: add IOC3 serio driver
From: Dmitry Torokhov @ 2019-07-01  8:19 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Ralf Baechle, Paul Burton, James Hogan, Lee Jones,
	David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
	Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby, linux-mips,
	linux-kernel, linux-input, netdev, linux-rtc, linux-serial
In-Reply-To: <20190613170636.6647-8-tbogendoerfer@suse.de>

Hi Thomas,

On Thu, Jun 13, 2019 at 07:06:33PM +0200, Thomas Bogendoerfer wrote:
> This patch adds a platform driver for supporting keyboard and mouse
> interface of SGI IOC3 chips.
> 
> Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
> ---
>  drivers/input/serio/Kconfig   |  10 +++
>  drivers/input/serio/Makefile  |   1 +
>  drivers/input/serio/ioc3kbd.c | 158 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 169 insertions(+)
>  create mode 100644 drivers/input/serio/ioc3kbd.c
> 
> diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
> index f3e18f8ef9ca..373a1646019e 100644
> --- a/drivers/input/serio/Kconfig
> +++ b/drivers/input/serio/Kconfig
> @@ -165,6 +165,16 @@ config SERIO_MACEPS2
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called maceps2.
>  
> +config SERIO_SGI_IOC3
> +	tristate "SGI IOC3 PS/2 controller"
> +	depends on SGI_MFD_IOC3
> +	help
> +	  Say Y here if you have an SGI Onyx2, SGI Octane or IOC3 PCI card
> +	  and you want to attach and use a keyboard, mouse, or both.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called ioc3kbd.
> +
>  config SERIO_LIBPS2
>  	tristate "PS/2 driver library"
>  	depends on SERIO_I8042 || SERIO_I8042=n
> diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
> index 67950a5ccb3f..6d97bad7b844 100644
> --- a/drivers/input/serio/Makefile
> +++ b/drivers/input/serio/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_HIL_MLC)		+= hp_sdc_mlc.o hil_mlc.o
>  obj-$(CONFIG_SERIO_PCIPS2)	+= pcips2.o
>  obj-$(CONFIG_SERIO_PS2MULT)	+= ps2mult.o
>  obj-$(CONFIG_SERIO_MACEPS2)	+= maceps2.o
> +obj-$(CONFIG_SERIO_SGI_IOC3)	+= ioc3kbd.o
>  obj-$(CONFIG_SERIO_LIBPS2)	+= libps2.o
>  obj-$(CONFIG_SERIO_RAW)		+= serio_raw.o
>  obj-$(CONFIG_SERIO_AMS_DELTA)	+= ams_delta_serio.o
> diff --git a/drivers/input/serio/ioc3kbd.c b/drivers/input/serio/ioc3kbd.c
> new file mode 100644
> index 000000000000..26fcf57465d6
> --- /dev/null
> +++ b/drivers/input/serio/ioc3kbd.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * SGI IOC3 PS/2 controller driver for linux
> + *
> + * Copyright (C) 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
> + *
> + * Based on code Copyright (C) 2005 Stanislaw Skowronek <skylark@unaligned.org>
> + *               Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/serio.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +#include <asm/sn/ioc3.h>
> +
> +struct ioc3kbd_data {
> +	struct ioc3_serioregs __iomem *regs;
> +	struct serio *kbd, *aux;
> +};
> +
> +static int ioc3kbd_write(struct serio *dev, u8 val)
> +{
> +	struct ioc3kbd_data *d = dev->port_data;
> +	unsigned long timeout = 0;
> +	u32 mask;
> +
> +	mask = (dev == d->aux) ? KM_CSR_M_WRT_PEND : KM_CSR_K_WRT_PEND;
> +	while ((readl(&d->regs->km_csr) & mask) && (timeout < 1000)) {
> +		udelay(100);
> +		timeout++;
> +	}
> +
> +	if (timeout >= 1000)
> +		return -1;

-ETIMEDOUT?

> +
> +	writel(val, dev == d->aux ?  &d->regs->m_wd : &d->regs->k_wd);

Nit: there are 2 spaces after ?, only one is needed.

> +
> +	return 0;
> +}
> +
> +static irqreturn_t ioc3kbd_intr(int itq, void *dev_id)
> +{
> +	struct ioc3kbd_data *d = dev_id;
> +	u32 data_k, data_m;
> +
> +	data_k = readl(&d->regs->k_rd);
> +	data_m = readl(&d->regs->m_rd);
> +
> +	if (data_k & KM_RD_VALID_0)
> +		serio_interrupt(d->kbd,
> +		(data_k >> KM_RD_DATA_0_SHIFT) & 0xff, 0);

This is weird formatting, you need one more tab here.

> +	if (data_k & KM_RD_VALID_1)
> +		serio_interrupt(d->kbd,
> +		(data_k >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
> +	if (data_k & KM_RD_VALID_2)
> +		serio_interrupt(d->kbd,
> +		(data_k >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
> +	if (data_m & KM_RD_VALID_0)
> +		serio_interrupt(d->aux,
> +		(data_m >> KM_RD_DATA_0_SHIFT) & 0xff, 0);
> +	if (data_m & KM_RD_VALID_1)
> +		serio_interrupt(d->aux,
> +		(data_m >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
> +	if (data_m & KM_RD_VALID_2)
> +		serio_interrupt(d->aux,
> +		(data_m >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
> +
> +	return 0;
> +}
> +
> +static int ioc3kbd_probe(struct platform_device *pdev)
> +{
> +	struct ioc3_serioregs __iomem *regs;
> +	struct device *dev = &pdev->dev;
> +	struct ioc3kbd_data *d;
> +	struct serio *sk, *sa;
> +	struct resource *mem;
> +	int irq, ret;
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	regs = devm_ioremap_resource(&pdev->dev, mem);

We have a brand new helper: devm_platform_ioremap_resource()

> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return -ENXIO;
> +
> +	d = devm_kzalloc(&pdev->dev, sizeof(struct ioc3kbd_data), GFP_KERNEL);

I think we nor prefer deriving type from the pointer:

	d = evm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL);

> +	if (!d)
> +		return -ENOMEM;
> +
> +	ret = devm_request_irq(&pdev->dev, irq, ioc3kbd_intr, IRQF_SHARED,
> +			       "ioc3-kbd", d);
> +	if (ret) {
> +		dev_err(&pdev->dev, "could not request IRQ %d\n", irq);
> +		return ret;
> +	}

You need to make sure that interrupt will not fire while serio ports are
not yet allocated/registered. Is there a way to inhibit interrupt
generation on controller side?

> +
> +	sk = kzalloc(sizeof(struct serio), GFP_KERNEL);

	sk = kzalloc(sizeof(*sk), GFP_KERNEL);

> +	if (!sk)
> +		return -ENOMEM;
> +
> +	sa = kzalloc(sizeof(struct serio), GFP_KERNEL);

	sa = kzalloc(sizeof(*sa), GFP_KERNEL);

> +	if (!sa) {
> +		kfree(sk);
> +		return -ENOMEM;
> +	}
> +
> +	sk->id.type = SERIO_8042;
> +	sk->write = ioc3kbd_write;
> +	snprintf(sk->name, sizeof(sk->name), "IOC3 keyboard %d", pdev->id);
> +	snprintf(sk->phys, sizeof(sk->phys), "ioc3/serio%dkbd", pdev->id);
> +	sk->port_data = d;
> +	sk->dev.parent = &pdev->dev;
> +
> +	sa->id.type = SERIO_8042;
> +	sa->write = ioc3kbd_write;
> +	snprintf(sa->name, sizeof(sa->name), "IOC3 auxiliary %d", pdev->id);
> +	snprintf(sa->phys, sizeof(sa->phys), "ioc3/serio%daux", pdev->id);
> +	sa->port_data = d;
> +	sa->dev.parent = dev;
> +
> +	d->regs = regs;
> +	d->kbd = sk;
> +	d->aux = sa;
> +
> +	platform_set_drvdata(pdev, d);
> +	serio_register_port(d->kbd);
> +	serio_register_port(d->aux);
> +	return 0;
> +}
> +
> +static int ioc3kbd_remove(struct platform_device *pdev)
> +{
> +	struct ioc3kbd_data *d = platform_get_drvdata(pdev);
> +
> +	serio_unregister_port(d->kbd);
> +	serio_unregister_port(d->aux);

If you unregister ports while interrupt is registered/enabled you may
get a crash.

> +	return 0;
> +}
> +
> +static struct platform_driver ioc3kbd_driver = {
> +	.probe          = ioc3kbd_probe,
> +	.remove         = ioc3kbd_remove,
> +	.driver = {
> +		.name = "ioc3-kbd",
> +	},
> +};
> +module_platform_driver(ioc3kbd_driver);
> +
> +MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
> +MODULE_DESCRIPTION("SGI IOC3 serio driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.13.7
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2] Input: atmel_mxt_ts - fix -Wunused-const-variable
From: Dmitry Torokhov @ 2019-07-01  8:19 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Nathan Huckleberry, nick, linux-input, LKML, clang-built-linux
In-Reply-To: <CAKwvOd=252Ak-VQ20XtsGaRXEfraxtNTNjhjYfdrsWv_7OHsoQ@mail.gmail.com>

On Thu, Jun 13, 2019 at 11:26:41AM -0700, Nick Desaulniers wrote:
> On Thu, Jun 13, 2019 at 11:24 AM 'Nathan Huckleberry' via Clang Built
> Linux <clang-built-linux@googlegroups.com> wrote:
> > Changes from v1 -> v2
> > * Moved definition of mxt_video_fops into existing ifdef
> 
> Thanks for the v2.
> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>

Applied, thank you.

> 
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -256,16 +256,6 @@ enum v4l_dbg_inputs {
> >         MXT_V4L_INPUT_MAX,
> >  };
> >
> > -static const struct v4l2_file_operations mxt_video_fops = {
> > -       .owner = THIS_MODULE,
> > -       .open = v4l2_fh_open,
> > -       .release = vb2_fop_release,
> > -       .unlocked_ioctl = video_ioctl2,
> > -       .read = vb2_fop_read,
> > -       .mmap = vb2_fop_mmap,
> > -       .poll = vb2_fop_poll,
> > -};
> > -
> >  enum mxt_suspend_mode {
> >         MXT_SUSPEND_DEEP_SLEEP  = 0,
> >         MXT_SUSPEND_T9_CTRL     = 1,
> > @@ -2218,6 +2208,16 @@ static int mxt_init_t7_power_cfg(struct mxt_data *data)
> >  }
> >
> >  #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
> > +static const struct v4l2_file_operations mxt_video_fops = {
> > +       .owner = THIS_MODULE,
> > +       .open = v4l2_fh_open,
> > +       .release = vb2_fop_release,
> > +       .unlocked_ioctl = video_ioctl2,
> > +       .read = vb2_fop_read,
> > +       .mmap = vb2_fop_mmap,
> > +       .poll = vb2_fop_poll,
> > +};
> > +
> 
> -- 
> Thanks,
> ~Nick Desaulniers

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] HID: apple: Fix stuck function keys when using FN
From: Benjamin Tissoires @ 2019-07-01  8:32 UTC (permalink / raw)
  To: João Moreno; +Cc: Jiri Kosina, open list:HID CORE LAYER, lkml
In-Reply-To: <CAHxFc3QC147B6j4pBztjK7stLgCveeYhJWojai_SbKNbnpC9yw@mail.gmail.com>

Hi João,

On Sun, Jun 30, 2019 at 10:15 PM João Moreno <mail@joaomoreno.com> wrote:
>
> Hi Jiri & Benjamin,
>
> Let me know if you need something else to get this patch moving forward. This
> fixes an issue I hit daily, it would be great to get it fixed.

Sorry for the delay, I am very busy with internal corporate stuff, and
I tried setting up a new CI system at home, and instead of spending a
couple of ours, I am down to 2 weeks of hard work, without possibility
to switch to the new right now :(
Anyway.

>
> Thanks.
>
> On Mon, 10 Jun 2019 at 23:31, Joao Moreno <mail@joaomoreno.com> wrote:
> >
> > This fixes an issue in which key down events for function keys would be
> > repeatedly emitted even after the user has raised the physical key. For
> > example, the driver fails to emit the F5 key up event when going through
> > the following steps:
> > - fnmode=1: hold FN, hold F5, release FN, release F5
> > - fnmode=2: hold F5, hold FN, release F5, release FN

Ouch :/

> >
> > The repeated F5 key down events can be easily verified using xev.
> >
> > Signed-off-by: Joao Moreno <mail@joaomoreno.com>
> > ---
> >  drivers/hid/hid-apple.c | 21 +++++++++++----------
> >  1 file changed, 11 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
> > index 1cb41992aaa1..81867a6fa047 100644
> > --- a/drivers/hid/hid-apple.c
> > +++ b/drivers/hid/hid-apple.c
> > @@ -205,20 +205,21 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
> >                 trans = apple_find_translation (table, usage->code);
> >
> >                 if (trans) {
> > -                       if (test_bit(usage->code, asc->pressed_fn))
> > -                               do_translate = 1;
> > -                       else if (trans->flags & APPLE_FLAG_FKEY)
> > -                               do_translate = (fnmode == 2 && asc->fn_on) ||
> > -                                       (fnmode == 1 && !asc->fn_on);
> > +                       int fn_on = value ? asc->fn_on :
> > +                               test_bit(usage->code, asc->pressed_fn);
> > +
> > +                       if (!value)
> > +                               clear_bit(usage->code, asc->pressed_fn);
> > +                       else if (asc->fn_on)
> > +                               set_bit(usage->code, asc->pressed_fn);

I have the feeling that this is not the correct fix here.

I might be wrong, but the following sequence might also mess up the
driver state, depending on how the reports are emitted:
- hold FN, hold F4, hold F5, release F4, release FN, release F5

The reason is that the driver only considers you have one key pressed
with the modifier, and as the code changed its state based on the last
value.

IMO a better fix would:

- keep the existing `trans` mapping lookout
- whenever a `trans` mapping gets found:
  * get both translated and non-translated currently reported values
(`test_bit(keycode, input_dev->key)`)
  * if one of them is set to true, then consider the keycode to be the
one of the key (no matter fn_on)
    -> deal with `value` with the corrected keycode
  * if the key was not pressed:
    -> chose the keycode based on `fn_on` and `fnmode` states
    and report the key press event

This should remove the nasty pressed_fn state which depends on the
other pressed keys.

Cheers,
Benjamin

> > +
> > +                       if (trans->flags & APPLE_FLAG_FKEY)
> > +                               do_translate = (fnmode == 2 && fn_on) ||
> > +                                       (fnmode == 1 && !fn_on);
> >                         else
> >                                 do_translate = asc->fn_on;
> >
> >                         if (do_translate) {
> > -                               if (value)
> > -                                       set_bit(usage->code, asc->pressed_fn);
> > -                               else
> > -                                       clear_bit(usage->code, asc->pressed_fn);
> > -
> >                                 input_event(input, usage->type, trans->to,
> >                                                 value);
> >
> > --
> > 2.19.1
> >

^ permalink raw reply

* Re: [PATCH 3/3] video: fbdev: don't print error message on framebuffer_alloc() failure
From: Benjamin Tissoires @ 2019-07-01  8:37 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: linux-fbdev, Jiri Kosina, lkml, dri-devel, Bruno Prémont,
	open list:HID CORE LAYER
In-Reply-To: <3da197ed-a701-2aa7-d775-2bdbe9deab4a@samsung.com>

Hi Bartlomiej,

On Fri, Jun 14, 2019 at 4:52 PM Bartlomiej Zolnierkiewicz
<b.zolnierkie@samsung.com> wrote:
>
> framebuffer_alloc() can fail only on kzalloc() memory allocation
> failure and since kzalloc() will print error message in such case
> we can omit printing extra error message in drivers (which BTW is
> what the majority of framebuffer_alloc() users is doing already).
>
> Cc: "Bruno Prémont" <bonbons@linux-vserver.org>
> Cc: Jiri Kosina <jikos@kernel.org>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> ---
>  drivers/hid/hid-picolcd_fb.c                   |    4 +---
>  drivers/video/fbdev/amifb.c                    |    4 +---
>  drivers/video/fbdev/arkfb.c                    |    4 +---
>  drivers/video/fbdev/atmel_lcdfb.c              |    4 +---
>  drivers/video/fbdev/aty/aty128fb.c             |    5 ++---
>  drivers/video/fbdev/aty/atyfb_base.c           |   10 ++++------
>  drivers/video/fbdev/aty/radeon_base.c          |    2 --
>  drivers/video/fbdev/chipsfb.c                  |    1 -
>  drivers/video/fbdev/cirrusfb.c                 |    5 +----
>  drivers/video/fbdev/da8xx-fb.c                 |    1 -
>  drivers/video/fbdev/efifb.c                    |    1 -
>  drivers/video/fbdev/grvga.c                    |    4 +---
>  drivers/video/fbdev/gxt4500.c                  |    5 ++---
>  drivers/video/fbdev/hyperv_fb.c                |    4 +---
>  drivers/video/fbdev/i740fb.c                   |    4 +---
>  drivers/video/fbdev/imsttfb.c                  |    5 +----
>  drivers/video/fbdev/intelfb/intelfbdrv.c       |    5 ++---
>  drivers/video/fbdev/jz4740_fb.c                |    4 +---
>  drivers/video/fbdev/mb862xx/mb862xxfbdrv.c     |    5 +----
>  drivers/video/fbdev/mbx/mbxfb.c                |    4 +---
>  drivers/video/fbdev/omap/omapfb_main.c         |    2 --
>  drivers/video/fbdev/omap2/omapfb/omapfb-main.c |    6 +-----
>  drivers/video/fbdev/platinumfb.c               |    5 ++---
>  drivers/video/fbdev/pmag-aa-fb.c               |    4 +---
>  drivers/video/fbdev/pmag-ba-fb.c               |    4 +---
>  drivers/video/fbdev/pmagb-b-fb.c               |    4 +---
>  drivers/video/fbdev/pvr2fb.c                   |    6 +-----
>  drivers/video/fbdev/riva/fbdev.c               |    1 -
>  drivers/video/fbdev/s3c-fb.c                   |    4 +---
>  drivers/video/fbdev/s3fb.c                     |    4 +---
>  drivers/video/fbdev/sh_mobile_lcdcfb.c         |    8 ++------
>  drivers/video/fbdev/sm501fb.c                  |    4 +---
>  drivers/video/fbdev/sm712fb.c                  |    1 -
>  drivers/video/fbdev/smscufx.c                  |    4 +---
>  drivers/video/fbdev/ssd1307fb.c                |    4 +---
>  drivers/video/fbdev/sunxvr1000.c               |    1 -
>  drivers/video/fbdev/sunxvr2500.c               |    1 -
>  drivers/video/fbdev/sunxvr500.c                |    1 -
>  drivers/video/fbdev/tgafb.c                    |    4 +---
>  drivers/video/fbdev/udlfb.c                    |    4 +---
>  drivers/video/fbdev/via/viafbdev.c             |    6 +-----
>  drivers/video/fbdev/vt8623fb.c                 |    4 +---
>  42 files changed, 40 insertions(+), 123 deletions(-)
>
> Index: b/drivers/hid/hid-picolcd_fb.c
> ===================================================================
> --- a/drivers/hid/hid-picolcd_fb.c
> +++ b/drivers/hid/hid-picolcd_fb.c
> @@ -522,10 +522,8 @@ int picolcd_init_framebuffer(struct pico
>                         sizeof(struct fb_deferred_io) +
>                         sizeof(struct picolcd_fb_data) +
>                         PICOLCDFB_SIZE, dev);
> -       if (info == NULL) {
> -               dev_err(dev, "failed to allocate a framebuffer\n");
> +       if (!info)
>                 goto err_nomem;
> -       }

It would have been better to split this change as the HID and fbdev
are different trees.

However, I do not expect a conflict here (there hasn't been updates of
hid-picolcd_fb.c in a while), so feel free to take this patch through
the fbdev tree with my:
Acked-By: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Cheers,
Benjamin

>
>         info->fbdefio = info->par;
>         *info->fbdefio = picolcd_fb_defio;
> Index: b/drivers/video/fbdev/amifb.c
> ===================================================================
> --- a/drivers/video/fbdev/amifb.c
> +++ b/drivers/video/fbdev/amifb.c
> @@ -3554,10 +3554,8 @@ static int __init amifb_probe(struct pla
>         custom.dmacon = DMAF_ALL | DMAF_MASTER;
>
>         info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev);
> -       if (!info) {
> -               dev_err(&pdev->dev, "framebuffer_alloc failed\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         strcpy(info->fix.id, "Amiga ");
>         info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
> Index: b/drivers/video/fbdev/arkfb.c
> ===================================================================
> --- a/drivers/video/fbdev/arkfb.c
> +++ b/drivers/video/fbdev/arkfb.c
> @@ -954,10 +954,8 @@ static int ark_pci_probe(struct pci_dev
>
>         /* Allocate and fill driver data structure */
>         info = framebuffer_alloc(sizeof(struct arkfb_info), &(dev->dev));
> -       if (! info) {
> -               dev_err(&(dev->dev), "cannot allocate memory\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         mutex_init(&par->open_lock);
> Index: b/drivers/video/fbdev/atmel_lcdfb.c
> ===================================================================
> --- a/drivers/video/fbdev/atmel_lcdfb.c
> +++ b/drivers/video/fbdev/atmel_lcdfb.c
> @@ -1053,10 +1053,8 @@ static int __init atmel_lcdfb_probe(stru
>
>         ret = -ENOMEM;
>         info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev);
> -       if (!info) {
> -               dev_err(dev, "cannot allocate memory\n");
> +       if (!info)
>                 goto out;
> -       }
>
>         sinfo = info->par;
>         sinfo->pdev = pdev;
> Index: b/drivers/video/fbdev/aty/aty128fb.c
> ===================================================================
> --- a/drivers/video/fbdev/aty/aty128fb.c
> +++ b/drivers/video/fbdev/aty/aty128fb.c
> @@ -2102,10 +2102,9 @@ static int aty128_probe(struct pci_dev *
>
>         /* We have the resources. Now virtualize them */
>         info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev);
> -       if (info == NULL) {
> -               printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
> +       if (!info)
>                 goto err_free_mmio;
> -       }
> +
>         par = info->par;
>
>         info->pseudo_palette = par->pseudo_palette;
> Index: b/drivers/video/fbdev/aty/atyfb_base.c
> ===================================================================
> --- a/drivers/video/fbdev/aty/atyfb_base.c
> +++ b/drivers/video/fbdev/aty/atyfb_base.c
> @@ -3550,10 +3550,9 @@ static int atyfb_pci_probe(struct pci_de
>
>         /* Allocate framebuffer */
>         info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
> -       if (!info) {
> -               PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
> +
>         par = info->par;
>         par->bus_type = PCI;
>         info->fix = atyfb_fix;
> @@ -3643,10 +3642,9 @@ static int __init atyfb_atari_probe(void
>                 }
>
>                 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
> -               if (!info) {
> -                       PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
> +               if (!info)
>                         return -ENOMEM;
> -               }
> +
>                 par = info->par;
>
>                 info->fix = atyfb_fix;
> Index: b/drivers/video/fbdev/aty/radeon_base.c
> ===================================================================
> --- a/drivers/video/fbdev/aty/radeon_base.c
> +++ b/drivers/video/fbdev/aty/radeon_base.c
> @@ -2294,8 +2294,6 @@ static int radeonfb_pci_register(struct
>
>         info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
>         if (!info) {
> -               printk (KERN_ERR "radeonfb (%s): could not allocate memory\n",
> -                       pci_name(pdev));
>                 ret = -ENOMEM;
>                 goto err_disable;
>         }
> Index: b/drivers/video/fbdev/chipsfb.c
> ===================================================================
> --- a/drivers/video/fbdev/chipsfb.c
> +++ b/drivers/video/fbdev/chipsfb.c
> @@ -366,7 +366,6 @@ static int chipsfb_pci_init(struct pci_d
>
>         p = framebuffer_alloc(0, &dp->dev);
>         if (p == NULL) {
> -               dev_err(&dp->dev, "Cannot allocate framebuffer structure\n");
>                 rc = -ENOMEM;
>                 goto err_disable;
>         }
> Index: b/drivers/video/fbdev/cirrusfb.c
> ===================================================================
> --- a/drivers/video/fbdev/cirrusfb.c
> +++ b/drivers/video/fbdev/cirrusfb.c
> @@ -2093,7 +2093,6 @@ static int cirrusfb_pci_register(struct
>
>         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
>         if (!info) {
> -               printk(KERN_ERR "cirrusfb: could not allocate memory\n");
>                 ret = -ENOMEM;
>                 goto err_out;
>         }
> @@ -2206,10 +2205,8 @@ static int cirrusfb_zorro_register(struc
>         struct cirrusfb_info *cinfo;
>
>         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
> -       if (!info) {
> -               printk(KERN_ERR "cirrusfb: could not allocate memory\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         zcl = (const struct zorrocl *)ent->driver_data;
>         btype = zcl->type;
> Index: b/drivers/video/fbdev/da8xx-fb.c
> ===================================================================
> --- a/drivers/video/fbdev/da8xx-fb.c
> +++ b/drivers/video/fbdev/da8xx-fb.c
> @@ -1400,7 +1400,6 @@ static int fb_probe(struct platform_devi
>         da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
>                                         &device->dev);
>         if (!da8xx_fb_info) {
> -               dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
>                 ret = -ENOMEM;
>                 goto err_pm_runtime_disable;
>         }
> Index: b/drivers/video/fbdev/efifb.c
> ===================================================================
> --- a/drivers/video/fbdev/efifb.c
> +++ b/drivers/video/fbdev/efifb.c
> @@ -448,7 +448,6 @@ static int efifb_probe(struct platform_d
>
>         info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
>         if (!info) {
> -               pr_err("efifb: cannot allocate framebuffer\n");
>                 err = -ENOMEM;
>                 goto err_release_mem;
>         }
> Index: b/drivers/video/fbdev/grvga.c
> ===================================================================
> --- a/drivers/video/fbdev/grvga.c
> +++ b/drivers/video/fbdev/grvga.c
> @@ -341,10 +341,8 @@ static int grvga_probe(struct platform_d
>         char *options = NULL, *mode_opt = NULL;
>
>         info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
> -       if (!info) {
> -               dev_err(&dev->dev, "framebuffer_alloc failed\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
>          *
> Index: b/drivers/video/fbdev/gxt4500.c
> ===================================================================
> --- a/drivers/video/fbdev/gxt4500.c
> +++ b/drivers/video/fbdev/gxt4500.c
> @@ -642,10 +642,9 @@ static int gxt4500_probe(struct pci_dev
>         }
>
>         info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);
> -       if (!info) {
> -               dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n");
> +       if (!info)
>                 goto err_free_fb;
> -       }
> +
>         par = info->par;
>         cardtype = ent->driver_data;
>         par->refclk_ps = cardinfo[cardtype].refclk_ps;
> Index: b/drivers/video/fbdev/hyperv_fb.c
> ===================================================================
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
> @@ -771,10 +771,8 @@ static int hvfb_probe(struct hv_device *
>         int ret;
>
>         info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
> -       if (!info) {
> -               pr_err("No memory for framebuffer info\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         par->info = info;
> Index: b/drivers/video/fbdev/i740fb.c
> ===================================================================
> --- a/drivers/video/fbdev/i740fb.c
> +++ b/drivers/video/fbdev/i740fb.c
> @@ -1005,10 +1005,8 @@ static int i740fb_probe(struct pci_dev *
>         u8 *edid;
>
>         info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
> -       if (!info) {
> -               dev_err(&(dev->dev), "cannot allocate framebuffer\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         mutex_init(&par->open_lock);
> Index: b/drivers/video/fbdev/imsttfb.c
> ===================================================================
> --- a/drivers/video/fbdev/imsttfb.c
> +++ b/drivers/video/fbdev/imsttfb.c
> @@ -1477,11 +1477,8 @@ static int imsttfb_probe(struct pci_dev
>                 printk(KERN_ERR "imsttfb: no OF node for pci device\n");
>
>         info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev);
> -
> -       if (!info) {
> -               printk(KERN_ERR "imsttfb: Can't allocate memory\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>
> Index: b/drivers/video/fbdev/intelfb/intelfbdrv.c
> ===================================================================
> --- a/drivers/video/fbdev/intelfb/intelfbdrv.c
> +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
> @@ -491,10 +491,9 @@ static int intelfb_pci_register(struct p
>         }
>
>         info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev);
> -       if (!info) {
> -               ERR_MSG("Could not allocate memory for intelfb_info.\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
> +
>         if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
>                 ERR_MSG("Could not allocate cmap for intelfb_info.\n");
>                 goto err_out_cmap;
> Index: b/drivers/video/fbdev/jz4740_fb.c
> ===================================================================
> --- a/drivers/video/fbdev/jz4740_fb.c
> +++ b/drivers/video/fbdev/jz4740_fb.c
> @@ -544,10 +544,8 @@ static int jzfb_probe(struct platform_de
>         }
>
>         fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
> -       if (!fb) {
> -               dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
> +       if (!fb)
>                 return -ENOMEM;
> -       }
>
>         fb->fbops = &jzfb_ops;
>         fb->flags = FBINFO_DEFAULT;
> Index: b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
> ===================================================================
> --- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
> +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
> @@ -684,10 +684,8 @@ static int of_platform_mb862xx_probe(str
>         }
>
>         info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);
> -       if (info == NULL) {
> -               dev_err(dev, "cannot allocate framebuffer\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         par->info = info;
> @@ -1009,7 +1007,6 @@ static int mb862xx_pci_probe(struct pci_
>
>         info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);
>         if (!info) {
> -               dev_err(dev, "framebuffer alloc failed\n");
>                 ret = -ENOMEM;
>                 goto dis_dev;
>         }
> Index: b/drivers/video/fbdev/mbx/mbxfb.c
> ===================================================================
> --- a/drivers/video/fbdev/mbx/mbxfb.c
> +++ b/drivers/video/fbdev/mbx/mbxfb.c
> @@ -899,10 +899,8 @@ static int mbxfb_probe(struct platform_d
>         }
>
>         fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
> -       if (fbi == NULL) {
> -               dev_err(&dev->dev, "framebuffer_alloc failed\n");
> +       if (!fbi)
>                 return -ENOMEM;
> -       }
>
>         mfbi = fbi->par;
>         fbi->pseudo_palette = mfbi->pseudo_palette;
> Index: b/drivers/video/fbdev/omap/omapfb_main.c
> ===================================================================
> --- a/drivers/video/fbdev/omap/omapfb_main.c
> +++ b/drivers/video/fbdev/omap/omapfb_main.c
> @@ -1515,8 +1515,6 @@ static int planes_init(struct omapfb_dev
>                 fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct),
>                                         fbdev->dev);
>                 if (fbi == NULL) {
> -                       dev_err(fbdev->dev,
> -                               "unable to allocate memory for plane info\n");
>                         planes_cleanup(fbdev);
>                         return -ENOMEM;
>                 }
> Index: b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
> ===================================================================
> --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
> +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
> @@ -1892,12 +1892,8 @@ static int omapfb_create_framebuffers(st
>
>                 fbi = framebuffer_alloc(sizeof(struct omapfb_info),
>                                 fbdev->dev);
> -
> -               if (fbi == NULL) {
> -                       dev_err(fbdev->dev,
> -                               "unable to allocate memory for plane info\n");
> +               if (!fbi)
>                         return -ENOMEM;
> -               }
>
>                 clear_fb_info(fbi);
>
> Index: b/drivers/video/fbdev/platinumfb.c
> ===================================================================
> --- a/drivers/video/fbdev/platinumfb.c
> +++ b/drivers/video/fbdev/platinumfb.c
> @@ -538,10 +538,9 @@ static int platinumfb_probe(struct platf
>         dev_info(&odev->dev, "Found Apple Platinum video hardware\n");
>
>         info = framebuffer_alloc(sizeof(*pinfo), &odev->dev);
> -       if (info == NULL) {
> -               dev_err(&odev->dev, "Failed to allocate fbdev !\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
> +
>         pinfo = info->par;
>
>         if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) ||
> Index: b/drivers/video/fbdev/pmag-aa-fb.c
> ===================================================================
> --- a/drivers/video/fbdev/pmag-aa-fb.c
> +++ b/drivers/video/fbdev/pmag-aa-fb.c
> @@ -165,10 +165,8 @@ static int pmagaafb_probe(struct device
>         int err;
>
>         info = framebuffer_alloc(sizeof(struct aafb_par), dev);
> -       if (!info) {
> -               printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         dev_set_drvdata(dev, info);
> Index: b/drivers/video/fbdev/pmag-ba-fb.c
> ===================================================================
> --- a/drivers/video/fbdev/pmag-ba-fb.c
> +++ b/drivers/video/fbdev/pmag-ba-fb.c
> @@ -150,10 +150,8 @@ static int pmagbafb_probe(struct device
>         int err;
>
>         info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
> -       if (!info) {
> -               printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         dev_set_drvdata(dev, info);
> Index: b/drivers/video/fbdev/pmagb-b-fb.c
> ===================================================================
> --- a/drivers/video/fbdev/pmagb-b-fb.c
> +++ b/drivers/video/fbdev/pmagb-b-fb.c
> @@ -257,10 +257,8 @@ static int pmagbbfb_probe(struct device
>         int err;
>
>         info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
> -       if (!info) {
> -               printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         dev_set_drvdata(dev, info);
> Index: b/drivers/video/fbdev/pvr2fb.c
> ===================================================================
> --- a/drivers/video/fbdev/pvr2fb.c
> +++ b/drivers/video/fbdev/pvr2fb.c
> @@ -1069,12 +1069,8 @@ static int __init pvr2fb_init(void)
>  #endif
>
>         fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
> -
> -       if (!fb_info) {
> -               printk(KERN_ERR "Failed to allocate memory for fb_info\n");
> +       if (!fb_info)
>                 return -ENOMEM;
> -       }
> -
>
>         currentpar = fb_info->par;
>
> Index: b/drivers/video/fbdev/riva/fbdev.c
> ===================================================================
> --- a/drivers/video/fbdev/riva/fbdev.c
> +++ b/drivers/video/fbdev/riva/fbdev.c
> @@ -1902,7 +1902,6 @@ static int rivafb_probe(struct pci_dev *
>
>         info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);
>         if (!info) {
> -               printk (KERN_ERR PFX "could not allocate memory\n");
>                 ret = -ENOMEM;
>                 goto err_ret;
>         }
> Index: b/drivers/video/fbdev/s3c-fb.c
> ===================================================================
> --- a/drivers/video/fbdev/s3c-fb.c
> +++ b/drivers/video/fbdev/s3c-fb.c
> @@ -1189,10 +1189,8 @@ static int s3c_fb_probe_win(struct s3c_f
>
>         fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
>                                    palette_size * sizeof(u32), sfb->dev);
> -       if (!fbinfo) {
> -               dev_err(sfb->dev, "failed to allocate framebuffer\n");
> +       if (!fbinfo)
>                 return -ENOMEM;
> -       }
>
>         windata = sfb->pdata->win[win_no];
>         initmode = *sfb->pdata->vtiming;
> Index: b/drivers/video/fbdev/s3fb.c
> ===================================================================
> --- a/drivers/video/fbdev/s3fb.c
> +++ b/drivers/video/fbdev/s3fb.c
> @@ -1128,10 +1128,8 @@ static int s3_pci_probe(struct pci_dev *
>
>         /* Allocate and fill driver data structure */
>         info = framebuffer_alloc(sizeof(struct s3fb_info), &(dev->dev));
> -       if (!info) {
> -               dev_err(&(dev->dev), "cannot allocate memory\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         mutex_init(&par->open_lock);
> Index: b/drivers/video/fbdev/sh_mobile_lcdcfb.c
> ===================================================================
> --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
> +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
> @@ -1644,10 +1644,8 @@ sh_mobile_lcdc_overlay_fb_init(struct sh
>
>         /* Allocate and initialize the frame buffer device. */
>         info = framebuffer_alloc(0, priv->dev);
> -       if (info == NULL) {
> -               dev_err(priv->dev, "unable to allocate fb_info\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         ovl->info = info;
>
> @@ -2138,10 +2136,8 @@ sh_mobile_lcdc_channel_fb_init(struct sh
>          * list and allocate the color map.
>          */
>         info = framebuffer_alloc(0, priv->dev);
> -       if (info == NULL) {
> -               dev_err(priv->dev, "unable to allocate fb_info\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         ch->info = info;
>
> Index: b/drivers/video/fbdev/sm501fb.c
> ===================================================================
> --- a/drivers/video/fbdev/sm501fb.c
> +++ b/drivers/video/fbdev/sm501fb.c
> @@ -1868,10 +1868,8 @@ static int sm501fb_probe_one(struct sm50
>         }
>
>         fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev);
> -       if (fbi == NULL) {
> -               dev_err(info->dev, "cannot allocate %s framebuffer\n", name);
> +       if (!fbi)
>                 return -ENOMEM;
> -       }
>
>         par = fbi->par;
>         par->info = info;
> Index: b/drivers/video/fbdev/sm712fb.c
> ===================================================================
> --- a/drivers/video/fbdev/sm712fb.c
> +++ b/drivers/video/fbdev/sm712fb.c
> @@ -1538,7 +1538,6 @@ static int smtcfb_pci_probe(struct pci_d
>
>         info = framebuffer_alloc(sizeof(*sfb), &pdev->dev);
>         if (!info) {
> -               dev_err(&pdev->dev, "framebuffer_alloc failed\n");
>                 err = -ENOMEM;
>                 goto failed_free;
>         }
> Index: b/drivers/video/fbdev/smscufx.c
> ===================================================================
> --- a/drivers/video/fbdev/smscufx.c
> +++ b/drivers/video/fbdev/smscufx.c
> @@ -1653,10 +1653,8 @@ static int ufx_usb_probe(struct usb_inte
>
>         /* allocates framebuffer driver structure, not framebuffer memory */
>         info = framebuffer_alloc(0, &usbdev->dev);
> -       if (!info) {
> -               dev_err(dev->gdev, "framebuffer_alloc failed\n");
> +       if (!info)
>                 goto e_nomem;
> -       }
>
>         dev->info = info;
>         info->par = dev;
> Index: b/drivers/video/fbdev/ssd1307fb.c
> ===================================================================
> --- a/drivers/video/fbdev/ssd1307fb.c
> +++ b/drivers/video/fbdev/ssd1307fb.c
> @@ -556,10 +556,8 @@ static int ssd1307fb_probe(struct i2c_cl
>         }
>
>         info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);
> -       if (!info) {
> -               dev_err(&client->dev, "Couldn't allocate framebuffer.\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         par->info = info;
> Index: b/drivers/video/fbdev/sunxvr1000.c
> ===================================================================
> --- a/drivers/video/fbdev/sunxvr1000.c
> +++ b/drivers/video/fbdev/sunxvr1000.c
> @@ -121,7 +121,6 @@ static int gfb_probe(struct platform_dev
>
>         info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);
>         if (!info) {
> -               printk(KERN_ERR "gfb: Cannot allocate fb_info\n");
>                 err = -ENOMEM;
>                 goto err_out;
>         }
> Index: b/drivers/video/fbdev/sunxvr2500.c
> ===================================================================
> --- a/drivers/video/fbdev/sunxvr2500.c
> +++ b/drivers/video/fbdev/sunxvr2500.c
> @@ -132,7 +132,6 @@ static int s3d_pci_register(struct pci_d
>
>         info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev);
>         if (!info) {
> -               printk(KERN_ERR "s3d: Cannot allocate fb_info\n");
>                 err = -ENOMEM;
>                 goto err_disable;
>         }
> Index: b/drivers/video/fbdev/sunxvr500.c
> ===================================================================
> --- a/drivers/video/fbdev/sunxvr500.c
> +++ b/drivers/video/fbdev/sunxvr500.c
> @@ -272,7 +272,6 @@ static int e3d_pci_register(struct pci_d
>
>         info = framebuffer_alloc(sizeof(struct e3d_info), &pdev->dev);
>         if (!info) {
> -               printk(KERN_ERR "e3d: Cannot allocate fb_info\n");
>                 err = -ENOMEM;
>                 goto err_disable;
>         }
> Index: b/drivers/video/fbdev/tgafb.c
> ===================================================================
> --- a/drivers/video/fbdev/tgafb.c
> +++ b/drivers/video/fbdev/tgafb.c
> @@ -1416,10 +1416,8 @@ static int tgafb_register(struct device
>
>         /* Allocate the fb and par structures.  */
>         info = framebuffer_alloc(sizeof(struct tga_par), dev);
> -       if (!info) {
> -               printk(KERN_ERR "tgafb: Cannot allocate memory\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         dev_set_drvdata(dev, info);
> Index: b/drivers/video/fbdev/udlfb.c
> ===================================================================
> --- a/drivers/video/fbdev/udlfb.c
> +++ b/drivers/video/fbdev/udlfb.c
> @@ -1689,10 +1689,8 @@ static int dlfb_usb_probe(struct usb_int
>
>         /* allocates framebuffer driver structure, not framebuffer memory */
>         info = framebuffer_alloc(0, &dlfb->udev->dev);
> -       if (!info) {
> -               dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n");
> +       if (!info)
>                 goto error;
> -       }
>
>         dlfb->info = info;
>         info->par = dlfb;
> Index: b/drivers/video/fbdev/via/viafbdev.c
> ===================================================================
> --- a/drivers/video/fbdev/via/viafbdev.c
> +++ b/drivers/video/fbdev/via/viafbdev.c
> @@ -1756,10 +1756,8 @@ int via_fb_pci_probe(struct viafb_dev *v
>         viafbinfo = framebuffer_alloc(viafb_par_length +
>                 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8),
>                 &vdev->pdev->dev);
> -       if (!viafbinfo) {
> -               printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
> +       if (!viafbinfo)
>                 return -ENOMEM;
> -       }
>
>         viaparinfo = (struct viafb_par *)viafbinfo->par;
>         viaparinfo->shared = viafbinfo->par + viafb_par_length;
> @@ -1834,8 +1832,6 @@ int via_fb_pci_probe(struct viafb_dev *v
>                 viafbinfo1 = framebuffer_alloc(viafb_par_length,
>                                 &vdev->pdev->dev);
>                 if (!viafbinfo1) {
> -                       printk(KERN_ERR
> -                       "allocate the second framebuffer struct error\n");
>                         rc = -ENOMEM;
>                         goto out_fb_release;
>                 }
> Index: b/drivers/video/fbdev/vt8623fb.c
> ===================================================================
> --- a/drivers/video/fbdev/vt8623fb.c
> +++ b/drivers/video/fbdev/vt8623fb.c
> @@ -669,10 +669,8 @@ static int vt8623_pci_probe(struct pci_d
>
>         /* Allocate and fill driver data structure */
>         info = framebuffer_alloc(sizeof(struct vt8623fb_info), &(dev->dev));
> -       if (! info) {
> -               dev_err(&(dev->dev), "cannot allocate memory\n");
> +       if (!info)
>                 return -ENOMEM;
> -       }
>
>         par = info->par;
>         mutex_init(&par->open_lock);
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH] drm: bridge: DRM_SIL_SII8620 should depend on, not select INPUT
From: Andrzej Hajda @ 2019-07-01  9:26 UTC (permalink / raw)
  To: Randy Dunlap, dri-devel, LKML, Ronald Tschalär
  Cc: Inki Dae, Laurent Pinchart, linux-input@vger.kernel.org
In-Reply-To: <a7edece4-fec4-5811-27a9-ca6c275a4c40@samsung.com>

On 01.07.2019 11:23, Andrzej Hajda wrote:
> On 01.07.2019 05:39, Randy Dunlap wrote:
>> From: Randy Dunlap <rdunlap@infradead.org>
>>
>> A single driver should not enable (select) an entire subsystem,
>> such as INPUT, so change the 'select' to "depends on".
>>
>> Fixes: d6abe6df706c ("drm/bridge: sil_sii8620: do not have a dependency of RC_CORE")
>>
>> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
>> Cc: Inki Dae <inki.dae@samsung.com>
>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
>> Cc: dri-devel@lists.freedesktop.org
>> ---
>> Linus has written this a couple of times in the last 15 years or so,
>> but my search fu cannot find it.  And there are a few drivers in the
>> kernel tree that do this, but we shouldn't be adding more that do so.
>
> The proper solution has been already posted [1], but it has not been
> applied yet to input tree?
>
> Randy are there chances your patchset will appear in ML in near future,
> or should I merge your sii8620 patch alone?


Ups, I used wrong surname, I meant Ronald, added him input ML to cc.


Regards

Andrzej



>
>
> [1]:
> https://lore.kernel.org/lkml/20190419081926.13567-2-ronald@innovation.ch/
>
>
> Regards
>
> Andrzej
>
>
>
>>  drivers/gpu/drm/bridge/Kconfig |    3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> --- lnx-52-rc7.orig/drivers/gpu/drm/bridge/Kconfig
>> +++ lnx-52-rc7/drivers/gpu/drm/bridge/Kconfig
>> @@ -83,10 +83,9 @@ config DRM_PARADE_PS8622
>>  
>>  config DRM_SIL_SII8620
>>  	tristate "Silicon Image SII8620 HDMI/MHL bridge"
>> -	depends on OF
>> +	depends on OF && INPUT
>>  	select DRM_KMS_HELPER
>>  	imply EXTCON
>> -	select INPUT
>>  	select RC_CORE
>>  	help
>>  	  Silicon Image SII8620 HDMI/MHL bridge chip driver.
>>
>>
>>
>>

^ permalink raw reply

* Re: [PATCH v3] HID: sb0540: add support for Creative SB0540 IR receivers
From: Benjamin Tissoires @ 2019-07-01  9:45 UTC (permalink / raw)
  To: Bastien Nocera
  Cc: open list:HID CORE LAYER, lkml, Jiri Kosina, Bastien Nocera
In-Reply-To: <20190626140618.8944-1-hadess@hadess.net>

Hi Bastien,

On Wed, Jun 26, 2019 at 4:07 PM Bastien Nocera <hadess@hadess.net> wrote:
>
> From: Bastien Nocera <bnocera@redhat.com>
>
> Add a new hid driver for the Creative SB0540 IR receiver. This receiver
> is usually coupled with an RM-1500 or an RM-1800 remote control.
>
> The scrollwheels on the RM-1800 remote are not bound, as they are
> labelled for specific audio controls that don't usually exist on most
> systems. They can be remapped using standard Linux keyboard
> remapping tools.

Much better commit message :)
Thanks!

I have a few nitpicks however

>
> Signed-off-by: Bastien Nocera <bnocera@redhat.com>
> ---
>  drivers/hid/Kconfig               |   9 ++
>  drivers/hid/Makefile              |   1 +
>  drivers/hid/hid-creative-sb0540.c | 254 ++++++++++++++++++++++++++++++
>  drivers/hid/hid-ids.h             |   1 +
>  4 files changed, 265 insertions(+)
>  create mode 100644 drivers/hid/hid-creative-sb0540.c
>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 3872e03d9a59..f16c4bd822e4 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -273,6 +273,15 @@ config HID_CP2112
>         and gpiochip to expose these functions of the CP2112. The
>         customizable USB descriptor fields are exposed as sysfs attributes.
>
> +config HID_CREATIVE_SB0540
> +       tristate "Creative SB0540 infrared receiver"
> +       depends on USB_HID
> +       ---help---

checkpatch.pl complains here that new help texts should use "help" not
"---help---"

And BTW, checkpatch.pl complains *a lot*, so please fix most of the
warnings in the next submission (not sure you can go to 0 for a new
driver, but you should be able to get rid of most of them).

> +       Support for Creative infrared SB0540-compatible remote controls, such
> +       as the RM-1500 and RM-1800 remotes.
> +
> +       Say Y here if you want support for Creative SB0540 infrared receiver.
> +
>  config HID_CYPRESS
>         tristate "Cypress mouse and barcode readers"
>         depends on HID
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index cc5d827c9164..1ad662fe37b6 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_HID_ALPS)                += hid-alps.o
>  obj-$(CONFIG_HID_ACRUX)                += hid-axff.o
>  obj-$(CONFIG_HID_APPLE)                += hid-apple.o
>  obj-$(CONFIG_HID_APPLEIR)      += hid-appleir.o
> +obj-$(CONFIG_HID_CREATIVE_SB0540)      += hid-creative-sb0540.c
>  obj-$(CONFIG_HID_ASUS)         += hid-asus.o
>  obj-$(CONFIG_HID_AUREAL)       += hid-aureal.o
>  obj-$(CONFIG_HID_BELKIN)       += hid-belkin.o
> diff --git a/drivers/hid/hid-creative-sb0540.c b/drivers/hid/hid-creative-sb0540.c
> new file mode 100644
> index 000000000000..a94542cbdd33
> --- /dev/null
> +++ b/drivers/hid/hid-creative-sb0540.c
> @@ -0,0 +1,254 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * HID driver for the Creative SB0540 receiver
> + *
> + * Copyright (C) 2019 Red Hat Inc. All Rights Reserved
> + *
> + */
> +
> +#include <linux/device.h>
> +#include <linux/hid.h>
> +#include <linux/module.h>
> +#include "hid-ids.h"
> +
> +MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
> +MODULE_DESCRIPTION("HID Creative SB0540 receiver");
> +MODULE_LICENSE("GPL");
> +
> +static const unsigned short creative_sb0540_key_table[] = {
> +       KEY_POWER,
> +       KEY_RESERVED,           /* text: 24bit */
> +       KEY_RESERVED,           /* 24bit wheel up */
> +       KEY_RESERVED,           /* 24bit wheel down */
> +       KEY_RESERVED,           /* text: CMSS */
> +       KEY_RESERVED,           /* CMSS wheel Up */
> +       KEY_RESERVED,           /* CMSS wheel Down */
> +       KEY_RESERVED,           /* text: EAX */
> +       KEY_RESERVED,           /* EAX wheel up */
> +       KEY_RESERVED,           /* EAX wheel down */
> +       KEY_RESERVED,           /* text: 3D Midi */
> +       KEY_RESERVED,           /* 3D Midi wheel up */
> +       KEY_RESERVED,           /* 3D Midi wheel down */
> +       KEY_MUTE,
> +       KEY_VOLUMEUP,
> +       KEY_VOLUMEDOWN,
> +       KEY_UP,
> +       KEY_LEFT,
> +       KEY_RIGHT,
> +       KEY_REWIND,
> +       KEY_OK,
> +       KEY_FASTFORWARD,
> +       KEY_DOWN,
> +       KEY_AGAIN,              /* text: Return, symbol: Jump to */
> +       KEY_PLAY,               /* text: Start */
> +       KEY_ESC,                /* text: Cancel */
> +       KEY_RECORD,
> +       KEY_OPTION,
> +       KEY_MENU,               /* text: Display */
> +       KEY_PREVIOUS,
> +       KEY_PLAYPAUSE,
> +       KEY_NEXT,
> +       KEY_SLOW,
> +       KEY_STOP,
> +       KEY_NUMERIC_1,
> +       KEY_NUMERIC_2,
> +       KEY_NUMERIC_3,
> +       KEY_NUMERIC_4,
> +       KEY_NUMERIC_5,
> +       KEY_NUMERIC_6,
> +       KEY_NUMERIC_7,
> +       KEY_NUMERIC_8,
> +       KEY_NUMERIC_9,
> +       KEY_NUMERIC_0
> +};
> +
> +/* Codes and keys from lirc's
> + * remotes/creative/lircd.conf.alsa_usb
> + * order and size must match creative_sb0540_key_table[] above */

Please follow the kernel coding style:
/*
 * Codes and keys from lirc's
 * remotes/creative/lircd.conf.alsa_usb
 * order and size must match creative_sb0540_key_table[] above
 */

And same for all the multi-line comments.

> +static const unsigned short creative_sb0540_codes[] = {
> +       0x619E,
> +       0x916E,
> +       0x926D,
> +       0x936C,
> +       0x718E,
> +       0x946B,
> +       0x956A,
> +       0x8C73,
> +       0x9669,
> +       0x9768,
> +       0x9867,
> +       0x9966,
> +       0x9A65,
> +       0x6E91,
> +       0x629D,
> +       0x639C,
> +       0x7B84,
> +       0x6B94,
> +       0x728D,
> +       0x8778,
> +       0x817E,
> +       0x758A,
> +       0x8D72,
> +       0x8E71,
> +       0x8877,
> +       0x7C83,
> +       0x738C,
> +       0x827D,
> +       0x7689,
> +       0x7F80,
> +       0x7986,
> +       0x7A85,
> +       0x7D82,
> +       0x857A,
> +       0x8B74,
> +       0x8F70,
> +       0x906F,
> +       0x8A75,
> +       0x847B,
> +       0x7887,
> +       0x8976,
> +       0x837C,
> +       0x7788,
> +       0x807F
> +};
> +
> +struct creative_sb0540 {
> +       struct input_dev *input_dev;
> +       struct hid_device *hid;
> +       unsigned short keymap[ARRAY_SIZE(creative_sb0540_key_table)];
> +};
> +
> +static inline u64 reverse(u64 data, int bits)
> +{
> +       int i;
> +       u64 c;
> +
> +       c = 0;
> +       for (i = 0; i < bits; i++) {
> +               c |= (u64) (((data & (((u64) 1) << i)) ? 1 : 0)) << (bits - 1 - i);
> +       }
> +       return (c);
> +}
> +
> +static int get_key(struct creative_sb0540 *creative_sb0540, u64 keycode)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(creative_sb0540_codes); i++) {
> +               if (creative_sb0540_codes[i] == keycode)
> +                       return creative_sb0540->keymap[i];
> +       }
> +
> +       return 0;
> +
> +}
> +
> +static int creative_sb0540_raw_event(struct hid_device *hid, struct hid_report *report,
> +        u8 *data, int len)
> +{
> +       struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
> +       u64 code, main_code;
> +       int key;
> +
> +       if (len != 6)
> +               goto out;
> +
> +       /* From daemons/hw_hiddev.c sb0540_rec() in lirc */
> +       code = reverse(data[5], 8);
> +       main_code = (code << 8) + ((~code) & 0xff);
> +
> +       /* Flip to get values in the same format as
> +        * remotes/creative/lircd.conf.alsa_usb in lirc */
> +       main_code = ((main_code & 0xff) << 8) + ((main_code & 0xff00) >> 8);
> +
> +       key = get_key(creative_sb0540, main_code);
> +       if (key == 0 || key == KEY_RESERVED) {
> +               hid_err(hid, "Could not get a key for main_code %llX\n", main_code);
> +               goto out;

I don't really like the got out here.

Why not changing the condition above to
if (key && key != KEY_RESERVED) and include the block below in the true case?

> +       }
> +
> +       input_report_key(creative_sb0540->input_dev, key, 1);
> +       input_report_key(creative_sb0540->input_dev, key, 0);
> +       input_sync(creative_sb0540->input_dev);
> +
> +out:
> +       /* let hidraw and hiddev handle the report */
> +       return 0;
> +}
> +
> +static int creative_sb0540_input_configured(struct hid_device *hid,
> +               struct hid_input *hidinput)
> +{
> +       struct input_dev *input_dev = hidinput->input;
> +       struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
> +       int i;
> +
> +       creative_sb0540->input_dev = input_dev;
> +
> +       input_dev->keycode = creative_sb0540->keymap;
> +       input_dev->keycodesize = sizeof(unsigned short);
> +       input_dev->keycodemax = ARRAY_SIZE(creative_sb0540->keymap);
> +
> +       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
> +
> +       memcpy(creative_sb0540->keymap, creative_sb0540_key_table, sizeof(creative_sb0540->keymap));
> +       for (i = 0; i < ARRAY_SIZE(creative_sb0540_key_table); i++)
> +               set_bit(creative_sb0540->keymap[i], input_dev->keybit);
> +       clear_bit(KEY_RESERVED, input_dev->keybit);
> +
> +       return 0;
> +}
> +
> +static int creative_sb0540_input_mapping(struct hid_device *hid,
> +               struct hid_input *hi, struct hid_field *field,
> +               struct hid_usage *usage, unsigned long **bit, int *max)
> +{

Please add a comment here that we are remapping them ourselves, so we
can skip the hid-input processing.

> +       return -1;
> +}
> +
> +static int creative_sb0540_probe(struct hid_device *hid, const struct hid_device_id *id)
> +{
> +       int ret;
> +       struct creative_sb0540 *creative_sb0540;
> +
> +       creative_sb0540 = devm_kzalloc(&hid->dev, sizeof(struct creative_sb0540), GFP_KERNEL);
> +       if (!creative_sb0540)
> +               return -ENOMEM;
> +
> +       creative_sb0540->hid = hid;
> +
> +       /* force input as some remotes bypass the input registration */
> +       hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;

Does this still applies to your remote?

Cheers,
Benjamin

> +
> +       hid_set_drvdata(hid, creative_sb0540);
> +
> +       ret = hid_parse(hid);
> +       if (ret) {
> +               hid_err(hid, "parse failed\n");
> +               return ret;
> +       }
> +
> +       ret = hid_hw_start(hid, HID_CONNECT_DEFAULT);
> +       if (ret) {
> +               hid_err(hid, "hw start failed\n");
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct hid_device_id creative_sb0540_devices[] = {
> +       { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB0540) },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(hid, creative_sb0540_devices);
> +
> +static struct hid_driver creative_sb0540_driver = {
> +       .name = "creative-sb0540",
> +       .id_table = creative_sb0540_devices,
> +       .raw_event = creative_sb0540_raw_event,
> +       .input_configured = creative_sb0540_input_configured,
> +       .probe = creative_sb0540_probe,
> +       .input_mapping = creative_sb0540_input_mapping,
> +};
> +module_hid_driver(creative_sb0540_driver);
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 826324997686..206b7065da86 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -312,6 +312,7 @@
>  #define USB_VENDOR_ID_CREATIVELABS     0x041e
>  #define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51     0x322c
>  #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801
> +#define USB_DEVICE_ID_CREATIVE_SB0540  0x3100
>
>  #define USB_VENDOR_ID_CVTOUCH          0x1ff7
>  #define USB_DEVICE_ID_CVTOUCH_SCREEN   0x0013
> --
> 2.21.0
>

^ permalink raw reply

* [PATCH v4] HID: sb0540: add support for Creative SB0540 IR receivers
From: Bastien Nocera @ 2019-07-01 10:08 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel, Jiri Kosina, Benjamin Tissoires, Bastien Nocera

From: Bastien Nocera <bnocera@redhat.com>

Add a new hid driver for the Creative SB0540 IR receiver. This receiver
is usually coupled with an RM-1500 or an RM-1800 remote control.

The scrollwheels on the RM-1800 remote are not bound, as they are
labelled for specific audio controls that don't usually exist on most
systems. They can be remapped using standard Linux keyboard
remapping tools.

Signed-off-by: Bastien Nocera <bnocera@redhat.com>
---
 MAINTAINERS                       |   6 +
 drivers/hid/Kconfig               |   9 +
 drivers/hid/Makefile              |   1 +
 drivers/hid/hid-creative-sb0540.c | 268 ++++++++++++++++++++++++++++++
 drivers/hid/hid-ids.h             |   1 +
 5 files changed, 285 insertions(+)
 create mode 100644 drivers/hid/hid-creative-sb0540.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d0ed735994a5..6fc022d152c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4227,6 +4227,12 @@ S:	Maintained
 F:	Documentation/filesystems/cramfs.txt
 F:	fs/cramfs/
 
+CREATIVE SB0540
+M:	Bastien Nocera <hadess@hadess.net>
+L:	linux-input@vger.kernel.org
+S:	Maintained
+F:	drivers/hid/hid-creative-sb0540.c
+
 CRYPTO API
 M:	Herbert Xu <herbert@gondor.apana.org.au>
 M:	"David S. Miller" <davem@davemloft.net>
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 3872e03d9a59..a70999f9c639 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -273,6 +273,15 @@ config HID_CP2112
 	and gpiochip to expose these functions of the CP2112. The
 	customizable USB descriptor fields are exposed as sysfs attributes.
 
+config HID_CREATIVE_SB0540
+	tristate "Creative SB0540 infrared receiver"
+	depends on USB_HID
+	help
+	Support for Creative infrared SB0540-compatible remote controls, such
+	as the RM-1500 and RM-1800 remotes.
+
+	Say Y here if you want support for Creative SB0540 infrared receiver.
+
 config HID_CYPRESS
 	tristate "Cypress mouse and barcode readers"
 	depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index cc5d827c9164..1ad662fe37b6 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_HID_ALPS)		+= hid-alps.o
 obj-$(CONFIG_HID_ACRUX)		+= hid-axff.o
 obj-$(CONFIG_HID_APPLE)		+= hid-apple.o
 obj-$(CONFIG_HID_APPLEIR)	+= hid-appleir.o
+obj-$(CONFIG_HID_CREATIVE_SB0540)	+= hid-creative-sb0540.c
 obj-$(CONFIG_HID_ASUS)		+= hid-asus.o
 obj-$(CONFIG_HID_AUREAL)	+= hid-aureal.o
 obj-$(CONFIG_HID_BELKIN)	+= hid-belkin.o
diff --git a/drivers/hid/hid-creative-sb0540.c b/drivers/hid/hid-creative-sb0540.c
new file mode 100644
index 000000000000..6b7c81ccf310
--- /dev/null
+++ b/drivers/hid/hid-creative-sb0540.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HID driver for the Creative SB0540 receiver
+ *
+ * Copyright (C) 2019 Red Hat Inc. All Rights Reserved
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include "hid-ids.h"
+
+MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
+MODULE_DESCRIPTION("HID Creative SB0540 receiver");
+MODULE_LICENSE("GPL");
+
+static const unsigned short creative_sb0540_key_table[] = {
+	KEY_POWER,
+	KEY_RESERVED,		/* text: 24bit */
+	KEY_RESERVED,		/* 24bit wheel up */
+	KEY_RESERVED,		/* 24bit wheel down */
+	KEY_RESERVED,		/* text: CMSS */
+	KEY_RESERVED,		/* CMSS wheel Up */
+	KEY_RESERVED,		/* CMSS wheel Down */
+	KEY_RESERVED,		/* text: EAX */
+	KEY_RESERVED,		/* EAX wheel up */
+	KEY_RESERVED,		/* EAX wheel down */
+	KEY_RESERVED,		/* text: 3D Midi */
+	KEY_RESERVED,		/* 3D Midi wheel up */
+	KEY_RESERVED,		/* 3D Midi wheel down */
+	KEY_MUTE,
+	KEY_VOLUMEUP,
+	KEY_VOLUMEDOWN,
+	KEY_UP,
+	KEY_LEFT,
+	KEY_RIGHT,
+	KEY_REWIND,
+	KEY_OK,
+	KEY_FASTFORWARD,
+	KEY_DOWN,
+	KEY_AGAIN,		/* text: Return, symbol: Jump to */
+	KEY_PLAY,		/* text: Start */
+	KEY_ESC,		/* text: Cancel */
+	KEY_RECORD,
+	KEY_OPTION,
+	KEY_MENU,		/* text: Display */
+	KEY_PREVIOUS,
+	KEY_PLAYPAUSE,
+	KEY_NEXT,
+	KEY_SLOW,
+	KEY_STOP,
+	KEY_NUMERIC_1,
+	KEY_NUMERIC_2,
+	KEY_NUMERIC_3,
+	KEY_NUMERIC_4,
+	KEY_NUMERIC_5,
+	KEY_NUMERIC_6,
+	KEY_NUMERIC_7,
+	KEY_NUMERIC_8,
+	KEY_NUMERIC_9,
+	KEY_NUMERIC_0
+};
+
+/*
+ * Codes and keys from lirc's
+ * remotes/creative/lircd.conf.alsa_usb
+ * order and size must match creative_sb0540_key_table[] above
+ */
+static const unsigned short creative_sb0540_codes[] = {
+	0x619E,
+	0x916E,
+	0x926D,
+	0x936C,
+	0x718E,
+	0x946B,
+	0x956A,
+	0x8C73,
+	0x9669,
+	0x9768,
+	0x9867,
+	0x9966,
+	0x9A65,
+	0x6E91,
+	0x629D,
+	0x639C,
+	0x7B84,
+	0x6B94,
+	0x728D,
+	0x8778,
+	0x817E,
+	0x758A,
+	0x8D72,
+	0x8E71,
+	0x8877,
+	0x7C83,
+	0x738C,
+	0x827D,
+	0x7689,
+	0x7F80,
+	0x7986,
+	0x7A85,
+	0x7D82,
+	0x857A,
+	0x8B74,
+	0x8F70,
+	0x906F,
+	0x8A75,
+	0x847B,
+	0x7887,
+	0x8976,
+	0x837C,
+	0x7788,
+	0x807F
+};
+
+struct creative_sb0540 {
+	struct input_dev *input_dev;
+	struct hid_device *hid;
+	unsigned short keymap[ARRAY_SIZE(creative_sb0540_key_table)];
+};
+
+static inline u64 reverse(u64 data, int bits)
+{
+	int i;
+	u64 c;
+
+	c = 0;
+	for (i = 0; i < bits; i++) {
+		c |= (u64) (((data & (((u64) 1) << i)) ? 1 : 0))
+			<< (bits - 1 - i);
+	}
+	return (c);
+}
+
+static int get_key(struct creative_sb0540 *creative_sb0540, u64 keycode)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(creative_sb0540_codes); i++) {
+		if (creative_sb0540_codes[i] == keycode)
+			return creative_sb0540->keymap[i];
+	}
+
+	return 0;
+
+}
+
+static int creative_sb0540_raw_event(struct hid_device *hid,
+	struct hid_report *report, u8 *data, int len)
+{
+	struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
+	u64 code, main_code;
+	int key;
+
+	if (len != 6)
+		goto out;
+
+	/* From daemons/hw_hiddev.c sb0540_rec() in lirc */
+	code = reverse(data[5], 8);
+	main_code = (code << 8) + ((~code) & 0xff);
+
+	/*
+	 * Flip to get values in the same format as
+	 * remotes/creative/lircd.conf.alsa_usb in lirc
+	 */
+	main_code = ((main_code & 0xff) << 8) +
+		((main_code & 0xff00) >> 8);
+
+	key = get_key(creative_sb0540, main_code);
+	if (key == 0 || key == KEY_RESERVED) {
+		hid_err(hid, "Could not get a key for main_code %llX\n",
+			main_code);
+		return 0;
+	}
+
+	input_report_key(creative_sb0540->input_dev, key, 1);
+	input_report_key(creative_sb0540->input_dev, key, 0);
+	input_sync(creative_sb0540->input_dev);
+
+	/* let hidraw and hiddev handle the report */
+	return 0;
+}
+
+static int creative_sb0540_input_configured(struct hid_device *hid,
+		struct hid_input *hidinput)
+{
+	struct input_dev *input_dev = hidinput->input;
+	struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
+	int i;
+
+	creative_sb0540->input_dev = input_dev;
+
+	input_dev->keycode = creative_sb0540->keymap;
+	input_dev->keycodesize = sizeof(unsigned short);
+	input_dev->keycodemax = ARRAY_SIZE(creative_sb0540->keymap);
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+
+	memcpy(creative_sb0540->keymap, creative_sb0540_key_table,
+		sizeof(creative_sb0540->keymap));
+	for (i = 0; i < ARRAY_SIZE(creative_sb0540_key_table); i++)
+		set_bit(creative_sb0540->keymap[i], input_dev->keybit);
+	clear_bit(KEY_RESERVED, input_dev->keybit);
+
+	return 0;
+}
+
+static int creative_sb0540_input_mapping(struct hid_device *hid,
+		struct hid_input *hi, struct hid_field *field,
+		struct hid_usage *usage, unsigned long **bit, int *max)
+{
+	/*
+	 * We are remapping the keys ourselves, so ignore the hid-input
+	 * keymap processing.
+	 */
+	return -1;
+}
+
+static int creative_sb0540_probe(struct hid_device *hid,
+		const struct hid_device_id *id)
+{
+	int ret;
+	struct creative_sb0540 *creative_sb0540;
+
+	creative_sb0540 = devm_kzalloc(&hid->dev,
+		sizeof(struct creative_sb0540), GFP_KERNEL);
+
+	if (!creative_sb0540)
+		return -ENOMEM;
+
+	creative_sb0540->hid = hid;
+
+	/* force input as some remotes bypass the input registration */
+	hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
+
+	hid_set_drvdata(hid, creative_sb0540);
+
+	ret = hid_parse(hid);
+	if (ret) {
+		hid_err(hid, "parse failed\n");
+		return ret;
+	}
+
+	ret = hid_hw_start(hid, HID_CONNECT_DEFAULT);
+	if (ret) {
+		hid_err(hid, "hw start failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static const struct hid_device_id creative_sb0540_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB0540) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, creative_sb0540_devices);
+
+static struct hid_driver creative_sb0540_driver = {
+	.name = "creative-sb0540",
+	.id_table = creative_sb0540_devices,
+	.raw_event = creative_sb0540_raw_event,
+	.input_configured = creative_sb0540_input_configured,
+	.probe = creative_sb0540_probe,
+	.input_mapping = creative_sb0540_input_mapping,
+};
+module_hid_driver(creative_sb0540_driver);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 826324997686..206b7065da86 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -312,6 +312,7 @@
 #define USB_VENDOR_ID_CREATIVELABS	0x041e
 #define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51	0x322c
 #define USB_DEVICE_ID_PRODIKEYS_PCMIDI	0x2801
+#define USB_DEVICE_ID_CREATIVE_SB0540	0x3100
 
 #define USB_VENDOR_ID_CVTOUCH		0x1ff7
 #define USB_DEVICE_ID_CVTOUCH_SCREEN	0x0013
-- 
2.21.0

^ permalink raw reply related

* Re: [PATCH v3] HID: sb0540: add support for Creative SB0540 IR receivers
From: Bastien Nocera @ 2019-07-01 10:10 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: open list:HID CORE LAYER, lkml, Jiri Kosina, Bastien Nocera
In-Reply-To: <CAO-hwJJDf68gqgJZHQtAdjZcEzuL+LbOJD=OYHtod1xN6G+GjA@mail.gmail.com>

On Mon, 2019-07-01 at 11:45 +0200, Benjamin Tissoires wrote:
> Hi Bastien,
> 
> On Wed, Jun 26, 2019 at 4:07 PM Bastien Nocera <hadess@hadess.net>
> wrote:
> > From: Bastien Nocera <bnocera@redhat.com>
> > 
> > Add a new hid driver for the Creative SB0540 IR receiver. This
> > receiver
> > is usually coupled with an RM-1500 or an RM-1800 remote control.
> > 
> > The scrollwheels on the RM-1800 remote are not bound, as they are
> > labelled for specific audio controls that don't usually exist on
> > most
> > systems. They can be remapped using standard Linux keyboard
> > remapping tools.
> 
> Much better commit message :)
> Thanks!
> 
> I have a few nitpicks however

Most of the checkpatch.pl warnings are now fixed. I ignored the one
about writing docs for the symbol (I have no idea what it wants, looks
like a false positive) and the too long line for the USB device match.

<snip>
> > +       /* force input as some remotes bypass the input
> > registration */
> > +       hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
> 
> Does this still applies to your remote?

Yes, you mentioned it in your original review as well, and it was
necessary.

v4's been sent.

Thanks!

^ permalink raw reply

* Re: [PATCH v4] HID: sb0540: add support for Creative SB0540 IR receivers
From: Benjamin Tissoires @ 2019-07-01 10:15 UTC (permalink / raw)
  To: Bastien Nocera
  Cc: open list:HID CORE LAYER, lkml, Jiri Kosina, Bastien Nocera
In-Reply-To: <20190701100819.6032-1-hadess@hadess.net>

On Mon, Jul 1, 2019 at 12:08 PM Bastien Nocera <hadess@hadess.net> wrote:
>
> From: Bastien Nocera <bnocera@redhat.com>
>
> Add a new hid driver for the Creative SB0540 IR receiver. This receiver
> is usually coupled with an RM-1500 or an RM-1800 remote control.
>
> The scrollwheels on the RM-1800 remote are not bound, as they are
> labelled for specific audio controls that don't usually exist on most
> systems. They can be remapped using standard Linux keyboard
> remapping tools.
>
> Signed-off-by: Bastien Nocera <bnocera@redhat.com>
> ---
>  MAINTAINERS                       |   6 +
>  drivers/hid/Kconfig               |   9 +
>  drivers/hid/Makefile              |   1 +
>  drivers/hid/hid-creative-sb0540.c | 268 ++++++++++++++++++++++++++++++
>  drivers/hid/hid-ids.h             |   1 +
>  5 files changed, 285 insertions(+)
>  create mode 100644 drivers/hid/hid-creative-sb0540.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d0ed735994a5..6fc022d152c8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4227,6 +4227,12 @@ S:       Maintained
>  F:     Documentation/filesystems/cramfs.txt
>  F:     fs/cramfs/
>
> +CREATIVE SB0540
> +M:     Bastien Nocera <hadess@hadess.net>
> +L:     linux-input@vger.kernel.org
> +S:     Maintained
> +F:     drivers/hid/hid-creative-sb0540.c
> +
>  CRYPTO API
>  M:     Herbert Xu <herbert@gondor.apana.org.au>
>  M:     "David S. Miller" <davem@davemloft.net>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 3872e03d9a59..a70999f9c639 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -273,6 +273,15 @@ config HID_CP2112
>         and gpiochip to expose these functions of the CP2112. The
>         customizable USB descriptor fields are exposed as sysfs attributes.
>
> +config HID_CREATIVE_SB0540
> +       tristate "Creative SB0540 infrared receiver"
> +       depends on USB_HID
> +       help
> +       Support for Creative infrared SB0540-compatible remote controls, such
> +       as the RM-1500 and RM-1800 remotes.
> +
> +       Say Y here if you want support for Creative SB0540 infrared receiver.
> +
>  config HID_CYPRESS
>         tristate "Cypress mouse and barcode readers"
>         depends on HID
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index cc5d827c9164..1ad662fe37b6 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_HID_ALPS)                += hid-alps.o
>  obj-$(CONFIG_HID_ACRUX)                += hid-axff.o
>  obj-$(CONFIG_HID_APPLE)                += hid-apple.o
>  obj-$(CONFIG_HID_APPLEIR)      += hid-appleir.o
> +obj-$(CONFIG_HID_CREATIVE_SB0540)      += hid-creative-sb0540.c

I forgot to mention that sparse was complaining about:

scripts/Makefile.build:283: target 'drivers/hid/hid-creative-sb0540.c'
doesn't match the target pattern

And it turns out your line should read `hid-creative-sb0540.o` not
`hid-creative-sb0540.c`

Cheers,
Benjamin


>  obj-$(CONFIG_HID_ASUS)         += hid-asus.o
>  obj-$(CONFIG_HID_AUREAL)       += hid-aureal.o
>  obj-$(CONFIG_HID_BELKIN)       += hid-belkin.o
> diff --git a/drivers/hid/hid-creative-sb0540.c b/drivers/hid/hid-creative-sb0540.c
> new file mode 100644
> index 000000000000..6b7c81ccf310
> --- /dev/null
> +++ b/drivers/hid/hid-creative-sb0540.c
> @@ -0,0 +1,268 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * HID driver for the Creative SB0540 receiver
> + *
> + * Copyright (C) 2019 Red Hat Inc. All Rights Reserved
> + *
> + */
> +
> +#include <linux/device.h>
> +#include <linux/hid.h>
> +#include <linux/module.h>
> +#include "hid-ids.h"
> +
> +MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
> +MODULE_DESCRIPTION("HID Creative SB0540 receiver");
> +MODULE_LICENSE("GPL");
> +
> +static const unsigned short creative_sb0540_key_table[] = {
> +       KEY_POWER,
> +       KEY_RESERVED,           /* text: 24bit */
> +       KEY_RESERVED,           /* 24bit wheel up */
> +       KEY_RESERVED,           /* 24bit wheel down */
> +       KEY_RESERVED,           /* text: CMSS */
> +       KEY_RESERVED,           /* CMSS wheel Up */
> +       KEY_RESERVED,           /* CMSS wheel Down */
> +       KEY_RESERVED,           /* text: EAX */
> +       KEY_RESERVED,           /* EAX wheel up */
> +       KEY_RESERVED,           /* EAX wheel down */
> +       KEY_RESERVED,           /* text: 3D Midi */
> +       KEY_RESERVED,           /* 3D Midi wheel up */
> +       KEY_RESERVED,           /* 3D Midi wheel down */
> +       KEY_MUTE,
> +       KEY_VOLUMEUP,
> +       KEY_VOLUMEDOWN,
> +       KEY_UP,
> +       KEY_LEFT,
> +       KEY_RIGHT,
> +       KEY_REWIND,
> +       KEY_OK,
> +       KEY_FASTFORWARD,
> +       KEY_DOWN,
> +       KEY_AGAIN,              /* text: Return, symbol: Jump to */
> +       KEY_PLAY,               /* text: Start */
> +       KEY_ESC,                /* text: Cancel */
> +       KEY_RECORD,
> +       KEY_OPTION,
> +       KEY_MENU,               /* text: Display */
> +       KEY_PREVIOUS,
> +       KEY_PLAYPAUSE,
> +       KEY_NEXT,
> +       KEY_SLOW,
> +       KEY_STOP,
> +       KEY_NUMERIC_1,
> +       KEY_NUMERIC_2,
> +       KEY_NUMERIC_3,
> +       KEY_NUMERIC_4,
> +       KEY_NUMERIC_5,
> +       KEY_NUMERIC_6,
> +       KEY_NUMERIC_7,
> +       KEY_NUMERIC_8,
> +       KEY_NUMERIC_9,
> +       KEY_NUMERIC_0
> +};
> +
> +/*
> + * Codes and keys from lirc's
> + * remotes/creative/lircd.conf.alsa_usb
> + * order and size must match creative_sb0540_key_table[] above
> + */
> +static const unsigned short creative_sb0540_codes[] = {
> +       0x619E,
> +       0x916E,
> +       0x926D,
> +       0x936C,
> +       0x718E,
> +       0x946B,
> +       0x956A,
> +       0x8C73,
> +       0x9669,
> +       0x9768,
> +       0x9867,
> +       0x9966,
> +       0x9A65,
> +       0x6E91,
> +       0x629D,
> +       0x639C,
> +       0x7B84,
> +       0x6B94,
> +       0x728D,
> +       0x8778,
> +       0x817E,
> +       0x758A,
> +       0x8D72,
> +       0x8E71,
> +       0x8877,
> +       0x7C83,
> +       0x738C,
> +       0x827D,
> +       0x7689,
> +       0x7F80,
> +       0x7986,
> +       0x7A85,
> +       0x7D82,
> +       0x857A,
> +       0x8B74,
> +       0x8F70,
> +       0x906F,
> +       0x8A75,
> +       0x847B,
> +       0x7887,
> +       0x8976,
> +       0x837C,
> +       0x7788,
> +       0x807F
> +};
> +
> +struct creative_sb0540 {
> +       struct input_dev *input_dev;
> +       struct hid_device *hid;
> +       unsigned short keymap[ARRAY_SIZE(creative_sb0540_key_table)];
> +};
> +
> +static inline u64 reverse(u64 data, int bits)
> +{
> +       int i;
> +       u64 c;
> +
> +       c = 0;
> +       for (i = 0; i < bits; i++) {
> +               c |= (u64) (((data & (((u64) 1) << i)) ? 1 : 0))
> +                       << (bits - 1 - i);
> +       }
> +       return (c);
> +}
> +
> +static int get_key(struct creative_sb0540 *creative_sb0540, u64 keycode)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(creative_sb0540_codes); i++) {
> +               if (creative_sb0540_codes[i] == keycode)
> +                       return creative_sb0540->keymap[i];
> +       }
> +
> +       return 0;
> +
> +}
> +
> +static int creative_sb0540_raw_event(struct hid_device *hid,
> +       struct hid_report *report, u8 *data, int len)
> +{
> +       struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
> +       u64 code, main_code;
> +       int key;
> +
> +       if (len != 6)
> +               goto out;
> +
> +       /* From daemons/hw_hiddev.c sb0540_rec() in lirc */
> +       code = reverse(data[5], 8);
> +       main_code = (code << 8) + ((~code) & 0xff);
> +
> +       /*
> +        * Flip to get values in the same format as
> +        * remotes/creative/lircd.conf.alsa_usb in lirc
> +        */
> +       main_code = ((main_code & 0xff) << 8) +
> +               ((main_code & 0xff00) >> 8);
> +
> +       key = get_key(creative_sb0540, main_code);
> +       if (key == 0 || key == KEY_RESERVED) {
> +               hid_err(hid, "Could not get a key for main_code %llX\n",
> +                       main_code);
> +               return 0;
> +       }
> +
> +       input_report_key(creative_sb0540->input_dev, key, 1);
> +       input_report_key(creative_sb0540->input_dev, key, 0);
> +       input_sync(creative_sb0540->input_dev);
> +
> +       /* let hidraw and hiddev handle the report */
> +       return 0;
> +}
> +
> +static int creative_sb0540_input_configured(struct hid_device *hid,
> +               struct hid_input *hidinput)
> +{
> +       struct input_dev *input_dev = hidinput->input;
> +       struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
> +       int i;
> +
> +       creative_sb0540->input_dev = input_dev;
> +
> +       input_dev->keycode = creative_sb0540->keymap;
> +       input_dev->keycodesize = sizeof(unsigned short);
> +       input_dev->keycodemax = ARRAY_SIZE(creative_sb0540->keymap);
> +
> +       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
> +
> +       memcpy(creative_sb0540->keymap, creative_sb0540_key_table,
> +               sizeof(creative_sb0540->keymap));
> +       for (i = 0; i < ARRAY_SIZE(creative_sb0540_key_table); i++)
> +               set_bit(creative_sb0540->keymap[i], input_dev->keybit);
> +       clear_bit(KEY_RESERVED, input_dev->keybit);
> +
> +       return 0;
> +}
> +
> +static int creative_sb0540_input_mapping(struct hid_device *hid,
> +               struct hid_input *hi, struct hid_field *field,
> +               struct hid_usage *usage, unsigned long **bit, int *max)
> +{
> +       /*
> +        * We are remapping the keys ourselves, so ignore the hid-input
> +        * keymap processing.
> +        */
> +       return -1;
> +}
> +
> +static int creative_sb0540_probe(struct hid_device *hid,
> +               const struct hid_device_id *id)
> +{
> +       int ret;
> +       struct creative_sb0540 *creative_sb0540;
> +
> +       creative_sb0540 = devm_kzalloc(&hid->dev,
> +               sizeof(struct creative_sb0540), GFP_KERNEL);
> +
> +       if (!creative_sb0540)
> +               return -ENOMEM;
> +
> +       creative_sb0540->hid = hid;
> +
> +       /* force input as some remotes bypass the input registration */
> +       hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
> +
> +       hid_set_drvdata(hid, creative_sb0540);
> +
> +       ret = hid_parse(hid);
> +       if (ret) {
> +               hid_err(hid, "parse failed\n");
> +               return ret;
> +       }
> +
> +       ret = hid_hw_start(hid, HID_CONNECT_DEFAULT);
> +       if (ret) {
> +               hid_err(hid, "hw start failed\n");
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct hid_device_id creative_sb0540_devices[] = {
> +       { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB0540) },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(hid, creative_sb0540_devices);
> +
> +static struct hid_driver creative_sb0540_driver = {
> +       .name = "creative-sb0540",
> +       .id_table = creative_sb0540_devices,
> +       .raw_event = creative_sb0540_raw_event,
> +       .input_configured = creative_sb0540_input_configured,
> +       .probe = creative_sb0540_probe,
> +       .input_mapping = creative_sb0540_input_mapping,
> +};
> +module_hid_driver(creative_sb0540_driver);
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 826324997686..206b7065da86 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -312,6 +312,7 @@
>  #define USB_VENDOR_ID_CREATIVELABS     0x041e
>  #define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51     0x322c
>  #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801
> +#define USB_DEVICE_ID_CREATIVE_SB0540  0x3100
>
>  #define USB_VENDOR_ID_CVTOUCH          0x1ff7
>  #define USB_DEVICE_ID_CVTOUCH_SCREEN   0x0013
> --
> 2.21.0
>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox