Re: [RFC] iio: Add support for describing scan offsets in buffer ops

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

 



On 03/05/16 14:37, Crestez Dan Leonard wrote:
> Hello,
> 
> This is a tentative proposal with no code attached. This issue came up
> while hacking on the mpu6050 driver but it applies to other complex
> devices and a solution belongs in the IIO core.
I'm not so convinced (yet).  This is actually a fairly unusual case and the
'byte mangling' can often be handled in a relatively fixed way in a
driver whereas it can be more complex in the core.

Interesting idea though..  Effectively you are hand specifying the
demux tables that we generate and making them more flexible.
> 
> One IIO limitation is that while samples can be described through a
> relatively generic scan_type they must be placed in the output buffer
> according to an specific iio alignment algorithm. For example if the
> device has one 16bit channel and one 32bit channel the output needs to
> have 16bits of padding between them. When this does not match the
> hardware format the solution is for the driver to unpack the hardware
> samples and repack them in the iio format.
It's pretty much got to happen somewhere to get the data into a form that
can be used at speed. Remember we are doing this on the back of expensive
bus transactions (a lot of the time).
> 
> I propose that we add a new function in iio_buffer_setup_ops which looks
> like this:
> 
> int (*get_scan_offsets)(struct iio_dev *indio_dev,
>                         off_t *scan_offsets,
> 			size_t *sample_bytes);
> 
> This would be called when enabling a buffer to fetch the offset in the
> sample for each channel (by scan_index) based on the currently
> configured scan mask. Then the iio core would then handle rearranging
> sample bytes as expected by the buffer consumer. Driver implementations
> could look something like this:
> 
> off_t pos = 0;
> if (scan_mask & (1 << SCAN_INDEX_TEMP))) {
>     scan_offsets[SCAN_INDEX_TEMP] = pos++;
> }
> /* No 2-bytes alignment here! */
> if (scan_mask & SCAN_MASK_ACCEL_ANY) {
>     scan_offsets[SCAN_INDEX_ACCEL_X] = pos + 0;
>     scan_offsets[SCAN_INDEX_ACCEL_Y] = pos + 2;
>     scan_offsets[SCAN_INDEX_ACCEL_Z] = pos + 4;
>     pos += 6;
> }
> *sample_bytes = pos;
Sure - this side is straight forward enough.  It's the core complexity
that makes me wonder if this is worthwhile.  Btw if this is worth doing
then we should really be looking at non byte aligned packed records as
well (just to make it really hideous!)

The killer in here is endian requirements. If the core is repacking data
it will need to understand these completely.  Two options exist, either
the core needs to 'edit' the shift provided by the driver, or it needs
to do endian dependent data realignment.

Take a typical 3 byte unaligned packed record being expanded to a
4 byte aligned record.  I think the easy cases are:

ABC -> 0ABC
CBA -> CBA0
so endian dependent shifts.

Whereas a repack in the driver should inherently know what the right combination
should be. 

I'm not saying it couldn't be done in the core of course, merely that
it is more complex that it initially looks.

I've already suggested we might look at doing a few 'special cases'
to relax the power of two requirement - but I'd do that off the back of
the current description rather than introducing another.  It does have
the same complexity issues though so until we have code I'm
unconvinced it is worth it.

> 
> This could be implemented as an extension to the current buffer demuxing
> support which currently only deals with differences in scan_masks. This
> mechanism would very nicely deal with devices where it is not possible
> to select X/Y/Z individually because the iio core would just ignore the
> gap in offsets.
> 
> This can even be exposed to userspace in a compatible manner. User would
> do something like:
> 
>     ioctl(iio_fd, IIO_USER_HANDLES_SCAN_OFFSETS, 1);
>     ioctl(iio_fd, IIO_GET_SCAN_OFFSETS, &scan_offsets, &sample_bytes);
> 
> When the consumer is marked as aware of scan offsets this way the iio
> core can skip demuxing for increased performance. The IIO core can
> implement IIO_GET_SCAN_OFFSETS itself when the driver has no custom
> implementation. An application could rely on IIO_GET_SCAN_OFFSETS for
> all devices as long as it's acceptable to ignore old kernels.
Be careful here. The demux wasn't actually written in the first
place for this usage at all (it was an added bonus)

It's about sending different streams
of data to different consumers. That is definitely not compatible
with passing this stuff up to user space as it's downright complex
to do.  Making in kernel consumers aware of this more complex handling
is going to be fiddly.  Again could be done, but is it worth it?
I suppose we could make the demux aware of what it is sending to, but
that adds more complexity.
> 
> This would be particularly useful if IIO sample buffers are
> memory-mapped eventually. I think that this extension would be
> incrementally useful to that effort.

Perhaps.  I'm interested to hear other views on this suggestion, but
right now I'm not convinced.  I'd argue that we want clean data
presentations to userspace and that the restrictions as they currently
stand are not really that burdensome on the data.

The exception is dma buffers - in those cases it really might be the
case that we want to allow more complex alignment.

Right now there is no option to have multiple consumers for a dma
buffer and I'm not sure there ever will be.  However, they don't
fall into categories where we use the multiconsumer stuff now
(which is mostly about SoC ADCs with lots of different types of
channel for things like thermal / battery monitoring - there are
other issues there between polled and pushed data flows, but that
is a whole different issue!)

Hence for DMA buffers there is no need to enforce the power of
two byte alignment requirements though, the first time this
happens we should think carefully about whether we 'want' to
allow the additional flexibility.

Jonathan
 

--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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