版权声明:本文为博主原创文章,未经博主允许不得转载。
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 《常识》
- ¥应用程序----->系统内核----->设备驱动----->硬件设备
- ¥设备驱动既是系统内核的下属,又是硬件设备的老大。
- ¥在inux系统中用一个文件来代表一个设备。这个文件就叫设备文件。设备驱动的责任是将应用程序对设备文件
- 的打开、读、写、定位等操作转化为对硬件设备的打开、读、写、定位等操作。而对于任何硬件设备,应用程序
- 只需利用这些基本操作就可以完全控制它!
- ¥编写linux设备驱动需要的知识结构:
- 1、40%的设计模式相关知识。设计模式是系统内核限定的,做别人的下属就得按照别人的规矩办事。
- 2、30%的内核工作原理相关知识。内核是你领导,领会领导意图才能把事情办好。
- 3、30%的硬件相关知识。控制好硬件是你的的本质工作,你得把你的小弟管理好.
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
《常识》
¥应用程序----->系统内核----->设备驱动----->硬件设备
¥设备驱动既是系统内核的下属,又是硬件设备的老大。
¥在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");
#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 */
#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
#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>
/* 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 */
#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 */
/* 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)
/* 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 */
/* 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 */
-
顶
- 0
-
踩
- 0
我的同类文章
- •led字符设备驱动2011-11-10
- •LED驱动GPIO相关头文件简要分析2011-10-26
- •arm-linux-gcc交叉工具链的使用2011-10-24
- •linux字符设备驱动学习笔记22011-10-17
- •s3c6410 GPIO驱动总结2011-10-31
- •OK6410系列之01---模块编程2011-10-24
- •linux字符设备驱动学习笔记32011-10-17
- •linux字符设备驱动学习笔记12011-10-12