0001
0002
0003
0004
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
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
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
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
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
0190
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
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
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
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
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
0361 .name = "HID-SENSOR-INT-020b",
0362 },
0363 { }
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);