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
12 #include "../common/hid-sensors/hid-sensor-trigger.h"
13
14 enum hinge_channel {
15 CHANNEL_SCAN_INDEX_HINGE_ANGLE,
16 CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
17 CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
18 CHANNEL_SCAN_INDEX_MAX,
19 };
20
21 #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX
22
23 static const u32 hinge_addresses[CHANNEL_SCAN_INDEX_MAX] = {
24 HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
25 HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2),
26 HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3)
27 };
28
29 static const char *const hinge_labels[CHANNEL_SCAN_INDEX_MAX] = { "hinge",
30 "screen",
31 "keyboard" };
32
33 struct hinge_state {
34 struct iio_dev *indio_dev;
35 struct hid_sensor_hub_attribute_info hinge[CHANNEL_SCAN_INDEX_MAX];
36 struct hid_sensor_hub_callbacks callbacks;
37 struct hid_sensor_common common_attributes;
38 const char *labels[CHANNEL_SCAN_INDEX_MAX];
39 struct {
40 u32 hinge_val[3];
41 aligned_s64 timestamp;
42 } scan;
43
44 int scale_pre_decml;
45 int scale_post_decml;
46 int scale_precision;
47 int value_offset;
48 u64 timestamp;
49 };
50
51 static const u32 hinge_sensitivity_addresses[] = {
52 HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
53 };
54
55 /* Channel definitions */
56 static const struct iio_chan_spec hinge_channels[] = {
57 {
58 .type = IIO_ANGL,
59 .indexed = 1,
60 .channel = 0,
61 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
62 .info_mask_shared_by_type =
63 BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
64 BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
65 .scan_index = CHANNEL_SCAN_INDEX_HINGE_ANGLE,
66 .scan_type = {
67 .sign = 's',
68 .storagebits = 32,
69 },
70 }, {
71 .type = IIO_ANGL,
72 .indexed = 1,
73 .channel = 1,
74 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
75 .info_mask_shared_by_type =
76 BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
77 BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
78 .scan_index = CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
79 .scan_type = {
80 .sign = 's',
81 .storagebits = 32,
82 },
83 }, {
84 .type = IIO_ANGL,
85 .indexed = 1,
86 .channel = 2,
87 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
88 .info_mask_shared_by_type =
89 BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
90 BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
91 .scan_index = CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
92 .scan_type = {
93 .sign = 's',
94 .storagebits = 32,
95 },
96 },
97 IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
98 };
99
100 /* Adjust channel real bits based on report descriptor */
hinge_adjust_channel_realbits(struct iio_chan_spec * channels,int channel,int size)101 static void hinge_adjust_channel_realbits(struct iio_chan_spec *channels,
102 int channel, int size)
103 {
104 channels[channel].scan_type.realbits = size * 8;
105 }
106
107 /* Channel read_raw handler */
hinge_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)108 static int hinge_read_raw(struct iio_dev *indio_dev,
109 struct iio_chan_spec const *chan,
110 int *val, int *val2, long mask)
111 {
112 struct hinge_state *st = iio_priv(indio_dev);
113 struct hid_sensor_hub_device *hsdev;
114 int report_id;
115 s32 min;
116
117 hsdev = st->common_attributes.hsdev;
118 switch (mask) {
119 case IIO_CHAN_INFO_RAW:
120 hid_sensor_power_state(&st->common_attributes, true);
121 report_id = st->hinge[chan->scan_index].report_id;
122 min = st->hinge[chan->scan_index].logical_minimum;
123 if (report_id < 0) {
124 hid_sensor_power_state(&st->common_attributes, false);
125 return -EINVAL;
126 }
127
128 *val = sensor_hub_input_attr_get_raw_value(st->common_attributes.hsdev,
129 hsdev->usage,
130 hinge_addresses[chan->scan_index],
131 report_id,
132 SENSOR_HUB_SYNC, min < 0);
133
134 hid_sensor_power_state(&st->common_attributes, false);
135 return IIO_VAL_INT;
136 case IIO_CHAN_INFO_SCALE:
137 *val = st->scale_pre_decml;
138 *val2 = st->scale_post_decml;
139 return st->scale_precision;
140 case IIO_CHAN_INFO_OFFSET:
141 *val = st->value_offset;
142 return IIO_VAL_INT;
143 case IIO_CHAN_INFO_SAMP_FREQ:
144 return hid_sensor_read_samp_freq_value(&st->common_attributes,
145 val, val2);
146 case IIO_CHAN_INFO_HYSTERESIS:
147 return hid_sensor_read_raw_hyst_value(&st->common_attributes,
148 val, val2);
149 default:
150 return -EINVAL;
151 }
152 }
153
154 /* Channel write_raw handler */
hinge_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)155 static int hinge_write_raw(struct iio_dev *indio_dev,
156 struct iio_chan_spec const *chan,
157 int val, int val2, long mask)
158 {
159 struct hinge_state *st = iio_priv(indio_dev);
160
161 switch (mask) {
162 case IIO_CHAN_INFO_SAMP_FREQ:
163 return hid_sensor_write_samp_freq_value(&st->common_attributes,
164 val, val2);
165 case IIO_CHAN_INFO_HYSTERESIS:
166 return hid_sensor_write_raw_hyst_value(&st->common_attributes,
167 val, val2);
168 default:
169 return -EINVAL;
170 }
171 }
172
hinge_read_label(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,char * label)173 static int hinge_read_label(struct iio_dev *indio_dev,
174 struct iio_chan_spec const *chan, char *label)
175 {
176 struct hinge_state *st = iio_priv(indio_dev);
177
178 return sysfs_emit(label, "%s\n", st->labels[chan->channel]);
179 }
180
181 static const struct iio_info hinge_info = {
182 .read_raw = hinge_read_raw,
183 .write_raw = hinge_write_raw,
184 .read_label = hinge_read_label,
185 };
186
187 /*
188 * Callback handler to send event after all samples are received
189 * and captured.
190 */
hinge_proc_event(struct hid_sensor_hub_device * hsdev,u32 usage_id,void * priv)191 static int hinge_proc_event(struct hid_sensor_hub_device *hsdev,
192 u32 usage_id, void *priv)
193 {
194 struct iio_dev *indio_dev = platform_get_drvdata(priv);
195 struct hinge_state *st = iio_priv(indio_dev);
196
197 if (atomic_read(&st->common_attributes.data_ready)) {
198 if (!st->timestamp)
199 st->timestamp = iio_get_time_ns(indio_dev);
200
201 iio_push_to_buffers_with_timestamp(indio_dev, &st->scan,
202 st->timestamp);
203
204 st->timestamp = 0;
205 }
206 return 0;
207 }
208
209 /* Capture samples in local storage */
hinge_capture_sample(struct hid_sensor_hub_device * hsdev,u32 usage_id,size_t raw_len,char * raw_data,void * priv)210 static int hinge_capture_sample(struct hid_sensor_hub_device *hsdev,
211 u32 usage_id,
212 size_t raw_len, char *raw_data,
213 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 */
hinge_parse_report(struct platform_device * pdev,struct hid_sensor_hub_device * hsdev,struct iio_chan_spec * channels,u32 usage_id,struct hinge_state * st)236 static int hinge_parse_report(struct platform_device *pdev,
237 struct hid_sensor_hub_device *hsdev,
238 struct iio_chan_spec *channels,
239 u32 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 */
hid_hinge_probe(struct platform_device * pdev)264 static int hid_hinge_probe(struct platform_device *pdev)
265 {
266 struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
267 struct hinge_state *st;
268 struct iio_dev *indio_dev;
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(&pdev->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 */
hid_hinge_remove(struct platform_device * pdev)345 static void hid_hinge_remove(struct platform_device *pdev)
346 {
347 struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
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
356 static const struct platform_device_id hid_hinge_ids[] = {
357 {
358 /* Format: HID-SENSOR-INT-usage_id_in_hex_lowercase */
359 .name = "HID-SENSOR-INT-020b",
360 },
361 { }
362 };
363 MODULE_DEVICE_TABLE(platform, hid_hinge_ids);
364
365 static struct platform_driver hid_hinge_platform_driver = {
366 .id_table = hid_hinge_ids,
367 .driver = {
368 .name = KBUILD_MODNAME,
369 .pm = &hid_sensor_pm_ops,
370 },
371 .probe = hid_hinge_probe,
372 .remove = hid_hinge_remove,
373 };
374 module_platform_driver(hid_hinge_platform_driver);
375
376 MODULE_DESCRIPTION("HID Sensor INTEL Hinge");
377 MODULE_AUTHOR("Ye Xiang <xiang.ye@intel.com>");
378 MODULE_LICENSE("GPL");
379 MODULE_IMPORT_NS("IIO_HID");
380