Hi deee Ho peeps,
I am currently writing drivers for couple of ROHM light sensors. At
least two RGBC+IR and one ALS. I have some difficulties deciding how
some of the IIO API values should be mapped to the sensor configs. (So,
not missing much, right? Basically just THE THING any IIO driver is
expected to do XD).
Okay, that's for the intro. I'll ask about the ALS first.
=== The Hardware:
The sensor gets the data from 3 photo-diodes - values from each are
readable via own channel (say, data0, data1, data2).
data0 and data1 have the sensitivity peaks around 500 and 600 nm - which
is visible light but channels are not really R/G/B. The data2 is
probably IR - but I am not really 100% sure so I plan to skip it at first.
The channel gain can be set individually,. The sampling time can be set
globally for all channels.
=== The driver draft I'm working with
I have some kind of formula for converting the channel0 and channel1
data to lux. So, I thought I'll provide 3 channels from driver - one
IIO_CHAN_INFO_PROCESSED IIO_LIGHT channel spilling out luxes (with
appropriate scale) - and two IIO_INTENSITY channels spilling out the raw
register values so that if greater accuracy is needed one can do better
algorithms to user-space.
Q1 - does this sound like reasonable option?
Then, I thought I'll support setting the GAIN for channels using the
IIO_CHAN_INFO_SCALE. Straightforward division / multiplication (I hope).
Eg, for the IIO_INTENSITY channels I though I'll just implement
raw_write/raw_read for scale so, that raw_read returns
IIO_VAL_INT_PLUS_NANO - and then for example gain 4x would be
val = 0, val2 = 250 MEGA, 8x would be 0, 1 * GIGA / 8 ...
Eg, val2 for gain values > 1 would be GIGA/gain using IIO_VAL_INT_PLUS_NANO.
I hope this makes sense :)
Well, currently my "not-yet-implemented using C w/o floats" - algorithm
takes the scale into account and always returns luxes (for
IIO_CHAN_INFO_PROCESSED IIO_LIGHT - channel). However, the IIO_INTENSITY
channels return raw data from registers - so setting GAIN (scale) has
direct impact to the INTENSITY values. I guess this is Ok as the
IIO_CHAN_INFO_SCALE is only set in .info_mask_separate for the
IIO_INTENSITY type channels - not for the IIO_CHAN_INFO_PROCESSED
IIO_LIGHT channel. [Even though I decided to go this route I am still
somewhat unsure if this is the right thing to do(tm). My problem is that
in HW level, setting the GAIN does also impact the data based on which
the IIO_LIGHT values are computed. The scale just is not visible in
computed values as it is taken into account by the equation.
Furthermore, setting GAIN(or scale) for IIO_LIGHT would not be
unambiguous as the IIO_LIGHT is composed from two channels, both having
own gain settings.]
I hope this is all Ok from interface POV.
Now, finally, my dear persistent readers - the question:
As mentioned, sensor allows setting the sampling time. I thought I'll
map this to the IIO_CHAN_INFO_INT_TIME. This config is not per/channel
in the hardware. Again, my lux-computing algorithm takes the integration
time into account - and changing the time should not be reflected to the
IIO_LIGHT channel values (other than accuracy). However, the values
spilled from raw IIO_INTENSITY channels will change when integration
time is changed. So, should I use the info_mask_shared_by_type =
BIT(IIO_CHAN_INFO_INT_TIME) for IIO_INTENSITY channels?
Sorry for the long post. I do appreciate all help/pointers on my journey
to writing my first light sensor drivers ;) And yes, my plan is to send
out the patches - when I first get the sensor hardware at my hands ;)
Yours,
-- Matti
--
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland
~~ When things go utterly wrong vim users can always type :help! ~~