Merge tag 'tegra-for-5.14-rc3-arm64-dt' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / iio / position / hid-sensor-custom-intel-hinge.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * HID Sensors Driver
4  * Copyright (c) 2020, Intel Corporation.
5  */
6 #include <linux/hid-sensor-hub.h>
7 #include <linux/iio/buffer.h>
8 #include <linux/iio/iio.h>
9 #include <linux/platform_device.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12
13 #include "../common/hid-sensors/hid-sensor-trigger.h"
14
15 enum hinge_channel {
16         CHANNEL_SCAN_INDEX_HINGE_ANGLE,
17         CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
18         CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
19         CHANNEL_SCAN_INDEX_MAX,
20 };
21
22 #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX
23
24 static const u32 hinge_addresses[CHANNEL_SCAN_INDEX_MAX] = {
25         HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
26         HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2),
27         HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3)
28 };
29
30 static const char *const hinge_labels[CHANNEL_SCAN_INDEX_MAX] = { "hinge",
31                                                                   "screen",
32                                                                   "keyboard" };
33
34 struct hinge_state {
35         struct iio_dev *indio_dev;
36         struct hid_sensor_hub_attribute_info hinge[CHANNEL_SCAN_INDEX_MAX];
37         struct hid_sensor_hub_callbacks callbacks;
38         struct hid_sensor_common common_attributes;
39         const char *labels[CHANNEL_SCAN_INDEX_MAX];
40         struct {
41                 u32 hinge_val[3];
42                 u64 timestamp __aligned(8);
43         } scan;
44
45         int scale_pre_decml;
46         int scale_post_decml;
47         int scale_precision;
48         int value_offset;
49         u64 timestamp;
50 };
51
52 static const u32 hinge_sensitivity_addresses[] = {
53         HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
54 };
55
56 /* Channel definitions */
57 static const struct iio_chan_spec hinge_channels[] = {
58         {
59                 .type = IIO_ANGL,
60                 .indexed = 1,
61                 .channel = 0,
62                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
63                 .info_mask_shared_by_type =
64                         BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
65                         BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
66                 .scan_index = CHANNEL_SCAN_INDEX_HINGE_ANGLE,
67                 .scan_type = {
68                         .sign = 's',
69                         .storagebits = 32,
70                 },
71         }, {
72                 .type = IIO_ANGL,
73                 .indexed = 1,
74                 .channel = 1,
75                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
76                 .info_mask_shared_by_type =
77                         BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
78                         BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
79                 .scan_index = CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
80                 .scan_type = {
81                         .sign = 's',
82                         .storagebits = 32,
83                 },
84         }, {
85                 .type = IIO_ANGL,
86                 .indexed = 1,
87                 .channel = 2,
88                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
89                 .info_mask_shared_by_type =
90                         BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
91                         BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
92                 .scan_index = CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
93                 .scan_type = {
94                         .sign = 's',
95                         .storagebits = 32,
96                 },
97         },
98         IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
99 };
100
101 /* Adjust channel real bits based on report descriptor */
102 static void hinge_adjust_channel_realbits(struct iio_chan_spec *channels,
103                                           int channel, int size)
104 {
105         channels[channel].scan_type.realbits = size * 8;
106 }
107
108 /* Channel read_raw handler */
109 static int hinge_read_raw(struct iio_dev *indio_dev,
110                           struct iio_chan_spec const *chan, int *val, int *val2,
111                           long mask)
112 {
113         struct hinge_state *st = iio_priv(indio_dev);
114         struct hid_sensor_hub_device *hsdev;
115         int report_id;
116         s32 min;
117
118         hsdev = st->common_attributes.hsdev;
119         switch (mask) {
120         case IIO_CHAN_INFO_RAW:
121                 hid_sensor_power_state(&st->common_attributes, true);
122                 report_id = st->hinge[chan->scan_index].report_id;
123                 min = st->hinge[chan->scan_index].logical_minimum;
124                 if (report_id < 0) {
125                         hid_sensor_power_state(&st->common_attributes, false);
126                         return -EINVAL;
127                 }
128
129                 *val = sensor_hub_input_attr_get_raw_value(st->common_attributes.hsdev,
130                                                            hsdev->usage,
131                                                            hinge_addresses[chan->scan_index],
132                                                            report_id,
133                                                            SENSOR_HUB_SYNC, min < 0);
134
135                 hid_sensor_power_state(&st->common_attributes, false);
136                 return IIO_VAL_INT;
137         case IIO_CHAN_INFO_SCALE:
138                 *val = st->scale_pre_decml;
139                 *val2 = st->scale_post_decml;
140                 return st->scale_precision;
141         case IIO_CHAN_INFO_OFFSET:
142                 *val = st->value_offset;
143                 return IIO_VAL_INT;
144         case IIO_CHAN_INFO_SAMP_FREQ:
145                 return hid_sensor_read_samp_freq_value(&st->common_attributes,
146                                                        val, val2);
147         case IIO_CHAN_INFO_HYSTERESIS:
148                 return hid_sensor_read_raw_hyst_value(&st->common_attributes,
149                                                       val, val2);
150         default:
151                 return -EINVAL;
152         }
153 }
154
155 /* Channel write_raw handler */
156 static int hinge_write_raw(struct iio_dev *indio_dev,
157                            struct iio_chan_spec const *chan, int val, int val2,
158                            long mask)
159 {
160         struct hinge_state *st = iio_priv(indio_dev);
161
162         switch (mask) {
163         case IIO_CHAN_INFO_SAMP_FREQ:
164                 return hid_sensor_write_samp_freq_value(&st->common_attributes,
165                                                         val, val2);
166         case IIO_CHAN_INFO_HYSTERESIS:
167                 return hid_sensor_write_raw_hyst_value(&st->common_attributes,
168                                                        val, val2);
169         default:
170                 return -EINVAL;
171         }
172 }
173
174 static int hinge_read_label(struct iio_dev *indio_dev,
175                             struct iio_chan_spec const *chan, char *label)
176 {
177         struct hinge_state *st = iio_priv(indio_dev);
178
179         return sprintf(label, "%s\n", st->labels[chan->channel]);
180 }
181
182 static const struct iio_info hinge_info = {
183         .read_raw = hinge_read_raw,
184         .write_raw = hinge_write_raw,
185         .read_label = hinge_read_label,
186 };
187
188 /*
189  * Callback handler to send event after all samples are received
190  * and captured.
191  */
192 static int hinge_proc_event(struct hid_sensor_hub_device *hsdev,
193                             unsigned int usage_id, void *priv)
194 {
195         struct iio_dev *indio_dev = platform_get_drvdata(priv);
196         struct hinge_state *st = iio_priv(indio_dev);
197
198         if (atomic_read(&st->common_attributes.data_ready)) {
199                 if (!st->timestamp)
200                         st->timestamp = iio_get_time_ns(indio_dev);
201
202                 iio_push_to_buffers_with_timestamp(indio_dev, &st->scan,
203                                                    st->timestamp);
204
205                 st->timestamp = 0;
206         }
207         return 0;
208 }
209
210 /* Capture samples in local storage */
211 static int hinge_capture_sample(struct hid_sensor_hub_device *hsdev,
212                                 unsigned int usage_id, size_t raw_len,
213                                 char *raw_data, void *priv)
214 {
215         struct iio_dev *indio_dev = platform_get_drvdata(priv);
216         struct hinge_state *st = iio_priv(indio_dev);
217         int offset;
218
219         switch (usage_id) {
220         case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1):
221         case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2):
222         case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3):
223                 offset = usage_id - HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1);
224                 st->scan.hinge_val[offset] = *(u32 *)raw_data;
225                 return 0;
226         case HID_USAGE_SENSOR_TIME_TIMESTAMP:
227                 st->timestamp = hid_sensor_convert_timestamp(&st->common_attributes,
228                                                              *(int64_t *)raw_data);
229                 return 0;
230         default:
231                 return -EINVAL;
232         }
233 }
234
235 /* Parse report which is specific to an usage id */
236 static int hinge_parse_report(struct platform_device *pdev,
237                               struct hid_sensor_hub_device *hsdev,
238                               struct iio_chan_spec *channels,
239                               unsigned int usage_id, struct hinge_state *st)
240 {
241         int ret;
242         int i;
243
244         for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; ++i) {
245                 ret = sensor_hub_input_get_attribute_info(hsdev,
246                                                           HID_INPUT_REPORT,
247                                                           usage_id,
248                                                           hinge_addresses[i],
249                                                           &st->hinge[i]);
250                 if (ret < 0)
251                         return ret;
252
253                 hinge_adjust_channel_realbits(channels, i, st->hinge[i].size);
254         }
255
256         st->scale_precision = hid_sensor_format_scale(HID_USAGE_SENSOR_HINGE,
257                         &st->hinge[CHANNEL_SCAN_INDEX_HINGE_ANGLE],
258                         &st->scale_pre_decml, &st->scale_post_decml);
259
260         return ret;
261 }
262
263 /* Function to initialize the processing for usage id */
264 static int hid_hinge_probe(struct platform_device *pdev)
265 {
266         struct hinge_state *st;
267         struct iio_dev *indio_dev;
268         struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
269         int ret;
270         int i;
271
272         indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
273         if (!indio_dev)
274                 return -ENOMEM;
275
276         platform_set_drvdata(pdev, indio_dev);
277
278         st = iio_priv(indio_dev);
279         st->common_attributes.hsdev = hsdev;
280         st->common_attributes.pdev = pdev;
281         st->indio_dev = indio_dev;
282         for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; i++)
283                 st->labels[i] = hinge_labels[i];
284
285         ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage,
286                                                  &st->common_attributes,
287                                                  hinge_sensitivity_addresses,
288                                                  ARRAY_SIZE(hinge_sensitivity_addresses));
289         if (ret) {
290                 dev_err(&pdev->dev, "failed to setup common attributes\n");
291                 return ret;
292         }
293
294         indio_dev->num_channels = ARRAY_SIZE(hinge_channels);
295         indio_dev->channels = devm_kmemdup(&indio_dev->dev, hinge_channels,
296                                            sizeof(hinge_channels), GFP_KERNEL);
297         if (!indio_dev->channels)
298                 return -ENOMEM;
299
300         ret = hinge_parse_report(pdev, hsdev,
301                                  (struct iio_chan_spec *)indio_dev->channels,
302                                  hsdev->usage, st);
303         if (ret) {
304                 dev_err(&pdev->dev, "failed to setup attributes\n");
305                 return ret;
306         }
307
308         indio_dev->info = &hinge_info;
309         indio_dev->name = "hinge";
310         indio_dev->modes = INDIO_DIRECT_MODE;
311
312         atomic_set(&st->common_attributes.data_ready, 0);
313         ret = hid_sensor_setup_trigger(indio_dev, indio_dev->name,
314                                        &st->common_attributes);
315         if (ret < 0) {
316                 dev_err(&pdev->dev, "trigger setup failed\n");
317                 return ret;
318         }
319
320         st->callbacks.send_event = hinge_proc_event;
321         st->callbacks.capture_sample = hinge_capture_sample;
322         st->callbacks.pdev = pdev;
323         ret = sensor_hub_register_callback(hsdev, hsdev->usage, &st->callbacks);
324         if (ret < 0) {
325                 dev_err(&pdev->dev, "callback reg failed\n");
326                 goto error_remove_trigger;
327         }
328
329         ret = iio_device_register(indio_dev);
330         if (ret) {
331                 dev_err(&pdev->dev, "device register failed\n");
332                 goto error_remove_callback;
333         }
334
335         return ret;
336
337 error_remove_callback:
338         sensor_hub_remove_callback(hsdev, hsdev->usage);
339 error_remove_trigger:
340         hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
341         return ret;
342 }
343
344 /* Function to deinitialize the processing for usage id */
345 static int hid_hinge_remove(struct platform_device *pdev)
346 {
347         struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
348         struct iio_dev *indio_dev = platform_get_drvdata(pdev);
349         struct hinge_state *st = iio_priv(indio_dev);
350
351         iio_device_unregister(indio_dev);
352         sensor_hub_remove_callback(hsdev, hsdev->usage);
353         hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
354
355         return 0;
356 }
357
358 static const struct platform_device_id hid_hinge_ids[] = {
359         {
360                 /* Format: HID-SENSOR-INT-usage_id_in_hex_lowercase */
361                 .name = "HID-SENSOR-INT-020b",
362         },
363         { /* sentinel */ }
364 };
365 MODULE_DEVICE_TABLE(platform, hid_hinge_ids);
366
367 static struct platform_driver hid_hinge_platform_driver = {
368         .id_table = hid_hinge_ids,
369         .driver = {
370                 .name   = KBUILD_MODNAME,
371                 .pm     = &hid_sensor_pm_ops,
372         },
373         .probe          = hid_hinge_probe,
374         .remove         = hid_hinge_remove,
375 };
376 module_platform_driver(hid_hinge_platform_driver);
377
378 MODULE_DESCRIPTION("HID Sensor INTEL Hinge");
379 MODULE_AUTHOR("Ye Xiang <xiang.ye@intel.com>");
380 MODULE_LICENSE("GPL");
381 MODULE_IMPORT_NS(IIO_HID);