lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 13 Mar 2023 15:34:31 +0200
From:   Matti Vaittinen <mazziesaccount@...il.com>
To:     Jonathan Cameron <jic23@...nel.org>
Cc:     Matti Vaittinen <matti.vaittinen@...rohmeurope.com>,
        Lars-Peter Clausen <lars@...afoo.de>,
        Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
        Dmitry Osipenko <dmitry.osipenko@...labora.com>,
        Paul Gazzillo <paul@...zz.com>,
        Shreeya Patel <shreeya.patel@...labora.com>,
        Zhigang Shi <Zhigang.Shi@...eon.com>,
        linux-kernel@...r.kernel.org, linux-iio@...r.kernel.org
Subject: Re: [PATCH v3 5/6] iio: light: ROHM BU27034 Ambient Light Sensor

On 3/12/23 19:39, Jonathan Cameron wrote:
> On Mon, 6 Mar 2023 11:23:50 +0200
> Matti Vaittinen <mazziesaccount@...il.com> wrote:
> 
>> ROHM BU27034 is an ambient light sensor with 3 channels and 3 photo diodes
>> capable of detecting a very wide range of illuminance. Typical application
>> is adjusting LCD and backlight power of TVs and mobile phones.
>>
>> Add initial  support for the ROHM BU27034 ambient light sensor.
>>
>> NOTE:
>> 	- Driver exposes 4 channels. One IIO_LIGHT channel providing the
>> 	  calculated lux values based on measured data from diodes #0 and
>> 	  #1. In addition, 3 IIO_INTENSITY channels are emitting the raw
>> 	  register data from all diodes for more intense user-space
>> 	  computations.
>> 	- Sensor has GAIN values that can be adjusted from 1x to 4096x.
>> 	- Sensor has adjustible measurement times of 5, 55, 100, 200 and
>> 	  400 mS. Driver does not support 5 mS which has special
>> 	  limitations.
>> 	- Driver exposes standard 'scale' adjustment which is
>> 	  implemented by:
>> 		1) Trying to adjust only the GAIN
>> 		2) If GAIN adjustment alone can't provide requested
>> 		   scale, adjusting both the time and the gain is
>> 		   attempted.
>> 	- Driver exposes writable INT_TIME property that can be used
>> 	  for adjusting the measurement time. Time adjustment will also
>> 	  cause the driver to try to adjust the GAIN so that the
>> 	  overall scale is kept as close to the original as possible.
>>
>> Signed-off-by: Matti Vaittinen <mazziesaccount@...il.com>
>>
>> ---
>>
>> Please note: There are few "unfinished" discussions regarding at least:
>>
>> - PROCESSED channel scale.
> 
> Hopefully the reply in the other thread covered this.
> It's not PROCESSED as you need to apply the * 1000 so just
> make it _RAW.
> 

Your reply in the other thread was just fine :) I think I'll round the 
result to luxes (which should be sufficient to many users if I am not 
mistaken) - and provide the PROCESSED values to user-space for the sake 
of the ultimate simplicity for users.

>> - Implementation details when avoiding division by zero.
>>
>> I have implemented those for this version in a way that I see the best.
>> It would have been better to wait for discussions to finish - but I will
>> be away from the computer for a week - so I wanted to send out the v3
>> with fixes so that people who are interested can do a review while I am
>> away.
> 
> I'm getting behind with review anyway so a week delay on this sounds great to
> me ;)  I might get to your other series as a result though don't think I'll get there today.
> 

Oh, the week elapsed already ;) But don't sweat on it - this series grew 
quite large so spending time on reviewing makes perfect sense. I _know_ 
reviewing, and especially careful reviewing, takes time. And energy. 
Sometimes we lack of both, occasionally just the other :) Thanks for all 
the effort you and Andy have put on this so far!

> 
>> +static int bu27034_calc_mlux(struct bu27034_data *data, __le16 *res, int *val)
>> +{
>> +	unsigned int gain0, gain1, meastime;
>> +	unsigned int d1_d0_ratio_scaled;
>> +	u16  ch0, ch1;
>> +	u64 helper64;
>> +	int ret;
>> +
>> +	/*
>> +	 * We return 0 luxes if calculation fails. This should be reasonably
>> +	 * easy to spot from the buffers especially if raw-data channels show
>> +	 * valid values
>> +	 */
>> +	*val = 0;
>> +
>> +	/*  Avoid div by zero. */
>> +	if (!res[0])
>> +		ch0 = 1;
>> +	else
>> +		ch0 = le16_to_cpu(res[0]);
>> +
>> +	if (!res[1])
>> +		ch1 = 1;
>> +	else
>> +		ch1 = le16_to_cpu(res[1]);
>> +
> 
> As per other thread. Really don't like the check on 0 before
> the endian conversion.  Sure it can be done, but it's a micro optimization that
> seems unnecessary.

Ugh... Andy pointed me the max_t(). I'll use it even though I do really 
dislike that change a lot.

> 
> ...
> 
>> +
>> +static int bu27034_read_raw(struct iio_dev *idev,
>> +			   struct iio_chan_spec const *chan,
>> +			   int *val, int *val2, long mask)
>> +{
>> +	struct bu27034_data *data = iio_priv(idev);
>> +	int ret;
>> +
>> +	switch (mask) {
>> +	case IIO_CHAN_INFO_INT_TIME:
>> +		*val = bu27034_get_int_time(data);
>> +		if (*val < 0)
>> +			return *val;
>> +
>> +		/*
>> +		 * We use 50000 uS internally for all calculations and only
>> +		 * convert it to 55000 before returning it to the user.
>> +		 *
>> +		 * This is because the data-sheet says the time is 55 mS - but
>> +		 * vendor provided computations used 50 mS.
> 
> No chance of a clarification?  would be lovely to not do this!

Actually, since the current code uses the multiplier-field in 
gts-helpers - it may be we can just use the 55000 in the tables now. I 
need to check it. So perhaps we can avoid this one now! Thanks!

> 
>> +		 */
>> +		if (*val == 50000)
>> +			*val = 55000;
>> +
>> +		return IIO_VAL_INT;
>> +
>> +	case IIO_CHAN_INFO_SCALE:
>> +		return bu27034_get_scale(data, chan->channel, val, val2);
>> +
>> +	case IIO_CHAN_INFO_RAW:
>> +	{
>> +		if (chan->type != IIO_INTENSITY)
>> +			return -EINVAL;
>> +
>> +		if (chan->channel < BU27034_CHAN_DATA0 ||
>> +		    chan->channel > BU27034_CHAN_DATA2)
>> +			return -EINVAL;
>> +
>> +		/* Don't mess with measurement enabling while buffering */
>> +		ret = iio_device_claim_direct_mode(idev);
>> +		if (ret)
>> +			return ret;
>> +
>> +		mutex_lock(&data->mutex);
>> +		/*
>> +		 * Reading one channel at a time is ineffiecient but we don't
> 
> spell check comments.
> 
>> +		 * care here. Buffered version should be used if performance is
>> +		 * an issue.
>> +		 */
>> +		ret = bu27034_get_single_result(data, chan->channel, val);
>> +
>> +		mutex_unlock(&data->mutex);
>> +		iio_device_release_direct_mode(idev);
>> +
>> +		if (ret)
>> +			return ret;
>> +
>> +		return IIO_VAL_INT;
>> +	}
>> +
>> +	case IIO_CHAN_INFO_PROCESSED:
>> +		if (chan->type != IIO_LIGHT)
>> +			return -EINVAL;
>> +
>> +		/* Don't mess with measurement enabling while buffering */
>> +		ret = iio_device_claim_direct_mode(idev);
>> +		if (ret)
>> +			return ret;
>> +
>> +		mutex_lock(&data->mutex);
>> +
>> +		ret = bu27034_get_mlux(data, val);
>> +
>> +		mutex_unlock(&data->mutex);
>> +		iio_device_release_direct_mode(idev);
>> +
>> +		if (ret)
>> +			return ret;
>> +
>> +		return IIO_VAL_INT;
>> +
>> +	default:
>> +		return -EINVAL;
>> +
>> +	}
>> +
>> +	return ret;
> 
> I would hope you can't get here. If you can fix that so
> that the lack of return here allows the compiler to know  you didn't
> intend to get here and hence complain about it.
> 

Sigh. I personally still think functions should return from the end... 
Well, I will revise this for v4.

> 
>> +static int bu27034_probe(struct i2c_client *i2c)
>> +{
>> +	struct device *dev = &i2c->dev;
>> +	struct bu27034_data *data;
>> +	struct regmap *regmap;
>> +	struct iio_dev *idev;
>> +	unsigned int part_id, reg;
>> +	int ret;
>> +
>> +	regmap = devm_regmap_init_i2c(i2c, &bu27034_regmap);
>> +	if (IS_ERR(regmap))
>> +		return dev_err_probe(dev, PTR_ERR(regmap),
>> +				     "Failed to initialize Regmap\n");
>> +
>> +	idev = devm_iio_device_alloc(dev, sizeof(*data));
>> +	if (!idev)
>> +		return -ENOMEM;
>> +
>> +	ret = devm_regulator_get_enable(dev, "vdd");
>> +	if (ret && ret != -ENODEV)
> 
> Why the special -ENODEV handling?
> You should get a stub regulator if one isn't provided by firmware.
> If you don't get a stub, or a real regulator that's a failure so we should
> return the error code and fail the probe.

I am actually not sure. Maybe my test setup didn't have the dummy 
regulator assigned. I will re-check this.


The comments which I just skipped are something I more or less agree with :)

Best Regards
	-- Matti


-- 
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ