diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-02-25 14:11:41 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-02-25 14:11:41 +0100 |
commit | d4551c189d6e6a3fcf7f625bd4b273e770fad35a (patch) | |
tree | db1968720fcdb2563e94f36951dfa1de5b15aabd /drivers/iio/light | |
parent | Merge 6.8-rc5 into char-misc-next (diff) | |
parent | iio: imu: bmi323: Add ACPI Match Table (diff) | |
download | linux-d4551c189d6e6a3fcf7f625bd4b273e770fad35a.tar.xz linux-d4551c189d6e6a3fcf7f625bd4b273e770fad35a.zip |
Merge tag 'iio-for-6.9a' of http://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next
Jonathan writes:
IIO: 1st set of new device support, features and cleanup for 6.9
IIO Backend support
===================
New approach from Nuno Sa to the problem of reuse of drivers with
IIO devices that are actually the combination of a highspeed chip
and an FPGA core handling the data capture and flows. It will hopefully
also apply to some other split designs. The ad9467 and axi-adi drivers
are converted over to this framework.
New device support
==================
adi,admfm2000
- New driver for this dual microwave down converter.
ams,as73211
- Add support for as7331 UV sensor.
richtek,rtq6056
- Add support for related parts RTQ6053 and RTQ6059
st,lsm6dsx
- Add ASM330LHHXG1 accelerometer and gyro support (mainly IDs)
ti,ads1298
- New driver for this medical ADC.
Features
========
tests
- Unit tests for the gain-time-scale helper library.
bosch,bmi088
- I2C support.
bosh,bmi160
- Add 10EC5280 ACPI ID. Used in a number of devices that won't get fixed.
The ID is actually a PCI ID belonging to realtech. No response was received
to earlier attempts to notify them of this.
The manufacturers of some devices have replied to say they will not fix
this incorrect ID. Add the ID and hope it isn't a problem.
bosch,bmi323
- Add BOSC0200 ACPI ID. Note this is a duplicate of one in the bmc150
driver (it appears these parts share a windows driver).
Both drivers perform an ID check that is safe on the other part before
successfully probing.
hid-sensors-als
- Add color temperature and chromaticity support. Note this is a replacement
for the series reverted in 6.8 that correctly handles all the potential
channel combinations.
honeywell,hsc030pa
- Triggered buffer support (after driver cleanup).
honeywell,mprls00025pa
- Improved error handling.
- New DT binding to allow use of part number triplet as provided in data sheet
to specify equivalent of most of the binding more efficiently.
- SPI support.
memsic,mxc4005
- ACPI ID MDA6655 as seen in the Chuwi Minibook X 2023
ti,hdc3020
- Add threshold event support (after some driver cleanup)
veml,vcnl4000
- Switch to high resolution proximity measurement.
Cleanup
=======
Various minor typo fixes and better use of defines etc.
Treewide
- Stop using ACPI_PTR(). The savings in space are small and not worth
the complexity of __maybe_unused of ifdef guards. To avoid use in
new IIO drivers based on copy and paste, clean it out.
- cleanup.h based handling of iio_device_claim_direct_mode()/
iio_device_release_direct_mode() using scope_cond_guard().
In many drivers this is combined with other automated cleanup
to give maximum simplifications.
An initial set of drivers are converted over to this infrastructure.
Tools
- Use rewinddir() instead of seekdir() to return to start of file.
core
- Make iio_bus_type constant.
adi,ad16475
- Use irq_get_trigger_type() instead of opencoding.
adi,ad16480
- Use irq_get_trigger_type() instead of opencoding.
adi,ad-sigma-delta
- Avoid overwriting IRQ flags if provided by firmware.
ams,as73211
- Use IIO_VAL_FRACTIONAL for scales to simplify the code and potentially
improve accuracy.
gts-library
- Use a div64_u64() instead of a loop to do a division.
honeywell,mprls00025pa
- Clean up dt-binding doc.
- Drop defaults when DT binding not providing values. Very unlikely
these were useful given they were wrong for vast majority of supported
devices.
- Whitespace cleanup
miramems,da280
- Use i2c_get_match_data() to replace hand rolled ACPI matching code.
semtech,sx9324
- Avoid unnecessary copying of property strings.
st,lsm6dsx
- Improve docs, particularly wrt to making addition of new device
support less noisy.
st,lsm9ds0
- Use dev_err_probe() in all probe() error handling.
- Improved header includes.
- Tidy up termination of ID tables.
ti,ads1014
- Correct upper bound on PGA (wrong value had no actual impact)
ti,afe4403/4404
- devm_ useage to simplify error handling in probe() and allow() remove to
be dropped.
voltage-divider
- Add dt-binding for io-channel-cells to allow such a device to be both
an IIO consumer and IIO producer at the same time.
* tag 'iio-for-6.9a' of http://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (106 commits)
iio: imu: bmi323: Add ACPI Match Table
iio: accel: bmc150: Document duplicate ACPI entries with bmi323 driver
iio: adc: ti-ads1298: Add driver
dt-bindings: iio: adc: ti-ads1298: Add bindings
iio: pressure: hsc030pa add triggered buffer
iio: pressure: hsc030pa add mandatory delay
iio: pressure: hsc030pa: update datasheet URLs
iio: pressure: hsc030pa: include cleanup
iio: pressure: hsc030pa: use signed type to hold div_64() result
dt-bindings: iio: pressure: honeywell,hsc030pa.yaml add spi props
iio: st_sensors: lsm9ds0: Use common style for terminator in ID tables
iio: st_sensors: lsm9ds0: Don't use "proxy" headers
iio: st_sensors: lsm9ds0: Use dev_err_probe() everywhere
iio: adc: adi-axi-adc: move to backend framework
iio: adc: ad9467: convert to backend framework
iio: add the IIO backend framework
iio: buffer-dmaengine: export buffer alloc and free functions
of: property: add device link support for io-backends
dt-bindings: adc: axi-adc: update bindings for backend framework
dt-bindings: adc: ad9467: add new io-backend property
...
Diffstat (limited to 'drivers/iio/light')
-rw-r--r-- | drivers/iio/light/Kconfig | 5 | ||||
-rw-r--r-- | drivers/iio/light/as73211.c | 142 | ||||
-rw-r--r-- | drivers/iio/light/hid-sensor-als.c | 122 | ||||
-rw-r--r-- | drivers/iio/light/jsa1212.c | 4 | ||||
-rw-r--r-- | drivers/iio/light/ltr501.c | 3 | ||||
-rw-r--r-- | drivers/iio/light/max44000.c | 6 | ||||
-rw-r--r-- | drivers/iio/light/rpr0521.c | 4 | ||||
-rw-r--r-- | drivers/iio/light/stk3310.c | 4 | ||||
-rw-r--r-- | drivers/iio/light/us5182d.c | 4 | ||||
-rw-r--r-- | drivers/iio/light/vcnl4000.c | 36 |
10 files changed, 269 insertions, 61 deletions
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 143003232d1c..fd5a9879a582 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/as73211.c b/drivers/iio/light/as73211.c index ec97a3a46839..be0068081ebb 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 <ceggers@arri.de> * @@ -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 <linux/bitfield.h> @@ -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 b6c4bef2a7bb..260281194f61 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 37e2807041a1..869196746045 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c @@ -12,10 +12,10 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/delay.h> #include <linux/i2c.h> #include <linux/mutex.h> -#include <linux/acpi.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -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 061c122fdc5e..8c516ede9116 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -10,6 +10,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/i2c.h> #include <linux/err.h> #include <linux/delay.h> @@ -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 db96c5b73100..26b464b1b650 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -10,6 +10,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/regmap.h> @@ -19,7 +20,6 @@ #include <linux/iio/buffer.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <linux/acpi.h> #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 bbb8581622f2..40d5732b5e32 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -10,11 +10,11 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/delay.h> -#include <linux/acpi.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -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 72b08d870d33..7b71ad71d78d 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 <linux/acpi.h> #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/events.h> #include <linux/iio/iio.h> @@ -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 61b3b2aea626..9189a1d4d7e1 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/acpi.h> +#include <linux/mod_devicetable.h> #include <linux/delay.h> #include <linux/i2c.h> #include <linux/iio/events.h> @@ -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 fdf763a04b0b..4e3641ff2ed4 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; |