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