Pinctrl one of the fundamental concepts of the subsystem [turn]

Transfer: https://blog.csdn.net/u012830148/article/details/80609337

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: HTTPS: //blog.csdn.net/u012830148/article/details/80609337
1.Linux Pinctrl subsystem Introduction
In many internal soc all contain pin controller, through the register pin controller, we can configure one or a set of pin functions and features. On the software side, Linux kernel provides pinctrl subsystem, the purpose of the harmonization of the soc manufacturers pin foot management.

2.Linux Pinctrl subsystem provides functionality
    (1) management system can control all the pin, at system initialization time, enumerate all the pin can be controlled, and identify those pin.

    (2) management of these pin multiplexing (Multiplexing). For the SOC, which pin is arranged in addition to normal GPIO outside, it may also be composed of a plurality of pins a pin group, the stroke specific function. pin control subsystem to manage all the pin group.

    (3) Configuration of the characteristics of these pin. E.g. driver strength to enable or disable pull-up on the pin, pull-down resistor, the pin configuration.

3.pinctrl related concepts
The main objective of the ordinary driver calls the pin control subsystem has two:

    (1) setting function of the multiplexing device.

    (2) setting pin electrical characteristics of the corresponding device.

Multiplexing device setting function to understand two concepts, it is a function, is another pin group. is a functional abstraction function, corresponding to a logical HW Block, for example the SPI0. While the specific function of a given name, we can not determine where such use of pins. For example, flexible design, the SPI0 function inside the chip to the lead pin group {C6, C7, C8, C9}, may lead to a further pin group {C22.C23, C24, C25}, but there is no doubt that the two Active a pin group can not, after all, the interior of the circuit chip SPI0 only a logical function, and therefore only a function of the given function Selector pin group selector MUX function can be set.

Further, since the required power management, a management device may be in a power state, e.g. SLEEP or idle, this time, all belonging to the device pin will need to be in another state.

The above requirements, it defines the concept of pin control state, that it might be in a lot of states, device driver can switch the device is in the state. In order to facilitate the management pin control state there is the concept of pin control state holder of a device used to manage all the pin control state.

To sum up, the driver calls the ordinary pin control subsystem interface is only three steps:

(1) drive to load or run, get a handle pin control state holder of

(2) setting pin control state

(3) driving unloading or exit, the release pin control state holder handle

4. Relationship between subsystems GPIO


The figure shows the relationship between the subsystem and pinctrl gpio subsystem, i.e. in fact the management subsystem pinctrl gpio up together, all operations are needed to complete gpio through pinctrl subsystem, so that if a pin has been applied for gpio, then through pinctrl subsystem application will return an error when a function.

5. Relations with unified device driver model
learned from "pinctrl subsystem diagram", the unified linux kernel device driver model is also called functional pinctrl subsystem. unified linux kernel device driver model provides a binding mechanism in the device driver and, once the match will call the driver's probe function.

The probe function before calling the ticket, the driver model has actually requested a pin, and (provided that the dts files are defined in the drive node named "default" of pinctrl configuration).

Driver Model driver calls the probe function places:

static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
        ......
/* If using pinctrl, bind pins now before probing */
ret = pinctrl_bind_pins(dev); //对该device涉及的pin进行pin control相关设定
if (ret)
goto probe_failed;

if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
goto probe_failed;
}

if (dev->bus->probe) { //下面是真正的probe过程。
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}

driver_bound(dev);
ret = 1;
pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
        .....
}
pinctrl_bind_pins函数定义:

#define PINCTRL_STATE_DEFAULT "default"
#define PINCTRL_STATE_IDLE "idle"
#define PINCTRL_STATE_SLEEP "sleep"
int pinctrl_bind_pins(struct device *dev)
{
int ret;

dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
if (!dev->pins)
return -ENOMEM;

dev->pins->p = devm_pinctrl_get(dev); //获取pinctrl
if (IS_ERR(dev->pins->p)) {
dev_dbg(dev, "no pinctrl handle\n");
ret = PTR_ERR(dev->pins->p);
goto cleanup_alloc;
}

dev->pins->default_state = pinctrl_lookup_state(dev->pins->p, //查找这个pin的default状态
PINCTRL_STATE_DEFAULT);
if (IS_ERR(dev->pins->default_state)) {
dev_dbg(dev, "no default pinctrl state\n");
= 0 RET;
GOTO cleanup_get;
}

RET = pinctrl_select_state (the dev-> pins-> P, the dev-> pins-> default_state); // Set default state of the pin
IF (RET) {
dev_dbg (dev, "failed to the activate default State pinctrl \ n-");
GOTO cleanup_get;
}

return 0;
of realizing the drive model, drive Probe difficult to see before, has a pin arranged to the default application, of course, already counted pinctrl + 1'd.

Driver The probe function can be obtained by a handle pinctrl devm_pinctrl_get, recalling pinctrl_select_state disposed pin state itself.

6. Relationship of the device tree
may define the need to use the driving pin arranged in the driving device tree source node in the file.

device-Node-name {
   // definition of the device own properties
    pinctrl-names = "SLEEP", "default", "IDLE";
    pinctrl-0 = & xxx_State_sleep;
    pinctrl-. 1 = & xxx_state_default;
    pinctrl-2 = & xxx_state_idle;
}
pinctrl -0 pinctrl-1 pinctrl-2 ..... represents one state of the apparatus, where we have defined three pinctrl-0 pinctrl-1 pinctrl- 2, is the number 0,1,2 pinctrl-names corresponding the index string array. Wherein pinctrl-0 is "sleep" state, pinctrl-1 is the "default" state, pinctrl-2 is "idle" state. And xxx_state_sleep, xxx_state_default, xxx_state_idel is driving a particular pin configuration items, the device needs to be defined in pinctrl node:

pinctrl @ e01b0000 {
pinctrl-names = "default";
      pinctrl-0 = <& state_default>;

     state_default: pinctrl_default {
      };

xxx_state_sleep: xxx_sleep {
         xxx_mfp {
            Actions, Groups = "fmp1_3_1spi0_ss", "mfp1_3_1_spi0_miso", "mfp1_5_4";
            Actions, = function "SPI0";
         };
       };

pinctrl loading subsystem, function calls pinctrl_dt_to_map dts parsed file configuration items related pinctrl and reference nodes according to respective drive dts relationship pinctrl will be linked to each phandle device tree node child-driven, each driver can get pinctrl configured through its own dev handle.


7. master drive and the relationship between
the machine driver kernel, it is necessary to pinctrl associated hardware operations master image into a compliant structure pinctrl_desc linux pinctrl subsystem, and calls pinctrl_register registered to pinctrl subsystem, such pinctrl child the system can be converted into concrete acts upper operate the hardware:

pinctrl_desc {struct
const char * name;
struct pinctrl_pin_desc pins * const; // why the description of each pin.
unsigned int npins; // indicates how many pin can be controlled. pins and npins two members to determine the pin information a pin controller can control.
const struct pinctrl_ops * pctlops; // global control function
const struct pinmux_ops * pmxops; // multiplexed pins associated operating function
const struct pinconf_ops * confops; // pin to configure the characteristics (e.g., pull-up / pull -down)
struct * Module1 owner;
};
pctlops member callback function Description:

pinctrl_ops {struct
int (* get_groups_count) (* struct pinctrl_dev pctldev); // number of the pin controller pin group support
const char * (* get_group_name) ( struct pinctrl_dev * pctldev, // given a selector (index), acquiring specified Group of the pin name
unsigned Selector);
int (* get_group_pins) (* struct pinctrl_dev pctldev, // given a selector (index) acquires the designated information of the pin in the pin Group (Group of the pin
unsigned number // ,, comprising Selector a pin, the pin ID is what each)
const unsigned ** pins,
unsigned * num_pins);
void (* pin_dbg_show) (struct pinctrl_dev pctldev *, S * struct seq_file, Debug // fs of the callback interfaces
unsigned offset);
int (* dt_node_to_map) (struct pinctrl_dev * pctldev, // a pin configuration node analysis and save results into a mapping table
struct device_node * np_config, // entry for each entry represents a Setting (setting a multiplexing function, or an electrical characteristic setting)
struct pinctrl_map ** Map, unsigned * num_maps);
void (dt_free_map *) (* struct pinctrl_dev pctldev, // dt_node_to_map inverse function.
struct pinctrl_map the Map *, unsigned num_maps);
};
pmxops member callback function Description:

pinmux_ops {struct
int (Request *) (* struct pinctrl_dev pctldev, unsigned offset); This function needs to be called before // pinctrl multiplexing subsystem particular setting, the main driver is determined to make the bottom of the complex of a pin by setting whether the ok
int (* free) (struct pinctrl_dev * pctldev, unsigned offset); // inverse function of the request, calling the request function requests take up a certain pin of the resource, you can call the free release of these resources.
int (* get_functions_count) (struct pinctrl_dev * pctldev); // returns the number of function pin controller supports.
const char * (* get_function_name) ( struct pinctrl_dev * pctldev, // given a selector (index) to obtain the specified function name.
unsigned Selector);
int (* get_function_groups) (* struct pinctrl_dev pctldev, // given a selector ( index) Gets the specified function of the pin group information.
unsigned Selector,
const char const * ** Groups,
unsigned * const NUM_GROUPS);
int (* enable) (struct pinctrl_dev * pctldev, unsigned func_selector, // enable a function of course give me a selector function selector and pin group of
unsigned group_selector);
void (* disable) (struct pinctrl_dev * pctldev, unsigned func_selector, / / enable inverse function
unsigned group_selector);
int (* gpio_request_enable) (* struct pinctrl_dev pctldev, // Request and enable a single PIN GPIO
struct pinctrl_gpio_range Range *,
unsigned offset);
void (gpio_disable_free *) (* struct pinctrl_dev pctldev, // gpio_request_free inverse function
struct pinctrl_gpio_range Range *,
unsigned offset);
int (* gpio_set_direction) (* struct pinctrl_dev pctldev, gpio direction // set the callback function
struct pinctrl_gpio_range Range *,
unsigned offset,
BOOL INPUT);
};
Confops member callback function Description:

pinconf_ops {struct
#ifdef CONFIG_GENERIC_PINCONF
BOOL is_generic;
#endif
. int (* pin_config_get) (* struct pinctrl_dev pctldev, // given a pin ID and config type ID, obtain the specified pin type configuration
unsigned PIN,
unsigned Long config *);
int (* pin_config_set) (* struct pinctrl_dev pctldev, // to set a specified pin configuration
unsigned pin,
unsigned Long config);
int (* pin_config_set_bulk) (* struct pinctrl_dev pctldev,
unsigned pin,
unsigned Long * configs ,
unsigned num_configs);
int (* pin_config_group_get) (* struct pinctrl_dev pctldev, // pin group as a unit to obtain configuration information on the PIN.
unsigned Selector,
unsigned Long * config);
int (*pin_config_group_set) (struct pinctrl_dev *pctldev,//以pin group为单位,设定pin group 的特性配置。
unsigned selector,
unsigned long config);
int (*pin_config_group_set_bulk) (struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long *configs,
unsigned num_configs);
int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev, //debug接口
const char *arg,
unsigned long *config);
void (*pin_config_dbg_show) (struct pinctrl_dev *pctldev, //debug接口
struct seq_file *s,
unsigned offset);
void (*pin_config_group_dbg_show) (struct pinctrl_dev *pctldev, //debug接口
struct seq_file *s,
unsigned selector);
void (* pin_config_config_dbg_show) (struct pinctrl_dev * pctldev, // debug interfaces
struct seq_file S *,
unsigned Long config);
};
7.dts file keyword table pinctrl
7.1 naming table pin
    pin names follow the naming of the IC spec the following table named to the default function of each pin name, but will change the function of each pin configuration with actual use.

    Using the keyword "actions, pins" in the dts (different vendors, this is the torch of the core) followed by the name of the array to define which pin is required, such as:

{i2c0_over_uart0_pull_up
Actions, pins = "P_UART0_RX", "P_UART0_TX";
Actions, pull = <2>;
}
7.2-the MUX Group Function Table
  7.2.1 Mux Group name tables
    pin group in accordance with the name of a register bit and named. For example: MFP_CTL1 bit22: 21, the pin 10 defines a mux: P_LVDS_OEP, P_LVDS_OEN, P_LVDS_ODP, P_LVDS_ODN, P_LVDS_OCP, P_LVDS_OCN, P_LVDS_OBP, P_LVDS_OBN, P_LVDS_OAP, P_LVDS_OAN. The pin group name is mfp1_22_21.

    Some mfp register cell, set to a certain value will be configured as a plurality of different pin functions. Then the cell in the same pin can not be classified as a pin group. Case basis having to dismantle, then dismantle the pin group name will be added to a number suffix.

    For example: The IC SPEC, mfp1 bit [31:29] 3 may control pin: P_KS_IN0, P_KS_IN1, P_KS_IN2 the cell in 0x11 This option will now pin 2 are defined as pwm0, pwm1, pwm4..

Then it will be split into three group: respectively "mfp1_31_29_ks_in2", "mfp1_31_29_ks_in2", "mfp1_31_29_ks_in0". After several mfp cell division, there are still mutually exclusive relationship between them on the hardware, such as the mfp1_31_29_ks_in2 the function selected pwm0, mfp1_31_29_ks_in1 the function selected pwm1, can work. But the mfp1_31_29_ks_in2 the function selected pwm0, mfp1_31_29_ks_in1 the function selected jtag, it will return an error.

    In pin group name list also see "xxx_dummy" naming, this pin group might be used in pinmux settings. These pin group only one mux function, so the mfp register does not indicate, however, and these may gpio pin multiplexing, these applications can help identify potential pin multiplexing and error gpio it exists.

Using the keyword "actions, groups" followed by the name of the array mux Group in dts Mux group to define what is required, such as:

sd0_mfp_cmd_clk{

     actions,groups = "mfp2_8_7","mfp2_6_5";

     actions,function = "sd0";

};

Group-function 7.2.2MUX
    Mux Group controlled pin, can be changed by setting the Mux Function way of internal communication IC, so that the same set of different pin functions as, for example:

{sd0_mfp_cmd_clk
Actions, Groups = "mfp2_8_7", "mfp2_6_5";
Actions, function = "JTAG";
};
7.2.3 Group Drive
configuration values used in exactly the same paddrv IC spec definition of PAD_DRVx register.

For certain pin pin driving capability can be provided (i.e., power supply capacity), can be configured by configuring the pin drive capability level of the driver group.

Using the keyword "actions, paddrv" dts in the heel defining pin driving capability level group "actions, groups" specified drive group which represents the driving capability of use, such as:

sd0_d0_d3_cmd_clk_paddrv {
Actions, Groups = "paddrv1_19_18", "paddrv1_17_16";
Actions, paddrv = ". 1" / * Level. 1, Range: 0 ~. 3 * /
}
represents P_SD0_CLK "paddrv1_19_18" represents P_SD0_CMD and paddrv1_17_16 represented using a driving capability to enhance data stability.
7.2.4 Pin Pull Up / Down
after use keyword "actions, pull" keep down data in the dts defined "actions, pin" pulldown pin on which the specified group used, such as:

{sd0_pull_d0_d3_cmd
Actions, pins = "P_SD0_CMD", "P_SD0_CLK";
Actions, pull = <. 1>;
};
shows a P_SD0_CMD P_SD0_CLK and two pull-down pin.

actions, pull = <0>, indicates a pull-down function off

actions, pull = <1>, pull down

Pull actions, pull = <2>, represents

The PIN-GPIO 7.2.5
pin in addition to various functions as multiplexing, can also be configured to use GPIO, pinctrl GPIO subsystem management subsystems up, so when the application will check the GPIO of the corresponding pin gpio whether the application has been driven for other functions of the other. It will complain if the application has been applied, and vice versa.

8 using dts pinctrl described configuration
in pinctrl configuration 8.1dts
all pinctrl-state pin controller device are defined in the node:

在kernel/arch/arm64/boot/dts/s700_pinctrl.dtsi 中

/ {

Pinctrl @ e01b0000 {
compatible = "Actions, S700-pinctrl";
REG = <0 0xe01b0000 0 0x1000>;

pinctrl-names = "default";
pinctrl-0 = <& state_default>;
Clocks = <& Clock CLK_GPIO>;
Clock- = names "of the MFP";

state_default: pinctrl_default {
};

and the reference defining a sub driving pin controller device nodes in the node, i.e. node pinctrl-state.

Each driver uses a method pinctrl-state reference node:

pinctrl-N: a description of the state of the device requires the use of a pin (pin state), corresponding to the above-described state. Value of N must be sequentially incremented from zero. The value pin phandle configuration nodes pinctrl-N attribute. pinctrl-N attribute references pin configuration nodes must be a direct child node of the pin controller device node.

pinctrl-names: for each pin state defines a name. Each sequence corresponds to the name of a pin state. Pinctrl-0 names such as "default", pinctrl-1 corresponds to the name of "idle". If the property can not be specified pinctrl-names, this is the case, pin state name is "N" character of the property. For example pinctrl-0 is the name of the character "0"

MMC @ e0330000 {
pinctrl-names = "pinctrl_mmc0", "share_uart2_5";
pinctrl-0 = <& mm0_pinctrl_state>;
pinctrl-. 1 = <& mmc_share_uart_state>;
}
In the above example, MMC drive defined pinctrl-state there are two, wherein mmc0_state_default is a direct child node at defined pin controller device node, it represents sd0 the pin group as sd function, and mmc_share_uart_state indicates as serial function wherein mmc_state_default corresponding pinctrl-names attribute to default, and mmc_share_uart_state corresponding pinctrl-names property share_uart2_5.
8.2 pin mapping database establishment of
the pin controller device node configured kernel is how to get to the pin mapping database and use it?

There are two cases established by looking at pinctrl subsystem code learned pin mapping database:

Case is the master driver calls pinctrl_register registered machine structure when the struct pinctrl_desc to pinctrl subsystem by pinctrl_register call pinctrl_get created.

    Another is that each driver calls devm_pinctrl_get when loaded by a unified driver model device driver and device in the bind call instead pinctrl_get created.

In case a specific analysis pinctrl_get through code.
----------------
Disclaimer: This article is CSDN blogger "Moby Dick into the sea" original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source and link this statement.
Original link: https: //blog.csdn.net/u012830148/article/details/80609337

Guess you like

Origin www.cnblogs.com/sky-heaven/p/11531693.html