Add ISL29501 support.
Subsystems (2)
v6 cover Add ISL29501 support.
Hi,
Here's v6 of this serie, please find the changelog below.
Thanks,
Mathieu
v6:
* Extract floating registers support as a separated, wip patch.
* Style corrections
v5:
* Use IIO_MOD_LIGHT_CLEAR modifier for IIO_INTENSITY channel describing ambient light intensity and remove extended_names doing so.
* Fix a possible leakage in isl29501_trigger_handler function. v4:
* Fix build warnings and rebase on top of next-20180628
v3:
* Renamings to add isl29501 prefix
* Rename "amb" -> "light" in extended fields
* Move mutex lock/unlock to register_read and register_write functions
* Improve IIO_PHASE scale output with a better pi estimation v2:
* Add missing eof new line
* Do not set .indexed to true for all channels
* Add a .extended to differenciate "magnitude" and "ambient_light" intensity channels
* Return isl29501_begin_acquisition result in isl29501_init_chip
* Fix buffer size in isl29501_trigger_handler
Mathieu Othacehe (3):
iio: Add channel for Phase
iio: light: isl29501: Add support for the ISL29501 ToF sensor.
iio: light: isl29501: Add support floating registers.
Documentation/ABI/testing/sysfs-bus-iio | 7 + .../ABI/testing/sysfs-bus-iio-isl29501 | 47 + .../bindings/iio/light/isl29501.txt | 13 + drivers/iio/industrialio-core.c | 1 + drivers/iio/light/Kconfig | 13 + drivers/iio/light/Makefile | 1 + drivers/iio/light/isl29501.c | 1125 +++++++++++++++++ include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 + 9 files changed, 1210 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-isl29501 create mode 100644 Documentation/devicetree/bindings/iio/light/isl29501.txt create mode 100644 drivers/iio/light/isl29501.c
Signature · 1 line
2.17.1
PATCH v6 1/3 iio: Add channel for Phase
Add new channel type support for phase.
This channel may be used by Time-of-flight sensors to express the phase difference between emitted and received signals. Those sensor will then use the phase shift of return signals to approximate the distance to objects.
--- Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++ drivers/iio/industrialio-core.c | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 ++ 4 files changed, 11 insertions(+)
Documentation/ABI/testing/sysfs-bus-iio +7 -0
@@ -1675,3 +1675,10 @@ KernelVersion: 4.12 Contact: [email protected] Description: Raw counter device counters direction for channel Y. + +What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_raw +KernelVersion: 4.18 +Contact: [email protected] +Description: + Raw (unscaled) phase difference reading from channel Y + that can be processed to radians.
drivers/iio/industrialio-core.c +1 -0
@@ -86,6 +86,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_INDEX] = "index", [IIO_GRAVITY] = "gravity", [IIO_POSITIONRELATIVE] = "positionrelative", + [IIO_PHASE] = "phase", };static const char *const iio_modifier_names[] = {
include/uapi/linux/iio/types.h +1 -0
@@ -45,6 +45,7 @@ enum iio_chan_type {IIO_INDEX ,IIO_GRAVITY ,IIO_POSITIONRELATIVE , + IIO_PHASE, }; enum iio_modifier {
tools/iio/iio_event_monitor.c +2 -0
@@ -59,6 +59,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_UVINDEX] = "uvindex", [IIO_GRAVITY] = "gravity", [IIO_POSITIONRELATIVE] = "positionrelative", + [IIO_PHASE] = "phase", };static const char *const iio_ev_type_text[] = {
@@ -153,6 +154,7 @@ static bool event_is_known(struct iio_event_data *event)case IIO_UVINDEX :case IIO_GRAVITY :case IIO_POSITIONRELATIVE : +case IIO_PHASE :break ;default :return false;
Signature · 1 line
2.17.1
PATCH v6 2/3 iio: light: isl29501: Add support for the ISL29501 ToF sensor.
In reply to Mathieu OthaceheThis patch adds support for the ISL29501 Time of Flight sensor.
--- .../ABI/testing/sysfs-bus-iio-isl29501 | 47 + .../bindings/iio/light/isl29501.txt | 13 + drivers/iio/light/Kconfig | 13 + drivers/iio/light/Makefile | 1 + drivers/iio/light/isl29501.c | 1022 +++++++++++++++++ 5 files changed, 1096 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-isl29501 create mode 100644 Documentation/devicetree/bindings/iio/light/isl29501.txt create mode 100644 drivers/iio/light/isl29501.c
Documentation/ABI/testing/sysfs-bus-iio-isl29501 new file +47 -0
@@ -0,0 +1,47 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_agc_gain +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_agc_gain_bias +KernelVersion: 4.18 +Contact: [email protected] +Description: + This sensor has an automatic gain control (agc) loop + which sets the analog signal levels at an optimum + level by controlling programmable gain amplifiers. The + criteria for optimal gain is determined by the sensor. + + Return the actual gain value as an integer in [0; 65536] + range when read from. + + The agc gain read when measuring crosstalk shall be + written into in_proximity0_agc_gain_bias. + +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calib_phase_temp_a +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calib_phase_temp_b +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calib_phase_light_a +What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calib_phase_light_b +KernelVersion: 4.18 +Contact: [email protected] +Description: + The sensor is able to perform correction of distance + measurements due to changing temperature and ambient + light conditions. It can be programmed to correct for + a second order error polynomial. + + Phase data has to be collected when temperature and + ambient light are modulated independently. + + Then a least squares curve fit to a second order + polynomial has to be generated from the data. The + resultant curves have the form ax^2 + bx + c. + + From those two curves, a and b coefficients shall be + stored in in_proximity0_calib_phase_temp_a and + in_proximity0_calib_phase_temp_b for temperature and + in in_proximity0_calib_phase_light_a and + in_proximity0_calib_phase_light_b for ambient light. + + Those values must be integer in [0; 8355840] range. + + Finally, the c constant is set by the sensor + internally. + + The value stored in sensor is displayed when read from.
Documentation/devicetree/bindings/iio/light/isl29501.txt new file +13 -0
@@ -0,0 +1,13 @@ +* ISL29501 Time-of-flight sensor. + +Required properties: + + - compatible : should be "renesas,isl29501" + - reg : the I2C address of the sensor + +Example: + +isl29501@57 { + compatible = "renesas,isl29501"; + reg = <0x57>; +};
drivers/iio/light/Kconfig +13 -0
@@ -194,6 +194,19 @@ config ISL29125 To compile this driver as a module, choose M here: the module will be called isl29125. +config ISL29501 + tristate "Intersil ISL29501 Time Of Flight sensor" + depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select IIO_KFIFO_BUF + help + Say Y here if you want to build a driver for the Intersil ISL29501 + Time of Flight sensor. + + To compile this driver as a module, choose M here: the module will be + called isl29501. + config HID_SENSOR_ALS depends on HID_SENSOR_HUB select IIO_BUFFER
drivers/iio/light/Makefile +1 -0
@@ -23,6 +23,7 @@ obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o obj-$(CONFIG_ISL29125) += isl29125.o +obj-$(CONFIG_ISL29501) += isl29501.o obj-$(CONFIG_JSA1212) += jsa1212.o obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o obj-$(CONFIG_LTR501) += ltr501.o
drivers/iio/light/isl29501.c new file +1022 -0
1,022 lines not on this page · raw message
Signature · 1 line
2.17.1
PATCH v6 3/3 iio: light: isl29501: Add support floating registers.
In reply to Mathieu OthaceheThis is work in progress. A new IIO ABI allowing floating value read and write through sysfs has to be defined first.
--- drivers/iio/light/isl29501.c | 121 ++++++++++++++++++++++++++++++++--- 1 file changed, 112 insertions(+), 9 deletions(-)
drivers/iio/light/isl29501.c +112 -9
@@ -112,11 +112,17 @@ struct isl29501_private {enum isl29501_register_name {REG_DISTANCE , +REG_AMPLITUDE ,REG_PHASE , +REG_I_RAW , +REG_Q_RAW ,REG_TEMPERATURE ,REG_AMBIENT_LIGHT ,REG_GAIN , +REG_I_BIAS , +REG_Q_BIAS ,REG_GAIN_BIAS , +REG_AMPL_BIAS ,REG_PHASE_EXP ,REG_CALIB_PHASE_TEMP_A ,REG_CALIB_PHASE_TEMP_B ,
@@ -133,6 +139,7 @@ enum isl29501_register_name {struct isl29501_register_desc {u8 msb;u8 lsb; +u8 exp; };static const struct isl29501_register_desc isl29501_registers[] = {
@@ -140,10 +147,25 @@ static const struct isl29501_register_desc isl29501_registers[] = { .msb = ISL29501_DISTANCE_MSB_DATA, .lsb = ISL29501_DISTANCE_LSB_DATA, }, + [REG_AMPLITUDE] = { + .msb = ISL29501_MAGNITUDE_MSB, + .lsb = ISL29501_MAGNITUDE_LSB, + .exp = ISL29501_MAGNITUDE_EXPONENT, + }, [REG_PHASE] = { .msb = ISL29501_PHASE_MSB, .lsb = ISL29501_PHASE_LSB, }, + [REG_I_RAW] = { + .msb = ISL29501_I_RAW_MSB, + .lsb = ISL29501_I_RAW_LSB, + .exp = ISL29501_I_RAW_EXPONENT, + }, + [REG_Q_RAW] = { + .msb = ISL29501_Q_RAW_MSB, + .lsb = ISL29501_Q_RAW_LSB, + .exp = ISL29501_Q_RAW_EXPONENT, + }, [REG_TEMPERATURE] = { .lsb = ISL29501_DIE_TEMPERATURE, },
@@ -154,10 +176,25 @@ static const struct isl29501_register_desc isl29501_registers[] = { .msb = ISL29501_GAIN_MSB, .lsb = ISL29501_GAIN_LSB, }, + [REG_I_BIAS] = { + .msb = ISL29501_CROSSTALK_I_MSB, + .lsb = ISL29501_CROSSTALK_I_LSB, + .exp = ISL29501_CROSSTALK_I_EXPONENT, + }, + [REG_Q_BIAS] = { + .msb = ISL29501_CROSSTALK_Q_MSB, + .lsb = ISL29501_CROSSTALK_Q_LSB, + .exp = ISL29501_CROSSTALK_Q_EXPONENT, + }, [REG_GAIN_BIAS] = { .msb = ISL29501_CROSSTALK_GAIN_MSB, .lsb = ISL29501_CROSSTALK_GAIN_LSB, }, + [REG_AMPL_BIAS] = { + .msb = ISL29501_MAGNITUDE_REF_MSB, + .lsb = ISL29501_MAGNITUDE_REF_LSB, + .exp = ISL29501_MAGNITUDE_REF_EXP, + }, [REG_PHASE_EXP] = { .lsb = ISL29501_PHASE_EXPONENT, },
@@ -199,7 +236,7 @@ static int isl29501_register_read(struct isl29501_private *isl29501, u32 *val) {const struct isl29501_register_desc *reg = &isl29501_registers[name]; -u8 msb =0 , lsb =0 ; +u8 msb =0 , lsb =0 , exp =0 ;s32 ret;mutex_lock (&isl29501->lock);
@@ -216,9 +253,16 @@ static int isl29501_register_read(struct isl29501_private *isl29501, goto err; lsb = ret; } + +if (reg->exp) { + ret =i2c_smbus_read_byte_data (isl29501->client, reg->exp); +if (ret <0 ) + goto err; + exp = ret; + }mutex_unlock (&isl29501->lock); - *val = (msb <<8 ) + lsb; + *val = ((msb <<8 ) + lsb) << exp;return 0 ; err:
@@ -238,9 +282,14 @@ static u32 isl29501_register_write(struct isl29501_private *isl29501,if (!reg->msb && value >U8_MAX )return -ERANGE ; -if (value >U16_MAX ) +if (!reg->exp && value >U16_MAX )return -ERANGE ; +if (reg->exp) { +/* TODO: Implement float write */ +return -EINVAL ; + } +if (!reg->msb) { lsb = value &0xFF ; }else {
@@ -519,6 +568,28 @@ static const struct iio_chan_spec isl29501_channels[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), }, + { + .type = IIO_INTENSITY, + .scan_index = -1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + }, + { + .type = IIO_INTENSITY, + .scan_index = -1, + .modified = 1, + .channel2 = IIO_MOD_I, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + }, + { + .type = IIO_INTENSITY, + .scan_index = -1, + .modified = 1, + .channel2 = IIO_MOD_Q, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + }, { .type = IIO_CURRENT, .scan_index = -1,
@@ -633,13 +704,23 @@ static int isl29501_get_raw(struct isl29501_private *isl29501,return IIO_VAL_INT ;case IIO_INTENSITY : - ret =isl29501_register_read (isl29501, -REG_AMBIENT_LIGHT , - raw); -if (ret <0 ) -return ret; +switch (chan->channel2) { +case IIO_NO_MOD : +case IIO_MOD_I : +case IIO_MOD_Q : +/* TODO: implement float read */ +return -EINVAL ; +case IIO_MOD_LIGHT_CLEAR : + ret =isl29501_register_read (isl29501, +REG_AMBIENT_LIGHT , + raw); +if (ret <0 ) +return ret; -return IIO_VAL_INT ; +return IIO_VAL_INT ; +default : +return -EINVAL ; + }case IIO_PHASE : ret =isl29501_register_read (isl29501,REG_PHASE , raw);if (ret <0 )
@@ -684,6 +765,8 @@ static int isl29501_get_scale(struct isl29501_private *isl29501,return IIO_VAL_INT_PLUS_NANO ;case IIO_INTENSITY : +if (chan->channel2 !=IIO_MOD_LIGHT_CLEAR ) +return -EINVAL ;/* light = raw_light * 35 / 10000 (mA) */ *val =35 ; *val2 =10000 ;
@@ -729,6 +812,16 @@ static int isl29501_get_calibbias(struct isl29501_private *isl29501,return isl29501_register_read (isl29501,REG_DISTANCE_BIAS , bias); +case IIO_INTENSITY : +switch (chan->channel2) { +case IIO_NO_MOD : +case IIO_MOD_I : +case IIO_MOD_Q : +/* TODO: Implement float read */ +return -EINVAL ; +default : +return -EINVAL ; + }case IIO_TEMP : return isl29501_register_read(isl29501, REG_TEMPERATURE_BIAS,
@@ -858,6 +951,16 @@ static int isl29501_set_calibbias(struct isl29501_private *isl29501,return isl29501_register_write (isl29501,REG_DISTANCE_BIAS , bias); +case IIO_INTENSITY : +switch (chan->channel2) { +case IIO_NO_MOD : +case IIO_MOD_I : +case IIO_MOD_Q : +/* TODO: Implement float read */ +return -EINVAL ; +default : +return -EINVAL ; + }case IIO_TEMP : return isl29501_register_write(isl29501, REG_TEMPERATURE_BIAS,
Signature · 1 line
2.17.1