~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 《常识》 ¥应用程序----->系统内核----->设备驱动----->硬件设备 ¥设备驱动既是系统内核的下属,又是硬件设备的老大。 ¥在inux系统中用一个文件来代表一个设备。这个文件就叫设备文件。设备驱动的责任是将应用程序对设备文件 的打开、读、写、定位等操作转化为对硬件设备的打开、读、写、定位等操作。而对于任何硬件设备,应用程序 只需利用这些基本操作就可以完全控制它! ¥编写linux设备驱动需要的知识结构: 1、40%的设计模式相关知识。设计模式是系统内核限定的,做别人的下属就得按照别人的规矩办事。 2、30%的内核工作原理相关知识。内核是你领导,领会领导意图才能把事情办好。 3、30%的硬件相关知识。控制好硬件是你的的本质工作,你得把你的小弟管理好. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~一、<mach/gpio.h>头文件:
在简要介绍了led驱动相关头文件的基础上(参考:点击打开链接),可以发现这些头文件里面包含了很多gpio的宏定义和gpio的操作函数。利用这些宏定义和操作函数,我们就能够很好地控制gpio以达到我们的目的。GPIO相关的的头文件包括<mach/gpio.h>、<plat/regs-gpio.h>和<plat/gpio-cfg.h>。下面是对这些头文件进行简单的分析,如有不正确,希望留言指正:
/* linux/arch/arm/mach-s3c6400/include/mach/gpio.h * * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * * S3C6400 - GPIO lib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #define gpio_get_value __gpio_get_value //对gpio单个引脚的读函数进行了宏定义 #define gpio_set_value __gpio_set_value //对gpio单个引脚的写函数进行了宏定义 #define gpio_cansleep __gpio_cansleep //??? #define gpio_to_irq __gpio_to_irq //??? /* GPIO bank sizes */ //这里对每个端口(gpioa--gpioq)的引脚个数进行了宏定义 #define S3C64XX_GPIO_A_NR (8) #define S3C64XX_GPIO_B_NR (7) #define S3C64XX_GPIO_C_NR (8) #define S3C64XX_GPIO_D_NR (5) #define S3C64XX_GPIO_E_NR (5) #define S3C64XX_GPIO_F_NR (16) #define S3C64XX_GPIO_G_NR (7) #define S3C64XX_GPIO_H_NR (10) #define S3C64XX_GPIO_I_NR (16) #define S3C64XX_GPIO_J_NR (12) #define S3C64XX_GPIO_K_NR (16) #define S3C64XX_GPIO_L_NR (15) #define S3C64XX_GPIO_M_NR (6) #define S3C64XX_GPIO_N_NR (16) #define S3C64XX_GPIO_O_NR (16) #define S3C64XX_GPIO_P_NR (15) #define S3C64XX_GPIO_Q_NR (9) /* GPIO bank numbes */ /* CONFIG_S3C_GPIO_SPACE allows the user to select extra * space for debugging purposes so that any accidental * change from one gpio bank to another can be caught. */ #define S3C64XX_GPIO_NEXT(__gpio) \ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) //用黏贴符号(双#号)来运算的,以A组的0起始,依次加每组的GPIO个数 enum s3c_gpio_number { S3C64XX_GPIO_A_START = 0, S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A), S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B), S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C), S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D), S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E), S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F), S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G), S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H), S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I), S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J), S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K), S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L), S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M), S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N), S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O), S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P), }; /* S3C64XX GPIO number definitions. */ //以下定义了单个引脚的号码,在某些函数中我们可以直接这些宏定义访问单个引脚 #define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr)) #define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr)) #define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr)) #define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr)) #define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr)) #define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr)) #define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr)) #define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr)) #define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr)) #define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr)) #define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr)) #define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr)) #define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr)) #define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr)) #define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr)) #define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr)) #define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr)) /* the end of the S3C64XX specific gpios */ //定义了引脚号的范围,引脚号必须小于这个数,不然就是无效的 #define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) #define S3C_GPIO_END S3C64XX_GPIO_END /* define the number of gpios we need to the one after the GPQ() range */ //与上面一样,定义了引脚的总个数,引脚号不能超过这个数,我们可以利用它判断某个引脚编号的有效性。 #define ARCH_NR_GPIOS (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) //由上面的分析可知,这个头文件对s3c64xx系列的芯片的引脚进行了统一的编号,按GPA-->GPQ的顺序对给每个引脚编了个号。 #include <asm-generic/gpio.h> //这个头文件是包含在此文件中的,它里面包含了许多gpio的操作函数,而这些函数可以直接使用上述宏定义对具体的单个引脚进行操作,如下:
#ifndef _ASM_GENERIC_GPIO_H #define _ASM_GENERIC_GPIO_H #include <linux/types.h> #include <linux/errno.h> #ifdef CONFIG_GPIOLIB #include <linux/compiler.h> /* Platforms may implement their GPIO interface with library code, * at a small performance cost for non-inlined operations and some * extra memory (for code and for per-GPIO table entries). * * While the GPIO programming interface defines valid GPIO numbers * to be in the range 0..MAX_INT, this library restricts them to the * smaller range 0..ARCH_NR_GPIOS-1. */ #ifndef ARCH_NR_GPIOS #define ARCH_NR_GPIOS 256 #endif static inline int gpio_is_valid(int number) { /* only some non-negative numbers are valid */ return ((unsigned)number) < ARCH_NR_GPIOS; } struct seq_file; struct module; /** * struct gpio_chip - abstract a GPIO controller * @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. * 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); int base; u16 ngpio; unsigned can_sleep:1; unsigned exported:1; }; extern const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset); extern int __must_check gpiochip_reserve(int start, int ngpio); /* add/remove chips */ extern int gpiochip_add(struct gpio_chip *chip); extern int __must_check gpiochip_remove(struct gpio_chip *chip); /* Always use the library code for GPIO management calls, * or when sleeping may be involved. */ extern int gpio_request(unsigned gpio, const char *label); //通过查看该gpio保存的记录标志是否为NULL来判断GPIO是否被占用,并为它去个*lable //例如:if(gpio_request(S3C64XX_GPB(0), "GPB")) extern void gpio_free(unsigned gpio); //释放gpio,就是把对应GPIO口的控制标志FLAG_REQUESTED清掉,成NULL,之后可以再被其他调用。 extern int gpio_direction_input(unsigned gpio); //将gpio配置成输入模式 extern int gpio_direction_output(unsigned gpio, int value); //将gpio配置成输出模式,并且将gpio置为value, //例如:gpio_direction_output (S3C64XX_GPB(0), 1) extern int gpio_get_value_cansleep(unsigned gpio);//??? extern void gpio_set_value_cansleep(unsigned gpio, int value);//??? /* A platform's <asm/gpio.h> code may want to inline the I/O calls when * the GPIO is constant and refers to some always-present controller, * giving direct access to chip registers and tight bitbanging loops. */ extern int __gpio_get_value(unsigned gpio); //读取gpio的值 extern void __gpio_set_value(unsigned gpio, int value); //设置gpio的值为value extern int __gpio_cansleep(unsigned gpio);//??? extern int __gpio_to_irq(unsigned gpio);///??? #ifdef CONFIG_GPIO_SYSFS /* * A sysfs interface can be exported by individual drivers if they want, * but more typically is configured entirely from userspace. */ extern int gpio_export(unsigned gpio, bool direction_may_change); extern void gpio_unexport(unsigned gpio); #endif /* CONFIG_GPIO_SYSFS */ #else /* !CONFIG_HAVE_GPIO_LIB */ static inline int gpio_is_valid(int number) { /* only non-negative numbers are valid */ return number >= 0; } /* platforms that don't directly support access to GPIOs through I2C, SPI, * or other blocking infrastructure can use these wrappers. */ static inline int gpio_cansleep(unsigned gpio) { return 0; } static inline int gpio_get_value_cansleep(unsigned gpio) { might_sleep(); return gpio_get_value(gpio); } static inline void gpio_set_value_cansleep(unsigned gpio, int value) { might_sleep(); gpio_set_value(gpio, value); } #endif /* !CONFIG_HAVE_GPIO_LIB */ #ifndef CONFIG_GPIO_SYSFS /* sysfs support is only available with gpiolib, where it's optional */ static inline int gpio_export(unsigned gpio, bool direction_may_change) { return -ENOSYS; } static inline void gpio_unexport(unsigned gpio) { } #endif /* CONFIG_GPIO_SYSFS */ #endif /* _ASM_GENERIC_GPIO_H */
二、<plat/regs-gpio.h>头文件:
/* linux/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h * * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * http://armlinux.simtec.co.uk/ * * S3C64XX - GPIO register definitions */ #ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H #define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__ //这里包含了从a-q的相关头文件,这些头文件里分别是gpa-gpq相关的宏, //以下只列出<plat/gpio-bank-m.h>中的内容 #include <plat/gpio-bank-a.h> #include <plat/gpio-bank-b.h> #include <plat/gpio-bank-c.h> #include <plat/gpio-bank-d.h> #include <plat/gpio-bank-e.h> #include <plat/gpio-bank-f.h> #include <plat/gpio-bank-g.h> #include <plat/gpio-bank-h.h> #include <plat/gpio-bank-i.h> #include <plat/gpio-bank-j.h> #include <plat/gpio-bank-k.h> #include <plat/gpio-bank-l.h> #include <plat/gpio-bank-m.h> #include <plat/gpio-bank-n.h> #include <plat/gpio-bank-q.h> #include <plat/gpio-bank-o.h> #include <plat/gpio-bank-p.h> #include <plat/gpio-bank-q.h> #include <mach/map.h> /* Base addresses for each of the banks */ //由虚拟地址加偏移地址计算基地址。以GPM的基地址计算为例: //gpm的虚拟地址是S3C64XX_VA_GPIO,定义在mach/map.h中: //#define S3C64XX_VA_GPIO S3C_ADDR(0x00500000) //S3C_ADDR(0x00500000)是定义在plat/map.h中的: //#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE+ (x)) //S3C_ADDR_BASE是全局虚拟地址,它的定义是:#define S3C_ADDR_BASE (0xF4000000) //void __iomem __force *作用是强制转化为地址 //综合以上,GPM的宏S3C64XX_GPM_BASE展开的情形是: //(0xF4000000+0x00500000)+ 0x0820 = 0xf4500820,括号里面的是虚拟地址,后面的是 //偏移量,查S3C6410的手册会发现这个地址刚好是GPMCON寄存器的地址!!!!!
#define S3C64XX_GPA_BASE (S3C64XX_VA_GPIO + 0x0000) #define S3C64XX_GPB_BASE (S3C64XX_VA_GPIO + 0x0020) #define S3C64XX_GPC_BASE (S3C64XX_VA_GPIO + 0x0040) #define S3C64XX_GPD_BASE (S3C64XX_VA_GPIO + 0x0060) #define S3C64XX_GPE_BASE (S3C64XX_VA_GPIO + 0x0080) #define S3C64XX_GPF_BASE (S3C64XX_VA_GPIO + 0x00A0) #define S3C64XX_GPG_BASE (S3C64XX_VA_GPIO + 0x00C0) #define S3C64XX_GPH_BASE (S3C64XX_VA_GPIO + 0x00E0) #define S3C64XX_GPI_BASE (S3C64XX_VA_GPIO + 0x0100) #define S3C64XX_GPJ_BASE (S3C64XX_VA_GPIO + 0x0120) #define S3C64XX_GPK_BASE (S3C64XX_VA_GPIO + 0x0800) #define S3C64XX_GPL_BASE (S3C64XX_VA_GPIO + 0x0810) #define S3C64XX_GPM_BASE (S3C64XX_VA_GPIO + 0x0820) #define S3C64XX_GPN_BASE (S3C64XX_VA_GPIO + 0x0830) #define S3C64XX_GPO_BASE (S3C64XX_VA_GPIO + 0x0140) #define S3C64XX_GPP_BASE (S3C64XX_VA_GPIO + 0x0160) #define S3C64XX_GPQ_BASE (S3C64XX_VA_GPIO + 0x0180) #define S3C64XX_SPC_BASE (S3C64XX_VA_GPIO + 0x01A0) #define S3C64XX_MEM0CONSTOP (S3C64XX_VA_GPIO + 0x01B0) #define S3C64XX_MEM1CONSTOP (S3C64XX_VA_GPIO + 0x01B4) #define S3C64XX_MEM0CONSLP0 (S3C64XX_VA_GPIO + 0x01C0) #define S3C64XX_MEM0CONSLP1 (S3C64XX_VA_GPIO + 0x01C4) #define S3C64XX_MEM1CONSLP (S3C64XX_VA_GPIO + 0x01C8) #define S3C64XX_MEM0DRVCON (S3C64XX_VA_GPIO + 0x01D0) #define S3C64XX_MEM1DRVCON (S3C64XX_VA_GPIO + 0x01D4) #define S3C64XX_EINT0CON0 (S3C64XX_VA_GPIO + 0x0900) #define S3C64XX_EINT0CON1 (S3C64XX_VA_GPIO + 0x0904) #define S3C64XX_EINT0FLTCON0 (S3C64XX_VA_GPIO + 0x0910) #define S3C64XX_EINT0FLTCON1 (S3C64XX_VA_GPIO + 0x0914) #define S3C64XX_EINT0FLTCON2 (S3C64XX_VA_GPIO + 0x0918) #define S3C64XX_EINT0FLTCON3 (S3C64XX_VA_GPIO + 0x091C) #define S3C64XX_EINT0MASK (S3C64XX_VA_GPIO + 0x0920) #define S3C64XX_EINT0PEND (S3C64XX_VA_GPIO + 0x0924) #define S3C64XX_SPCONSLP (S3C64XX_VA_GPIO + 0x0880) #define S3C64XX_SLPEN (S3C64XX_VA_GPIO + 0x0930) #define S3C64XX_EINT12CON (S3C64XX_VA_GPIO + 0x0200) #define S3C64XX_EINT34CON (S3C64XX_VA_GPIO + 0x0204) #define S3C64XX_EINT56CON (S3C64XX_VA_GPIO + 0x0208) #define S3C64XX_EINT78CON (S3C64XX_VA_GPIO + 0x020C) #define S3C64XX_EINT9CON (S3C64XX_VA_GPIO + 0x0210) #define S3C64XX_EINT12FLTCON (S3C64XX_VA_GPIO + 0x0220) #define S3C64XX_EINT34FLTCON (S3C64XX_VA_GPIO + 0x0224) #define S3C64XX_EINT56FLTCON (S3C64XX_VA_GPIO + 0x0228) #define S3C64XX_EINT78FLTCON (S3C64XX_VA_GPIO + 0x022C) #define S3C64XX_EINT9FLTCON (S3C64XX_VA_GPIO + 0x0230) #define S3C64XX_EINT12MASK (S3C64XX_VA_GPIO + 0x0240) #define S3C64XX_EINT34MASK (S3C64XX_VA_GPIO + 0x0244) #define S3C64XX_EINT56MASK (S3C64XX_VA_GPIO + 0x0248) #define S3C64XX_EINT78MASK (S3C64XX_VA_GPIO + 0x024C) #define S3C64XX_EINT9MASK (S3C64XX_VA_GPIO + 0x0250) #define S3C64XX_EINT12PEND (S3C64XX_VA_GPIO + 0x0260) #define S3C64XX_EINT34PEND (S3C64XX_VA_GPIO + 0x0264) #define S3C64XX_EINT56PEND (S3C64XX_VA_GPIO + 0x0268) #define S3C64XX_EINT78PEND (S3C64XX_VA_GPIO + 0x026C) #define S3C64XX_EINT9PEND (S3C64XX_VA_GPIO + 0x0270) #define S3C64XX_PRIORITY (S3C64XX_VA_GPIO + 0x0280) #define S3C64XX_SERVICE (S3C64XX_VA_GPIO + 0x0284) #define S3C64XX_SERVICEPEND (S3C64XX_VA_GPIO + 0x0288) /* values for S3C_EXTINT0 */ #define S3C64XX_EXTINT_LOWLEV (0x00) #define S3C64XX_EXTINT_HILEV (0x01) #define S3C64XX_EXTINT_FALLEDGE (0x02) #define S3C64XX_EXTINT_RISEEDGE (0x04) #define S3C64XX_EXTINT_BOTHEDGE (0x06) #endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */
以下仅列出<plat/gpio-bank-m.h>中的内容:
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-m.h * * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * http://armlinux.simtec.co.uk/ * * GPIO Bank M register and configuration definitions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #define S3C64XX_GPMCON (S3C64XX_GPM_BASE + 0x00) //经过上面的计算容易知道,这个宏就是GPMCON的地址 #define S3C64XX_GPMDAT (S3C64XX_GPM_BASE + 0x04) //GPMDAT的地址 #define S3C64XX_GPMPUD (S3C64XX_GPM_BASE + 0x08) //GPMPUD的地址 #define S3C64XX_GPM_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) #define S3C64XX_GPM_INPUT(__gpio) (0x0 << ((__gpio) * 2)) //输入的配置数据宏,将GPMCON与之按位与就能将gpio位配置为输入 #define S3C64XX_GPM_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) //输出的配置数据宏,将GPMCON与之按位或就能将gpio位配置为输出 #define S3C64XX_GPM0_HOSTIF_CS (0x02 << 0) #define S3C64XX_GPM0_EINT23 (0x03 << 0) #define S3C64XX_GPM0_RESERVED1 (0x04 << 0) #define S3C64XX_GPM0_DATA_CF10 (0x05 << 0) #define S3C64XX_GPM0_CE_CF0 (0x06 << 0) #define S3C64XX_GPM0_RESERVED2 (0x07 << 0) #define S3C64XX_GPM1_HOSTIF_CS_M (0x02 << 0) #define S3C64XX_GPM1_EINT24 (0x03 << 0) #define S3C64XX_GPM1_RESERVED1 (0x04 << 0) #define S3C64XX_GPM1_DATA_CF11 (0x05 << 0) #define S3C64XX_GPM1_CE_CF1 (0x06 << 0) #define S3C64XX_GPM1_RESERVED2 (0x07 << 0) #define S3C64XX_GPM2_HOSTIF_IF_CS_S (0x02 << 0) #define S3C64XX_GPM2_EINT25 (0x03 << 0) #define S3C64XX_GPM2_HOSTIF_MDP_VSYNC (0x04 << 0) #define S3C64XX_GPM2_DATA_CF12 (0x05 << 0) #define S3C64XX_GPM2_IORD_CF (0x06 << 0) #define S3C64XX_GPM2_RESERVED2 (0x07 << 0) #define S3C64XX_GPM3_HOSTIF_WE (0x02 << 0) #define S3C64XX_GPM3_EINT26 (0x03 << 0) #define S3C64XX_GPM3_RESERVED1 (0x04 << 0) #define S3C64XX_GPM3_DATA_CF13 (0x05 << 0) #define S3C64XX_GPM3_IOWR_CF (0x06 << 0) #define S3C64XX_GPM3_RESERVED2 (0x07 << 0) #define S3C64XX_GPM4_HOSTIF_OE (0x02 << 0) #define S3C64XX_GPM4_EINT27 (0x03 << 0) #define S3C64XX_GPM4_RESERVED1 (0x04 << 0) #define S3C64XX_GPM4_DATA_CF14 (0x05 << 0) #define S3C64XX_GPM4_IORDY_CF (0x06 << 0) #define S3C64XX_GPM4_RESERVED2 (0x07 << 0) #define S3C64XX_GPM5_HOSTIF_INTR (0x02 << 0) #define S3C64XX_GPM5_CF_DATA_DIR (0x03 << 0) #define S3C64XX_GPM5_RESERVED1 (0x04 << 0) #define S3C64XX_GPM5_DATA_CF15 (0x05 << 0) #define S3C64XX_GPM5_RESERVED2 (0x06 << 0) #define S3C64XX_GPM5_RESERVED3 (0x07 << 0)
三、<plat/gpio-cfg.h>头文件:
/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h * * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * * S3C Platform - GPIO pin configuration * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ /* This file contains the necessary definitions to get the basic gpio * pin configuration done such as setting a pin to input or output or * changing the pull-{up,down} configurations. */ /* Note, this interface is being added to the s3c64xx arch first and will * be added to the s3c24xx systems later. */ #ifndef __PLAT_GPIO_CFG_H #define __PLAT_GPIO_CFG_H __FILE__ typedef unsigned int __bitwise__ s3c_gpio_pull_t; /* forward declaration if gpio-core.h hasn't been included */ struct s3c_gpio_chip; /** * 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 int cfg_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); }; #define S3C_GPIO_SPECIAL_MARK (0xfffffff0) #define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x)) /* Defines for generic pin configurations */ #define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) #define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) #define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) #define s3c_gpio_is_cfg_special(_cfg) \ (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK) /** * s3c_gpio_cfgpin() - Change the GPIO function of a pin. * @pin The pin number to configure. * @to The configuration for the pin's function. * * Configure which function is actually connected to the external * pin, such as an gpio input, output or some form of special function * connected to an internal peripheral block. */ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); //此宏函数将pin引脚配置成“to”功能,to可以取/* Defines for generic pin configurations */ 中定义的值 /* Define values for the pull-{up,down} available for each gpio pin. * * These values control the state of the weak pull-{up,down} resistors * available on most pins on the S3C series. Not all chips support both * up or down settings, and it may be dependant on the chip that is being * used to whether the particular mode is available. */ #define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) #define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) #define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) /** * s3c_gpio_setpull() - set the state of a gpio pin pull resistor * @pin: The pin number to configure the pull resistor. * @pull: The configuration for the pull resistor. * * This function sets the state of the pull-{up,down} resistor for the * specified pin. It will return 0 if successfull, or a negative error * code if the pin cannot support the requested pull setting. */ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); //将pin引脚的上拉电阻设置成“pull”状态,pull可以去上面宏定义的那些值 /** * s3c_gpio_getpull() - get the pull resistor state of a gpio pin * @pin: The pin number to get the settings for * * Read the pull resistor value for the specified pin. */ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); //读取pin引脚上拉电阻的状态 #endif /* __PLAT_GPIO_CFG_H */
LED驱动GPIO相关头文件简要分析
最新推荐文章于 2023-04-19 22:36:39 发布