3 * Copyright (c) 2014, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include <linux/device.h>
16 #include <linux/platform_device.h>
17 #include <linux/module.h>
18 #include <linux/interrupt.h>
19 #include <linux/irq.h>
20 #include <linux/slab.h>
21 #include <linux/hid-sensor-hub.h>
22 #include <linux/iio/iio.h>
23 #include <linux/iio/sysfs.h>
24 #include <linux/iio/buffer.h>
25 #include <linux/iio/trigger_consumer.h>
26 #include <linux/iio/triggered_buffer.h>
27 #include "../common/hid-sensors/hid-sensor-trigger.h"
29 struct dev_rot_state
{
30 struct hid_sensor_hub_callbacks callbacks
;
31 struct hid_sensor_common common_attributes
;
32 struct hid_sensor_hub_attribute_info quaternion
;
36 /* Channel definitions */
37 static const struct iio_chan_spec dev_rot_channels
[] = {
41 .channel2
= IIO_MOD_QUATERNION
,
42 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
43 .info_mask_shared_by_type
= BIT(IIO_CHAN_INFO_SAMP_FREQ
) |
44 BIT(IIO_CHAN_INFO_HYSTERESIS
)
48 /* Adjust channel real bits based on report descriptor */
49 static void dev_rot_adjust_channel_bit_mask(struct iio_chan_spec
*chan
,
52 chan
->scan_type
.sign
= 's';
53 /* Real storage bits will change based on the report desc. */
54 chan
->scan_type
.realbits
= size
* 8;
55 /* Maximum size of a sample to capture is u32 */
56 chan
->scan_type
.storagebits
= sizeof(u32
) * 8;
57 chan
->scan_type
.repeat
= 4;
60 /* Channel read_raw handler */
61 static int dev_rot_read_raw(struct iio_dev
*indio_dev
,
62 struct iio_chan_spec
const *chan
,
63 int size
, int *vals
, int *val_len
,
66 struct dev_rot_state
*rot_state
= iio_priv(indio_dev
);
74 case IIO_CHAN_INFO_RAW
:
76 for (i
= 0; i
< 4; ++i
)
77 vals
[i
] = rot_state
->sampled_vals
[i
];
78 ret_type
= IIO_VAL_INT_MULTIPLE
;
83 case IIO_CHAN_INFO_SAMP_FREQ
:
84 ret_type
= hid_sensor_read_samp_freq_value(
85 &rot_state
->common_attributes
, &vals
[0], &vals
[1]);
87 case IIO_CHAN_INFO_HYSTERESIS
:
88 ret_type
= hid_sensor_read_raw_hyst_value(
89 &rot_state
->common_attributes
, &vals
[0], &vals
[1]);
99 /* Channel write_raw handler */
100 static int dev_rot_write_raw(struct iio_dev
*indio_dev
,
101 struct iio_chan_spec
const *chan
,
106 struct dev_rot_state
*rot_state
= iio_priv(indio_dev
);
110 case IIO_CHAN_INFO_SAMP_FREQ
:
111 ret
= hid_sensor_write_samp_freq_value(
112 &rot_state
->common_attributes
, val
, val2
);
114 case IIO_CHAN_INFO_HYSTERESIS
:
115 ret
= hid_sensor_write_raw_hyst_value(
116 &rot_state
->common_attributes
, val
, val2
);
125 static const struct iio_info dev_rot_info
= {
126 .driver_module
= THIS_MODULE
,
127 .read_raw_multi
= &dev_rot_read_raw
,
128 .write_raw
= &dev_rot_write_raw
,
131 /* Function to push data to buffer */
132 static void hid_sensor_push_data(struct iio_dev
*indio_dev
, u8
*data
, int len
)
134 dev_dbg(&indio_dev
->dev
, "hid_sensor_push_data >>\n");
135 iio_push_to_buffers(indio_dev
, (u8
*)data
);
136 dev_dbg(&indio_dev
->dev
, "hid_sensor_push_data <<\n");
140 /* Callback handler to send event after all samples are received and captured */
141 static int dev_rot_proc_event(struct hid_sensor_hub_device
*hsdev
,
145 struct iio_dev
*indio_dev
= platform_get_drvdata(priv
);
146 struct dev_rot_state
*rot_state
= iio_priv(indio_dev
);
148 dev_dbg(&indio_dev
->dev
, "dev_rot_proc_event\n");
149 if (atomic_read(&rot_state
->common_attributes
.data_ready
))
150 hid_sensor_push_data(indio_dev
,
151 (u8
*)rot_state
->sampled_vals
,
152 sizeof(rot_state
->sampled_vals
));
157 /* Capture samples in local storage */
158 static int dev_rot_capture_sample(struct hid_sensor_hub_device
*hsdev
,
160 size_t raw_len
, char *raw_data
,
163 struct iio_dev
*indio_dev
= platform_get_drvdata(priv
);
164 struct dev_rot_state
*rot_state
= iio_priv(indio_dev
);
166 if (usage_id
== HID_USAGE_SENSOR_ORIENT_QUATERNION
) {
167 memcpy(rot_state
->sampled_vals
, raw_data
,
168 sizeof(rot_state
->sampled_vals
));
169 dev_dbg(&indio_dev
->dev
, "Recd Quat len:%zu::%zu\n", raw_len
,
170 sizeof(rot_state
->sampled_vals
));
176 /* Parse report which is specific to an usage id*/
177 static int dev_rot_parse_report(struct platform_device
*pdev
,
178 struct hid_sensor_hub_device
*hsdev
,
179 struct iio_chan_spec
*channels
,
181 struct dev_rot_state
*st
)
185 ret
= sensor_hub_input_get_attribute_info(hsdev
,
188 HID_USAGE_SENSOR_ORIENT_QUATERNION
,
193 dev_rot_adjust_channel_bit_mask(&channels
[0],
194 st
->quaternion
.size
/ 4);
196 dev_dbg(&pdev
->dev
, "dev_rot %x:%x\n", st
->quaternion
.index
,
197 st
->quaternion
.report_id
);
199 dev_dbg(&pdev
->dev
, "dev_rot: attrib size %d\n",
200 st
->quaternion
.size
);
202 /* Set Sensitivity field ids, when there is no individual modifier */
203 if (st
->common_attributes
.sensitivity
.index
< 0) {
204 sensor_hub_input_get_attribute_info(hsdev
,
205 HID_FEATURE_REPORT
, usage_id
,
206 HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS
|
207 HID_USAGE_SENSOR_DATA_ORIENTATION
,
208 &st
->common_attributes
.sensitivity
);
209 dev_dbg(&pdev
->dev
, "Sensitivity index:report %d:%d\n",
210 st
->common_attributes
.sensitivity
.index
,
211 st
->common_attributes
.sensitivity
.report_id
);
217 /* Function to initialize the processing for usage id */
218 static int hid_dev_rot_probe(struct platform_device
*pdev
)
221 static char *name
= "dev_rotation";
222 struct iio_dev
*indio_dev
;
223 struct dev_rot_state
*rot_state
;
224 struct hid_sensor_hub_device
*hsdev
= pdev
->dev
.platform_data
;
226 indio_dev
= devm_iio_device_alloc(&pdev
->dev
,
227 sizeof(struct dev_rot_state
));
228 if (indio_dev
== NULL
)
231 platform_set_drvdata(pdev
, indio_dev
);
233 rot_state
= iio_priv(indio_dev
);
234 rot_state
->common_attributes
.hsdev
= hsdev
;
235 rot_state
->common_attributes
.pdev
= pdev
;
237 ret
= hid_sensor_parse_common_attributes(hsdev
,
238 HID_USAGE_SENSOR_DEVICE_ORIENTATION
,
239 &rot_state
->common_attributes
);
241 dev_err(&pdev
->dev
, "failed to setup common attributes\n");
245 indio_dev
->channels
= devm_kmemdup(&pdev
->dev
, dev_rot_channels
,
246 sizeof(dev_rot_channels
),
248 if (!indio_dev
->channels
) {
249 dev_err(&pdev
->dev
, "failed to duplicate channels\n");
253 ret
= dev_rot_parse_report(pdev
, hsdev
,
254 (struct iio_chan_spec
*)indio_dev
->channels
,
255 HID_USAGE_SENSOR_DEVICE_ORIENTATION
,
258 dev_err(&pdev
->dev
, "failed to setup attributes\n");
262 indio_dev
->num_channels
= ARRAY_SIZE(dev_rot_channels
);
263 indio_dev
->dev
.parent
= &pdev
->dev
;
264 indio_dev
->info
= &dev_rot_info
;
265 indio_dev
->name
= name
;
266 indio_dev
->modes
= INDIO_DIRECT_MODE
;
268 ret
= iio_triggered_buffer_setup(indio_dev
, &iio_pollfunc_store_time
,
271 dev_err(&pdev
->dev
, "failed to initialize trigger buffer\n");
274 atomic_set(&rot_state
->common_attributes
.data_ready
, 0);
275 ret
= hid_sensor_setup_trigger(indio_dev
, name
,
276 &rot_state
->common_attributes
);
278 dev_err(&pdev
->dev
, "trigger setup failed\n");
279 goto error_unreg_buffer_funcs
;
282 ret
= iio_device_register(indio_dev
);
284 dev_err(&pdev
->dev
, "device register failed\n");
285 goto error_remove_trigger
;
288 rot_state
->callbacks
.send_event
= dev_rot_proc_event
;
289 rot_state
->callbacks
.capture_sample
= dev_rot_capture_sample
;
290 rot_state
->callbacks
.pdev
= pdev
;
291 ret
= sensor_hub_register_callback(hsdev
,
292 HID_USAGE_SENSOR_DEVICE_ORIENTATION
,
293 &rot_state
->callbacks
);
295 dev_err(&pdev
->dev
, "callback reg failed\n");
296 goto error_iio_unreg
;
302 iio_device_unregister(indio_dev
);
303 error_remove_trigger
:
304 hid_sensor_remove_trigger(&rot_state
->common_attributes
);
305 error_unreg_buffer_funcs
:
306 iio_triggered_buffer_cleanup(indio_dev
);
310 /* Function to deinitialize the processing for usage id */
311 static int hid_dev_rot_remove(struct platform_device
*pdev
)
313 struct hid_sensor_hub_device
*hsdev
= pdev
->dev
.platform_data
;
314 struct iio_dev
*indio_dev
= platform_get_drvdata(pdev
);
315 struct dev_rot_state
*rot_state
= iio_priv(indio_dev
);
317 sensor_hub_remove_callback(hsdev
, HID_USAGE_SENSOR_DEVICE_ORIENTATION
);
318 iio_device_unregister(indio_dev
);
319 hid_sensor_remove_trigger(&rot_state
->common_attributes
);
320 iio_triggered_buffer_cleanup(indio_dev
);
325 static const struct platform_device_id hid_dev_rot_ids
[] = {
327 /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
328 .name
= "HID-SENSOR-20008a",
332 MODULE_DEVICE_TABLE(platform
, hid_dev_rot_ids
);
334 static struct platform_driver hid_dev_rot_platform_driver
= {
335 .id_table
= hid_dev_rot_ids
,
337 .name
= KBUILD_MODNAME
,
339 .probe
= hid_dev_rot_probe
,
340 .remove
= hid_dev_rot_remove
,
342 module_platform_driver(hid_dev_rot_platform_driver
);
344 MODULE_DESCRIPTION("HID Sensor Device Rotation");
345 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
346 MODULE_LICENSE("GPL");