0

I am building LineageOS 14.1 from source and I am integrating a PCF857x GPIO-expander driver into my Linux kernel (Version ~3.2 Linux). The driver itself (pcf857x.c, pcf857x.h) is already included in the kernel. So I just need to set it up to specify my specific GPIO expander (PCF8574). As this is built on an older version of the Linux kernel, I use a board file to setup this driver.

/* PCF8574 GPIO expander platform data */
static struct pcf857x_platform_data pcf857x_data[] = {
    {
            .gpio_base = 300,   
    },
};

/* I2C1 */
static struct i2c_board_info i2c_devs1[] __initdata = {
    {
        I2C_BOARD_INFO("pcf857x", 0x20),
            .type = "pcf8574",
            .platform_data = &pcf857x_data[0],
    },  
};

When I eventually flash the LineageOS build onto my hardware (Samsung Galaxy S2 AT&T i777 which runs on an Exynos4210 SoC), I see the device registered on the appropriate I2C bus at the correct address (I2C1 at 0x20). However, I do not see any GPIOs being registered. For now, I have not actually connected my expander to my I2C1 bus yet, but I think I should still be able to see the GPIOs registered. Specifically, I should see GPIO 300-307 registered (as it is an 8 bit expander). But I don't.

The GPIOs that I do see from the hardware via "cat /sys/kernel/debug/gpio" range from 0-287. Since I don't want to conflict with any physical GPIO, I chose my expander GPIOs to be out of this range (300+). Part of the problem I believe is that GPIOs out of this range don't exist. When I try to export GPIO 300, nothing happen (echo 300 > /sys/class/gpio/export). In the kernel, there is a macro "ARCH_NR_GPIOS" that defines the total number of GPIOs (both built-in/SoC GPIOs and more such as those on GPIO expanders). I tried increasing this ARCH_NR_GPIOS several times, even to 1000 at one point. But I still cannot export anything beyond the original 0-287 GPIOs (I can't export some of these as some are currently used by other drivers but I can export many of them). What do you think the issue might be?

JoeG
  • 33
  • 1
  • 7
  • Perhaps you may need to work with existing and connected hardware? Otherwise you need a virtual machine that has a model of such device being emulated. – 0andriy Apr 04 '18 at 23:14
  • Thanks for the response. Will test that. I'm also trying to see where in the kernel I can also expand my GPIOs (e.g., gpio-exynos4.c). Thanks again for your feedback. Will hopefully update soon. – JoeG Apr 05 '18 at 00:59
  • I gave it a try but no success unfortunately. The thing is, I can't even export any GPIOs beyond 287. If I type in "echo 300 > /sys/class/gpio/export" I don't see anything. So I'm just working on trying to export any GPIO beyond 287. I think I need to expand my GPIOs in the kernel as aforementioned. I think that will solve the issue. How do I expand the number of GPIOs recognized by the kernel? Looks like playing with ARCH_NR_GPIOS doesn't work for me. – JoeG Apr 05 '18 at 02:56
  • Do you **really** have actual hardware connected? What tools from `libgpiod` project show you (ah, okay, kernel you have is too antique, so, check */sys/class/gpio/...* in this case)? – 0andriy May 12 '18 at 19:49
  • I connected the device to what I believed was the appropriate i2c bus at the time. I did not, at the time, have the i2cdetect tools installed so I was unable to ensure that I was actually connected to the proper i2c bus. There are about 15 i2c buses. So it's possible I was connected to the wrong bus. I have the i2cdetect tools now. However, I have taken down my setup so I cannot test this as of now. But I do believe you are correct about having the hardware connected. I went through the code and I did see probe functions, indicating that the kernel probes the device if it is present. – JoeG May 14 '18 at 21:03
  • Will test later I hope but I have currently decided to go with a uC instead of a GPIO expander (as I require other functionalities). But again, I believe you are correct about the device needing to be connected to the system during the booting process (as that is when the probe function is called I believe). – JoeG May 14 '18 at 21:07
  • Actually it depends how you enumerate the device. At running kernel you may always modprobe the driver and **bind** any i2c device on the bus to that driver (of course you must be sure the device is connected and the driver is compatible for it). – 0andriy May 14 '18 at 21:12
  • That is true. I had the driver associated with a certain bus on my board file (not device tree as my kernel version is older). But you are right. I forgot that I could just bind the i2c device on whatever bus the device is on to the corresponding driver. Therefore, I don't need to worry about what bus I'm on (so long as I can find the device) and I can bind device to driver at any time (not just during booting). Thanks for that info! – JoeG May 14 '18 at 21:17
  • 1
    I think the following stackoverflow Q and A might be very relevant to my question posted here: https://stackoverflow.com/questions/37168540/linux-arm-why-is-gpiochipnum-only-created-if-i2c-gpio-expander-is-present-at – JoeG May 14 '18 at 21:23
  • Yes, and this article: https://lwn.net/Articles/143397/ – 0andriy May 14 '18 at 21:28
  • Great! Thanks again 0andriy for all your help! – JoeG May 14 '18 at 21:35

0 Answers0