Linux下s3c6410的GPIO操作(1)

发布者:老实巴交的大叔最新更新时间:2022-06-08 来源: eefocus关键字:Linux  s3c6410  GPIO操作 手机看文章 扫描二维码
随时随地手机看文章

1、arch/arm/plat-s3c64xx/gpiolib.c文件中有如下:



arch_initcall(s3c64xx_gpiolib_init);这个应该实在系统初始化时调用。


static __init int s3c64xx_gpiolib_init(void)

{

s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),

   s3c64xx_gpiolib_add_4bit);



s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),

   s3c64xx_gpiolib_add_4bit2);



s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), NULL);



return 0;

}


这三的蓝色部分是什么呢?看下面的源码,应该知道其是个struct s3c_gpio_chip *chips结构体,在同一个文件中定义,现在原始的结构体:


/**

 * struct s3c_gpio_chip - wrapper for specific implementation of gpio对具体GPIO的包装

 * @chip: The chip structure to be exported via gpiolib. 芯片的结构,配置通过gpiolib向外输出

 * @base: The base pointer to the gpio configuration registers.

 * @config: special function and pull-resistor control information.

 *

 * This wrapper provides the necessary information for the Samsung

 * specific gpios being registered with gpiolib.

 */

struct s3c_gpio_chip {

struct gpio_chip chip;

struct s3c_gpio_cfg*config;

void __iomem*base;

};


struct gpio_chip源码如下:


/**

 * struct gpio_chip - abstract a GPIO controller 对GPIO控制器的抽象

 * @label: for diagnostics为判断而设

 * @dev: optional device providing the GPIOs

 * @owner: helps prevent removal of modules exporting active GPIOs

 * @request: optional hook for chip-specific activation, such as

 *enabling module power and clock; may sleep

 * @free: optional hook for chip-specific deactivation, such as

 *disabling module power and clock; may sleep

 * @direction_input: configures signal "offset" as input, or returns error

 * @get: returns value for signal "offset"; for output signals this

 *returns either the value actually sensed, or zero

 * @direction_output: configures signal "offset" as output, or returns error

 * @set: assigns output value for signal "offset"

 * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;

 *implementation may not sleep

 * @dbg_show: optional routine to show contents in debugfs; default code

 *will be used when this is omitted, but custom code can show extra

 *state (such as pullup/pulldown configuration).

 * @base: identifies the first GPIO number handled by this chip; or, if

 *negative during registration, requests dynamic ID allocation.

 * @ngpio: the number of GPIOs handled by this controller; the last GPIO

 *handled is (base + ngpio - 1).

 * @can_sleep: flag must be set iff get()/set() methods sleep, as they

 *must while accessing GPIO expander chips over I2C or SPI

 *

 * A gpio_chip can help platforms abstract various sources of GPIOs so

 * they can all be accessed through a common programing interface.


帮助具体平台抽象各种GPIO来源,是能用统一的接口操作

 * Example sources would be SOC controllers, FPGAs, multifunction

 * chips, dedicated GPIO expanders, and so on.

 *

 * Each chip controls a number of signals, identified in method calls

 * by "offset" values in the range 0..(@ngpio - 1).  When those signals

 * are referenced through calls like gpio_get_value(gpio), the offset

 * is calculated by subtracting @base from the gpio number.

 */

struct gpio_chip {

const char*label;

struct device*dev;

struct module*owner;



int(*request)(struct gpio_chip *chip,

unsigned offset);

void(*free)(struct gpio_chip *chip,

unsigned offset);



int(*direction_input)(struct gpio_chip *chip,

unsigned offset);

int(*get)(struct gpio_chip *chip,

unsigned offset);

int(*direction_output)(struct gpio_chip *chip,

unsigned offset, int value);

void(*set)(struct gpio_chip *chip,

unsigned offset, int value);



int(*to_irq)(struct gpio_chip *chip,

unsigned offset);



void(*dbg_show)(struct seq_file *s,

struct gpio_chip *chip);

intbase;

u16ngpio;

unsignedcan_sleep:1;

unsignedexported:1;

};


再看具体的实例:


static struct s3c_gpio_chipgpio_4bit[] = {与上面第一个相对应

{

.base= S3C64XX_GPA_BASE,

.config= &gpio_4bit_cfg_eint0111,

.chip= {

.base= S3C64XX_GPA(0),

.ngpio= S3C64XX_GPIO_A_NR,

.label= "GPA",

},

}, {

.base= S3C64XX_GPB_BASE,

.config= &gpio_4bit_cfg_eint0111,

.chip= {

.base= S3C64XX_GPB(0),

.ngpio= S3C64XX_GPIO_B_NR,

.label= "GPB",

},

}, {

.base= S3C64XX_GPC_BASE,

.config= &gpio_4bit_cfg_eint0111,

.chip= {

.base= S3C64XX_GPC(0),

.ngpio= S3C64XX_GPIO_C_NR,

.label= "GPC",

},

}, {

.base= S3C64XX_GPD_BASE,

.config= &gpio_4bit_cfg_eint0111,

.chip= {

.base= S3C64XX_GPD(0),

.ngpio= S3C64XX_GPIO_D_NR,

.label= "GPD",

},

}, {

.base= S3C64XX_GPE_BASE,

.config= &gpio_4bit_cfg_noint,

.chip= {

.base= S3C64XX_GPE(0),

.ngpio= S3C64XX_GPIO_E_NR,

.label= "GPE",

},

}, {

.base= S3C64XX_GPG_BASE,

.config= &gpio_4bit_cfg_eint0111,

.chip= {

.base= S3C64XX_GPG(0),

.ngpio= S3C64XX_GPIO_G_NR,

.label= "GPG",

},

}, {

.base= S3C64XX_GPM_BASE,

.config= &gpio_4bit_cfg_eint0011,

.chip= {

.base= S3C64XX_GPM(0),

.ngpio= S3C64XX_GPIO_M_NR,

.label= "GPM",

},

},

};


第二部分:


static struct s3c_gpio_chipgpio_4bit2[] = {与上面第二个相对应

{

.base= S3C64XX_GPH_BASE + 0x4,

.config= &gpio_4bit_cfg_eint0111,

.chip= {

.base= S3C64XX_GPH(0),

.ngpio= S3C64XX_GPIO_H_NR,

.label= "GPH",

},

}, {

.base= S3C64XX_GPK_BASE + 0x4,

.config= &gpio_4bit_cfg_noint,

.chip= {

.base= S3C64XX_GPK(0),

.ngpio= S3C64XX_GPIO_K_NR,

.label= "GPK",

},

}, {

.base= S3C64XX_GPL_BASE + 0x4,

.config= &gpio_4bit_cfg_eint0011,

.chip= {

.base= S3C64XX_GPL(0),

.ngpio= S3C64XX_GPIO_L_NR,

.label= "GPL",

},

},

};


第三部分:


static struct s3c_gpio_chipgpio_2bit[]= {与上面第三个相对应

{

.base= S3C64XX_GPF_BASE,

.config= &gpio_2bit_cfg_eint11,

.chip= {

.base= S3C64XX_GPF(0),

.ngpio= S3C64XX_GPIO_F_NR,

.label= "GPF",

},

}, {

.base= S3C64XX_GPI_BASE,

.config= &gpio_2bit_cfg_noint,

.chip= {

.base= S3C64XX_GPI(0),

.ngpio= S3C64XX_GPIO_I_NR,

.label= "GPI",

},

}, {

.base= S3C64XX_GPJ_BASE,

.config= &gpio_2bit_cfg_noint,

.chip= {

.base= S3C64XX_GPJ(0),

.ngpio= S3C64XX_GPIO_J_NR,

.label= "GPJ",

},

}, {

.base= S3C64XX_GPN_BASE,

.config= &gpio_2bit_cfg_eint10,

.chip= {

.base= S3C64XX_GPN(0),

.ngpio= S3C64XX_GPIO_N_NR,

.label= "GPN",

},

}, {

.base= S3C64XX_GPO_BASE,

.config= &gpio_2bit_cfg_eint11,

.chip= {

.base= S3C64XX_GPO(0),

.ngpio= S3C64XX_GPIO_O_NR,

.label= "GPO",

},

}, {

.base= S3C64XX_GPP_BASE,

.config= &gpio_2bit_cfg_eint11,

.chip= {

.base= S3C64XX_GPP(0),

.ngpio= S3C64XX_GPIO_P_NR,

.label= "GPP",

},

}, {

.base= S3C64XX_GPQ_BASE,

.config= &gpio_2bit_cfg_eint11,

.chip= {

.base= S3C64XX_GPQ(0),

.ngpio= S3C64XX_GPIO_Q_NR,

.label= "GPQ",

},

},

};


.config= &gpio_2bit_cfg_eint11类似的这些是什么呢?这涉及到上面的结构体


struct s3c_gpio_chip {

struct gpio_chip chip;

struct s3c_gpio_cfg*config;

void __iomem*base;

};


源码如下:注意看注释,讲的很明白。


/**

 * struct s3c_gpio_cfg GPIO configuration

 * @cfg_eint: Configuration setting when used for external interrupt source外部中断

 * @get_pull: Read the current pull configuration for the GPIO

 * @set_pull: Set the current pull configuraiton for the GPIO

 * @set_config: Set the current configuration for the GPIO

 * @get_config: Read the current configuration for the GPIO

 *

 * Each chip can have more than one type of GPIO bank available and some

 * have different capabilites even when they have the same control register

 * layouts. Provide an point to vector control routine and provide any

 * per-bank configuration information that other systems such as the

 * external interrupt code will need.

 */ 指向具体端口的函数调转表

struct s3c_gpio_cfg {

unsigned intcfg_eint;



s3c_gpio_pull_t(*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);

int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,

   s3c_gpio_pull_t pull);



unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);

int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,

      unsigned config);

};




那么上的这三个有什么不同呢?看下面这段就可知道了:




/* GPIO bank summary:

 *

 * BankGPIO端口GPIOs数目Style类型控制位数目SlpCon端口A 睡眠模式配置寄存ExtInt Group外部中断

 * A8 4BitYes1

 * B7 4BitYes1

 * C8 4BitYes2

 * D5 4BitYes3

 * E5 4BitYesNone

 * F16 2BitYes4 [1]

 * G7 4BitYes5

 * H10 4Bit[2]Yes6

 * I16 2BitYesNone

 * J12 2BitYesNone

 * K16 4Bit[2]NoNone

 * L15 4Bit[2] NoNone

 * M6 4BitNoIRQ_EINT

 * N16 2BitNoIRQ_EINT

 * O16 2BitYes7

 * P15 2BitYes8

 * Q9 2BitYes9

 *

 * [1] BANKF pins 14,15 do not form part of the external interrupt sources

 * [2] BANK has two control registers, GPxCON0 and GPxCON1

 */


对照下图应该明白了上面的


下面这个图对应gpio_4bit


下面这两个图对应gpio_4bit2,4为控制,2个控制寄存器


下面这两个图对应gpio_2bit,两位控制

注:体会一下,s3c_gpio_chip和gpio_chip两个结构体的不同指出。

关键字:Linux  s3c6410  GPIO操作 引用地址:Linux下s3c6410的GPIO操作(1)

上一篇:Linux下s3c6410的GPIO操作(3)
下一篇:s3c6410的UART设备驱动(4)

推荐阅读最新更新时间:2024-11-17 11:51

高级linux声卡架构ALSA概述及特点
ALSA 介绍 ALSA 概述 ALSA(Advanced Linux Sound Architecture )是高级 linux 声卡架构简称,是目前Linux的主流音频体系结构, 提供了音频和MIDI的支持。 除了声音设备驱动,ALSA还捆绑了一个用户空间驱动的库用于应用开发。开发者可以使用这些 ALSA 驱动进行高级 API 开发,可以通过 ALSA 库达成与声音设备的内核(直接)交互。 ALSA 特点如下: 高效的支持所有类型音频接口,从消费类声卡到专业多声道音频接口; 完全模块化的声卡驱动; 用户空间库 (alsa-lib) 可简化应用程序编程并提供更高级别的功能; 支持较旧的开放声音系统 (OSS) API,为
[嵌入式]
高级<font color='red'>linux</font>声卡架构ALSA概述及特点
TQ2440 学习笔记—— 34、移植 Linux 内核【 Makefile 分析 】
一、Linux Makefile 分析 (1)Makefile 的作用 a、决定编译哪些文件 b、怎样编译这些文件 c、怎样连接这些文件,最重要的是它们的顺序如何 Linux 内核中有很多个Makefile 文件,下面是 Makefile 文件的五大类: a、决定编译哪些文件。 Linux 内核的编译过程从顶层 Makefile 开始,然后递归地进入各级子目录调用它们的Makefile,分为3个步骤。 1、顶层 Makefile 决定内核根目录下哪些子目录将被编进内核。 2、arch/$(ARCH)/Makefile 决定arch/$(ARCH) 目录下哪些文件、哪些目录将被编进内核。 3、
[单片机]
TQ2440 学习笔记—— 34、移植 <font color='red'>Linux</font> 内核【 Makefile 分析 】
研华科技发布AIM-Linux社区并邀请用户加入
2022年6月,研华科技(Advantech)宣布启动一个技术支持论坛,即 AIM-Linux社区 。这是一个在线社区,旨在为研华科技和用户提供一个交流平台,在上面基于Arm和Linux的开发人员可与研华科技及其合作伙伴的工程师保持联系。 研华科技一直以来由研发工程师向用户提供丰富且直接的技术支持,然而我们也意识到,很多用户往往具有类似的疑问。因此,研华科技希望提供一个在线论坛——AIM-Linux社区,用户可以在这里发布问题、公开列出工程师反馈和技术解决方案。这样做的目的是通过共享集体知识、技术和活动造福社区。 研华科技副总裁Aaron Su表示,“研华科技投入了大量时间来了解我们的客户希望访问哪些信息,以及如何以
[工业控制]
研华科技发布AIM-<font color='red'>Linux</font>社区并邀请用户加入
S3C2440 Linux驱动移植——SPI
1. 配置内核 首先,修改arch/arm/plat-s3c24xx/Kconfig,这一步的目的是为了可以在内核中使能SPI0的配置函数。 修改后的内容如下: config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 bool S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 help SPI GPIO configuration code for BUS0 when connected to GPE11, GPE12 and GPE13. 接着配置内核,首先打开S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13选项,这样编译的时候会将 ar
[单片机]
S3C2440 <font color='red'>Linux</font>驱动移植——SPI
基于ARM和Linux的字符采集与识别系统
    传统纸质读物的数字化以及诸如条码识别等字符识别系统都离不开图像的读入与识别, 然而目前广泛使用的字符识别设备将这两部分独立开, 即由图像读入设备(如扫描仪)和安装于计算机上的识别软件构成, 但这样的设备构成离不开安装识别软件的计算机, 造成成本上升和使用不便。随着电子产品的普及, 具有摄像功能的电子产品及其上的识别软件也可以构成一个字符识别系统, 但是这种识别系统的识别速度受到摄像头调焦的限制, 难以广泛应用。文中提出的便携式字符采集和识别系统, 其硬件平台是基于接触式图像传感器( C IS) 与ARM9处理器S3C2410,软件平台是基于嵌入式L inux 系统, 可以克服以上两种设备的缺点, 同时满足方便性和快速性
[嵌入式]
在嵌入式Linux系统中使用的摄像头
1).目前越来越多的嵌入式系统采用摄像头应用,其中主要有下面几种方式 远程监控:如闭路电视系统,操作人员通过摄像头远程监控某个特定区域,小到一个小区,达到市政公共场所,都可能有这样的应用。 监控视频录制:另外一些监控系统不一定有操作人员一直监控,则会通过录制监控视频的方式在需要的时候调出相关视频进行查阅。 嵌入式视觉系统:嵌入式视觉系统会对视频图片进行处理并提取更多复杂信息,如雷达和城市智能交通应用。 视频传感器:如临床诊断设备会对采集的视频图像进行分析来诊断,智能购物设备通过采集视频图像分析使用者特征来定向推广销售等等。 2).环境配置 ./ ARM嵌入式模块系统:Toradex VF61以及 Colib
[单片机]
在嵌入式<font color='red'>Linux</font>系统中使用的摄像头
s3c6410 定时器中断的实现
6410手册中的相关内容 five 32-bit timers Timers 0 and 1 include a PWM function Each timer has its own 32-bit down-counter which is driven by the timer clock. The down-counter is initially loaded from the Timer Count Buffer register (TCNTBn). When the down-counter reaches zero, the timer interrupt request is generated to infor
[单片机]
<font color='red'>s3c6410</font> 定时器中断的实现
看大牌厂商PK——2010 ARM研讨会见闻
  前段时间,此起彼伏的厂商研讨会,让我们或多或少领略了一把Cortex的魅力。但毕竟各家都在宣扬自己的产品,没有比较。这次机会来了,7月22日在北京丽亭花苑三层水晶吊顶华丽的大厅里、ARM一年一度的嵌入式系统研讨会上,TI、NXP、Atmel和ST来了个当面PK,且让我们听听他们怎么说!   作为此次研讨会主角的ARM,无疑是个前瞻性的角色。就像几年前,ARM在研讨会上大力推广Cortex-M3时,当时也许很少有人预料到,这样一个新鲜的玩意儿可以有如此凶猛的态势,M3已经成为工程师热议的话题,附论坛中工程师的讨论: https://bbs.eeworld.com.cn/thread-110348-1-1.html 。2010年的
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved