Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * HID Sensors Driver
0004  * Copyright (c) 2020, Intel Corporation.
0005  */
0006 #include <linux/hid-sensor-hub.h>
0007 #include <linux/iio/buffer.h>
0008 #include <linux/iio/iio.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/module.h>
0011 #include <linux/mod_devicetable.h>
0012 
0013 #include "../common/hid-sensors/hid-sensor-trigger.h"
0014 
0015 enum hinge_channel {
0016     CHANNEL_SCAN_INDEX_HINGE_ANGLE,
0017     CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
0018     CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
0019     CHANNEL_SCAN_INDEX_MAX,
0020 };
0021 
0022 #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX
0023 
0024 static const u32 hinge_addresses[CHANNEL_SCAN_INDEX_MAX] = {
0025     HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
0026     HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2),
0027     HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3)
0028 };
0029 
0030 static const char *const hinge_labels[CHANNEL_SCAN_INDEX_MAX] = { "hinge",
0031                                   "screen",
0032                                   "keyboard" };
0033 
0034 struct hinge_state {
0035     struct iio_dev *indio_dev;
0036     struct hid_sensor_hub_attribute_info hinge[CHANNEL_SCAN_INDEX_MAX];
0037     struct hid_sensor_hub_callbacks callbacks;
0038     struct hid_sensor_common common_attributes;
0039     const char *labels[CHANNEL_SCAN_INDEX_MAX];
0040     struct {
0041         u32 hinge_val[3];
0042         u64 timestamp __aligned(8);
0043     } scan;
0044 
0045     int scale_pre_decml;
0046     int scale_post_decml;
0047     int scale_precision;
0048     int value_offset;
0049     u64 timestamp;
0050 };
0051 
0052 static const u32 hinge_sensitivity_addresses[] = {
0053     HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
0054 };
0055 
0056 /* Channel definitions */
0057 static const struct iio_chan_spec hinge_channels[] = {
0058     {
0059         .type = IIO_ANGL,
0060         .indexed = 1,
0061         .channel = 0,
0062         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0063         .info_mask_shared_by_type =
0064             BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
0065             BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
0066         .scan_index = CHANNEL_SCAN_INDEX_HINGE_ANGLE,
0067         .scan_type = {
0068             .sign = 's',
0069             .storagebits = 32,
0070         },
0071     }, {
0072         .type = IIO_ANGL,
0073         .indexed = 1,
0074         .channel = 1,
0075         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0076         .info_mask_shared_by_type =
0077             BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
0078             BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
0079         .scan_index = CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
0080         .scan_type = {
0081             .sign = 's',
0082             .storagebits = 32,
0083         },
0084     }, {
0085         .type = IIO_ANGL,
0086         .indexed = 1,
0087         .channel = 2,
0088         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0089         .info_mask_shared_by_type =
0090             BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
0091             BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
0092         .scan_index = CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
0093         .scan_type = {
0094             .sign = 's',
0095             .storagebits = 32,
0096         },
0097     },
0098     IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
0099 };
0100 
0101 /* Adjust channel real bits based on report descriptor */
0102 static void hinge_adjust_channel_realbits(struct iio_chan_spec *channels,
0103                       int channel, int size)
0104 {
0105     channels[channel].scan_type.realbits = size * 8;
0106 }
0107 
0108 /* Channel read_raw handler */
0109 static int hinge_read_raw(struct iio_dev *indio_dev,
0110               struct iio_chan_spec const *chan, int *val, int *val2,
0111               long mask)
0112 {
0113     struct hinge_state *st = iio_priv(indio_dev);
0114     struct hid_sensor_hub_device *hsdev;
0115     int report_id;
0116     s32 min;
0117 
0118     hsdev = st->common_attributes.hsdev;
0119     switch (mask) {
0120     case IIO_CHAN_INFO_RAW:
0121         hid_sensor_power_state(&st->common_attributes, true);
0122         report_id = st->hinge[chan->scan_index].report_id;
0123         min = st->hinge[chan->scan_index].logical_minimum;
0124         if (report_id < 0) {
0125             hid_sensor_power_state(&st->common_attributes, false);
0126             return -EINVAL;
0127         }
0128 
0129         *val = sensor_hub_input_attr_get_raw_value(st->common_attributes.hsdev,
0130                                hsdev->usage,
0131                                hinge_addresses[chan->scan_index],
0132                                report_id,
0133                                SENSOR_HUB_SYNC, min < 0);
0134 
0135         hid_sensor_power_state(&st->common_attributes, false);
0136         return IIO_VAL_INT;
0137     case IIO_CHAN_INFO_SCALE:
0138         *val = st->scale_pre_decml;
0139         *val2 = st->scale_post_decml;
0140         return st->scale_precision;
0141     case IIO_CHAN_INFO_OFFSET:
0142         *val = st->value_offset;
0143         return IIO_VAL_INT;
0144     case IIO_CHAN_INFO_SAMP_FREQ:
0145         return hid_sensor_read_samp_freq_value(&st->common_attributes,
0146                                val, val2);
0147     case IIO_CHAN_INFO_HYSTERESIS:
0148         return hid_sensor_read_raw_hyst_value(&st->common_attributes,
0149                               val, val2);
0150     default:
0151         return -EINVAL;
0152     }
0153 }
0154 
0155 /* Channel write_raw handler */
0156 static int hinge_write_raw(struct iio_dev *indio_dev,
0157                struct iio_chan_spec const *chan, int val, int val2,
0158                long mask)
0159 {
0160     struct hinge_state *st = iio_priv(indio_dev);
0161 
0162     switch (mask) {
0163     case IIO_CHAN_INFO_SAMP_FREQ:
0164         return hid_sensor_write_samp_freq_value(&st->common_attributes,
0165                             val, val2);
0166     case IIO_CHAN_INFO_HYSTERESIS:
0167         return hid_sensor_write_raw_hyst_value(&st->common_attributes,
0168                                val, val2);
0169     default:
0170         return -EINVAL;
0171     }
0172 }
0173 
0174 static int hinge_read_label(struct iio_dev *indio_dev,
0175                 struct iio_chan_spec const *chan, char *label)
0176 {
0177     struct hinge_state *st = iio_priv(indio_dev);
0178 
0179     return sprintf(label, "%s\n", st->labels[chan->channel]);
0180 }
0181 
0182 static const struct iio_info hinge_info = {
0183     .read_raw = hinge_read_raw,
0184     .write_raw = hinge_write_raw,
0185     .read_label = hinge_read_label,
0186 };
0187 
0188 /*
0189  * Callback handler to send event after all samples are received
0190  * and captured.
0191  */
0192 static int hinge_proc_event(struct hid_sensor_hub_device *hsdev,
0193                 unsigned int usage_id, void *priv)
0194 {
0195     struct iio_dev *indio_dev = platform_get_drvdata(priv);
0196     struct hinge_state *st = iio_priv(indio_dev);
0197 
0198     if (atomic_read(&st->common_attributes.data_ready)) {
0199         if (!st->timestamp)
0200             st->timestamp = iio_get_time_ns(indio_dev);
0201 
0202         iio_push_to_buffers_with_timestamp(indio_dev, &st->scan,
0203                            st->timestamp);
0204 
0205         st->timestamp = 0;
0206     }
0207     return 0;
0208 }
0209 
0210 /* Capture samples in local storage */
0211 static int hinge_capture_sample(struct hid_sensor_hub_device *hsdev,
0212                 unsigned int usage_id, size_t raw_len,
0213                 char *raw_data, void *priv)
0214 {
0215     struct iio_dev *indio_dev = platform_get_drvdata(priv);
0216     struct hinge_state *st = iio_priv(indio_dev);
0217     int offset;
0218 
0219     switch (usage_id) {
0220     case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1):
0221     case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2):
0222     case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3):
0223         offset = usage_id - HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1);
0224         st->scan.hinge_val[offset] = *(u32 *)raw_data;
0225         return 0;
0226     case HID_USAGE_SENSOR_TIME_TIMESTAMP:
0227         st->timestamp = hid_sensor_convert_timestamp(&st->common_attributes,
0228                                  *(int64_t *)raw_data);
0229         return 0;
0230     default:
0231         return -EINVAL;
0232     }
0233 }
0234 
0235 /* Parse report which is specific to an usage id */
0236 static int hinge_parse_report(struct platform_device *pdev,
0237                   struct hid_sensor_hub_device *hsdev,
0238                   struct iio_chan_spec *channels,
0239                   unsigned int usage_id, struct hinge_state *st)
0240 {
0241     int ret;
0242     int i;
0243 
0244     for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; ++i) {
0245         ret = sensor_hub_input_get_attribute_info(hsdev,
0246                               HID_INPUT_REPORT,
0247                               usage_id,
0248                               hinge_addresses[i],
0249                               &st->hinge[i]);
0250         if (ret < 0)
0251             return ret;
0252 
0253         hinge_adjust_channel_realbits(channels, i, st->hinge[i].size);
0254     }
0255 
0256     st->scale_precision = hid_sensor_format_scale(HID_USAGE_SENSOR_HINGE,
0257             &st->hinge[CHANNEL_SCAN_INDEX_HINGE_ANGLE],
0258             &st->scale_pre_decml, &st->scale_post_decml);
0259 
0260     return ret;
0261 }
0262 
0263 /* Function to initialize the processing for usage id */
0264 static int hid_hinge_probe(struct platform_device *pdev)
0265 {
0266     struct hinge_state *st;
0267     struct iio_dev *indio_dev;
0268     struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
0269     int ret;
0270     int i;
0271 
0272     indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
0273     if (!indio_dev)
0274         return -ENOMEM;
0275 
0276     platform_set_drvdata(pdev, indio_dev);
0277 
0278     st = iio_priv(indio_dev);
0279     st->common_attributes.hsdev = hsdev;
0280     st->common_attributes.pdev = pdev;
0281     st->indio_dev = indio_dev;
0282     for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; i++)
0283         st->labels[i] = hinge_labels[i];
0284 
0285     ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage,
0286                          &st->common_attributes,
0287                          hinge_sensitivity_addresses,
0288                          ARRAY_SIZE(hinge_sensitivity_addresses));
0289     if (ret) {
0290         dev_err(&pdev->dev, "failed to setup common attributes\n");
0291         return ret;
0292     }
0293 
0294     indio_dev->num_channels = ARRAY_SIZE(hinge_channels);
0295     indio_dev->channels = devm_kmemdup(&indio_dev->dev, hinge_channels,
0296                        sizeof(hinge_channels), GFP_KERNEL);
0297     if (!indio_dev->channels)
0298         return -ENOMEM;
0299 
0300     ret = hinge_parse_report(pdev, hsdev,
0301                  (struct iio_chan_spec *)indio_dev->channels,
0302                  hsdev->usage, st);
0303     if (ret) {
0304         dev_err(&pdev->dev, "failed to setup attributes\n");
0305         return ret;
0306     }
0307 
0308     indio_dev->info = &hinge_info;
0309     indio_dev->name = "hinge";
0310     indio_dev->modes = INDIO_DIRECT_MODE;
0311 
0312     atomic_set(&st->common_attributes.data_ready, 0);
0313     ret = hid_sensor_setup_trigger(indio_dev, indio_dev->name,
0314                        &st->common_attributes);
0315     if (ret < 0) {
0316         dev_err(&pdev->dev, "trigger setup failed\n");
0317         return ret;
0318     }
0319 
0320     st->callbacks.send_event = hinge_proc_event;
0321     st->callbacks.capture_sample = hinge_capture_sample;
0322     st->callbacks.pdev = pdev;
0323     ret = sensor_hub_register_callback(hsdev, hsdev->usage, &st->callbacks);
0324     if (ret < 0) {
0325         dev_err(&pdev->dev, "callback reg failed\n");
0326         goto error_remove_trigger;
0327     }
0328 
0329     ret = iio_device_register(indio_dev);
0330     if (ret) {
0331         dev_err(&pdev->dev, "device register failed\n");
0332         goto error_remove_callback;
0333     }
0334 
0335     return ret;
0336 
0337 error_remove_callback:
0338     sensor_hub_remove_callback(hsdev, hsdev->usage);
0339 error_remove_trigger:
0340     hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
0341     return ret;
0342 }
0343 
0344 /* Function to deinitialize the processing for usage id */
0345 static int hid_hinge_remove(struct platform_device *pdev)
0346 {
0347     struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
0348     struct iio_dev *indio_dev = platform_get_drvdata(pdev);
0349     struct hinge_state *st = iio_priv(indio_dev);
0350 
0351     iio_device_unregister(indio_dev);
0352     sensor_hub_remove_callback(hsdev, hsdev->usage);
0353     hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
0354 
0355     return 0;
0356 }
0357 
0358 static const struct platform_device_id hid_hinge_ids[] = {
0359     {
0360         /* Format: HID-SENSOR-INT-usage_id_in_hex_lowercase */
0361         .name = "HID-SENSOR-INT-020b",
0362     },
0363     { /* sentinel */ }
0364 };
0365 MODULE_DEVICE_TABLE(platform, hid_hinge_ids);
0366 
0367 static struct platform_driver hid_hinge_platform_driver = {
0368     .id_table = hid_hinge_ids,
0369     .driver = {
0370         .name   = KBUILD_MODNAME,
0371         .pm = &hid_sensor_pm_ops,
0372     },
0373     .probe      = hid_hinge_probe,
0374     .remove     = hid_hinge_remove,
0375 };
0376 module_platform_driver(hid_hinge_platform_driver);
0377 
0378 MODULE_DESCRIPTION("HID Sensor INTEL Hinge");
0379 MODULE_AUTHOR("Ye Xiang <xiang.ye@intel.com>");
0380 MODULE_LICENSE("GPL");
0381 MODULE_IMPORT_NS(IIO_HID);