Getting started with pinctrl subsystem linux

A pin controller is a piece of hardware, usually a set of registers, that can control PINs. It may be able to multiplex, bias, set load capacitance, set drive strength, etc. for individual pins or groups of pins.

 

PINMUX

 

PINCONF - electronic properties e.g. high impedance, tristate, input pin to VDD or GND using a certain resistor value - pull up and pull down so that the pin has a stable value when nothing is driving the rail it is connected to, or when it’s unconnected. Pin configuration can be programmed by adding configuration entries into the mapping table

 

 

say that we have a group of pins dealing with an SPI interface on { 0, 8, 16, 24 }, and a group of pins dealing with an I2C interface on pins on { 24, 25 }.

 

make a group

static const unsigned int spi0_pins[] = { 0, 8, 16, 24 };
static const unsigned int i2c0_pins[] = { 24, 25 };
//combine them 
static const struct foo_group foo_groups[] = {
        {
                .name = "spi0_grp",
                .pins = spi0_pins,
                .num_pins = ARRAY_SIZE(spi0_pins),
        },
        {
                .name = "i2c0_grp",
                .pins = i2c0_pins,
                .num_pins = ARRAY_SIZE(i2c0_pins),
        },
}; 
 

Then create functions to retrieve the name and pins of the group 

 

Interaction with the GPIO subsystem

We need a mapping so that the pin control subsystem can figure out which pin controller handles control of a certain GPIO pin GPIO ranges can be added to a pin controller instance.

struct gpio_chip chip_a;
struct gpio_chip chip_b;

static struct pinctrl_gpio_range gpio_range_a = {
        .name = "chip a",
        .id = 0,
        .base = 32,
        .pin_base = 32,
        .npins = 16,
        .gc = &chip_a;
};

static struct pinctrl_gpio_range gpio_range_b = {
        .name = "chip b",
        .id = 0,
        .base = 48,
        .pin_base = 64,
        .npins = 8,
        .gc = &chip_b;
};

{
        struct pinctrl_dev *pctl;
        ...
        pinctrl_add_gpio_range(pctl, &gpio_range_a);
        pinctrl_add_gpio_range(pctl, &gpio_range_b);
}

 

So now one pin controller handling two different GPIO chips. 

chip a” has 16 pins and “chip b” has 8 pins. The “chip a” and “chip b” have different .pin_base, which means a start pin number of the GPIO range.

 

tbc....

 
 

 

Comments

Popular posts from this blog

dev_get_platdata understanding

How to take systrace in android