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