1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2020, Intel Corporation.
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>
13 #include "../common/hid-sensors/hid-sensor-trigger.h"
16 CHANNEL_SCAN_INDEX_HINGE_ANGLE
,
17 CHANNEL_SCAN_INDEX_SCREEN_ANGLE
,
18 CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE
,
19 CHANNEL_SCAN_INDEX_MAX
,
22 #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX
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)
30 static const char *const hinge_labels
[CHANNEL_SCAN_INDEX_MAX
] = { "hinge",
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
];
42 aligned_s64 timestamp
;
52 static const u32 hinge_sensitivity_addresses
[] = {
53 HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
56 /* Channel definitions */
57 static const struct iio_chan_spec hinge_channels
[] = {
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
,
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
,
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
,
98 IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP
)
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
)
105 channels
[channel
].scan_type
.realbits
= size
* 8;
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
,
113 struct hinge_state
*st
= iio_priv(indio_dev
);
114 struct hid_sensor_hub_device
*hsdev
;
118 hsdev
= st
->common_attributes
.hsdev
;
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
;
125 hid_sensor_power_state(&st
->common_attributes
, false);
129 *val
= sensor_hub_input_attr_get_raw_value(st
->common_attributes
.hsdev
,
131 hinge_addresses
[chan
->scan_index
],
133 SENSOR_HUB_SYNC
, min
< 0);
135 hid_sensor_power_state(&st
->common_attributes
, false);
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
;
144 case IIO_CHAN_INFO_SAMP_FREQ
:
145 return hid_sensor_read_samp_freq_value(&st
->common_attributes
,
147 case IIO_CHAN_INFO_HYSTERESIS
:
148 return hid_sensor_read_raw_hyst_value(&st
->common_attributes
,
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
,
160 struct hinge_state
*st
= iio_priv(indio_dev
);
163 case IIO_CHAN_INFO_SAMP_FREQ
:
164 return hid_sensor_write_samp_freq_value(&st
->common_attributes
,
166 case IIO_CHAN_INFO_HYSTERESIS
:
167 return hid_sensor_write_raw_hyst_value(&st
->common_attributes
,
174 static int hinge_read_label(struct iio_dev
*indio_dev
,
175 struct iio_chan_spec
const *chan
, char *label
)
177 struct hinge_state
*st
= iio_priv(indio_dev
);
179 return sprintf(label
, "%s\n", st
->labels
[chan
->channel
]);
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
,
189 * Callback handler to send event after all samples are received
192 static int hinge_proc_event(struct hid_sensor_hub_device
*hsdev
,
193 unsigned int usage_id
, void *priv
)
195 struct iio_dev
*indio_dev
= platform_get_drvdata(priv
);
196 struct hinge_state
*st
= iio_priv(indio_dev
);
198 if (atomic_read(&st
->common_attributes
.data_ready
)) {
200 st
->timestamp
= iio_get_time_ns(indio_dev
);
202 iio_push_to_buffers_with_timestamp(indio_dev
, &st
->scan
,
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
)
215 struct iio_dev
*indio_dev
= platform_get_drvdata(priv
);
216 struct hinge_state
*st
= iio_priv(indio_dev
);
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
;
226 case HID_USAGE_SENSOR_TIME_TIMESTAMP
:
227 st
->timestamp
= hid_sensor_convert_timestamp(&st
->common_attributes
,
228 *(int64_t *)raw_data
);
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
)
244 for (i
= 0; i
< CHANNEL_SCAN_INDEX_MAX
; ++i
) {
245 ret
= sensor_hub_input_get_attribute_info(hsdev
,
253 hinge_adjust_channel_realbits(channels
, i
, st
->hinge
[i
].size
);
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
);
263 /* Function to initialize the processing for usage id */
264 static int hid_hinge_probe(struct platform_device
*pdev
)
266 struct hid_sensor_hub_device
*hsdev
= dev_get_platdata(&pdev
->dev
);
267 struct hinge_state
*st
;
268 struct iio_dev
*indio_dev
;
272 indio_dev
= devm_iio_device_alloc(&pdev
->dev
, sizeof(*st
));
276 platform_set_drvdata(pdev
, indio_dev
);
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
];
285 ret
= hid_sensor_parse_common_attributes(hsdev
, hsdev
->usage
,
286 &st
->common_attributes
,
287 hinge_sensitivity_addresses
,
288 ARRAY_SIZE(hinge_sensitivity_addresses
));
290 dev_err(&pdev
->dev
, "failed to setup common attributes\n");
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
)
300 ret
= hinge_parse_report(pdev
, hsdev
,
301 (struct iio_chan_spec
*)indio_dev
->channels
,
304 dev_err(&pdev
->dev
, "failed to setup attributes\n");
308 indio_dev
->info
= &hinge_info
;
309 indio_dev
->name
= "hinge";
310 indio_dev
->modes
= INDIO_DIRECT_MODE
;
312 atomic_set(&st
->common_attributes
.data_ready
, 0);
313 ret
= hid_sensor_setup_trigger(indio_dev
, indio_dev
->name
,
314 &st
->common_attributes
);
316 dev_err(&pdev
->dev
, "trigger setup failed\n");
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
);
325 dev_err(&pdev
->dev
, "callback reg failed\n");
326 goto error_remove_trigger
;
329 ret
= iio_device_register(indio_dev
);
331 dev_err(&pdev
->dev
, "device register failed\n");
332 goto error_remove_callback
;
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
);
344 /* Function to deinitialize the processing for usage id */
345 static void hid_hinge_remove(struct platform_device
*pdev
)
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
);
351 iio_device_unregister(indio_dev
);
352 sensor_hub_remove_callback(hsdev
, hsdev
->usage
);
353 hid_sensor_remove_trigger(indio_dev
, &st
->common_attributes
);
356 static const struct platform_device_id hid_hinge_ids
[] = {
358 /* Format: HID-SENSOR-INT-usage_id_in_hex_lowercase */
359 .name
= "HID-SENSOR-INT-020b",
363 MODULE_DEVICE_TABLE(platform
, hid_hinge_ids
);
365 static struct platform_driver hid_hinge_platform_driver
= {
366 .id_table
= hid_hinge_ids
,
368 .name
= KBUILD_MODNAME
,
369 .pm
= &hid_sensor_pm_ops
,
371 .probe
= hid_hinge_probe
,
372 .remove
= hid_hinge_remove
,
374 module_platform_driver(hid_hinge_platform_driver
);
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");