Linux下s3c6410的GPIO操作(1)

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_chipchip;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_chipchip;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外部中断* A84BitYes1* B74BitYes1* C84BitYes2* D54BitYes3* E54BitYesNone* F162BitYes4 [1]* G74BitYes5* H104Bit[2]Yes6* I162BitYesNone* J122BitYesNone* K164Bit[2]NoNone* L154Bit[2] NoNone* M64BitNoIRQ_EINT* N162BitNoIRQ_EINT* O162BitYes7* P152BitYes8* Q92BitYes9** [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操作(2)的链接

人创造奇迹常常是在瞬间,

Linux下s3c6410的GPIO操作(1)

相关文章:

你感兴趣的文章:

标签云: