Re: [questions] : gpiolib and gpioset behaviour

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

 



On Fri, Apr 26, 2024 at 03:37 PM, Kent Gibson wrote :
> On Fri, Apr 26, 2024 at 03:08:33PM +0200, Gilles BULOZ wrote:
>> On Fri, Apr 26, 2024 at 04:07 AM, Kent Gibson wrote :
>>> On Mon, Apr 22, 2024 at 06:49:05PM +0200, Gilles BULOZ wrote:
>>>> On Mon, Apr 22, 2024 at 3:55 PM Bartosz Golaszewski wrote :
>>>>> On Mon, Apr 22, 2024 at 2:44 PM Gilles BULOZ <gilles.buloz@xxxxxxxxxxx> wrote:
>>>>>>
>
>>>>
>>>
>>> I suspect you are referring to gpiolib here - the mask in gc->get_multiple()
>>> being unsigned long*.
>>>
>>> The uAPI that libgpiod uses is limited to 64 lines per request, but that is
>>> only relevant if you want to request more than 64 lines at once from userspace
>>> (you would have to break that into two requests to access all 112 lines).
>>>
>>> Note that the mask in gc->get_multiple() is unsigned long*, so it is a
>>> pointer to an array of unsigned long.  Its width is not limited by
>>> unsigned long, but by the bits parameter.  In your case the mask you pass
>>> should contain multiple unsigned longs to achieve 112 bits.
>>> Refer to gpiod_get_array_value_complex() for an example of building bitmap
>>> masks to pass to gc->get_multiple(), in that case via
>>> gpio_chip_get_multiple().
>>>
>>
>> I was refering the get_multiple/set_multiple callbacks in struct gpio_chip
>> that are defined like this :
>>  int (*get_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits);
>>  void (*set_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits);
>> With some debug in my GPIO chip driver implementing these functions, I saw that
>> the bits set in "mask" and the ones used in "bits" are the ones whose bit
>> numbers are directly matching the GPIO offset/line numbers of the chip. But I
>> only used unsigned long, not arrays, so I thought I was limited to offset/line
>> 31 on 32bit arch, and 63 on 64bit arch.
>> As you suggested, I'm currently having a look to gpiod_get_array_value_complex()
>> but I must admit I'm currently a little bit lost. I've never thought GPIO
>> implementation could become so complex for my brain :-)
>>
>
> The bit of primary interest that I was referring to was the DECLARE_BITMAP()
> as used for the fastpath mask:
>
>                 DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO);
>
> That does the sizing math for you.  In your case you would use 112 for
> the NGPIO.  There are also examples of using __set_bit() to set bits in
> the mask.  Take a look in linux/bitmaps.h and linux/bitops.h for the
> relevant definitions if you want to dig deeper.
>
> And, yeah, the amount of work that goes into just driving physical
> lines up and down, fundamentally just toggling bits, frequently makes my brain
> hurt too ;-).
>

Thanks very much for the tips !
I've added some debug in my GPIO chip driver in get_multiple()/set_multiple()
and clearly see that when using an unsigned long array for "mask" and "bits",
the second unsigned long in array is used starting from GPIO offset/line 64,
starting from bit 0, then 1 for offset/line 65...
For instance when I run "gpioget 0 65", get_multiple() is called with bit 1 of
mask[1] set and I return the level on bit 1 of bits[1] that is correctly
reported by gpioget.

But get_multiple is called by gpio_chip_get_multiple() than is called by
gpiod_get_array_value_complex() that is called either from 
 linehandle_ioctl() for GPIOHANDLE_GET_LINE_VALUES_IOCTL where we have DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
 linereq_get_values() for GPIO_V2_LINE_GET_VALUES_IOCTL  where we have DECLARE_BITMAP(vals, GPIO_V2_LINES_MAX);
so both vals with 64bits (GPIOHANDLES_MAX=GPIO_V2_LINES_MAX=64) so only one unsigned long.
But vals is passed as last argument unsigned long *value_bitmap to
gpiod_get_array_value_complex() that is passed as last argument
unsigned long *bits to gpio_chip_get_multiple() that
is passed as last argument unsigned long *bits to get_multiple() of my driver
where I'm supposed to fill data in the second unsigned logn of array for GPIO
offset/line >= 64 where we have only allocated one.
I'm probably wrong somewhere.

> Cheers,
> Kent.
> .





[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux