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