Re: [PATCH 5/5] iio: light: vcnl4000: add control of multi pulse

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed,  5 Feb 2020 11:16:55 +0100
Tomas Novotny <tomas@xxxxxxxxxx> wrote:

> Multi pulse settings allow to emit more pulses during one measurement
> (up to 8 on vcnl4040 and vcnl4200). The raw reading is approximately
> multiplied by the multi pulse settings. More information is available in
> the added documentation.
> 
> Multi pulse is specific only for proximity sensor. Only the vcnl4040 and
> vcnl4200 hardware supports this settings.

A few comments but this one is more or less good.

Thanks,

Jonathan

> 
> Signed-off-by: Tomas Novotny <tomas@xxxxxxxxxx>
> ---
>  Documentation/ABI/testing/sysfs-bus-iio-vcnl4000 | 21 +++++++++
>  drivers/iio/light/vcnl4000.c                     | 60 ++++++++++++++++++++++++
>  2 files changed, 81 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-vcnl4000 b/Documentation/ABI/testing/sysfs-bus-iio-vcnl4000
> index 4860f409dbf0..923a78dc9869 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio-vcnl4000
> +++ b/Documentation/ABI/testing/sysfs-bus-iio-vcnl4000
> @@ -16,3 +16,24 @@ KernelVersion:	5.7
>  Contact:	linux-iio@xxxxxxxxxxxxxxx
>  Description:
>  		The on/off available duty ratios.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/in_proximity_multi_pulse

This is less ambiguous than duty_cycle, but perhaps something 
in_proximity_led_pulse_count is more specific?

> +Date:		February 2020
> +KernelVersion:	5.7
> +Contact:	linux-iio@xxxxxxxxxxxxxxx
> +Description:
> +		Instead of one single pulse per every measurement, more pulses
> +		may be programmed. This leads to a longer led current on-time
> +		for each proximity measurement, which also results in a higher
> +		detection range. The raw reading is approximately multiplied by
> +		the multi pulse settings. The duty ration is not changed. The

Hmm. Normal meaning of duty ratio would be changed by this...  It's uneven but
multiple pulses == more on time hence lower duty ratio.

> +		settings cannot be changed when the proximity channel is
> +		enabled.  Valid values are in the respective '_available'
> +		attribute.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/in_proximity_multi_pulse_available
> +Date:		February 2020
> +KernelVersion:	5.7
> +Contact:	linux-iio@xxxxxxxxxxxxxxx
> +Description:
> +		List of multi pulse values.
> diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
> index a8c2ce1056a6..cc75e5e7e634 100644
> --- a/drivers/iio/light/vcnl4000.c
> +++ b/drivers/iio/light/vcnl4000.c
> @@ -46,6 +46,7 @@
>  
>  #define VCNL4200_AL_CONF	0x00 /* Ambient light configuration */
>  #define VCNL4200_PS_CONF1	0x03 /* Proximity configuration */
> +#define VCNL4200_PS_CONF3	0x04 /* Proximity conf., white channel, LED I */
>  #define VCNL4200_PS_DATA	0x08 /* Proximity data */
>  #define VCNL4200_AL_DATA	0x09 /* Ambient light data */
>  #define VCNL4200_DEV_ID		0x0e /* Device ID, slave address and version */
> @@ -65,6 +66,8 @@
>  #define VCNL4200_PS_DUTY_MASK	GENMASK(7, 6) /* Proximity duty ratio */
>  #define VCNL4200_PS_DUTY_SHIFT	6
>  #define VCNL4200_PS_SD		BIT(0) /* Proximity shutdown */
> +#define VCNL4200_PS_MPS_MASK	GENMASK(6, 5)
> +#define VCNL4200_PS_MPS_SHIFT	5

You could probably use the FIELD_PREP  macros etc to avoid having both mask and
shift defines.

>  
>  enum vcnl4000_device_ids {
>  	VCNL4000,
> @@ -223,11 +226,24 @@ static const char * const vcnl4200_ps_duty_ratio_items[] = {
>  	"1/1280"
>  };
>  
> +/* Values are directly mapped to register values. */
> +static const char * const vcnl4200_ps_multi_pulse_items[] = {
> +	"1",
> +	"2",
> +	"4",
> +	"8"
> +};
> +
>  static int vcnl4200_get_ps_duty_ratio(struct iio_dev *indio_dev,
>  				      const struct iio_chan_spec *chan);
>  static int vcnl4200_set_ps_duty_ratio(struct iio_dev *indio_dev,
>  				      const struct iio_chan_spec *chan,
>  				      unsigned int mode);
> +static int vcnl4200_get_ps_multi_pulse(struct iio_dev *indio_dev,
> +				       const struct iio_chan_spec *chan);
> +static int vcnl4200_set_ps_multi_pulse(struct iio_dev *indio_dev,
> +				       const struct iio_chan_spec *chan,
> +				       unsigned int mode);
>  
>  static const struct iio_enum vcnl4040_ps_duty_ratio_enum = {
>  	.items = vcnl4040_ps_duty_ratio_items,
> @@ -243,15 +259,26 @@ static const struct iio_enum vcnl4200_ps_duty_ratio_enum = {
>  	.set = vcnl4200_set_ps_duty_ratio,
>  };
>  
> +static const struct iio_enum vcnl4200_ps_multi_pulse_enum = {
> +	.items = vcnl4200_ps_multi_pulse_items,
> +	.num_items = ARRAY_SIZE(vcnl4200_ps_multi_pulse_items),
> +	.get = vcnl4200_get_ps_multi_pulse,
> +	.set = vcnl4200_set_ps_multi_pulse,
> +};
> +
>  static const struct iio_chan_spec_ext_info vcnl4040_ps_ext_info[] = {
>  	IIO_ENUM("duty_ratio", IIO_SEPARATE, &vcnl4040_ps_duty_ratio_enum),
>  	IIO_ENUM_AVAILABLE("duty_ratio", &vcnl4040_ps_duty_ratio_enum),
> +	IIO_ENUM("multi_pulse", IIO_SEPARATE, &vcnl4200_ps_multi_pulse_enum),
> +	IIO_ENUM_AVAILABLE("multi_pulse", &vcnl4200_ps_multi_pulse_enum),
>  	{ },
>  };
>  
>  static const struct iio_chan_spec_ext_info vcnl4200_ps_ext_info[] = {
>  	IIO_ENUM("duty_ratio", IIO_SEPARATE, &vcnl4200_ps_duty_ratio_enum),
>  	IIO_ENUM_AVAILABLE("duty_ratio", &vcnl4200_ps_duty_ratio_enum),
> +	IIO_ENUM("multi_pulse", IIO_SEPARATE, &vcnl4200_ps_multi_pulse_enum),
> +	IIO_ENUM_AVAILABLE("multi_pulse", &vcnl4200_ps_multi_pulse_enum),
>  	{ },
>  };
>  
> @@ -638,6 +665,39 @@ static int vcnl4200_set_ps_duty_ratio(struct iio_dev *indio_dev,
>  	return vcnl4200_set_samp_rate(data, IIO_PROXIMITY);
>  };
>  
> +static int vcnl4200_get_ps_multi_pulse(struct iio_dev *indio_dev,
> +				       const struct iio_chan_spec *chan)
> +{
> +	int ret;
> +	unsigned int val;
> +	struct vcnl4000_data *data = iio_priv(indio_dev);
> +
> +	ret = regmap_read(data->regmap, VCNL4200_PS_CONF3, &val);
> +	if (ret < 0)
> +		return ret;
> +
> +	val &= VCNL4200_PS_MPS_MASK;
> +	val >>= VCNL4200_PS_MPS_SHIFT;
> +
> +	return val;
> +};
> +
> +static int vcnl4200_set_ps_multi_pulse(struct iio_dev *indio_dev,
> +				       const struct iio_chan_spec *chan,
> +				       unsigned int mode)
> +{
> +	int ret;
> +	struct vcnl4000_data *data = iio_priv(indio_dev);
> +
> +	ret = vcnl4200_check_enabled(data, IIO_PROXIMITY);
> +	if (ret < 0)
> +		return ret;
> +
> +	return regmap_update_bits(data->regmap, VCNL4200_PS_CONF3,
> +				  VCNL4200_PS_MPS_MASK,
> +				  mode << VCNL4200_PS_MPS_SHIFT);
> +};
> +
>  static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
>  	[VCNL4000] = {
>  		.prod = "VCNL4000",




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux