From e54def4ad8144ab15f826416e2e0f290ef1901b4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 23:00:30 +0200 Subject: Adding upstream version 6.9.2. Signed-off-by: Daniel Baumann --- drivers/iio/light/Kconfig | 5 +- drivers/iio/light/al3010.c | 2 +- drivers/iio/light/al3320a.c | 1 - drivers/iio/light/as73211.c | 142 ++++++++++++++++++++++++++++++------- drivers/iio/light/hid-sensor-als.c | 122 ++++++++++++++++++++++++++----- drivers/iio/light/jsa1212.c | 4 +- drivers/iio/light/ltr501.c | 3 +- drivers/iio/light/max44000.c | 6 +- drivers/iio/light/rpr0521.c | 4 +- drivers/iio/light/stk3310.c | 4 +- drivers/iio/light/us5182d.c | 4 +- drivers/iio/light/vcnl4000.c | 36 +++++++++- drivers/iio/light/vl6180.c | 1 - 13 files changed, 270 insertions(+), 64 deletions(-) (limited to 'drivers/iio/light') diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 143003232d..fd5a9879a5 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -87,13 +87,14 @@ config APDS9960 module will be called apds9960 config AS73211 - tristate "AMS AS73211 XYZ color sensor" + tristate "AMS AS73211 XYZ color sensor and AMS AS7331 UV sensor" depends on I2C select IIO_BUFFER select IIO_TRIGGERED_BUFFER help If you say yes here you get support for the AMS AS73211 - JENCOLOR(R) Digital XYZ Sensor. + JENCOLOR(R) Digital XYZ and the AMS AS7331 UVA, UVB and UVC + ultraviolet sensors. For triggered measurements, you will need an additional trigger driver like IIO_HRTIMER_TRIGGER or IIO_SYSFS_TRIGGER. diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c index 8f0119f392..53569587cc 100644 --- a/drivers/iio/light/al3010.c +++ b/drivers/iio/light/al3010.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/iio/light/al3320a.c b/drivers/iio/light/al3320a.c index d5957d85c2..105f379b9b 100644 --- a/drivers/iio/light/al3320a.c +++ b/drivers/iio/light/al3320a.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c index ec97a3a468..be0068081e 100644 --- a/drivers/iio/light/as73211.c +++ b/drivers/iio/light/as73211.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor + * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor and AMS AS7331 + * UVA, UVB and UVC (DUV) Ultraviolet Sensor * * Author: Christian Eggers * @@ -9,7 +10,9 @@ * Color light sensor with 16-bit channels for x, y, z and temperature); * 7-bit I2C slave address 0x74 .. 0x77. * - * Datasheet: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf + * Datasheets: + * AS73211: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf + * AS7331: https://ams.com/documents/20143/9106314/AS7331_DS001047_4-00.pdf */ #include @@ -84,6 +87,20 @@ static const int as73211_hardwaregain_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, }; +struct as73211_data; + +/** + * struct as73211_spec_dev_data - device-specific data + * @intensity_scale: Function to retrieve intensity scale values. + * @channels: Device channels. + * @num_channels: Number of channels of the device. + */ +struct as73211_spec_dev_data { + int (*intensity_scale)(struct as73211_data *data, int chan, int *val, int *val2); + struct iio_chan_spec const *channels; + int num_channels; +}; + /** * struct as73211_data - Instance data for one AS73211 * @client: I2C client. @@ -94,6 +111,7 @@ static const int as73211_hardwaregain_avail[] = { * @mutex: Keeps cached registers in sync with the device. * @completion: Completion to wait for interrupt. * @int_time_avail: Available integration times (depend on sampling frequency). + * @spec_dev: device-specific configuration. */ struct as73211_data { struct i2c_client *client; @@ -104,6 +122,7 @@ struct as73211_data { struct mutex mutex; struct completion completion; int int_time_avail[AS73211_SAMPLE_TIME_NUM * 2]; + const struct as73211_spec_dev_data *spec_dev; }; #define AS73211_COLOR_CHANNEL(_color, _si, _addr) { \ @@ -138,6 +157,10 @@ struct as73211_data { #define AS73211_SCALE_Y 298384270 /* nW/m^2 */ #define AS73211_SCALE_Z 160241927 /* nW/m^2 */ +#define AS7331_SCALE_UVA 340000 /* nW/cm^2 */ +#define AS7331_SCALE_UVB 378000 /* nW/cm^2 */ +#define AS7331_SCALE_UVC 166000 /* nW/cm^2 */ + /* Channel order MUST match devices result register order */ #define AS73211_SCAN_INDEX_TEMP 0 #define AS73211_SCAN_INDEX_X 1 @@ -176,6 +199,28 @@ static const struct iio_chan_spec as73211_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), }; +static const struct iio_chan_spec as7331_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + .address = AS73211_OUT_TEMP, + .scan_index = AS73211_SCAN_INDEX_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + } + }, + AS73211_COLOR_CHANNEL(LIGHT_UVA, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1), + AS73211_COLOR_CHANNEL(LIGHT_UVB, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2), + AS73211_COLOR_CHANNEL(LIGHT_DUV, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3), + IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS), +}; + static unsigned int as73211_integration_time_1024cyc(struct as73211_data *data) { /* @@ -316,6 +361,48 @@ static int as73211_req_data(struct as73211_data *data) return 0; } +static int as73211_intensity_scale(struct as73211_data *data, int chan, + int *val, int *val2) +{ + switch (chan) { + case IIO_MOD_X: + *val = AS73211_SCALE_X; + break; + case IIO_MOD_Y: + *val = AS73211_SCALE_Y; + break; + case IIO_MOD_Z: + *val = AS73211_SCALE_Z; + break; + default: + return -EINVAL; + } + *val2 = as73211_integration_time_1024cyc(data) * as73211_gain(data); + + return IIO_VAL_FRACTIONAL; +} + +static int as7331_intensity_scale(struct as73211_data *data, int chan, + int *val, int *val2) +{ + switch (chan) { + case IIO_MOD_LIGHT_UVA: + *val = AS7331_SCALE_UVA; + break; + case IIO_MOD_LIGHT_UVB: + *val = AS7331_SCALE_UVB; + break; + case IIO_MOD_LIGHT_DUV: + *val = AS7331_SCALE_UVC; + break; + default: + return -EINVAL; + } + *val2 = as73211_integration_time_1024cyc(data) * as73211_gain(data); + + return IIO_VAL_FRACTIONAL; +} + static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { @@ -355,30 +442,13 @@ static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec cons *val2 = AS73211_SCALE_TEMP_MICRO; return IIO_VAL_INT_PLUS_MICRO; - case IIO_INTENSITY: { - unsigned int scale; - - switch (chan->channel2) { - case IIO_MOD_X: - scale = AS73211_SCALE_X; - break; - case IIO_MOD_Y: - scale = AS73211_SCALE_Y; - break; - case IIO_MOD_Z: - scale = AS73211_SCALE_Z; - break; - default: - return -EINVAL; - } - scale /= as73211_gain(data); - scale /= as73211_integration_time_1024cyc(data); - *val = scale; - return IIO_VAL_INT; + case IIO_INTENSITY: + return data->spec_dev->intensity_scale(data, chan->channel2, + val, val2); default: return -EINVAL; - }} + } case IIO_CHAN_INFO_SAMP_FREQ: /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */ @@ -676,13 +746,17 @@ static int as73211_probe(struct i2c_client *client) i2c_set_clientdata(client, indio_dev); data->client = client; + data->spec_dev = i2c_get_match_data(client); + if (!data->spec_dev) + return -EINVAL; + mutex_init(&data->mutex); init_completion(&data->completion); indio_dev->info = &as73211_info; indio_dev->name = AS73211_DRV_NAME; - indio_dev->channels = as73211_channels; - indio_dev->num_channels = ARRAY_SIZE(as73211_channels); + indio_dev->channels = data->spec_dev->channels; + indio_dev->num_channels = data->spec_dev->num_channels; indio_dev->modes = INDIO_DIRECT_MODE; ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); @@ -772,14 +846,28 @@ static int as73211_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(as73211_pm_ops, as73211_suspend, as73211_resume); +static const struct as73211_spec_dev_data as73211_spec = { + .intensity_scale = as73211_intensity_scale, + .channels = as73211_channels, + .num_channels = ARRAY_SIZE(as73211_channels), +}; + +static const struct as73211_spec_dev_data as7331_spec = { + .intensity_scale = as7331_intensity_scale, + .channels = as7331_channels, + .num_channels = ARRAY_SIZE(as7331_channels), +}; + static const struct of_device_id as73211_of_match[] = { - { .compatible = "ams,as73211" }, + { .compatible = "ams,as73211", &as73211_spec }, + { .compatible = "ams,as7331", &as7331_spec }, { } }; MODULE_DEVICE_TABLE(of, as73211_of_match); static const struct i2c_device_id as73211_id[] = { - { "as73211", 0 }, + { "as73211", (kernel_ulong_t)&as73211_spec }, + { "as7331", (kernel_ulong_t)&as7331_spec }, { } }; MODULE_DEVICE_TABLE(i2c, as73211_id); diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index b6c4bef2a7..260281194f 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -14,8 +14,11 @@ #include "../common/hid-sensors/hid-sensor-trigger.h" enum { - CHANNEL_SCAN_INDEX_INTENSITY = 0, - CHANNEL_SCAN_INDEX_ILLUM = 1, + CHANNEL_SCAN_INDEX_INTENSITY, + CHANNEL_SCAN_INDEX_ILLUM, + CHANNEL_SCAN_INDEX_COLOR_TEMP, + CHANNEL_SCAN_INDEX_CHROMATICITY_X, + CHANNEL_SCAN_INDEX_CHROMATICITY_Y, CHANNEL_SCAN_INDEX_MAX }; @@ -25,6 +28,7 @@ struct als_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info als[CHANNEL_SCAN_INDEX_MAX]; + struct iio_chan_spec channels[CHANNEL_SCAN_INDEX_MAX + 1]; struct { u32 illum[CHANNEL_SCAN_INDEX_MAX]; u64 timestamp __aligned(8); @@ -33,7 +37,18 @@ struct als_state { int scale_post_decml; int scale_precision; int value_offset; + int num_channels; s64 timestamp; + unsigned long als_scan_mask[2]; +}; + +/* The order of usage ids must match scan index starting from CHANNEL_SCAN_INDEX_INTENSITY */ +static const u32 als_usage_ids[] = { + HID_USAGE_SENSOR_LIGHT_ILLUM, + HID_USAGE_SENSOR_LIGHT_ILLUM, + HID_USAGE_SENSOR_LIGHT_COLOR_TEMPERATURE, + HID_USAGE_SENSOR_LIGHT_CHROMATICITY_X, + HID_USAGE_SENSOR_LIGHT_CHROMATICITY_Y, }; static const u32 als_sensitivity_addresses[] = { @@ -65,6 +80,40 @@ static const struct iio_chan_spec als_channels[] = { BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), .scan_index = CHANNEL_SCAN_INDEX_ILLUM, }, + { + .type = IIO_COLORTEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS) | + BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), + .scan_index = CHANNEL_SCAN_INDEX_COLOR_TEMP, + }, + { + .type = IIO_CHROMATICITY, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS) | + BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), + .scan_index = CHANNEL_SCAN_INDEX_CHROMATICITY_X, + }, + { + .type = IIO_CHROMATICITY, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS) | + BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), + .scan_index = CHANNEL_SCAN_INDEX_CHROMATICITY_Y, + }, IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP) }; @@ -103,6 +152,21 @@ static int als_read_raw(struct iio_dev *indio_dev, min = als_state->als[chan->scan_index].logical_minimum; address = HID_USAGE_SENSOR_LIGHT_ILLUM; break; + case CHANNEL_SCAN_INDEX_COLOR_TEMP: + report_id = als_state->als[chan->scan_index].report_id; + min = als_state->als[chan->scan_index].logical_minimum; + address = HID_USAGE_SENSOR_LIGHT_COLOR_TEMPERATURE; + break; + case CHANNEL_SCAN_INDEX_CHROMATICITY_X: + report_id = als_state->als[chan->scan_index].report_id; + min = als_state->als[chan->scan_index].logical_minimum; + address = HID_USAGE_SENSOR_LIGHT_CHROMATICITY_X; + break; + case CHANNEL_SCAN_INDEX_CHROMATICITY_Y: + report_id = als_state->als[chan->scan_index].report_id; + min = als_state->als[chan->scan_index].logical_minimum; + address = HID_USAGE_SENSOR_LIGHT_CHROMATICITY_Y; + break; default: report_id = -1; break; @@ -223,6 +287,18 @@ static int als_capture_sample(struct hid_sensor_hub_device *hsdev, als_state->scan.illum[CHANNEL_SCAN_INDEX_ILLUM] = sample_data; ret = 0; break; + case HID_USAGE_SENSOR_LIGHT_COLOR_TEMPERATURE: + als_state->scan.illum[CHANNEL_SCAN_INDEX_COLOR_TEMP] = sample_data; + ret = 0; + break; + case HID_USAGE_SENSOR_LIGHT_CHROMATICITY_X: + als_state->scan.illum[CHANNEL_SCAN_INDEX_CHROMATICITY_X] = sample_data; + ret = 0; + break; + case HID_USAGE_SENSOR_LIGHT_CHROMATICITY_Y: + als_state->scan.illum[CHANNEL_SCAN_INDEX_CHROMATICITY_Y] = sample_data; + ret = 0; + break; case HID_USAGE_SENSOR_TIME_TIMESTAMP: als_state->timestamp = hid_sensor_convert_timestamp(&als_state->common_attributes, *(s64 *)raw_data); @@ -238,27 +314,38 @@ static int als_capture_sample(struct hid_sensor_hub_device *hsdev, /* Parse report which is specific to an usage id*/ static int als_parse_report(struct platform_device *pdev, struct hid_sensor_hub_device *hsdev, - struct iio_chan_spec *channels, unsigned usage_id, struct als_state *st) { - int ret; + struct iio_chan_spec *channels; + int ret, index = 0; int i; - for (i = 0; i <= CHANNEL_SCAN_INDEX_ILLUM; ++i) { + channels = st->channels; + + for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; ++i) { ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT, usage_id, - HID_USAGE_SENSOR_LIGHT_ILLUM, + als_usage_ids[i], &st->als[i]); if (ret < 0) - return ret; - als_adjust_channel_bit_mask(channels, i, st->als[i].size); + continue; + + channels[index] = als_channels[i]; + st->als_scan_mask[0] |= BIT(i); + als_adjust_channel_bit_mask(channels, index, st->als[i].size); + ++index; dev_dbg(&pdev->dev, "als %x:%x\n", st->als[i].index, st->als[i].report_id); } + st->num_channels = index; + /* Return success even if one usage id is present */ + if (index) + ret = 0; + st->scale_precision = hid_sensor_format_scale(usage_id, &st->als[CHANNEL_SCAN_INDEX_INTENSITY], &st->scale_pre_decml, &st->scale_post_decml); @@ -294,15 +381,7 @@ static int hid_als_probe(struct platform_device *pdev) return ret; } - indio_dev->channels = devm_kmemdup(&pdev->dev, als_channels, - sizeof(als_channels), GFP_KERNEL); - if (!indio_dev->channels) { - dev_err(&pdev->dev, "failed to duplicate channels\n"); - return -ENOMEM; - } - ret = als_parse_report(pdev, hsdev, - (struct iio_chan_spec *)indio_dev->channels, hsdev->usage, als_state); if (ret) { @@ -310,8 +389,15 @@ static int hid_als_probe(struct platform_device *pdev) return ret; } - indio_dev->num_channels = - ARRAY_SIZE(als_channels); + /* Add timestamp channel */ + als_state->channels[als_state->num_channels] = als_channels[CHANNEL_SCAN_INDEX_TIMESTAMP]; + + /* +1 for adding timestamp channel */ + indio_dev->num_channels = als_state->num_channels + 1; + + indio_dev->channels = als_state->channels; + indio_dev->available_scan_masks = als_state->als_scan_mask; + indio_dev->info = &als_info; indio_dev->name = name; indio_dev->modes = INDIO_DIRECT_MODE; diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c index 37e2807041..8691967460 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c @@ -12,10 +12,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -438,7 +438,7 @@ static struct i2c_driver jsa1212_driver = { .driver = { .name = JSA1212_DRIVER_NAME, .pm = pm_sleep_ptr(&jsa1212_pm_ops), - .acpi_match_table = ACPI_PTR(jsa1212_acpi_match), + .acpi_match_table = jsa1212_acpi_match, }, .probe = jsa1212_probe, .remove = jsa1212_remove, diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 061c122fdc..8c516ede91 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -1639,7 +1640,7 @@ static struct i2c_driver ltr501_driver = { .name = LTR501_DRV_NAME, .of_match_table = ltr501_of_match, .pm = pm_sleep_ptr(<r501_pm_ops), - .acpi_match_table = ACPI_PTR(ltr_acpi_match), + .acpi_match_table = ltr_acpi_match, }, .probe = ltr501_probe, .remove = ltr501_remove, diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index db96c5b731..26b464b1b6 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include #define MAX44000_DRV_NAME "max44000" @@ -603,18 +603,16 @@ static const struct i2c_device_id max44000_id[] = { }; MODULE_DEVICE_TABLE(i2c, max44000_id); -#ifdef CONFIG_ACPI static const struct acpi_device_id max44000_acpi_match[] = { {"MAX44000", 0}, { } }; MODULE_DEVICE_TABLE(acpi, max44000_acpi_match); -#endif static struct i2c_driver max44000_driver = { .driver = { .name = MAX44000_DRV_NAME, - .acpi_match_table = ACPI_PTR(max44000_acpi_match), + .acpi_match_table = max44000_acpi_match, }, .probe = max44000_probe, .id_table = max44000_id, diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index bbb8581622..40d5732b5e 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -10,11 +10,11 @@ */ #include +#include #include #include #include #include -#include #include #include @@ -1119,7 +1119,7 @@ static struct i2c_driver rpr0521_driver = { .driver = { .name = RPR0521_DRV_NAME, .pm = pm_ptr(&rpr0521_pm_ops), - .acpi_match_table = ACPI_PTR(rpr0521_acpi_match), + .acpi_match_table = rpr0521_acpi_match, }, .probe = rpr0521_probe, .remove = rpr0521_remove, diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 72b08d870d..7b71ad71d7 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -7,11 +7,11 @@ * IIO driver for STK3310/STK3311. 7-bit I2C address: 0x48. */ -#include #include #include #include #include +#include #include #include #include @@ -712,7 +712,7 @@ static struct i2c_driver stk3310_driver = { .name = "stk3310", .of_match_table = stk3310_of_match, .pm = pm_sleep_ptr(&stk3310_pm_ops), - .acpi_match_table = ACPI_PTR(stk3310_acpi_id), + .acpi_match_table = stk3310_acpi_id, }, .probe = stk3310_probe, .remove = stk3310_remove, diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 61b3b2aea6..9189a1d4d7 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -972,7 +972,7 @@ static struct i2c_driver us5182d_driver = { .name = US5182D_DRV_NAME, .pm = pm_ptr(&us5182d_pm_ops), .of_match_table = us5182d_of_match, - .acpi_match_table = ACPI_PTR(us5182d_acpi_match), + .acpi_match_table = us5182d_acpi_match, }, .probe = us5182d_probe, .remove = us5182d_remove, diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index fdf763a04b..4e3641ff2e 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -90,6 +90,7 @@ #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */ #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity interrupt persistence setting */ +#define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high definition */ #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity interrupt mode */ #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity multi pulse number */ #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity current */ @@ -114,6 +115,13 @@ #define VCNL4010_INT_DRDY \ (BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS)) +#define VCNL4040_CONF3_PS_MPS_16BITS 3 /* 8 multi pulses */ +#define VCNL4040_CONF3_PS_LED_I_16BITS 3 /* 120 mA */ + +#define VCNL4040_CONF3_PS_SAMPLE_16BITS \ + (FIELD_PREP(VCNL4040_PS_CONF3_MPS, VCNL4040_CONF3_PS_MPS_16BITS) | \ + FIELD_PREP(VCNL4040_PS_MS_LED_I, VCNL4040_CONF3_PS_LED_I_16BITS)) + static const int vcnl4010_prox_sampling_frequency[][2] = { {1, 950000}, {3, 906250}, @@ -195,6 +203,7 @@ struct vcnl4000_data { enum vcnl4000_device_ids id; int rev; int al_scale; + int ps_scale; u8 ps_int; /* proximity interrupt mode */ u8 als_int; /* ambient light interrupt mode*/ const struct vcnl4000_chip_spec *chip_spec; @@ -345,6 +354,7 @@ static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on) static int vcnl4200_init(struct vcnl4000_data *data) { int ret, id; + u16 regval; ret = i2c_smbus_read_word_data(data->client, VCNL4200_DEV_ID); if (ret < 0) @@ -386,9 +396,32 @@ static int vcnl4200_init(struct vcnl4000_data *data) break; } data->al_scale = data->chip_spec->ulux_step; + data->ps_scale = 16; mutex_init(&data->vcnl4200_al.lock); mutex_init(&data->vcnl4200_ps.lock); + /* Use 16 bits proximity sensor readings */ + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + return ret; + + regval = ret | VCNL4040_PS_CONF2_PS_HD; + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, + regval); + if (ret < 0) + return ret; + + /* Align proximity sensor sample rate to 16 bits data width */ + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3); + if (ret < 0) + return ret; + + regval = ret | VCNL4040_CONF3_PS_SAMPLE_16BITS; + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, + regval); + if (ret < 0) + return ret; + ret = data->chip_spec->set_power_state(data, true); if (ret < 0) return ret; @@ -901,8 +934,9 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev, break; case IIO_PROXIMITY: ret = data->chip_spec->measure_proximity(data, val); + *val2 = data->ps_scale; if (!ret) - ret = IIO_VAL_INT; + ret = IIO_VAL_FRACTIONAL; break; default: ret = -EINVAL; diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c index d4948dfc31..dcadf6428a 100644 --- a/drivers/iio/light/vl6180.c +++ b/drivers/iio/light/vl6180.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3