1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * HID Sensors Driver
4  * Copyright (c) 2012, 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 enum {
20 	CHANNEL_SCAN_INDEX_INTENSITY = 0,
21 	CHANNEL_SCAN_INDEX_ILLUM = 1,
22 	CHANNEL_SCAN_INDEX_MAX
23 };
24 
25 #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX
26 
27 struct als_state {
28 	struct hid_sensor_hub_callbacks callbacks;
29 	struct hid_sensor_common common_attributes;
30 	struct hid_sensor_hub_attribute_info als_illum;
31 	struct {
32 		u32 illum[CHANNEL_SCAN_INDEX_MAX];
33 		u64 timestamp __aligned(8);
34 	} scan;
35 	int scale_pre_decml;
36 	int scale_post_decml;
37 	int scale_precision;
38 	int value_offset;
39 	s64 timestamp;
40 };
41 
42 /* Channel definitions */
43 static const struct iio_chan_spec als_channels[] = {
44 	{
45 		.type = IIO_INTENSITY,
46 		.modified = 1,
47 		.channel2 = IIO_MOD_LIGHT_BOTH,
48 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
49 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
50 		BIT(IIO_CHAN_INFO_SCALE) |
51 		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
52 		BIT(IIO_CHAN_INFO_HYSTERESIS),
53 		.scan_index = CHANNEL_SCAN_INDEX_INTENSITY,
54 	},
55 	{
56 		.type = IIO_LIGHT,
57 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
58 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
59 		BIT(IIO_CHAN_INFO_SCALE) |
60 		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
61 		BIT(IIO_CHAN_INFO_HYSTERESIS),
62 		.scan_index = CHANNEL_SCAN_INDEX_ILLUM,
63 	},
64 	IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
65 };
66 
67 /* Adjust channel real bits based on report descriptor */
68 static void als_adjust_channel_bit_mask(struct iio_chan_spec *channels,
69 					int channel, int size)
70 {
71 	channels[channel].scan_type.sign = 's';
72 	/* Real storage bits will change based on the report desc. */
73 	channels[channel].scan_type.realbits = size * 8;
74 	/* Maximum size of a sample to capture is u32 */
75 	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
76 }
77 
78 /* Channel read_raw handler */
79 static int als_read_raw(struct iio_dev *indio_dev,
80 			      struct iio_chan_spec const *chan,
81 			      int *val, int *val2,
82 			      long mask)
83 {
84 	struct als_state *als_state = iio_priv(indio_dev);
85 	int report_id = -1;
86 	u32 address;
87 	int ret_type;
88 	s32 min;
89 
90 	*val = 0;
91 	*val2 = 0;
92 	switch (mask) {
93 	case IIO_CHAN_INFO_RAW:
94 		switch (chan->scan_index) {
95 		case  CHANNEL_SCAN_INDEX_INTENSITY:
96 		case  CHANNEL_SCAN_INDEX_ILLUM:
97 			report_id = als_state->als_illum.report_id;
98 			min = als_state->als_illum.logical_minimum;
99 			address = HID_USAGE_SENSOR_LIGHT_ILLUM;
100 			break;
101 		default:
102 			report_id = -1;
103 			break;
104 		}
105 		if (report_id >= 0) {
106 			hid_sensor_power_state(&als_state->common_attributes,
107 						true);
108 			*val = sensor_hub_input_attr_get_raw_value(
109 					als_state->common_attributes.hsdev,
110 					HID_USAGE_SENSOR_ALS, address,
111 					report_id,
112 					SENSOR_HUB_SYNC,
113 					min < 0);
114 			hid_sensor_power_state(&als_state->common_attributes,
115 						false);
116 		} else {
117 			*val = 0;
118 			return -EINVAL;
119 		}
120 		ret_type = IIO_VAL_INT;
121 		break;
122 	case IIO_CHAN_INFO_SCALE:
123 		*val = als_state->scale_pre_decml;
124 		*val2 = als_state->scale_post_decml;
125 		ret_type = als_state->scale_precision;
126 		break;
127 	case IIO_CHAN_INFO_OFFSET:
128 		*val = als_state->value_offset;
129 		ret_type = IIO_VAL_INT;
130 		break;
131 	case IIO_CHAN_INFO_SAMP_FREQ:
132 		ret_type = hid_sensor_read_samp_freq_value(
133 				&als_state->common_attributes, val, val2);
134 		break;
135 	case IIO_CHAN_INFO_HYSTERESIS:
136 		ret_type = hid_sensor_read_raw_hyst_value(
137 				&als_state->common_attributes, val, val2);
138 		break;
139 	default:
140 		ret_type = -EINVAL;
141 		break;
142 	}
143 
144 	return ret_type;
145 }
146 
147 /* Channel write_raw handler */
148 static int als_write_raw(struct iio_dev *indio_dev,
149 			       struct iio_chan_spec const *chan,
150 			       int val,
151 			       int val2,
152 			       long mask)
153 {
154 	struct als_state *als_state = iio_priv(indio_dev);
155 	int ret = 0;
156 
157 	switch (mask) {
158 	case IIO_CHAN_INFO_SAMP_FREQ:
159 		ret = hid_sensor_write_samp_freq_value(
160 				&als_state->common_attributes, val, val2);
161 		break;
162 	case IIO_CHAN_INFO_HYSTERESIS:
163 		ret = hid_sensor_write_raw_hyst_value(
164 				&als_state->common_attributes, val, val2);
165 		break;
166 	default:
167 		ret = -EINVAL;
168 	}
169 
170 	return ret;
171 }
172 
173 static const struct iio_info als_info = {
174 	.read_raw = &als_read_raw,
175 	.write_raw = &als_write_raw,
176 };
177 
178 /* Callback handler to send event after all samples are received and captured */
179 static int als_proc_event(struct hid_sensor_hub_device *hsdev,
180 				unsigned usage_id,
181 				void *priv)
182 {
183 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
184 	struct als_state *als_state = iio_priv(indio_dev);
185 
186 	dev_dbg(&indio_dev->dev, "als_proc_event\n");
187 	if (atomic_read(&als_state->common_attributes.data_ready)) {
188 		if (!als_state->timestamp)
189 			als_state->timestamp = iio_get_time_ns(indio_dev);
190 
191 		iio_push_to_buffers_with_timestamp(indio_dev, &als_state->scan,
192 						   als_state->timestamp);
193 		als_state->timestamp = 0;
194 	}
195 
196 	return 0;
197 }
198 
199 /* Capture samples in local storage */
200 static int als_capture_sample(struct hid_sensor_hub_device *hsdev,
201 				unsigned usage_id,
202 				size_t raw_len, char *raw_data,
203 				void *priv)
204 {
205 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
206 	struct als_state *als_state = iio_priv(indio_dev);
207 	int ret = -EINVAL;
208 	u32 sample_data = *(u32 *)raw_data;
209 
210 	switch (usage_id) {
211 	case HID_USAGE_SENSOR_LIGHT_ILLUM:
212 		als_state->scan.illum[CHANNEL_SCAN_INDEX_INTENSITY] = sample_data;
213 		als_state->scan.illum[CHANNEL_SCAN_INDEX_ILLUM] = sample_data;
214 		ret = 0;
215 		break;
216 	case HID_USAGE_SENSOR_TIME_TIMESTAMP:
217 		als_state->timestamp = hid_sensor_convert_timestamp(&als_state->common_attributes,
218 								    *(s64 *)raw_data);
219 		break;
220 	default:
221 		break;
222 	}
223 
224 	return ret;
225 }
226 
227 /* Parse report which is specific to an usage id*/
228 static int als_parse_report(struct platform_device *pdev,
229 				struct hid_sensor_hub_device *hsdev,
230 				struct iio_chan_spec *channels,
231 				unsigned usage_id,
232 				struct als_state *st)
233 {
234 	int ret;
235 
236 	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
237 			usage_id,
238 			HID_USAGE_SENSOR_LIGHT_ILLUM,
239 			&st->als_illum);
240 	if (ret < 0)
241 		return ret;
242 	als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_INTENSITY,
243 				    st->als_illum.size);
244 	als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_ILLUM,
245 					st->als_illum.size);
246 
247 	dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index,
248 			st->als_illum.report_id);
249 
250 	st->scale_precision = hid_sensor_format_scale(
251 				HID_USAGE_SENSOR_ALS,
252 				&st->als_illum,
253 				&st->scale_pre_decml, &st->scale_post_decml);
254 
255 	/* Set Sensitivity field ids, when there is no individual modifier */
256 	if (st->common_attributes.sensitivity.index < 0) {
257 		sensor_hub_input_get_attribute_info(hsdev,
258 			HID_FEATURE_REPORT, usage_id,
259 			HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
260 			HID_USAGE_SENSOR_DATA_LIGHT,
261 			&st->common_attributes.sensitivity);
262 		dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
263 			st->common_attributes.sensitivity.index,
264 			st->common_attributes.sensitivity.report_id);
265 	}
266 	return ret;
267 }
268 
269 /* Function to initialize the processing for usage id */
270 static int hid_als_probe(struct platform_device *pdev)
271 {
272 	int ret = 0;
273 	static const char *name = "als";
274 	struct iio_dev *indio_dev;
275 	struct als_state *als_state;
276 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
277 
278 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state));
279 	if (!indio_dev)
280 		return -ENOMEM;
281 	platform_set_drvdata(pdev, indio_dev);
282 
283 	als_state = iio_priv(indio_dev);
284 	als_state->common_attributes.hsdev = hsdev;
285 	als_state->common_attributes.pdev = pdev;
286 
287 	ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_ALS,
288 					&als_state->common_attributes);
289 	if (ret) {
290 		dev_err(&pdev->dev, "failed to setup common attributes\n");
291 		return ret;
292 	}
293 
294 	indio_dev->channels = kmemdup(als_channels,
295 				      sizeof(als_channels), GFP_KERNEL);
296 	if (!indio_dev->channels) {
297 		dev_err(&pdev->dev, "failed to duplicate channels\n");
298 		return -ENOMEM;
299 	}
300 
301 	ret = als_parse_report(pdev, hsdev,
302 			       (struct iio_chan_spec *)indio_dev->channels,
303 			       HID_USAGE_SENSOR_ALS, als_state);
304 	if (ret) {
305 		dev_err(&pdev->dev, "failed to setup attributes\n");
306 		goto error_free_dev_mem;
307 	}
308 
309 	indio_dev->num_channels =
310 				ARRAY_SIZE(als_channels);
311 	indio_dev->info = &als_info;
312 	indio_dev->name = name;
313 	indio_dev->modes = INDIO_DIRECT_MODE;
314 
315 	atomic_set(&als_state->common_attributes.data_ready, 0);
316 
317 	ret = hid_sensor_setup_trigger(indio_dev, name,
318 				&als_state->common_attributes);
319 	if (ret < 0) {
320 		dev_err(&pdev->dev, "trigger setup failed\n");
321 		goto error_free_dev_mem;
322 	}
323 
324 	ret = iio_device_register(indio_dev);
325 	if (ret) {
326 		dev_err(&pdev->dev, "device register failed\n");
327 		goto error_remove_trigger;
328 	}
329 
330 	als_state->callbacks.send_event = als_proc_event;
331 	als_state->callbacks.capture_sample = als_capture_sample;
332 	als_state->callbacks.pdev = pdev;
333 	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ALS,
334 					&als_state->callbacks);
335 	if (ret < 0) {
336 		dev_err(&pdev->dev, "callback reg failed\n");
337 		goto error_iio_unreg;
338 	}
339 
340 	return ret;
341 
342 error_iio_unreg:
343 	iio_device_unregister(indio_dev);
344 error_remove_trigger:
345 	hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
346 error_free_dev_mem:
347 	kfree(indio_dev->channels);
348 	return ret;
349 }
350 
351 /* Function to deinitialize the processing for usage id */
352 static int hid_als_remove(struct platform_device *pdev)
353 {
354 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
355 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
356 	struct als_state *als_state = iio_priv(indio_dev);
357 
358 	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ALS);
359 	iio_device_unregister(indio_dev);
360 	hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
361 	kfree(indio_dev->channels);
362 
363 	return 0;
364 }
365 
366 static const struct platform_device_id hid_als_ids[] = {
367 	{
368 		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
369 		.name = "HID-SENSOR-200041",
370 	},
371 	{ /* sentinel */ }
372 };
373 MODULE_DEVICE_TABLE(platform, hid_als_ids);
374 
375 static struct platform_driver hid_als_platform_driver = {
376 	.id_table = hid_als_ids,
377 	.driver = {
378 		.name	= KBUILD_MODNAME,
379 		.pm	= &hid_sensor_pm_ops,
380 	},
381 	.probe		= hid_als_probe,
382 	.remove		= hid_als_remove,
383 };
384 module_platform_driver(hid_als_platform_driver);
385 
386 MODULE_DESCRIPTION("HID Sensor ALS");
387 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
388 MODULE_LICENSE("GPL");
389