LED驱动程序相关头文件简单介绍
2011-10-25 21:53
453 查看
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 《常识》 ¥应用程序----->系统内核----->设备驱动----->硬件设备 ¥设备驱动既是系统内核的下属,又是硬件设备的老大。 ¥在inux系统中用一个文件来代表一个设备。这个文件就叫设备文件。设备驱动的责任是将应用程序对设备文件 的打开、读、写、定位等操作转化为对硬件设备的打开、读、写、定位等操作。而对于任何硬件设备,应用程序 只需利用这些基本操作就可以完全控制它! ¥编写linux设备驱动需要的知识结构: 1、40%的设计模式相关知识。设计模式是系统内核限定的,做别人的下属就得按照别人的规矩办事。 2、30%的内核工作原理相关知识。内核是你领导,领会领导意图才能把事情办好。 3、30%的硬件相关知识。控制好硬件是你的的本质工作,你得把你的小弟管理好. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在解读OK6410官方提供的LED驱动程序源码的过程中,发现很多没见过的宏和函数。例如S3C64XX_GPM(0)、S3C64XX_GPM_OUTPUT(0)、__raw_writel(tmp,S3C64XX_GPMPUD)、__raw_writel(tmp,S3C64XX_GPMCON)等。而这些都包含在一些头文件里面。另一方面,我们自己动手编写LED的驱动程序也必须知道相关的头文件有哪些,对我们有哪些用。因此,我觉得在自己动手编写LED驱动程序之前对相关头文件进行简单的分析是非常有必要的。以下是我自己结合源码分析得出的一些结论,如有不正确的地方,希望能够得到指正。
OK6410官方提供的LED驱动程序源码:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/cdev.h> #include <asm/irq.h> #include <mach/gpio.h> #include <plat/regs-gpio.h> #include <plat/gpio-cfg.h> #include <mach/hardware.h> #include <linux/io.h> #define DEVICE_NAME "leds" #define LED_MAJOR 231 static unsigned long led_table [] = { S3C64XX_GPM(0), S3C64XX_GPM(1), S3C64XX_GPM(2), S3C64XX_GPM(3), }; static unsigned int led_cfg_table [] = { S3C64XX_GPM_OUTPUT(0), S3C64XX_GPM_OUTPUT(1), S3C64XX_GPM_OUTPUT(2), S3C64XX_GPM_OUTPUT(3), }; static int s3c6410_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { unsigned long tmp; switch(cmd) { case 0: case 1: if (arg > 4) { return -EINVAL; } tmp = __raw_readl(S3C64XX_GPMDAT); if(cmd) tmp &= (~(1<<arg)); else tmp |= (1<<arg); __raw_writel(tmp,S3C64XX_GPMDAT); // gpio_set_value(led_table[arg], !cmd); return 0; default: return -EINVAL; } } static struct file_operations s3c6410_leds_fops = { .owner = THIS_MODULE, .ioctl = s3c6410_leds_ioctl, }; static struct cdev cdev_leds; struct class * my_class; static int __init s3c6410_leds_init(void) { int ret; unsigned long tmp; int i; dev_t devno; printk(KERN_NOTICE "enter s3c6410_leds_init\n"); devno = MKDEV(LED_MAJOR,0); ret = register_chrdev_region(devno,1,DEVICE_NAME); ret = 0; if(ret<0) { printk(KERN_NOTICE "can not register led device"); return ret; } cdev_init(&cdev_leds,&s3c6410_leds_fops); cdev_leds.owner = THIS_MODULE; ret =cdev_add(&cdev_leds,devno,1); if(ret) { printk(KERN_NOTICE "can not add leds device"); return ret; } my_class = class_create(THIS_MODULE,"my_class"); if(IS_ERR(my_class)) { printk("Err: Failed in creating class\n"); return -1; } device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME); //gpm0-3 pull up tmp = __raw_readl(S3C64XX_GPMPUD); tmp &= (~0xFF); tmp |= 0xaa; __raw_writel(tmp,S3C64XX_GPMPUD); //gpm0-3 output mode tmp = __raw_readl(S3C64XX_GPMCON); tmp &= (~0xFFFF); tmp |= 0x1111; __raw_writel(tmp,S3C64XX_GPMCON); //gpm0-3 output 0 tmp = __raw_readl(S3C64XX_GPMDAT); tmp |= 0x10; __raw_writel(tmp,S3C64XX_GPMDAT); //printk("S3C64XX_GPMCON is %x\n",__raw_readl(S3C64XX_GPMCON)); //printk("S3C64XX_GPMDAT is %x\n",__raw_readl(S3C64XX_GPMDAT)); //printk("S3C64XX_GPMPUD is %x\n",__raw_readl(S3C64XX_GPMPUD)); printk(DEVICE_NAME " initialized\n"); return 0; } static void __exit s3c6410_leds_exit(void) { cdev_del(&cdev_leds); unregister_chrdev_region(MKDEV(LED_MAJOR,0),1); printk(KERN_NOTICE "s3c2440_leds_exit\n"); } module_init(s3c6410_leds_init); module_exit(s3c6410_leds_exit); MODULE_LICENSE("GPL");
一、模块相关头文件:
1、#include <linux/module.h>:在编写任何模块都需要包含此头文件。该头文件自动包含了 <linux/version.h>头文件,该头文件包含了宏MODULE_LICENSE("GPL")的定义。
2、#include <linux/init.h>:此头文件也是必须的,module_init()与module_exit()宏就是定义在它里面的。而且正是这个头文件定义了初始化函数加__init和推出函数加__exit的作用(static int __init s3c6410_leds_init(void)和static void __exit s3c6410_leds_exit(void))
3、#include <linux/kernel.h>:此头文件也是常用头文件,如果需要使用printk函数,则必须包含此头文件。另外该头文件还包含了<types.h>头文件,而这个头文件定义许多常用的数据类型,其中就包括设备号类型dev_t。如下:
#ifndef _LINUX_TYPES_H #define _LINUX_TYPES_H #ifdef __KERNEL__ #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] #endif #include <linux/posix_types.h> #include <asm/types.h> #ifndef __KERNEL_STRICT_NAMES typedef __u32 __kernel_dev_t; typedef __kernel_fd_set fd_set; typedef __kernel_dev_t dev_t; typedef __kernel_ino_t ino_t; typedef __kernel_mode_t mode_t; typedef __kernel_nlink_t nlink_t; typedef __kernel_off_t off_t; typedef __kernel_pid_t pid_t; typedef __kernel_daddr_t daddr_t; typedef __kernel_key_t key_t; typedef __kernel_suseconds_t suseconds_t; typedef __kernel_timer_t timer_t; typedef __kernel_clockid_t clockid_t; typedef __kernel_mqd_t mqd_t; #ifdef __KERNEL__ typedef _Bool bool; typedef __kernel_uid32_t uid_t; typedef __kernel_gid32_t gid_t; typedef __kernel_uid16_t uid16_t; typedef __kernel_gid16_t gid16_t; typedef unsigned long uintptr_t; #ifdef CONFIG_UID16 /* This is defined by include/asm-{arch}/posix_types.h */ typedef __kernel_old_uid_t old_uid_t; typedef __kernel_old_gid_t old_gid_t; #endif /* CONFIG_UID16 */ /* libc5 includes this file to define uid_t, thus uid_t can never change * when it is included by non-kernel code */ #else typedef __kernel_uid_t uid_t; typedef __kernel_gid_t gid_t; #endif /* __KERNEL__ */ #if defined(__GNUC__) typedef __kernel_loff_t loff_t; #endif /* * The following typedefs are also protected by individual ifdefs for * historical reasons: */ #ifndef _SIZE_T #define _SIZE_T typedef __kernel_size_t size_t; #endif #ifndef _SSIZE_T #define _SSIZE_T typedef __kernel_ssize_t ssize_t; #endif #ifndef _PTRDIFF_T #define _PTRDIFF_T typedef __kernel_ptrdiff_t ptrdiff_t; #endif #ifndef _TIME_T #define _TIME_T typedef __kernel_time_t time_t; #endif #ifndef _CLOCK_T #define _CLOCK_T typedef __kernel_clock_t clock_t; #endif #ifndef _CADDR_T #define _CADDR_T typedef __kernel_caddr_t caddr_t; #endif /* bsd */ typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; /* sysv */ typedef unsigned char unchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; #ifndef __BIT_TYPES_DEFINED__ #define __BIT_TYPES_DEFINED__ typedef __u8 u_int8_t; typedef __s8 int8_t; typedef __u16 u_int16_t; typedef __s16 int16_t; typedef __u32 u_int32_t; typedef __s32 int32_t; #endif /* !(__BIT_TYPES_DEFINED__) */ typedef __u8 uint8_t; typedef __u16 uint16_t; typedef __u32 uint32_t; #if defined(__GNUC__) typedef __u64 uint64_t; typedef __u64 u_int64_t; typedef __s64 int64_t; #endif /* this is a special 64bit data type that is 8-byte aligned */ #define aligned_u64 __u64 __attribute__((aligned(8))) #define aligned_be64 __be64 __attribute__((aligned(8))) #define aligned_le64 __le64 __attribute__((aligned(8))) /** * The type used for indexing onto a disc or disc partition. * * Linux always considers sectors to be 512 bytes long independently * of the devices real block size. */ #ifdef CONFIG_LBD typedef u64 sector_t; #else typedef unsigned long sector_t; #endif /* * The type of the inode's block count. */ #ifdef CONFIG_LSF typedef u64 blkcnt_t; #else typedef unsigned long blkcnt_t; #endif /* * The type of an index into the pagecache. Use a #define so asm/types.h * can override it. */ #ifndef pgoff_t #define pgoff_t unsigned long #endif #endif /* __KERNEL_STRICT_NAMES */ /* * Below are truly Linux-specific types that should never collide with * any application/library that wants linux/types.h. */ #ifdef __CHECKER__ #define __bitwise__ __attribute__((bitwise)) #else #define __bitwise__ #endif #ifdef __CHECK_ENDIAN__ #define __bitwise __bitwise__ #else #define __bitwise #endif typedef __u16 __bitwise __le16; typedef __u16 __bitwise __be16; typedef __u32 __bitwise __le32; typedef __u32 __bitwise __be32; #if defined(__GNUC__) typedef __u64 __bitwise __le64; typedef __u64 __bitwise __be64; #endif typedef __u16 __bitwise __sum16; typedef __u32 __bitwise __wsum; #ifdef __KERNEL__ typedef unsigned __bitwise__ gfp_t; typedef unsigned __bitwise__ fmode_t; #ifdef CONFIG_PHYS_ADDR_T_64BIT typedef u64 phys_addr_t; #else typedef u32 phys_addr_t; #endif typedef phys_addr_t resource_size_t; struct ustat { __kernel_daddr_t f_tfree; __kernel_ino_t f_tinode; char f_fname[6]; char f_fpack[6]; }; #endif /* __KERNEL__ */ #endif /* _LINUX_TYPES_H */
二、字符设备驱动相关头文件:
1、#include <linux/fs.h>:该头文件包含了常用的数据结构,当然也包括三种最重要的:struct file、struct file_operation、struct inode。另外该头文件还包含了<linux/ioctl.h>头文件。
2、#include <linux/cdev.h>:该头文件定义了struct cdev数据结构,也包含了字符设备操作的相关函数:
#ifndef _LINUX_CDEV_H #define _LINUX_CDEV_H #include <linux/kobject.h> #include <linux/kdev_t.h> #include <linux/list.h> struct file_operations; struct inode; struct module; struct cdev { struct kobject kobj; struct module *owner; const struct file_operations *ops; struct list_head list; dev_t dev; unsigned int count; }; void cdev_init(struct cdev *, const struct file_operations *); struct cdev *cdev_alloc(void); void cdev_put(struct cdev *p); int cdev_add(struct cdev *, dev_t, unsigned); void cdev_del(struct cdev *); void cd_forget(struct inode *); extern struct backing_dev_info directly_mappable_cdev_bdi; #endif
3、<linux/device.h>:包含自动创建设备文件的相关函数的申明:原函数中-class_create(THIS_MODULE,"my_class")、device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME)。
三、s3c64xx GPIO操作相关头文件:
1、#include <mach/gpio.h>:此头文件包含了对S3C64xx 各个GPIO的宏定义,并包含了各个端口的读写函数,如下:
/* 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 #define gpio_set_value __gpio_set_value #define gpio_cansleep __gpio_cansleep #define gpio_to_irq __gpio_to_irq /* GPIO bank sizes */ #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) 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) #include <asm-generic/gpio.h>
上面的头文件包含了<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); extern void gpio_free(unsigned gpio); extern int gpio_direction_input(unsigned gpio); extern int gpio_direction_output(unsigned gpio, int value); 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); extern void __gpio_set_value(unsigned gpio, int 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 */
2、#include <plat/regs-gpio.h>:定义了GPIO相关的数据宏:
/* 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__ #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-n.h> #include #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 */ #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-a.h>-------><plat/gpio-bank-q.h>系列头文件,而这些头文件里面定义了对应GPIO的一系列数据宏,例如 <plat/gpio-bank-m.h>里面定义的是led程序中用到的GPM端口相关的数据宏,如下:
/* 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) #define S3C64XX_GPMDAT (S3C64XX_GPM_BASE + 0x04) #define S3C64XX_GPMPUD (S3C64XX_GPM_BASE + 0x08) #define S3C64XX_GPM_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) #define S3C64XX_GPM_INPUT(__gpio) (0x0 << ((__gpio) * 2)) #define S3C64XX_GPM_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) #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)
3、#include <plat/gpio-cfg.h>:此头文件包含了GPIO的各种配置函数,例如设置输入输出方式,上拉电阻使能等等:
/* 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 pin The pin number to configure. * @pin 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); /* 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); /** * 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); #endif /* __PLAT_GPIO_CFG_H */
相关文章推荐
- LED驱动程序相关头文件简单介绍
- LED驱动GPIO相关头文件简要分析
- IMX6Q学习笔记———编写LED驱动和测试程序以及相关管脚配置
- LED驱动GPIO相关头文件简要分析
- 本文给出了一种方便实用的解决大文件的读取、存储等处理的方法,并结合相关程序代码对具体的实现过程进行了介绍
- 创建一个Android程序(简单介绍工程里面各个文件的作用)
- IMX6Q学习笔记——编写LED驱动和测试程序以及相关管脚配置
- FileOutputStream 类 和 FileInputStream类的简单介绍,附代码演示。以及一个复制媒体文件的小程序。
- 创建一个Android程序(简单介绍工程里面各个文件的作用)
- FileOutputStream 类 和 FileInputStream类的简单介绍,附代码演示。以及一个复制媒体文件的小程序
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
- SequenceInputStream类的简单介绍。以及用该类合并集合文件数据的程序代码。
- arm LED驱动小程序 可以通过modprobe 加载ko文件
- 简单介绍Eclipse的Project相关的隐藏配置文件
- 将Java程序变成可执行文件的简单方法
- JZ2440 启动NFS网络文件系统_初试led驱动
- 简单介绍一下BSP中的dirs文件和sources文件(WinCE
- solr4.2 solrconfig.xml配置文件简单介绍
- C下学生管理系统:从文件中读取30位学生的信息(含邮箱),并实现简单的增、删、查找、统计(邮箱使用人数)。---附程序哦!
- 3.4 最简单的设备驱动——LED灯驱动