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