pinctl_setting:如何统一管理pin state

pinctl_setting:如何统一管理pin state

总体框图:
在这里插入图片描述

pinctl_map
  • 保存了所有pin state所需要的pin group信息
pinctl_setting
  • 把pin group信息按pin state分类保存(将引脚组按照引脚状态进行分类保存)
目的
  • pinctl_map->pinctl_setting
for_each_maps()宏

drivers/pinctrl/core.h

#define for_each_maps(_maps_node_, _i_, _map_) \
	list_for_each_entry(_maps_node_, &pinctrl_maps, node) \ //遍历pinctrl_maps链表
		for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \   //遍历pinctrl_map结构体
			_i_ < _maps_node_->num_maps; \
			_i_++, _map_ = &_maps_node_->maps[_i_])
add_setting()函数

drivers/pinctrl/core.c

参数;add_setting(p, pctldev, map);

static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev,
		       const struct pinctrl_map *map)
{	
	struct pinctrl_state *state;
	struct pinctrl_setting *setting;
	
	state = find_state(p, map->name);
	if (!state)
		state = create_state(p, map->name);
	...
	setting = kzalloc(sizeof(*setting), GFP_KERNEL);
	if (!setting)
		return -ENOMEM;

	setting->type = map->type;

	if (pctldev)
		setting->pctldev = pctldev;
	else
		setting->pctldev =
			get_pinctrl_dev_from_devname(map->ctrl_dev_name);
	
    setting->dev_name = map->dev_name;
    
    switch (map->type) {
	case PIN_MAP_TYPE_MUX_GROUP:
		ret = pinmux_map_to_setting(map, setting);
		break;
	case PIN_MAP_TYPE_CONFIGS_PIN:
	case PIN_MAP_TYPE_CONFIGS_GROUP:
		ret = pinconf_map_to_setting(map, setting);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	...
	list_add_tail(&setting->node, &state->settings);
	
	return 0;
}
find_state()函数

drivers/pinctrl/core.c

static struct pinctrl_state *find_state(struct pinctrl *p,
					const char *name)
{
	struct pinctrl_state *state;

	list_for_each_entry(state, &p->states, node)
		if (!strcmp(state->name, name))
			return state;

	return NULL;
}
create_state()函数

drivers/pinctrl/core.c

static struct pinctrl_state *create_state(struct pinctrl *p,const char *name)
{
	struct pinctrl_state *state;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return ERR_PTR(-ENOMEM);

	state->name = name;
	INIT_LIST_HEAD(&state->settings);

	list_add_tail(&state->node, &p->states);

	return state;
}
pinmux_map_to_setting()函数

drivers/pinctrl/pinmux.c

int pinmux_map_to_setting(const struct pinctrl_map *map,struct pinctrl_setting *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
	//imx_pmx_ops
	const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
	char const * const *groups;
	unsigned num_groups;
	int ret;
	const char *group;
	...
	ret = pinmux_func_name_to_selector(pctldev, map->data.mux.function);
	...
	/*function的索引*/
	setting->data.mux.func = ret; // ret = 0
	
	ret = pmxops->get_function_groups(pctldev, setting->data.mux.func,&groups, &num_groups);
	
	if (map->data.mux.group) {
		//group节点名
		group = map->data.mux.group;
		ret = match_string(groups, num_groups, group);
		...
		}
	} else {
		group = groups[0];
	}
	
	ret = pinctrl_get_group_selector(pctldev, group);
	...
	setting->data.mux.group = ret;
	...
}
	
pinmux_func_name_to_selector()函数

drivers/pinctrl/pinmux.c

static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev,
					const char *function)
{
	const struct pinmux_ops *ops = pctldev->desc->pmxops;
	//imx_pmx_ops 返回值1
	unsigned nfuncs = ops->get_functions_count(pctldev);
	unsigned selector = 0;

	while (selector < nfuncs) {
		const char *fname = ops->get_function_name(pctldev, selector); //return function->name; iomux节点名

		if (!strcmp(function, fname))
			return selector;

		selector++;
	}

	return -EINVAL;
}
pinmux_generic_get_function_count()函数

drivers/pinctrl/pinmux.c

int pinmux_generic_get_function_count(struct pinctrl_dev *pctldev)
{
	return pctldev->num_functions;
}
pinmux_generic_get_function_name()函数

drivers/pinctrl/pinmux.c

const char * pinmux_generic_get_function_name(struct pinctrl_dev *pctldev,
				 unsigned int selector)
{
	struct function_desc *function;

	function = radix_tree_lookup(&pctldev->pin_function_tree,
				     selector);
	if (!function)
		return NULL;

	return function->name;
}
pinmux_generic_get_function_groups()函数

drivers/pinctrl/pinmux.c

int pinmux_generic_get_function_groups(struct pinctrl_dev *pctldev,
				       unsigned int selector,
				       const char * const **groups,
				       unsigned * const num_groups)
{
	struct function_desc *function;

	function = radix_tree_lookup(&pctldev->pin_function_tree,selector);
	if (!function) {c
		dev_err(pctldev->dev, "%s could not find function%i\n",__func__, selector);
		return -EINVAL;
	}
	*groups = function->group_names;
	*num_groups = function->num_group_names; //所有group数量

	return 0;
}
pinctrl_get_group_selector()函数

drivers/pinctrl/core.c

int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,const char *pin_group)
{
	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
	unsigned ngroups = pctlops->get_groups_count(pctldev); //group节点数量
	unsigned group_selector = 0;

	while (group_selector < ngroups) {
		const char *gname = pctlops->get_group_name(pctldev,
							    group_selector);
		if (gname && !strcmp(gname, pin_group)) {
			dev_dbg(pctldev->dev,
				"found group selector %u for %s\n",
				group_selector,
				pin_group);
			return group_selector;
		}

		group_selector++;
	}

	dev_err(pctldev->dev, "does not have pin group %s\n",
		pin_group);

	return -EINVAL;
}
pinctrl_generic_get_group_count()函数
int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev)
{
	return pctldev->num_groups;
}
pinctrl_generic_get_group_name()函数
const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev,
					   unsigned int selector)
{
	struct group_desc *group;

	group = radix_tree_lookup(&pctldev->pin_group_tree,
				  selector);
	if (!group)
		return NULL;

	return group->name;
}
pinconf_map_to_setting()函数
int pinconf_map_to_setting(const struct pinctrl_map *map,
			  struct pinctrl_setting *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
	int pin;

	switch (setting->type) {
	case PIN_MAP_TYPE_CONFIGS_PIN:
		pin = pin_get_from_name(pctldev,
					map->data.configs.group_or_pin);
		if (pin < 0) {
			dev_err(pctldev->dev, "could not map pin config for \"%s\"",
				map->data.configs.group_or_pin);
			return pin;
		}
		setting->data.configs.group_or_pin = pin;
		break;
		...
	}
	setting->data.configs.num_configs = map->data.configs.num_configs;
	setting->data.configs.configs = map->data.configs.configs;
	...
}
    
static void Custom_Setting_To_InitStc(uint8_t u8Key_Function) { switch(u8Key_Function) { case WHITEBALANCE: Key_WhiteBalance(); break; case IMAGEFREEZE: Key_ImageFreeze(); break; case ZOOM_IN: Key_ZoomIn(); break; case ZOOM_OUT: Key_ZoomOut(); break; case PHOTO: Key_Photo(); break; case VIDEO: Key_Video(); break; default: break; } } void Dealwith_Key(void) { AD_KeyPolling(); //check AD conversion result switch(GetKey()) // Get the logical key, and implement the functions { case KEY_ZOOM_OUT: Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Top_ShortRelease); break; case KEY_MENU: //top key middle press Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Top_MiddlePress); break; case KEY_LEFT_SHORT: //left key release Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Left_ShortRelease); break; case KEY_RECORD: //left key middle press Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Left_MiddlePress); break; case KEY_ZOOM_IN: //down key release Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Down_ShortRelease); break; case KEY_AWB: //down key middle press Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Down_MiddlePress); break; case KEY_PHOTO: //right key release Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Right_ShortRelease); break; case KEY_FREEZE: //right key middle press Custom_Setting_To_InitStc(g_stcSetting.stcPanelSetting.stcCustomSetting.u8Right_MiddlePress); break; default: break; } }优化这段代码
06-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值