全志H3平台pinctrl模块分析

原创 2016年05月31日 18:16:27

概要

Linux内核中提供了pinctrl子系统,目的是为了统一各SoC厂商的pin脚管理,避免各SoC厂商各自实现相同的pin脚管理子系统,减少SoC厂商系统移植工作量。

1.1 主要功能

1. 管理系统中所有可以控制的pin。在系统初始化的时候,枚举所有可以控制的pin,并标识这些pin。

2. 管理这些pin的复用(Multiplexing)。对于SOC而言,其引脚除了配置成普通GPIO之外,若干个引脚还可以组成一个pin group,形成特定的功能。例如pin number是{ 0, 8, 16, 24 }这四个引脚组合形成一个pin group,提供SPI的功能。pin control subsystem要管理所有的pin group。

3. 配置这些pin的特性。例如配置该引脚上的pull-up/down电阻,配置drive strength等。

4. 与GPIO子系统的交互

5. 实现pin中断

1.2 核心驱动源码文件

1.3 总体框架


2源码分析

kernel配置文件: lichee/linux-3.4/arch/arm/configs/sun8iw7p1smp_android_defconfig

系统配置文件:lichee\tools\pack\chips\sun8iw7p1\configs\dolphin-p1\sys_config.fex

arch/arm/mach-sunxi/ sys_config.c //分析、处理sys_config.fex文件。

drivers/pinctrl/ core.c //创建debug fs,提供pinctrl_register等函数接口。

drivers/pinctrl/ pinctrl-sun8iw7.c //该平台下的pin脚数据

2.1 驱动加载时主流程代码

(1) drivers/pinctrl/ pinctrl-sunxi.c


1 sunxi_pinctrl_probe函数:

pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); // devm_kzalloc基于slab分配在物理上连续的实际的内存, 并且带有释放内存的回调函数,当该设备与驱动分开时,自动释放内存。

pctl->desc = (struct sunxi_pinctrl_desc *)(&sunxi_pinctrl_data);

 

1.1 sunxi_pinctrl_build_state(pdev);//pctl->desc的子项数据复制到pctl相应子项。

 

1.2 pctl->pctl_dev = pinctrl_register(&sunxi_pctrl_desc, &pdev->dev, pctl); //创建pinctrl_dev设备,调用pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);注册所有的pin

1.2.1 pinctrl_register_pins对每一个pin脚调用 ret=pinctrl_register_one_pin(pctldev, pins[i].number, pins[i].name); //pin 的物理地址,名字存入pin_desc结构体,将该结构体加入pin_desc_tree链表。

1.2.2 pctldev->p = pinctrl_get_locked(pctldev->dev); //先调用find_pinctrl从pinctrl_list链表中查找看pin control state holder是否存在;存在,即表明其正在使用中;不存在时,调用create_pinctrl创建pinctrl,从pinctrl_maps链表查找对应devmaps_node,而maps里面的数据是从sys_config.fex文件分析获取,详见1.5。如找到对应的maps_node,则调用add_setting(p, map);该函数针对map->type填充pinctrl_setting相应成员变量,如果是PIN_MAP_TYPE_MUX_GROUP类型,填充之后,还会调用pin_request注册同组中所有的pin

最后将pinctrl加入pinctrl_list链表。

1.2.3 pinctrl_init_device_debugfs(pctldev); //注册debugfs

 

1.3 gpiochip_add //GPIO驱动将通过chip来与pinctrl联系,相应的操作将通过sunxi_pinctrl_gpio_chip结构的方法成员实现相应的操作。

将全局变量gpio_desc的成员变量chipflags赋初值。后续GPIO相应操作将通过gpio_desc进行。

1.3.1 of_gpiochip_add(chip);

初始化chip的相应变量,并增加chip->of_node的引用计数

1.3.2 gpiochip_export(chip)

创建gpiochip0设备,其属性文件用来show chip->ngpio, chip->label, chip->base

 

1.4 gpiochip_add_pin_range 建立动态链表chip->pin_rangesnodegpio_pin_range,其成员range包含pin脚基地址。

 

1.5 sunxi_pinctrl_parse_pin_cfg (pdev); //分析获取sys_config.fex文件中的配置,

1.5.1 sunxi_pinctrl_creat_mappings(pdev, pin_count, pin_list, device_name, state_name); //用配置数据填充pinctrl_map

1.5.2 pinctrl_register_mappings //创建pinctrl_maps,将pinctrl_map赋值给其maps成员变量,并加入pinctrl_maps链表。

 

1.6 sunxi_eint_gpio_init //注册中断

 

(2) drivers/gpio/ gpio-sunxi.c

1. gpio_sw_init // 读取sys_config.fex文件中gpio_para参数对应的配置数据组,有单独led_assign进行处理

1.1 gpio_request //pinctrl请求pin用作GPIO,成功后,该Pin仅能被GPIO驱动所使用,不能被其他驱动所混用

通过本文件的静态结构数组gpio_desc找到对应的pin脚的设置,具体数据见Pinctrl-sun8iw7.c (drivers\pinctrl)

chip->request 等价于执行 sunxi_pinctrl_gpio_chip. Request = sunxi_pinctrl_gpio_request

-> pinctrl_request_gpio -> pinmux_request_gpio -> pin_request -> pctldev->desc->pmxops->

(1. gpio_request_enable 2. request)

 

1.2 platform_device_register(gpio_sw_dev[i]) //注册平台设备

        gpio_sw_dev[i]->name = "gpio_sw";

        gpio_sw_dev[i]->id   = i;

        gpio_sw_dev[i]->dev.platform_data   = sw_pdata[i];

        gpio_sw_dev[i]->dev.release         = gpio_sw_release;

 

1.3 platform_driver_register(&gpio_sw_driver)

注册gpio_sw驱动,

gpio_sw_probe: 调用gpio_sw_cfg_set及gpio_sw_data_set函数根据参数配置设置,调用gpio_sw_classdev_register创建相应的设备属性文件,即提供接口给上层,如上接,写1/0等操作。根据sw_pdata->link创建超链接

/sys/class/gpio_sw /normal_led  -> PA15

/sys/class/gpio_sw /standby_led  -> PL10

 

/sys/devices/platform/gpio_sw.0/gpio_sw/PL10/cfg

/sys/devices/platform/gpio_sw.1/gpio_sw/PA15/cfg

2.2 向其他驱动模块提供的接口函数

1. GPIO驱动模块使用的接口:

pinctrl_get //获取设备的pin操作句柄

struct pinctrl *pinctrl_get(struct device *dev) à p = pinctrl_get_locked(dev); 

第641行调用find_pinctrl函数

第645行调用create_pinctrl,获取pinctrl结构体

pinctrl_put

devm_pinctrl_get

devm_pinctrl_put

pinctrl_lookup_state //查找pinctrl_state

pinctrl_select_state //pin句柄对应的pinctrl设置为state句柄对应的状态,其核心为通过pinmux_enable_setting或pinconf_apply_setting来调用pinctrl_descops来设置pin状态。

 

devm_pinctrl_get_select

devm_pinctrl_get_select_default

pin_config_get //获取指定pin的属性,最终是通过confops->pin_config_get获取

pin_config_set //设置指定pin的属性,最终是通过confops->pin_config_set设置

pin_config_group_get //与上类似,pin_config_group_get

pin_config_group_set //与上类似,pin_config_group_set

2.3 GPIO驱动使用的接口

drivers/gpio/ gpiolib.c

gpio_request

gpio_free

gpio_direction_input

gpio_direction_output

__gpio_get_value

__gpio_set_value

2.4 各数据之间的联系图

3 使用方法及实例

1. GPIO口配置:

lichee/tools/pack/chips/sun8iw7p1/configs/dolphin-p1/sys_config.fex 参照如下配置即可:

;----------------------------------------------------------------------------------

;userspace gpio interface for android

;----------------------------------------------------------------------------------

[gpio_para]

gpio_used       = 1

gpio_num        = 2

gpio_pin_1      = port:PL10<1><default><default><1>

gpio_pin_2      = port:PA15<1><default><default><0>

a. 向应用层提供的接口文件如下:

/sys/devices/platform/gpio_sw.0/gpio_sw/PL10/

/sys/devices/platform/gpio_sw.1/gpio_sw/PA15/

b. 内核其他模块使用:

#include <linux/gpio.h>

__gpio_get_value

__gpio_set_value

 

2. 非GPIO驱动模块的使用

#include <linux/pinctrl/consumer.h>

devm_pinctrl_get

pinctrl_lookup_state

pinctrl_select_state

4 参考文献

1.H3 Pinctrl(GPIO)接口使用说明V1.0.pdf

2. http://www.wowotech.net/gpio_subsystem/pin-control-subsystem.html/ comment-page-2#comments


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Linux内核驱动之GPIO子系统(一)GPIO的使用

分类: Linux内核驱动2012-10-31 21:12 162人阅读 评论(1) 收藏 举报 目录(?)[+] 一 概述   Linux内核中gpio是最简单...

Linux下s3c6410的GPIO操作(2)

1、还接着看上一篇的这个函数 arch_initcall(s3c64xx_gpiolib_init); static __init int s3c64xx_gpiolib_init(void) ...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

全志H3芯片支持4k点对点输出,高清广告机的福音

全志H3芯片支持4k点对点输出,4k硬解码。用来做4k的高清广告机十分合适。 我正在将a20上,广告机的一些内容移植到H3芯片上。大概2015年1月中旬出H3板卡。到时候直接上高清广告机方案。 4...

鼻息肉手术五问

鼻息肉摘除术是耳鼻喉科的常用手术。但在诊治过程中,患者会在术前、术后提出不少问题,归结起来不外以下五个方面。一、鼻息肉摘除术后为何又复发? 这个问题提得好,具有普遍性。能够说简直每位病员术前都会提出同...

ShowModalDialog的具体用法

应用背景:需要打开一个子窗体,将需要修改的数据传到子窗体,然后将子窗体中修改过的数据,传回父窗体。(父窗体不能被刷新)例如:父窗体只供用户查看,子窗体用于修改。方法:父窗体:dim xxx 返回值di...

Android WIFI应用简单开发实例

在网上参阅相关资料后,简单修改提炼,完成自己想要的简单开发实例,记之以备查阅。 主要功能:turn on wifi,scan wifi 热点,锁定wifi连接,监听wifi打开/关闭及网络连接/断开...
  • dlijun
  • dlijun
  • 2016-09-06 18:26
  • 1084

Linux内核中的pinctrl子系统应用实例

Linux内核中的pinctrl子系统应用实例     由于近期在做一个项目用到了pinctrl子系统,但是对pinctrl子系统了解又不是很多,所以遇到了麻烦,但是找度娘发现很少有同行对pinctr...

PINCTRL子系统

PINCTRL子系统用于处理: - 枚举和命名控制引脚 - 复用管脚,pad,金手指。 - 配置管脚、pad、金手指,如软件控制的偏置和驱动模式指定的管脚,如上拉/下拉,开漏极、...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)