Re: [PATCH 1/4] HID: hid-sensor-custom: Add custom sensor iio support

2020-11-18 Thread kernel test robot
Hi Ye,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on iio/togreg]
[also build test WARNING on linus/master v5.10-rc4 next-20201118]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Ye-Xiang/add-custom-hinge-sensor-support/20201119-110842
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
config: c6x-randconfig-r003-20201119 (attached as .config)
compiler: c6x-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/1f33733d65038ade4af057df7e5c126485ecb7c6
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Ye-Xiang/add-custom-hinge-sensor-support/20201119-110842
git checkout 1f33733d65038ade4af057df7e5c126485ecb7c6
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=c6x 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   drivers/hid/hid-sensor-custom.c: In function 'store_value':
   drivers/hid/hid-sensor-custom.c:401:7: warning: variable 'ret' set but not 
used [-Wunused-but-set-variable]
 401 |   int ret;
 |   ^~~
   In file included from include/linux/device.h:15,
from include/linux/miscdevice.h:7,
from drivers/hid/hid-sensor-custom.c:11:
   drivers/hid/hid-sensor-custom.c: In function 'get_known_custom_sensor_index':
>> drivers/hid/hid-sensor-custom.c:847:24: warning: format '%ld' expects 
>> argument of type 'long int', but argument 3 has type '__kernel_size_t' {aka 
>> 'unsigned int'} [-Wformat=]
 847 |   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
 |^~~
   include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt'
  19 | #define dev_fmt(fmt) fmt
 |  ^~~
   include/linux/hid.h:1180:2: note: in expansion of macro 'dev_err'
1180 |  dev_err(&(hid)->dev, fmt, ##__VA_ARGS__)
 |  ^~~
   drivers/hid/hid-sensor-custom.c:847:3: note: in expansion of macro 'hid_err'
 847 |   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
 |   ^~~
   drivers/hid/hid-sensor-custom.c:847:28: note: format string is defined here
 847 |   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
 |  ~~^
 ||
 |long int
 |  %d
   In file included from include/linux/device.h:15,
from include/linux/miscdevice.h:7,
from drivers/hid/hid-sensor-custom.c:11:
   drivers/hid/hid-sensor-custom.c:847:24: warning: format '%ld' expects 
argument of type 'long int', but argument 4 has type '__kernel_size_t' {aka 
'unsigned int'} [-Wformat=]
 847 |   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
 |^~~
   include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt'
  19 | #define dev_fmt(fmt) fmt
 |  ^~~
   include/linux/hid.h:1180:2: note: in expansion of macro 'dev_err'
1180 |  dev_err(&(hid)->dev, fmt, ##__VA_ARGS__)
 |  ^~~
   drivers/hid/hid-sensor-custom.c:847:3: note: in expansion of macro 'hid_err'
 847 |   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
 |   ^~~
   drivers/hid/hid-sensor-custom.c:847:35: note: format string is defined here
 847 |   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
 | ~~^
 |   |
 |   long int
 | %d

vim +847 drivers/hid/hid-sensor-custom.c

   771  
   772  static int get_known_custom_sensor_index(struct hid_sensor_hub_device 
*hsdev)
   773  {
   774  struct hid_sensor_hub_attribute_info sensor_manufacturer = { 0 
};
   775  struct hid_sensor_hub_attribute_info sensor_luid_info = { 0 };
   776  int report_size;
   777  int ret;
   778  u16 *w_buf;
   779  int w_buf_len;
   780  char *buf;
   781  int buf_len;
   782  int i;
   783  int index;
   784  
   785  w_buf_len = sizeof(u16) * HID_CUSTOM_MAX_FEATURE_BYTES;
   786  buf_len = sizeof(char) * HID_CUSTOM_MAX_FEATURE_BYTES;
   787  w_buf = kzalloc(w_buf_len, GFP_KERNEL);
   788  if (!w_buf)
   789  return -1;
   

[PATCH 1/4] HID: hid-sensor-custom: Add custom sensor iio support

2020-11-18 Thread Ye Xiang
Currently custom sensors properties are not decoded and it is up to
user space to interpret.

Some manufacturers already standardized the meaning of some custom sensors.
They can be presented as a proper IIO sensor. We can identify these sensors
based on manufacturer and serial number property in the report.

This change is identifying hinge sensor when the manufacturer is "INTEL".
This creates a platform device so that a sensor driver can be loaded to
process these sensors.

Signed-off-by: Ye Xiang 
---
 drivers/hid/hid-sensor-custom.c | 169 
 include/linux/hid-sensor-ids.h  |  39 
 2 files changed, 208 insertions(+)

diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c
index 4d25577a8573..6ef8387405b3 100644
--- a/drivers/hid/hid-sensor-custom.c
+++ b/drivers/hid/hid-sensor-custom.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2015, Intel Corporation.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -21,6 +22,7 @@
 #define HID_CUSTOM_TOTAL_ATTRS (HID_CUSTOM_MAX_CORE_ATTRS + 1)
 #define HID_CUSTOM_FIFO_SIZE   4096
 #define HID_CUSTOM_MAX_FEATURE_BYTES   64
+#define HID_SENSOR_USAGE_LENGTH (4 + 1)
 
 struct hid_sensor_custom_field {
int report_id;
@@ -50,6 +52,8 @@ struct hid_sensor_custom {
struct kfifo data_fifo;
unsigned long misc_opened;
wait_queue_head_t wait;
+   struct platform_device *custom_pdev;
+   bool custom_pdev_exposed;
 };
 
 /* Header for each sample to user space via dev interface */
@@ -746,11 +750,158 @@ static void hid_sensor_custom_dev_if_remove(struct 
hid_sensor_custom
 
 }
 
+/*
+ * use sensors luid which is defined in FW, such as ISH,
+ * to identify sensor.
+ */
+static char *known_sensor_luid[] = { "020B" };
+
+static int get_luid_table_index(unsigned char *usage_str)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(known_sensor_luid); i++) {
+   if (!strncmp(usage_str, known_sensor_luid[i],
+strlen(known_sensor_luid[i])))
+   return i;
+   }
+
+   return -1;
+}
+
+static int get_known_custom_sensor_index(struct hid_sensor_hub_device *hsdev)
+{
+   struct hid_sensor_hub_attribute_info sensor_manufacturer = { 0 };
+   struct hid_sensor_hub_attribute_info sensor_luid_info = { 0 };
+   int report_size;
+   int ret;
+   u16 *w_buf;
+   int w_buf_len;
+   char *buf;
+   int buf_len;
+   int i;
+   int index;
+
+   w_buf_len = sizeof(u16) * HID_CUSTOM_MAX_FEATURE_BYTES;
+   buf_len = sizeof(char) * HID_CUSTOM_MAX_FEATURE_BYTES;
+   w_buf = kzalloc(w_buf_len, GFP_KERNEL);
+   if (!w_buf)
+   return -1;
+
+   buf = kzalloc(buf_len, GFP_KERNEL);
+   if (!buf) {
+   kfree(w_buf);
+   return -1;
+   }
+
+   /* get manufacturer info */
+   ret = sensor_hub_input_get_attribute_info(
+   hsdev, HID_FEATURE_REPORT, hsdev->usage,
+   HID_USAGE_SENSOR_PROP_MANUFACTURER, _manufacturer);
+   if (ret < 0)
+   goto err_out;
+
+   report_size =
+   sensor_hub_get_feature(hsdev, sensor_manufacturer.report_id,
+  sensor_manufacturer.index, w_buf_len,
+  w_buf);
+   if (report_size <= 0) {
+   hid_err(hsdev->hdev,
+   "Failed to get sensor manufacturer info %d\n",
+   report_size);
+   goto err_out;
+   }
+
+   /* convert from wide char to char */
+   for (i = 0; i < buf_len - 1 && w_buf[i]; i++)
+   buf[i] = (char)w_buf[i];
+
+   /* ensure it's ISH sensor */
+   if (strncmp(buf, "INTEL", strlen("INTEL")))
+   goto err_out;
+
+   memset(w_buf, 0, w_buf_len);
+   memset(buf, 0, buf_len);
+
+   /* get real usage id */
+   ret = sensor_hub_input_get_attribute_info(
+   hsdev, HID_FEATURE_REPORT, hsdev->usage,
+   HID_USAGE_SENSOR_PROP_SERIAL_NUM, _luid_info);
+   if (ret < 0)
+   goto err_out;
+
+   report_size = sensor_hub_get_feature(hsdev, sensor_luid_info.report_id,
+sensor_luid_info.index, w_buf_len,
+w_buf);
+   if (report_size <= 0) {
+   hid_err(hsdev->hdev, "Failed to get real usage info %d\n",
+   report_size);
+   goto err_out;
+   }
+
+   /* convert from wide char to char */
+   for (i = 0; i < buf_len - 1 && w_buf[i]; i++)
+   buf[i] = (char)w_buf[i];
+
+   if (strlen(buf) != strlen(known_sensor_luid[0]) + 5) {
+   hid_err(hsdev->hdev, " %ld != %ld\n", strlen(buf),
+   strlen(known_sensor_luid[0]));
+   goto err_out;
+   }
+
+   /* get table index with luid (not matching 'LUID: