Linux pinctrl 概览

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,
	},
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值