Hi deeee Ho peeps,
The ROHM BU27034 work seems to be slowly converging :) So, it is a good
time to start working with the next sensor sitting on my table.
This time I am dealing with an RGB+c+IR sensor, which once again has
some peculiarities. I would again be very grateful for any and all
pointers so I could head to the right direction.
The IC has 4 data channels. First two being always RED and GREEN. Third
can be configured to BLUE or CLEAR and fourth can be set to CLEAR or IR.
I think I have the basic driver done. I expose all of the RGBC and IR as
own channels. Raw read is supported for all, and channels 3 and 4 are
configured for the read depending on channel to be read being B, C or IR.
The device has a "data ready" IRQ, which is used for a trigger.
Triggered buffer is supported and channel configuration is written at
buffer enable, based on the active_scan_mask. The available_scan_masks
field is populated to prevent enabling all of the B, C and IR at same
time (because only 2 of them can be measured at same time as only 2
channels can be configured for B, C and IR).
I have following questions:
1) I have no good knowledge as to what units the register values
represent. I know the greater value informs greater color intensity -
but that's about it. I currently just send out the raw register values
via IIO_INTENSITY raw channel - but I don't know if this is usual or if
typical user-space would expect the values to be some how 'normalized'?
With the current setup user-space needs to either just compare the
different channel values to each other to decide which colour dominates
- or perform some manual calibration using known light sources. I have
no idea if this is usual approach with RGB sensors? It seems to me that
for example the adjd_s311.c just returns raw register values - but I
don't know what the format is. Any insight on if the values should
represent some 'units' or if they can really just be 'register values
proportional to intensity of measured colour'.
2) The gain setting is once again ... eh ... complicated. The RGB and C
channels are sharing gain setting. There are a few supported gain values
- ranging from 1X to 1024X. The IR channel _shares_ again the high bits
of GAIN setting with the RGBC channels. Two lowest bits can be set
independently - but again, quite a few gain 'selector' field values are
marked as forbidden.
To make it worse, the IR gain values matching the selector field are
same as for RGBC - except the first selector. The sel 0 equals to gain
1X on RGBC, but gain 2X for IR. (1X is not supported for IR). So,
changing gain selector from 0 => 1 will cause gain to jump from 1X => 4X
for RGBC but from 2X => 4X for IR channel.
I see two options:
1) Use fixed high bits which means supporting only 4X and 16X gains -
for which changing the low selector bits is enough. In this case the
RGBC would have own gain setting, IR would have own and there would be
no shared bits.
2) Allow full range of supported gains to be set for RGBC - and disallow
setting gain for IR. However, change the IR gain to have same selector
as RGBC gain when RGBC gain is changed. (This prevents IR gain selector
from changing to an unsupported value when RGBC gain is changed). This
means that if user-space changes the gain for RGBC, it should also
read-back the gain for IR to detect the change. I have no idea if
existing user-space apps do this.
I think that no matter if we select option 1) or option 2) - we must
have own scale entries for all channels. This is needed for option 2)
because of the 1X vs 2X difference mentioned above.
I have currently implemented the option 2) because it supports wider
variety of gains - but I am unsure if this is "the right thing to do".
Any insight is appreciated!
Yours,
-- Matti
--
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland
~~ When things go utterly wrong vim users can always type :help! ~~