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