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