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