1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2012, Intel Corporation.
6 #include <linux/device.h>
7 #include <linux/platform_device.h>
8 #include <linux/module.h>
9 #include <linux/delay.h>
10 #include <linux/hid-sensor-hub.h>
11 #include <linux/workqueue.h>
12 #include <linux/iio/iio.h>
13 #include <linux/iio/trigger.h>
14 #include <linux/iio/triggered_buffer.h>
15 #include <linux/iio/trigger_consumer.h>
16 #include <linux/iio/sysfs.h>
17 #include "hid-sensor-trigger.h"
19 static ssize_t
_hid_sensor_set_report_latency(struct device
*dev
,
20 struct device_attribute
*attr
,
21 const char *buf
, size_t len
)
23 struct iio_dev
*indio_dev
= dev_to_iio_dev(dev
);
24 struct hid_sensor_common
*attrb
= iio_device_get_drvdata(indio_dev
);
25 int integer
, fract
, ret
;
28 ret
= iio_str_to_fixpoint(buf
, 100000, &integer
, &fract
);
32 latency
= integer
* 1000 + fract
/ 1000;
33 ret
= hid_sensor_set_report_latency(attrb
, latency
);
37 attrb
->latency_ms
= hid_sensor_get_report_latency(attrb
);
42 static ssize_t
_hid_sensor_get_report_latency(struct device
*dev
,
43 struct device_attribute
*attr
,
46 struct iio_dev
*indio_dev
= dev_to_iio_dev(dev
);
47 struct hid_sensor_common
*attrb
= iio_device_get_drvdata(indio_dev
);
50 latency
= hid_sensor_get_report_latency(attrb
);
54 return sprintf(buf
, "%d.%06u\n", latency
/ 1000, (latency
% 1000) * 1000);
57 static ssize_t
_hid_sensor_get_fifo_state(struct device
*dev
,
58 struct device_attribute
*attr
,
61 struct iio_dev
*indio_dev
= dev_to_iio_dev(dev
);
62 struct hid_sensor_common
*attrb
= iio_device_get_drvdata(indio_dev
);
65 latency
= hid_sensor_get_report_latency(attrb
);
69 return sprintf(buf
, "%d\n", !!latency
);
72 static IIO_DEVICE_ATTR(hwfifo_timeout
, 0644,
73 _hid_sensor_get_report_latency
,
74 _hid_sensor_set_report_latency
, 0);
75 static IIO_DEVICE_ATTR(hwfifo_enabled
, 0444,
76 _hid_sensor_get_fifo_state
, NULL
, 0);
78 static const struct iio_dev_attr
*hid_sensor_fifo_attributes
[] = {
79 &iio_dev_attr_hwfifo_timeout
,
80 &iio_dev_attr_hwfifo_enabled
,
84 static int _hid_sensor_power_state(struct hid_sensor_common
*st
, bool state
)
91 if (sensor_hub_device_open(st
->hsdev
))
94 atomic_inc(&st
->data_ready
);
96 state_val
= hid_sensor_get_usage_index(st
->hsdev
,
97 st
->power_state
.report_id
,
98 st
->power_state
.index
,
99 HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM
);
100 report_val
= hid_sensor_get_usage_index(st
->hsdev
,
101 st
->report_state
.report_id
,
102 st
->report_state
.index
,
103 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM
);
105 poll_value
= hid_sensor_read_poll_value(st
);
109 val
= atomic_dec_if_positive(&st
->data_ready
);
113 sensor_hub_device_close(st
->hsdev
);
114 state_val
= hid_sensor_get_usage_index(st
->hsdev
,
115 st
->power_state
.report_id
,
116 st
->power_state
.index
,
117 HID_USAGE_SENSOR_PROP_POWER_STATE_D4_POWER_OFF_ENUM
);
118 report_val
= hid_sensor_get_usage_index(st
->hsdev
,
119 st
->report_state
.report_id
,
120 st
->report_state
.index
,
121 HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM
);
124 if (state_val
>= 0) {
125 state_val
+= st
->power_state
.logical_minimum
;
126 sensor_hub_set_feature(st
->hsdev
, st
->power_state
.report_id
,
127 st
->power_state
.index
, sizeof(state_val
),
131 if (report_val
>= 0) {
132 report_val
+= st
->report_state
.logical_minimum
;
133 sensor_hub_set_feature(st
->hsdev
, st
->report_state
.report_id
,
134 st
->report_state
.index
,
139 pr_debug("HID_SENSOR %s set power_state %d report_state %d\n",
140 st
->pdev
->name
, state_val
, report_val
);
142 sensor_hub_get_feature(st
->hsdev
, st
->power_state
.report_id
,
143 st
->power_state
.index
,
144 sizeof(state_val
), &state_val
);
145 if (state
&& poll_value
)
146 msleep_interruptible(poll_value
* 2);
150 EXPORT_SYMBOL_NS(hid_sensor_power_state
, "IIO_HID");
152 int hid_sensor_power_state(struct hid_sensor_common
*st
, bool state
)
158 if (atomic_add_unless(&st
->runtime_pm_enable
, 1, 1))
159 pm_runtime_enable(&st
->pdev
->dev
);
162 atomic_inc(&st
->user_requested_state
);
163 ret
= pm_runtime_resume_and_get(&st
->pdev
->dev
);
165 atomic_dec(&st
->user_requested_state
);
166 pm_runtime_mark_last_busy(&st
->pdev
->dev
);
167 pm_runtime_use_autosuspend(&st
->pdev
->dev
);
168 ret
= pm_runtime_put_autosuspend(&st
->pdev
->dev
);
175 atomic_set(&st
->user_requested_state
, state
);
176 return _hid_sensor_power_state(st
, state
);
180 static void hid_sensor_set_power_work(struct work_struct
*work
)
182 struct hid_sensor_common
*attrb
= container_of(work
,
183 struct hid_sensor_common
,
186 if (attrb
->poll_interval
>= 0)
187 sensor_hub_set_feature(attrb
->hsdev
, attrb
->poll
.report_id
,
189 sizeof(attrb
->poll_interval
),
190 &attrb
->poll_interval
);
192 if (attrb
->raw_hystersis
>= 0)
193 sensor_hub_set_feature(attrb
->hsdev
,
194 attrb
->sensitivity
.report_id
,
195 attrb
->sensitivity
.index
,
196 sizeof(attrb
->raw_hystersis
),
197 &attrb
->raw_hystersis
);
199 if (attrb
->latency_ms
> 0)
200 hid_sensor_set_report_latency(attrb
, attrb
->latency_ms
);
202 if (atomic_read(&attrb
->user_requested_state
))
203 _hid_sensor_power_state(attrb
, true);
206 static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger
*trig
,
209 return hid_sensor_power_state(iio_trigger_get_drvdata(trig
), state
);
212 void hid_sensor_remove_trigger(struct iio_dev
*indio_dev
,
213 struct hid_sensor_common
*attrb
)
215 if (atomic_read(&attrb
->runtime_pm_enable
))
216 pm_runtime_disable(&attrb
->pdev
->dev
);
218 pm_runtime_set_suspended(&attrb
->pdev
->dev
);
220 cancel_work_sync(&attrb
->work
);
221 iio_trigger_unregister(attrb
->trigger
);
222 iio_trigger_free(attrb
->trigger
);
223 iio_triggered_buffer_cleanup(indio_dev
);
225 EXPORT_SYMBOL_NS(hid_sensor_remove_trigger
, "IIO_HID");
227 static const struct iio_trigger_ops hid_sensor_trigger_ops
= {
228 .set_trigger_state
= &hid_sensor_data_rdy_trigger_set_state
,
231 int hid_sensor_setup_trigger(struct iio_dev
*indio_dev
, const char *name
,
232 struct hid_sensor_common
*attrb
)
234 const struct iio_dev_attr
**fifo_attrs
;
236 struct iio_trigger
*trig
;
238 if (hid_sensor_batch_mode_supported(attrb
))
239 fifo_attrs
= hid_sensor_fifo_attributes
;
243 ret
= iio_triggered_buffer_setup_ext(indio_dev
,
244 &iio_pollfunc_store_time
, NULL
,
245 IIO_BUFFER_DIRECTION_IN
,
248 dev_err(&indio_dev
->dev
, "Triggered Buffer Setup Failed\n");
252 trig
= iio_trigger_alloc(indio_dev
->dev
.parent
,
253 "%s-dev%d", name
, iio_device_id(indio_dev
));
255 dev_err(&indio_dev
->dev
, "Trigger Allocate Failed\n");
257 goto error_triggered_buffer_cleanup
;
260 iio_trigger_set_drvdata(trig
, attrb
);
261 trig
->ops
= &hid_sensor_trigger_ops
;
262 ret
= iio_trigger_register(trig
);
265 dev_err(&indio_dev
->dev
, "Trigger Register Failed\n");
266 goto error_free_trig
;
268 attrb
->trigger
= trig
;
269 indio_dev
->trig
= iio_trigger_get(trig
);
271 ret
= pm_runtime_set_active(&indio_dev
->dev
);
273 goto error_unreg_trigger
;
275 iio_device_set_drvdata(indio_dev
, attrb
);
277 INIT_WORK(&attrb
->work
, hid_sensor_set_power_work
);
279 pm_suspend_ignore_children(&attrb
->pdev
->dev
, true);
280 /* Default to 3 seconds, but can be changed from sysfs */
281 pm_runtime_set_autosuspend_delay(&attrb
->pdev
->dev
,
285 iio_trigger_unregister(trig
);
287 iio_trigger_free(trig
);
288 error_triggered_buffer_cleanup
:
289 iio_triggered_buffer_cleanup(indio_dev
);
292 EXPORT_SYMBOL_NS(hid_sensor_setup_trigger
, "IIO_HID");
294 static int __maybe_unused
hid_sensor_suspend(struct device
*dev
)
296 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
297 struct hid_sensor_common
*attrb
= iio_device_get_drvdata(indio_dev
);
299 return _hid_sensor_power_state(attrb
, false);
302 static int __maybe_unused
hid_sensor_resume(struct device
*dev
)
304 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
305 struct hid_sensor_common
*attrb
= iio_device_get_drvdata(indio_dev
);
306 schedule_work(&attrb
->work
);
310 static int __maybe_unused
hid_sensor_runtime_resume(struct device
*dev
)
312 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
313 struct hid_sensor_common
*attrb
= iio_device_get_drvdata(indio_dev
);
314 return _hid_sensor_power_state(attrb
, true);
317 const struct dev_pm_ops hid_sensor_pm_ops
= {
318 SET_SYSTEM_SLEEP_PM_OPS(hid_sensor_suspend
, hid_sensor_resume
)
319 SET_RUNTIME_PM_OPS(hid_sensor_suspend
,
320 hid_sensor_runtime_resume
, NULL
)
322 EXPORT_SYMBOL_NS(hid_sensor_pm_ops
, "IIO_HID");
324 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
325 MODULE_DESCRIPTION("HID Sensor trigger processing");
326 MODULE_LICENSE("GPL");
327 MODULE_IMPORT_NS("IIO_HID_ATTRIBUTES");