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. > .