--- zzzz-none-000/linux-3.10.107/drivers/iio/light/adjd_s311.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/iio/light/adjd_s311.c 2021-02-04 17:41:59.000000000 +0000 @@ -14,7 +14,6 @@ */ #include -#include #include #include #include @@ -37,22 +36,14 @@ #define ADJD_S311_CAP_GREEN 0x07 #define ADJD_S311_CAP_BLUE 0x08 #define ADJD_S311_CAP_CLEAR 0x09 -#define ADJD_S311_INT_RED_LO 0x0a -#define ADJD_S311_INT_RED_HI 0x0b -#define ADJD_S311_INT_GREEN_LO 0x0c -#define ADJD_S311_INT_GREEN_HI 0x0d -#define ADJD_S311_INT_BLUE_LO 0x0e -#define ADJD_S311_INT_BLUE_HI 0x0f -#define ADJD_S311_INT_CLEAR_LO 0x10 -#define ADJD_S311_INT_CLEAR_HI 0x11 -#define ADJD_S311_DATA_RED_LO 0x40 -#define ADJD_S311_DATA_RED_HI 0x41 -#define ADJD_S311_DATA_GREEN_LO 0x42 -#define ADJD_S311_DATA_GREEN_HI 0x43 -#define ADJD_S311_DATA_BLUE_LO 0x44 -#define ADJD_S311_DATA_BLUE_HI 0x45 -#define ADJD_S311_DATA_CLEAR_LO 0x46 -#define ADJD_S311_DATA_CLEAR_HI 0x47 +#define ADJD_S311_INT_RED 0x0a +#define ADJD_S311_INT_GREEN 0x0c +#define ADJD_S311_INT_BLUE 0x0e +#define ADJD_S311_INT_CLEAR 0x10 +#define ADJD_S311_DATA_RED 0x40 +#define ADJD_S311_DATA_GREEN 0x42 +#define ADJD_S311_DATA_BLUE 0x44 +#define ADJD_S311_DATA_CLEAR 0x46 #define ADJD_S311_OFFSET_RED 0x48 #define ADJD_S311_OFFSET_GREEN 0x49 #define ADJD_S311_OFFSET_BLUE 0x4a @@ -73,8 +64,8 @@ IDX_RED, IDX_GREEN, IDX_BLUE, IDX_CLEAR }; -#define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED_LO + (chan) * 2) -#define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED_LO + (chan) * 2) +#define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED + (chan) * 2) +#define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED + (chan) * 2) #define ADJD_S311_CAP_REG(chan) (ADJD_S311_CAP_RED + (chan)) static int adjd_s311_req_data(struct iio_dev *indio_dev) @@ -122,50 +113,12 @@ return 0; } -static ssize_t adjd_s311_read_int_time(struct iio_dev *indio_dev, - uintptr_t private, const struct iio_chan_spec *chan, char *buf) -{ - struct adjd_s311_data *data = iio_priv(indio_dev); - s32 ret; - - ret = i2c_smbus_read_word_data(data->client, - ADJD_S311_INT_REG(chan->address)); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", ret & ADJD_S311_INT_MASK); -} - -static ssize_t adjd_s311_write_int_time(struct iio_dev *indio_dev, - uintptr_t private, const struct iio_chan_spec *chan, const char *buf, - size_t len) -{ - struct adjd_s311_data *data = iio_priv(indio_dev); - unsigned long int_time; - int ret; - - ret = kstrtoul(buf, 10, &int_time); - if (ret) - return ret; - - if (int_time > ADJD_S311_INT_MASK) - return -EINVAL; - - ret = i2c_smbus_write_word_data(data->client, - ADJD_S311_INT_REG(chan->address), int_time); - if (ret < 0) - return ret; - - return len; -} - static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adjd_s311_data *data = iio_priv(indio_dev); s64 time_ns = iio_get_time_ns(); - int len = 0; int i, j = 0; int ret = adjd_s311_req_data(indio_dev); @@ -180,13 +133,9 @@ goto done; data->buffer[j++] = ret & ADJD_S311_DATA_MASK; - len += 2; } - if (indio_dev->scan_timestamp) - *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64))) - = time_ns; - iio_push_to_buffers(indio_dev, (u8 *)data->buffer); + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, time_ns); done: iio_trigger_notify_done(indio_dev->trig); @@ -194,25 +143,21 @@ return IRQ_HANDLED; } -static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = { - { - .name = "integration_time", - .read = adjd_s311_read_int_time, - .write = adjd_s311_write_int_time, - }, - { } -}; - #define ADJD_S311_CHANNEL(_color, _scan_idx) { \ .type = IIO_INTENSITY, \ .modified = 1, \ .address = (IDX_##_color), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ .channel2 = (IIO_MOD_LIGHT_##_color), \ .scan_index = (_scan_idx), \ - .scan_type = IIO_ST('u', 10, 16, 0), \ - .ext_info = adjd_s311_ext_info, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 10, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ } static const struct iio_chan_spec adjd_s311_channels[] = { @@ -232,7 +177,8 @@ switch (mask) { case IIO_CHAN_INFO_RAW: - ret = adjd_s311_read_data(indio_dev, chan->address, val); + ret = adjd_s311_read_data(indio_dev, + ADJD_S311_DATA_REG(chan->address), val); if (ret < 0) return ret; return IIO_VAL_INT; @@ -243,6 +189,18 @@ return ret; *val = ret & ADJD_S311_CAP_MASK; return IIO_VAL_INT; + case IIO_CHAN_INFO_INT_TIME: + ret = i2c_smbus_read_word_data(data->client, + ADJD_S311_INT_REG(chan->address)); + if (ret < 0) + return ret; + *val = 0; + /* + * not documented, based on measurement: + * 4095 LSBs correspond to roughly 4 ms + */ + *val2 = ret & ADJD_S311_INT_MASK; + return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; } @@ -252,16 +210,20 @@ int val, int val2, long mask) { struct adjd_s311_data *data = iio_priv(indio_dev); - int ret; switch (mask) { case IIO_CHAN_INFO_HARDWAREGAIN: if (val < 0 || val > ADJD_S311_CAP_MASK) return -EINVAL; - ret = i2c_smbus_write_byte_data(data->client, + return i2c_smbus_write_byte_data(data->client, ADJD_S311_CAP_REG(chan->address), val); - return ret; + case IIO_CHAN_INFO_INT_TIME: + if (val != 0 || val2 < 0 || val2 > ADJD_S311_INT_MASK) + return -EINVAL; + + return i2c_smbus_write_word_data(data->client, + ADJD_S311_INT_REG(chan->address), val2); } return -EINVAL; } @@ -293,11 +255,10 @@ struct iio_dev *indio_dev; int err; - indio_dev = iio_device_alloc(sizeof(*data)); - if (indio_dev == NULL) { - err = -ENOMEM; - goto exit; - } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (indio_dev == NULL) + return -ENOMEM; + data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; @@ -312,7 +273,7 @@ err = iio_triggered_buffer_setup(indio_dev, NULL, adjd_s311_trigger_handler, NULL); if (err < 0) - goto exit_free_device; + return err; err = iio_device_register(indio_dev); if (err) @@ -324,9 +285,6 @@ exit_unreg_buffer: iio_triggered_buffer_cleanup(indio_dev); -exit_free_device: - iio_device_free(indio_dev); -exit: return err; } @@ -338,7 +296,6 @@ iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); kfree(data->buffer); - iio_device_free(indio_dev); return 0; }