1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * HID Sensors Driver
4 * Copyright (c) 2014, Intel Corporation.
5 */
6 #include <linux/bitops.h>
7 #include <linux/device.h>
8 #include <linux/platform_device.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/hid-sensor-hub.h>
12 #include <linux/iio/iio.h>
13 #include <linux/iio/buffer.h>
14 #include "../common/hid-sensors/hid-sensor-trigger.h"
15
16 enum {
17 CHANNEL_SCAN_INDEX_PRESSURE,
18 CHANNEL_SCAN_INDEX_TIMESTAMP,
19 };
20
21 struct press_state {
22 struct hid_sensor_hub_callbacks callbacks;
23 struct hid_sensor_common common_attributes;
24 struct hid_sensor_hub_attribute_info press_attr;
25 struct {
26 u32 press_data;
27 aligned_s64 timestamp;
28 } scan;
29 int scale_pre_decml;
30 int scale_post_decml;
31 int scale_precision;
32 int value_offset;
33 s64 timestamp;
34 };
35
36 static const u32 press_sensitivity_addresses[] = {
37 HID_USAGE_SENSOR_DATA_ATMOSPHERIC_PRESSURE,
38 HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE
39 };
40
41 /* Channel definitions */
42 static const struct iio_chan_spec press_channels[] = {
43 {
44 .type = IIO_PRESSURE,
45 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
46 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
47 BIT(IIO_CHAN_INFO_SCALE) |
48 BIT(IIO_CHAN_INFO_SAMP_FREQ) |
49 BIT(IIO_CHAN_INFO_HYSTERESIS),
50 .scan_index = CHANNEL_SCAN_INDEX_PRESSURE,
51 },
52 IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
53
54 };
55
56 /* Channel read_raw handler */
press_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)57 static int press_read_raw(struct iio_dev *indio_dev,
58 struct iio_chan_spec const *chan,
59 int *val, int *val2, long mask)
60 {
61 struct press_state *press_state = iio_priv(indio_dev);
62 int report_id = -1;
63 u32 address;
64 int ret_type;
65 s32 min;
66
67 *val = 0;
68 *val2 = 0;
69 switch (mask) {
70 case IIO_CHAN_INFO_RAW:
71 switch (chan->scan_index) {
72 case CHANNEL_SCAN_INDEX_PRESSURE:
73 report_id = press_state->press_attr.report_id;
74 min = press_state->press_attr.logical_minimum;
75 address = HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE;
76 break;
77 default:
78 report_id = -1;
79 break;
80 }
81 if (report_id >= 0) {
82 hid_sensor_power_state(&press_state->common_attributes,
83 true);
84 *val = sensor_hub_input_attr_get_raw_value(
85 press_state->common_attributes.hsdev,
86 HID_USAGE_SENSOR_PRESSURE, address,
87 report_id,
88 SENSOR_HUB_SYNC,
89 min < 0);
90 hid_sensor_power_state(&press_state->common_attributes,
91 false);
92 } else {
93 *val = 0;
94 return -EINVAL;
95 }
96 ret_type = IIO_VAL_INT;
97 break;
98 case IIO_CHAN_INFO_SCALE:
99 *val = press_state->scale_pre_decml;
100 *val2 = press_state->scale_post_decml;
101 ret_type = press_state->scale_precision;
102 break;
103 case IIO_CHAN_INFO_OFFSET:
104 *val = press_state->value_offset;
105 ret_type = IIO_VAL_INT;
106 break;
107 case IIO_CHAN_INFO_SAMP_FREQ:
108 ret_type = hid_sensor_read_samp_freq_value(
109 &press_state->common_attributes, val, val2);
110 break;
111 case IIO_CHAN_INFO_HYSTERESIS:
112 ret_type = hid_sensor_read_raw_hyst_value(
113 &press_state->common_attributes, val, val2);
114 break;
115 default:
116 ret_type = -EINVAL;
117 break;
118 }
119
120 return ret_type;
121 }
122
123 /* Channel write_raw handler */
press_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)124 static int press_write_raw(struct iio_dev *indio_dev,
125 struct iio_chan_spec const *chan,
126 int val, int val2, long mask)
127 {
128 struct press_state *press_state = iio_priv(indio_dev);
129 int ret = 0;
130
131 switch (mask) {
132 case IIO_CHAN_INFO_SAMP_FREQ:
133 ret = hid_sensor_write_samp_freq_value(
134 &press_state->common_attributes, val, val2);
135 break;
136 case IIO_CHAN_INFO_HYSTERESIS:
137 ret = hid_sensor_write_raw_hyst_value(
138 &press_state->common_attributes, val, val2);
139 break;
140 default:
141 ret = -EINVAL;
142 }
143
144 return ret;
145 }
146
147 static const struct iio_info press_info = {
148 .read_raw = &press_read_raw,
149 .write_raw = &press_write_raw,
150 };
151
152 /* Callback handler to send event after all samples are received and captured */
press_proc_event(struct hid_sensor_hub_device * hsdev,u32 usage_id,void * priv)153 static int press_proc_event(struct hid_sensor_hub_device *hsdev,
154 u32 usage_id, void *priv)
155 {
156 struct iio_dev *indio_dev = platform_get_drvdata(priv);
157 struct press_state *press_state = iio_priv(indio_dev);
158
159 dev_dbg(&indio_dev->dev, "press_proc_event\n");
160 if (atomic_read(&press_state->common_attributes.data_ready)) {
161 if (!press_state->timestamp)
162 press_state->timestamp = iio_get_time_ns(indio_dev);
163
164 iio_push_to_buffers_with_ts(indio_dev, &press_state->scan,
165 sizeof(press_state->scan),
166 press_state->timestamp);
167 }
168
169 return 0;
170 }
171
172 /* Capture samples in local storage */
press_capture_sample(struct hid_sensor_hub_device * hsdev,u32 usage_id,size_t raw_len,char * raw_data,void * priv)173 static int press_capture_sample(struct hid_sensor_hub_device *hsdev,
174 u32 usage_id,
175 size_t raw_len, char *raw_data,
176 void *priv)
177 {
178 struct iio_dev *indio_dev = platform_get_drvdata(priv);
179 struct press_state *press_state = iio_priv(indio_dev);
180 int ret = -EINVAL;
181
182 switch (usage_id) {
183 case HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE:
184 press_state->scan.press_data = *(u32 *)raw_data;
185 ret = 0;
186 break;
187 case HID_USAGE_SENSOR_TIME_TIMESTAMP:
188 press_state->timestamp = hid_sensor_convert_timestamp(
189 &press_state->common_attributes, *(s64 *)raw_data);
190 break;
191 default:
192 break;
193 }
194
195 return ret;
196 }
197
198 /* Parse report which is specific to an usage id*/
press_parse_report(struct platform_device * pdev,struct hid_sensor_hub_device * hsdev,struct iio_chan_spec * channels,u32 usage_id,struct press_state * st)199 static int press_parse_report(struct platform_device *pdev,
200 struct hid_sensor_hub_device *hsdev,
201 struct iio_chan_spec *channels,
202 u32 usage_id,
203 struct press_state *st)
204 {
205 int ret;
206
207 ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
208 usage_id,
209 HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE,
210 &st->press_attr);
211 if (ret < 0)
212 return ret;
213 channels[CHANNEL_SCAN_INDEX_PRESSURE].scan_type = (struct iio_scan_type) {
214 .format = 's',
215 .realbits = BYTES_TO_BITS(st->press_attr.size),
216 .storagebits = BITS_PER_TYPE(u32),
217 };
218
219 dev_dbg(&pdev->dev, "press %x:%x\n", st->press_attr.index,
220 st->press_attr.report_id);
221
222 st->scale_precision = hid_sensor_format_scale(
223 HID_USAGE_SENSOR_PRESSURE,
224 &st->press_attr,
225 &st->scale_pre_decml, &st->scale_post_decml);
226
227 return ret;
228 }
229
230 /* Function to initialize the processing for usage id */
hid_press_probe(struct platform_device * pdev)231 static int hid_press_probe(struct platform_device *pdev)
232 {
233 struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
234 int ret = 0;
235 static const char *name = "press";
236 struct iio_dev *indio_dev;
237 struct press_state *press_state;
238
239 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct press_state));
240 if (!indio_dev)
241 return -ENOMEM;
242 platform_set_drvdata(pdev, indio_dev);
243
244 press_state = iio_priv(indio_dev);
245 press_state->common_attributes.hsdev = hsdev;
246 press_state->common_attributes.pdev = pdev;
247
248 ret = hid_sensor_parse_common_attributes(hsdev,
249 HID_USAGE_SENSOR_PRESSURE,
250 &press_state->common_attributes,
251 press_sensitivity_addresses,
252 ARRAY_SIZE(press_sensitivity_addresses));
253 if (ret) {
254 dev_err(&pdev->dev, "failed to setup common attributes\n");
255 return ret;
256 }
257
258 indio_dev->channels = devm_kmemdup(&pdev->dev, press_channels,
259 sizeof(press_channels), GFP_KERNEL);
260 if (!indio_dev->channels) {
261 dev_err(&pdev->dev, "failed to duplicate channels\n");
262 return -ENOMEM;
263 }
264
265 ret = press_parse_report(pdev, hsdev,
266 (struct iio_chan_spec *)indio_dev->channels,
267 HID_USAGE_SENSOR_PRESSURE, press_state);
268 if (ret) {
269 dev_err(&pdev->dev, "failed to setup attributes\n");
270 return ret;
271 }
272
273 indio_dev->num_channels =
274 ARRAY_SIZE(press_channels);
275 indio_dev->info = &press_info;
276 indio_dev->name = name;
277 indio_dev->modes = INDIO_DIRECT_MODE;
278
279 atomic_set(&press_state->common_attributes.data_ready, 0);
280
281 ret = hid_sensor_setup_trigger(indio_dev, name,
282 &press_state->common_attributes);
283 if (ret) {
284 dev_err(&pdev->dev, "trigger setup failed\n");
285 return ret;
286 }
287
288 press_state->callbacks.send_event = press_proc_event;
289 press_state->callbacks.capture_sample = press_capture_sample;
290 press_state->callbacks.pdev = pdev;
291 ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_PRESSURE,
292 &press_state->callbacks);
293 if (ret < 0) {
294 dev_err(&pdev->dev, "callback reg failed\n");
295 goto error_remove_trigger;
296 }
297
298 ret = iio_device_register(indio_dev);
299 if (ret) {
300 dev_err(&pdev->dev, "device register failed\n");
301 goto error_remove_callback;
302 }
303
304 return ret;
305
306 error_remove_callback:
307 sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
308 error_remove_trigger:
309 hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
310 return ret;
311 }
312
313 /* Function to deinitialize the processing for usage id */
hid_press_remove(struct platform_device * pdev)314 static void hid_press_remove(struct platform_device *pdev)
315 {
316 struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
317 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
318 struct press_state *press_state = iio_priv(indio_dev);
319
320 iio_device_unregister(indio_dev);
321 sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
322 hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
323 }
324
325 static const struct platform_device_id hid_press_ids[] = {
326 {
327 /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
328 .name = "HID-SENSOR-200031",
329 },
330 { }
331 };
332 MODULE_DEVICE_TABLE(platform, hid_press_ids);
333
334 static struct platform_driver hid_press_platform_driver = {
335 .id_table = hid_press_ids,
336 .driver = {
337 .name = KBUILD_MODNAME,
338 .pm = &hid_sensor_pm_ops,
339 },
340 .probe = hid_press_probe,
341 .remove = hid_press_remove,
342 };
343 module_platform_driver(hid_press_platform_driver);
344
345 MODULE_DESCRIPTION("HID Sensor Pressure");
346 MODULE_AUTHOR("Archana Patni <archana.patni@intel.com>");
347 MODULE_LICENSE("GPL");
348 MODULE_IMPORT_NS("IIO_HID");
349