pinctrl相关文件
相关文件 | 作用 | 举例提供的函数,结构 |
---|---|---|
include/linux/pinctrl.h | 定义基本结构体: struct pinctrl_pin_desc; struct pin_gpio_range; struct pinctrl_ops; struct pinctrl_desc; 声明相关函数; | struct pinctrl_pin_desc{ unsigned number; const char *name; void *drv_data} |
drivers/pinctrl/core.h | 定义基本结构体: struct pinctrl_dev; struct pinctrl; struct_state; struct pinctrl_setting_mux; struct pinctrl_setting_configs; struct pinctrl_setting; struct pin_desc; struct pinctrl_maps; struct group_desc; 以generic为主要字段的操作函数声明 | int pinctrl_generic_get_group_count (struct pinctrl_dev *pctldev); |
drivers/pinctrl/devicetree.h | 与设备树相关的pinctrl操作函数声明 | int pinctrl_count_index_with_args (const struct device_node *np, const char *list_name); |
drivers/pinctrl/core.c drivers/base/pinctrl.c | pinctrl子系统的核心驱动 | void *pinctrl_dev_get_drvdata (struct pinctrl_dev *pctldev); int pinctrl_enable (struct pinctrl_dev *pctldev); |
pinctrl相关结构体
pinctrl_desc
pinctrl_dev
一些从结构体中看不出太多联系的,然而在函数中常用。
pinctrl重要函数
pinctrl_init
->pinctrl_init_debugfs
"pinctrl"
"pinctrl-devices"
"pinctrl-maps"
"pinctrl-handles"
pinctrl_register
->pinctrl_init_controller
->struct pinctrl_dev *pctldev;
->pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL);
->INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
->INIT_LIST_HEAD(&pctldev->node);
->ret = pinctrl_check_ops(pctldev);
->pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
->pinctrl_register_one_pin(pctldev, &pins[i]);
->pinctrl_enable
->pinctrl_claim_hogs
->create_pinctrl
->pinctrl_lookup_state
->pinctrl_select_state
->list_add_tail(&pctldev->node, &pinctrldev_list);
->pinctrl_init_device_debugfs;
"pins"
"pingroups"
"gpio-ranges"
int pinctrl_gpio_direction_output(unsigned gpio);
int pinctrl_register_mappings(const struct pinctrl_map *maps,
unsigned num_maps)
driver
struct wmt_pinctrl_data {
struct device *dev;
struct pinctrl_dev *pctl_dev;
/* must be initialized before calling wmt_pinctrl_probe */
void __iomem *base;
const struct wmt_pinctrl_bank_registers *banks;
const struct pinctrl_pin_desc *pins;
const char * const *groups;
u32 nbanks;
u32 npins;
u32 ngroups;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range gpio_range;
};
static const struct pinmux_ops wmt_pinmux_ops = {
.get_functions_count = wmt_pmx_get_functions_count,
.get_function_name = wmt_pmx_get_function_name,
.get_function_groups = wmt_pmx_get_function_groups,
.set_mux = wmt_pmx_set_mux,
.gpio_disable_free = wmt_pmx_gpio_disable_free,
.gpio_set_direction = wmt_pmx_gpio_set_direction,
};
static const struct pinctrl_ops wmt_pctl_ops = {
.get_groups_count = wmt_get_groups_count,
.get_group_name = wmt_get_group_name,
.get_group_pins = wmt_get_group_pins,
.dt_node_to_map = wmt_pctl_dt_node_to_map,
.dt_free_map = wmt_pctl_dt_free_map,
};
static const struct pinconf_ops wmt_pinconf_ops = {
.pin_config_get = wmt_pinconf_get,
.pin_config_set = wmt_pinconf_set,
};
static struct pinctrl_desc wmt_desc = {
.owner = THIS_MODULE,
.name = "pinctrl-wmt",
.pctlops = &wmt_pctl_ops,
.pmxops = &wmt_pinmux_ops,
.confops = &wmt_pinconf_ops,
};
static const struct gpio_chip wmt_gpio_chip = {
.label = "gpio-wmt",
.owner = THIS_MODULE,
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
.get_direction = wmt_gpio_get_direction,
.direction_input = wmt_gpio_direction_input,
.direction_output = wmt_gpio_direction_output,
.get = wmt_gpio_get_value,
.set = wmt_gpio_set_value,
.can_sleep = false,
};
int wmt_pinctrl_probe(struct platform_device *pdev,
struct wmt_pinctrl_data *data)
{
int err;
data->base = devm_platform_ioremap_resource(pdev, 0);
wmt_desc.pins = data->pins;
wmt_desc.npins = data->npins;
data->gpio_chip = wmt_gpio_chip;
data->gpio_chip.parent = &pdev->dev;
data->gpio_chip.of_node = pdev->dev.of_node;
data->gpio_chip.ngpio = data->nbanks * 32;
platform_set_drvdata(pdev, data);
data->dev = &pdev->dev;
data->pctl_dev = devm_pinctrl_register(&pdev->dev, &wmt_desc, data);
err = gpiochip_add_data(&data->gpio_chip, data);
err = gpiochip_add_pin_range(&data->gpio_chip, dev_name(data->dev),
0, 0, data->nbanks * 32);
dev_info(&pdev->dev, "Pin controller initialized\n");
return 0;
}
device
static int wm8850_pinctrl_probe(struct platform_device *pdev)
{
struct wmt_pinctrl_data *data;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
data->banks = wm8850_banks;
data->nbanks = ARRAY_SIZE(wm8850_banks);
return wmt_pinctrl_probe(pdev, data);
}
static const struct of_device_id wmt_pinctrl_of_match[] = {
{ .compatible = "wm,wm8850-pinctrl" },
{ /* sentinel */ },
};
static struct platform_driver wmt_pinctrl_driver = {
.probe = wm8850_pinctrl_probe,
.driver = {
.name = "pinctrl-wm8850",
.of_match_table = wmt_pinctrl_of_match,
.suppress_bind_attrs = true,
},
};