|
分类: linux驱动开发2011-10-25 21:53 3455人阅读 评论(1) 收藏 举报
[cpp] view plaincopy
1. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2. 《常识》
3. ¥应用程序----->系统内核----->设备驱动----->硬件设备
4. ¥设备驱动既是系统内核的下属,又是硬件设备的老大。
5. ¥在inux系统中用一个文件来代表一个设备。这个文件就叫设备文件。设备驱动的责任是将应用程序对设备文件
6. 的打开、读、写、定位等操作转化为对硬件设备的打开、读、写、定位等操作。而对于任何硬件设备,应用程序
7. 只需利用这些基本操作就可以完全控制它!
8. ¥编写linux设备驱动需要的知识结构:
9. 1、40%的设计模式相关知识。设计模式是系统内核限定的,做别人的下属就得按照别人的规矩办事。
10. 2、30%的内核工作原理相关知识。内核是你领导,领会领导意图才能把事情办好。
11. 3、30%的硬件相关知识。控制好硬件是你的的本质工作,你得把你的小弟管理好.
12. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在解读OK6410官方提供的LED驱动程序源码的过程中,发现很多没见过的宏和函数。例如S3C64XX_GPM(0)、S3C64XX_GPM_OUTPUT(0)、__raw_writel(tmp,S3C64XX_GPMPUD)、__raw_writel(tmp,S3C64XX_GPMCON)等。而这些都包含在一些头文件里面。另一方面,我们自己动手编写LED的驱动程序也必须知道相关的头文件有哪些,对我们有哪些用。因此,我觉得在自己动手编写LED驱动程序之前对相关头文件进行简单的分析是非常有必要的。以下是我自己结合源码分析得出的一些结论,如有不正确的地方,希望能够得到指正。
OK6410官方提供的LED驱动程序源码:
[cpp] view plaincopy
1. #include <linux/module.h>
2. #include <linux/kernel.h>
3. #include <linux/fs.h>
4. #include <linux/init.h>
5. #include <linux/miscdevice.h>
6. #include <linux/delay.h>
7. #include <linux/device.h>
8. #include <linux/cdev.h>
9. #include <asm/irq.h>
10. #include <mach/gpio.h>
11. #include <plat/regs-gpio.h>
12. #include <plat/gpio-cfg.h>
13. #include <mach/hardware.h>
14. #include <linux/io.h>
15.
16. #define DEVICE_NAME "leds"
17. #define LED_MAJOR 231
18.
19.
20. static unsigned long led_table [] = {
21. S3C64XX_GPM(0),
22. S3C64XX_GPM(1),
23. S3C64XX_GPM(2),
24. S3C64XX_GPM(3),
25. };
26.
27. static unsigned int led_cfg_table [] = {
28. S3C64XX_GPM_OUTPUT(0),
29. S3C64XX_GPM_OUTPUT(1),
30. S3C64XX_GPM_OUTPUT(2),
31. S3C64XX_GPM_OUTPUT(3),
32. };
33.
34. static int s3c6410_leds_ioctl(
35. struct inode *inode,
36. struct file *file,
37. unsigned int cmd,
38. unsigned long arg)
39. {
40. unsigned long tmp;
41. switch(cmd) {
42. case 0:
43. case 1:
44. if (arg > 4) {
45. return -EINVAL;
46. }
47. tmp = __raw_readl(S3C64XX_GPMDAT);
48. if(cmd)
49. tmp &= (~(1<<arg));
50. else
51. tmp |= (1<<arg);
52. __raw_writel(tmp,S3C64XX_GPMDAT);
53. // gpio_set_value(led_table[arg], !cmd);
54. return 0;
55. default:
56. return -EINVAL;
57. }
58. }
59.
60.
61. static struct file_operations s3c6410_leds_fops = {
62. .owner = THIS_MODULE,
63. .ioctl = s3c6410_leds_ioctl,
64. };
65.
66. static struct cdev cdev_leds;
67. struct class * my_class;
68.
69. static int __init s3c6410_leds_init(void)
70. {
71. int ret;
72. unsigned long tmp;
73. int i;
74. dev_t devno;
75. printk(KERN_NOTICE "enter s3c6410_leds_init\n");
76.
77.
78. devno = MKDEV(LED_MAJOR,0);
79.
80. ret = register_chrdev_region(devno,1,DEVICE_NAME);
81. ret = 0;
82. if(ret<0)
83. {
84. printk(KERN_NOTICE "can not register led device");
85. return ret;
86. }
87.
88. cdev_init(&cdev_leds,&s3c6410_leds_fops);
89. cdev_leds.owner = THIS_MODULE;
90.
91. ret =cdev_add(&cdev_leds,devno,1);
92. if(ret)
93. {
94. printk(KERN_NOTICE "can not add leds device");
95. return ret;
96. }
97.
98. my_class = class_create(THIS_MODULE,"my_class");
99. if(IS_ERR(my_class))
100. {
101. printk("Err: Failed in creating class\n");
102. return -1;
103. }
104.
105. device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME);
106.
107. //gpm0-3 pull up
108. tmp = __raw_readl(S3C64XX_GPMPUD);
109. tmp &= (~0xFF);
110. tmp |= 0xaa;
111. __raw_writel(tmp,S3C64XX_GPMPUD);
112.
113. //gpm0-3 output mode
114. tmp = __raw_readl(S3C64XX_GPMCON);
115. tmp &= (~0xFFFF);
116. tmp |= 0x1111;
117. __raw_writel(tmp,S3C64XX_GPMCON);
118.
119. //gpm0-3 output 0
120. tmp = __raw_readl(S3C64XX_GPMDAT);
121. tmp |= 0x10;
122. __raw_writel(tmp,S3C64XX_GPMDAT);
123.
124. //printk("S3C64XX_GPMCON is %x\n",__raw_readl(S3C64XX_GPMCON));
125. //printk("S3C64XX_GPMDAT is %x\n",__raw_readl(S3C64XX_GPMDAT));
126. //printk("S3C64XX_GPMPUD is %x\n",__raw_readl(S3C64XX_GPMPUD));
127.
128. printk(DEVICE_NAME " initialized\n");
129.
130. return 0;
131. }
132.
133. static void __exit s3c6410_leds_exit(void)
134. {
135. cdev_del(&cdev_leds);
136.
137. unregister_chrdev_region(MKDEV(LED_MAJOR,0),1);
138.
139. printk(KERN_NOTICE "s3c2440_leds_exit\n");
140. }
141.
142.
143. module_init(s3c6410_leds_init);
144. module_exit(s3c6410_leds_exit);
145.
146. 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。如下:
[cpp] view plaincopy
1. #ifndef _LINUX_TYPES_H
2. #define _LINUX_TYPES_H
3.
4. #ifdef __KERNEL__
5.
6. #define DECLARE_BITMAP(name,bits) \
7. unsigned long name[BITS_TO_LONGS(bits)]
8.
9. #endif
10.
11. #include <linux/posix_types.h>
12. #include <asm/types.h>
13.
14. #ifndef __KERNEL_STRICT_NAMES
15.
16. typedef __u32 __kernel_dev_t;
17.
18. typedef __kernel_fd_set fd_set;
19. typedef __kernel_dev_t dev_t;
20. typedef __kernel_ino_t ino_t;
21. typedef __kernel_mode_t mode_t;
22. typedef __kernel_nlink_t nlink_t;
23. typedef __kernel_off_t off_t;
24. typedef __kernel_pid_t pid_t;
25. typedef __kernel_daddr_t daddr_t;
26. typedef __kernel_key_t key_t;
27. typedef __kernel_suseconds_t suseconds_t;
28. typedef __kernel_timer_t timer_t;
29. typedef __kernel_clockid_t clockid_t;
30. typedef __kernel_mqd_t mqd_t;
31.
32. #ifdef __KERNEL__
33. typedef _Bool bool;
34.
35. typedef __kernel_uid32_t uid_t;
36. typedef __kernel_gid32_t gid_t;
37. typedef __kernel_uid16_t uid16_t;
38. typedef __kernel_gid16_t gid16_t;
39.
40. typedef unsigned long uintptr_t;
41.
42. #ifdef CONFIG_UID16
43. /* This is defined by include/asm-{arch}/posix_types.h */
44. typedef __kernel_old_uid_t old_uid_t;
45. typedef __kernel_old_gid_t old_gid_t;
46. #endif /* CONFIG_UID16 */
47.
48. /* libc5 includes this file to define uid_t, thus uid_t can never change
49. * when it is included by non-kernel code
50. */
51. #else
52. typedef __kernel_uid_t uid_t;
53. typedef __kernel_gid_t gid_t;
54. #endif /* __KERNEL__ */
55.
56. #if defined(__GNUC__)
57. typedef __kernel_loff_t loff_t;
58. #endif
59.
60. /*
61. * The following typedefs are also protected by individual ifdefs for
62. * historical reasons:
63. */
64. #ifndef _SIZE_T
65. #define _SIZE_T
66. typedef __kernel_size_t size_t;
67. #endif
68.
69. #ifndef _SSIZE_T
70. #define _SSIZE_T
71. typedef __kernel_ssize_t ssize_t;
72. #endif
73.
74. #ifndef _PTRDIFF_T
75. #define _PTRDIFF_T
76. typedef __kernel_ptrdiff_t ptrdiff_t;
77. #endif
78.
79. #ifndef _TIME_T
80. #define _TIME_T
81. typedef __kernel_time_t time_t;
82. #endif
83.
84. #ifndef _CLOCK_T
85. #define _CLOCK_T
86. typedef __kernel_clock_t clock_t;
87. #endif
88.
89. #ifndef _CADDR_T
90. #define _CADDR_T
91. typedef __kernel_caddr_t caddr_t;
92. #endif
93.
94. /* bsd */
95. typedef unsigned char u_char;
96. typedef unsigned short u_short;
97. typedef unsigned int u_int;
98. typedef unsigned long u_long;
99.
100. /* sysv */
101. typedef unsigned char unchar;
102. typedef unsigned short ushort;
103. typedef unsigned int uint;
104. typedef unsigned long ulong;
105.
106. #ifndef __BIT_TYPES_DEFINED__
107. #define __BIT_TYPES_DEFINED__
108.
109. typedef __u8 u_int8_t;
110. typedef __s8 int8_t;
111. typedef __u16 u_int16_t;
112. typedef __s16 int16_t;
113. typedef __u32 u_int32_t;
114. typedef __s32 int32_t;
115.
116. #endif /* !(__BIT_TYPES_DEFINED__) */
117.
118. typedef __u8 uint8_t;
119. typedef __u16 uint16_t;
120. typedef __u32 uint32_t;
121.
122. #if defined(__GNUC__)
123. typedef __u64 uint64_t;
124. typedef __u64 u_int64_t;
125. typedef __s64 int64_t;
126. #endif
127.
128. /* this is a special 64bit data type that is 8-byte aligned */
129. #define aligned_u64 __u64 __attribute__((aligned(8)))
130. #define aligned_be64 __be64 __attribute__((aligned(8)))
131. #define aligned_le64 __le64 __attribute__((aligned(8)))
132.
133. /**
134. * The type used for indexing onto a disc or disc partition.
135. *
136. * Linux always considers sectors to be 512 bytes long independently
137. * of the devices real block size.
138. */
139. #ifdef CONFIG_LBD
140. typedef u64 sector_t;
141. #else
142. typedef unsigned long sector_t;
143. #endif
144.
145. /*
146. * The type of the inode's block count.
147. */
148. #ifdef CONFIG_LSF
149. typedef u64 blkcnt_t;
150. #else
151. typedef unsigned long blkcnt_t;
152. #endif
153.
154. /*
155. * The type of an index into the pagecache. Use a #define so asm/types.h
156. * can override it.
157. */
158. #ifndef pgoff_t
159. #define pgoff_t unsigned long
160. #endif
161.
162. #endif /* __KERNEL_STRICT_NAMES */
163.
164. /*
165. * Below are truly Linux-specific types that should never collide with
166. * any application/library that wants linux/types.h.
167. */
168.
169. #ifdef __CHECKER__
170. #define __bitwise__ __attribute__((bitwise))
171. #else
172. #define __bitwise__
173. #endif
174. #ifdef __CHECK_ENDIAN__
175. #define __bitwise __bitwise__
176. #else
177. #define __bitwise
178. #endif
179.
180. typedef __u16 __bitwise __le16;
181. typedef __u16 __bitwise __be16;
182. typedef __u32 __bitwise __le32;
183. typedef __u32 __bitwise __be32;
184. #if defined(__GNUC__)
185. typedef __u64 __bitwise __le64;
186. typedef __u64 __bitwise __be64;
187. #endif
188. typedef __u16 __bitwise __sum16;
189. typedef __u32 __bitwise __wsum;
190.
191. #ifdef __KERNEL__
192. typedef unsigned __bitwise__ gfp_t;
193. typedef unsigned __bitwise__ fmode_t;
194.
195. #ifdef CONFIG_PHYS_ADDR_T_64BIT
196. typedef u64 phys_addr_t;
197. #else
198. typedef u32 phys_addr_t;
199. #endif
200.
201. typedef phys_addr_t resource_size_t;
202.
203. struct ustat {
204. __kernel_daddr_t f_tfree;
205. __kernel_ino_t f_tinode;
206. char f_fname[6];
207. char f_fpack[6];
208. };
209.
210. #endif /* __KERNEL__ */
211.
212. #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数据结构,也包含了字符设备操作的相关函数:
[cpp] view plaincopy
1. #ifndef _LINUX_CDEV_H
2. #define _LINUX_CDEV_H
3.
4. #include <linux/kobject.h>
5. #include <linux/kdev_t.h>
6. #include <linux/list.h>
7.
8. struct file_operations;
9. struct inode;
10. struct module;
11.
12. struct cdev {
13. struct kobject kobj;
14. struct module *owner;
15. const struct file_operations *ops;
16. struct list_head list;
17. dev_t dev;
18. unsigned int count;
19. };
20.
21. void cdev_init(struct cdev *, const struct file_operations *);
22.
23. struct cdev *cdev_alloc(void);
24.
25. void cdev_put(struct cdev *p);
26.
27. int cdev_add(struct cdev *, dev_t, unsigned);
28.
29. void cdev_del(struct cdev *);
30.
31. void cd_forget(struct inode *);
32.
33. extern struct backing_dev_info directly_mappable_cdev_bdi;
34.
35. #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的宏定义,并包含了各个端口的读写函数,如下:
[cpp] view plaincopy
1. /* linux/arch/arm/mach-s3c6400/include/mach/gpio.h
2. *
3. * Copyright 2008 Openmoko, Inc.
4. * Copyright 2008 Simtec Electronics
5. * http://armlinux.simtec.co.uk/
6. * Ben Dooks <ben@simtec.co.uk>
7. *
8. * S3C6400 - GPIO lib support
9. *
10. * This program is free software; you can redistribute it and/or modify
11. * it under the terms of the GNU General Public License version 2 as
12. * published by the Free Software Foundation.
13. */
14.
15. #define gpio_get_value __gpio_get_value
16. #define gpio_set_value __gpio_set_value
17. #define gpio_cansleep __gpio_cansleep
18. #define gpio_to_irq __gpio_to_irq
19.
20. /* GPIO bank sizes */
21. #define S3C64XX_GPIO_A_NR (8)
22. #define S3C64XX_GPIO_B_NR (7)
23. #define S3C64XX_GPIO_C_NR (8)
24. #define S3C64XX_GPIO_D_NR (5)
25. #define S3C64XX_GPIO_E_NR (5)
26. #define S3C64XX_GPIO_F_NR (16)
27. #define S3C64XX_GPIO_G_NR (7)
28. #define S3C64XX_GPIO_H_NR (10)
29. #define S3C64XX_GPIO_I_NR (16)
30. #define S3C64XX_GPIO_J_NR (12)
31. #define S3C64XX_GPIO_K_NR (16)
32. #define S3C64XX_GPIO_L_NR (15)
33. #define S3C64XX_GPIO_M_NR (6)
34. #define S3C64XX_GPIO_N_NR (16)
35. #define S3C64XX_GPIO_O_NR (16)
36. #define S3C64XX_GPIO_P_NR (15)
37. #define S3C64XX_GPIO_Q_NR (9)
38.
39. /* GPIO bank numbes */
40.
41. /* CONFIG_S3C_GPIO_SPACE allows the user to select extra
42. * space for debugging purposes so that any accidental
43. * change from one gpio bank to another can be caught.
44. */
45.
46. #define S3C64XX_GPIO_NEXT(__gpio) \
47. ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
48.
49. enum s3c_gpio_number {
50. S3C64XX_GPIO_A_START = 0,
51. S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
52. S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
53. S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
54. S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
55. S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
56. S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
57. S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
58. S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
59. S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
60. S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
61. S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
62. S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
63. S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
64. S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
65. S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
66. S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
67. };
68.
69. /* S3C64XX GPIO number definitions. */
70.
71. #define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr))
72. #define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr))
73. #define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr))
74. #define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr))
75. #define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr))
76. #define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr))
77. #define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr))
78. #define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr))
79. #define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr))
80. #define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr))
81. #define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr))
82. #define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr))
83. #define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr))
84. #define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr))
85. #define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr))
86. #define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr))
87. #define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr))
88.
89. /* the end of the S3C64XX specific gpios */
90. #define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
91. #define S3C_GPIO_END S3C64XX_GPIO_END
92.
93. /* define the number of gpios we need to the one after the GPQ() range */
94. #define ARCH_NR_GPIOS (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
95.
96. #include <asm-generic/gpio.h>
上面的头文件包含了<asm-generic/gpio.h>头文件,该头文件包含了GPIO的数据读写函数,如下:
[cpp] view plaincopy
1. #ifndef _ASM_GENERIC_GPIO_H
2. #define _ASM_GENERIC_GPIO_H
3.
4. #include <linux/types.h>
5. #include <linux/errno.h>
6.
7. #ifdef CONFIG_GPIOLIB
8.
9. #include <linux/compiler.h>
10.
11. /* Platforms may implement their GPIO interface with library code,
12. * at a small performance cost for non-inlined operations and some
13. * extra memory (for code and for per-GPIO table entries).
14. *
15. * While the GPIO programming interface defines valid GPIO numbers
16. * to be in the range 0..MAX_INT, this library restricts them to the
17. * smaller range 0..ARCH_NR_GPIOS-1.
18. */
19.
20. #ifndef ARCH_NR_GPIOS
21. #define ARCH_NR_GPIOS 256
22. #endif
23.
24. static inline int gpio_is_valid(int number)
25. {
26. /* only some non-negative numbers are valid */
27. return ((unsigned)number) < ARCH_NR_GPIOS;
28. }
29.
30. struct seq_file;
31. struct module;
32.
33. /**
34. * struct gpio_chip - abstract a GPIO controller
35. * @label: for diagnostics
36. * @dev: optional device providing the GPIOs
37. * @owner: helps prevent removal of modules exporting active GPIOs
38. * @request: optional hook for chip-specific activation, such as
39. * enabling module power and clock; may sleep
40. * @free: optional hook for chip-specific deactivation, such as
41. * disabling module power and clock; may sleep
42. * @direction_input: configures signal "offset" as input, or returns error
43. * @get: returns value for signal "offset"; for output signals this
44. * returns either the value actually sensed, or zero
45. * @direction_output: configures signal "offset" as output, or returns error
46. * @set: assigns output value for signal "offset"
47. * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
48. * implementation may not sleep
49. * @dbg_show: optional routine to show contents in debugfs; default code
50. * will be used when this is omitted, but custom code can show extra
51. * state (such as pullup/pulldown configuration).
52. * @base: identifies the first GPIO number handled by this chip; or, if
53. * negative during registration, requests dynamic ID allocation.
54. * @ngpio: the number of GPIOs handled by this controller; the last GPIO
55. * handled is (base + ngpio - 1).
56. * @can_sleep: flag must be set iff get()/set() methods sleep, as they
57. * must while accessing GPIO expander chips over I2C or SPI
58. *
59. * A gpio_chip can help platforms abstract various sources of GPIOs so
60. * they can all be accessed through a common programing interface.
61. * Example sources would be SOC controllers, FPGAs, multifunction
62. * chips, dedicated GPIO expanders, and so on.
63. *
64. * Each chip controls a number of signals, identified in method calls
65. * by "offset" values in the range 0..(@ngpio - 1). When those signals
66. * are referenced through calls like gpio_get_value(gpio), the offset
67. * is calculated by subtracting @base from the gpio number.
68. */
69. struct gpio_chip {
70. const char *label;
71. struct device *dev;
72. struct module *owner;
73.
74. int (*request)(struct gpio_chip *chip,
75. unsigned offset);
76. void (*free)(struct gpio_chip *chip,
77. unsigned offset);
78.
79. int (*direction_input)(struct gpio_chip *chip,
80. unsigned offset);
81. int (*get)(struct gpio_chip *chip,
82. unsigned offset);
83. int (*direction_output)(struct gpio_chip *chip,
84. unsigned offset, int value);
85. void (*set)(struct gpio_chip *chip,
86. unsigned offset, int value);
87.
88. int (*to_irq)(struct gpio_chip *chip,
89. unsigned offset);
90.
91. void (*dbg_show)(struct seq_file *s,
92. struct gpio_chip *chip);
93. int base;
94. u16 ngpio;
95. unsigned can_sleep:1;
96. unsigned exported:1;
97. };
98.
99. extern const char *gpiochip_is_requested(struct gpio_chip *chip,
100. unsigned offset);
101. extern int __must_check gpiochip_reserve(int start, int ngpio);
102.
103. /* add/remove chips */
104. extern int gpiochip_add(struct gpio_chip *chip);
105. extern int __must_check gpiochip_remove(struct gpio_chip *chip);
106.
107.
108. /* Always use the library code for GPIO management calls,
109. * or when sleeping may be involved.
110. */
111. extern int gpio_request(unsigned gpio, const char *label);
112. extern void gpio_free(unsigned gpio);
113.
114. extern int gpio_direction_input(unsigned gpio);
115. extern int gpio_direction_output(unsigned gpio, int value);
116.
117. extern int gpio_get_value_cansleep(unsigned gpio);
118. extern void gpio_set_value_cansleep(unsigned gpio, int value);
119.
120.
121. /* A platform's <asm/gpio.h> code may want to inline the I/O calls when
122. * the GPIO is constant and refers to some always-present controller,
123. * giving direct access to chip registers and tight bitbanging loops.
124. */
125. extern int __gpio_get_value(unsigned gpio);
126. extern void __gpio_set_value(unsigned gpio, int value);
127.
128. extern int __gpio_cansleep(unsigned gpio);
129.
130. extern int __gpio_to_irq(unsigned gpio);
131.
132. #ifdef CONFIG_GPIO_SYSFS
133.
134. /*
135. * A sysfs interface can be exported by individual drivers if they want,
136. * but more typically is configured entirely from userspace.
137. */
138. extern int gpio_export(unsigned gpio, bool direction_may_change);
139. extern void gpio_unexport(unsigned gpio);
140.
141. #endif /* CONFIG_GPIO_SYSFS */
142.
143. #else /* !CONFIG_HAVE_GPIO_LIB */
144.
145. static inline int gpio_is_valid(int number)
146. {
147. /* only non-negative numbers are valid */
148. return number >= 0;
149. }
150.
151. /* platforms that don't directly support access to GPIOs through I2C, SPI,
152. * or other blocking infrastructure can use these wrappers.
153. */
154.
155. static inline int gpio_cansleep(unsigned gpio)
156. {
157. return 0;
158. }
159.
160. static inline int gpio_get_value_cansleep(unsigned gpio)
161. {
162. might_sleep();
163. return gpio_get_value(gpio);
164. }
165.
166. static inline void gpio_set_value_cansleep(unsigned gpio, int value)
167. {
168. might_sleep();
169. gpio_set_value(gpio, value);
170. }
171.
172. #endif /* !CONFIG_HAVE_GPIO_LIB */
173.
174. #ifndef CONFIG_GPIO_SYSFS
175.
176. /* sysfs support is only available with gpiolib, where it's optional */
177.
178. static inline int gpio_export(unsigned gpio, bool direction_may_change)
179. {
180. return -ENOSYS;
181. }
182.
183. static inline void gpio_unexport(unsigned gpio)
184. {
185. }
186. #endif /* CONFIG_GPIO_SYSFS */
187.
188. #endif /* _ASM_GENERIC_GPIO_H */
2、#include <plat/regs-gpio.h>:定义了GPIO相关的数据宏:
[cpp] view plaincopy
1. /* linux/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
2. *
3. * Copyright 2008 Openmoko, Inc.
4. * Copyright 2008 Simtec Electronics
5. * Ben Dooks <ben@simtec.co.uk>
6. * http://armlinux.simtec.co.uk/
7. *
8. * S3C64XX - GPIO register definitions
9. */
10.
11. #ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H
12. #define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__
13.
14. #include <plat/gpio-bank-a.h>
15. #include <plat/gpio-bank-b.h>
16. #include <plat/gpio-bank-c.h>
17. #include <plat/gpio-bank-d.h>
18. #include <plat/gpio-bank-e.h>
19. #include <plat/gpio-bank-f.h>
20. #include <plat/gpio-bank-g.h>
21. #include <plat/gpio-bank-h.h>
22. #include <plat/gpio-bank-i.h>
23. #include <plat/gpio-bank-j.h>
24. #include <plat/gpio-bank-k.h>
25. #include <plat/gpio-bank-l.h>
26. #include <plat/gpio-bank-n.h>
27. #include #include <plat/gpio-bank-q.h>
28. #include <plat/gpio-bank-o.h>
29. #include <plat/gpio-bank-p.h>
30. #include <plat/gpio-bank-q.h>
31. #include <mach/map.h>
32.
33. /* Base addresses for each of the banks */
34.
35. #define S3C64XX_GPA_BASE (S3C64XX_VA_GPIO + 0x0000)
36. #define S3C64XX_GPB_BASE (S3C64XX_VA_GPIO + 0x0020)
37. #define S3C64XX_GPC_BASE (S3C64XX_VA_GPIO + 0x0040)
38. #define S3C64XX_GPD_BASE (S3C64XX_VA_GPIO + 0x0060)
39. #define S3C64XX_GPE_BASE (S3C64XX_VA_GPIO + 0x0080)
40. #define S3C64XX_GPF_BASE (S3C64XX_VA_GPIO + 0x00A0)
41. #define S3C64XX_GPG_BASE (S3C64XX_VA_GPIO + 0x00C0)
42. #define S3C64XX_GPH_BASE (S3C64XX_VA_GPIO + 0x00E0)
43. #define S3C64XX_GPI_BASE (S3C64XX_VA_GPIO + 0x0100)
44. #define S3C64XX_GPJ_BASE (S3C64XX_VA_GPIO + 0x0120)
45. #define S3C64XX_GPK_BASE (S3C64XX_VA_GPIO + 0x0800)
46. #define S3C64XX_GPL_BASE (S3C64XX_VA_GPIO + 0x0810)
47. #define S3C64XX_GPM_BASE (S3C64XX_VA_GPIO + 0x0820)
48. #define S3C64XX_GPN_BASE (S3C64XX_VA_GPIO + 0x0830)
49. #define S3C64XX_GPO_BASE (S3C64XX_VA_GPIO + 0x0140)
50. #define S3C64XX_GPP_BASE (S3C64XX_VA_GPIO + 0x0160)
51. #define S3C64XX_GPQ_BASE (S3C64XX_VA_GPIO + 0x0180)
52. #define S3C64XX_SPC_BASE (S3C64XX_VA_GPIO + 0x01A0)
53. #define S3C64XX_MEM0CONSTOP (S3C64XX_VA_GPIO + 0x01B0)
54. #define S3C64XX_MEM1CONSTOP (S3C64XX_VA_GPIO + 0x01B4)
55. #define S3C64XX_MEM0CONSLP0 (S3C64XX_VA_GPIO + 0x01C0)
56. #define S3C64XX_MEM0CONSLP1 (S3C64XX_VA_GPIO + 0x01C4)
57. #define S3C64XX_MEM1CONSLP (S3C64XX_VA_GPIO + 0x01C8)
58. #define S3C64XX_MEM0DRVCON (S3C64XX_VA_GPIO + 0x01D0)
59. #define S3C64XX_MEM1DRVCON (S3C64XX_VA_GPIO + 0x01D4)
60. #define S3C64XX_EINT0CON0 (S3C64XX_VA_GPIO + 0x0900)
61. #define S3C64XX_EINT0CON1 (S3C64XX_VA_GPIO + 0x0904)
62. #define S3C64XX_EINT0FLTCON0 (S3C64XX_VA_GPIO + 0x0910)
63. #define S3C64XX_EINT0FLTCON1 (S3C64XX_VA_GPIO + 0x0914)
64. #define S3C64XX_EINT0FLTCON2 (S3C64XX_VA_GPIO + 0x0918)
65. #define S3C64XX_EINT0FLTCON3 (S3C64XX_VA_GPIO + 0x091C)
66. #define S3C64XX_EINT0MASK (S3C64XX_VA_GPIO + 0x0920)
67. #define S3C64XX_EINT0PEND (S3C64XX_VA_GPIO + 0x0924)
68. #define S3C64XX_SPCONSLP (S3C64XX_VA_GPIO + 0x0880)
69. #define S3C64XX_SLPEN (S3C64XX_VA_GPIO + 0x0930)
70. #define S3C64XX_EINT12CON (S3C64XX_VA_GPIO + 0x0200)
71. #define S3C64XX_EINT34CON (S3C64XX_VA_GPIO + 0x0204)
72. #define S3C64XX_EINT56CON (S3C64XX_VA_GPIO + 0x0208)
73. #define S3C64XX_EINT78CON (S3C64XX_VA_GPIO + 0x020C)
74. #define S3C64XX_EINT9CON (S3C64XX_VA_GPIO + 0x0210)
75. #define S3C64XX_EINT12FLTCON (S3C64XX_VA_GPIO + 0x0220)
76. #define S3C64XX_EINT34FLTCON (S3C64XX_VA_GPIO + 0x0224)
77. #define S3C64XX_EINT56FLTCON (S3C64XX_VA_GPIO + 0x0228)
78. #define S3C64XX_EINT78FLTCON (S3C64XX_VA_GPIO + 0x022C)
79. #define S3C64XX_EINT9FLTCON (S3C64XX_VA_GPIO + 0x0230)
80. #define S3C64XX_EINT12MASK (S3C64XX_VA_GPIO + 0x0240)
81. #define S3C64XX_EINT34MASK (S3C64XX_VA_GPIO + 0x0244)
82. #define S3C64XX_EINT56MASK (S3C64XX_VA_GPIO + 0x0248)
83. #define S3C64XX_EINT78MASK (S3C64XX_VA_GPIO + 0x024C)
84. #define S3C64XX_EINT9MASK (S3C64XX_VA_GPIO + 0x0250)
85. #define S3C64XX_EINT12PEND (S3C64XX_VA_GPIO + 0x0260)
86. #define S3C64XX_EINT34PEND (S3C64XX_VA_GPIO + 0x0264)
87. #define S3C64XX_EINT56PEND (S3C64XX_VA_GPIO + 0x0268)
88. #define S3C64XX_EINT78PEND (S3C64XX_VA_GPIO + 0x026C)
89. #define S3C64XX_EINT9PEND (S3C64XX_VA_GPIO + 0x0270)
90. #define S3C64XX_PRIORITY (S3C64XX_VA_GPIO + 0x0280)
91. #define S3C64XX_SERVICE (S3C64XX_VA_GPIO + 0x0284)
92. #define S3C64XX_SERVICEPEND (S3C64XX_VA_GPIO + 0x0288)
93.
94. /* values for S3C_EXTINT0 */
95. #define S3C64XX_EXTINT_LOWLEV (0x00)
96. #define S3C64XX_EXTINT_HILEV (0x01)
97. #define S3C64XX_EXTINT_FALLEDGE (0x02)
98. #define S3C64XX_EXTINT_RISEEDGE (0x04)
99. #define S3C64XX_EXTINT_BOTHEDGE (0x06)
100.
101. #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端口相关的数据宏,如下:
[cpp] view plaincopy
1. /* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-m.h
2. *
3. * Copyright 2008 Openmoko, Inc.
4. * Copyright 2008 Simtec Electronics
5. * Ben Dooks <ben@simtec.co.uk>
6. * http://armlinux.simtec.co.uk/
7. *
8. * GPIO Bank M register and configuration definitions
9. *
10. * This program is free software; you can redistribute it and/or modify
11. * it under the terms of the GNU General Public License version 2 as
12. * published by the Free Software Foundation.
13. */
14.
15. #define S3C64XX_GPMCON (S3C64XX_GPM_BASE + 0x00)
16. #define S3C64XX_GPMDAT (S3C64XX_GPM_BASE + 0x04)
17. #define S3C64XX_GPMPUD (S3C64XX_GPM_BASE + 0x08)
18.
19. #define S3C64XX_GPM_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
20. #define S3C64XX_GPM_INPUT(__gpio) (0x0 << ((__gpio) * 2))
21. #define S3C64XX_GPM_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
22.
23. #define S3C64XX_GPM0_HOSTIF_CS (0x02 << 0)
24. #define S3C64XX_GPM0_EINT23 (0x03 << 0)
25. #define S3C64XX_GPM0_RESERVED1 (0x04 << 0)
26. #define S3C64XX_GPM0_DATA_CF10 (0x05 << 0)
27. #define S3C64XX_GPM0_CE_CF0 (0x06 << 0)
28. #define S3C64XX_GPM0_RESERVED2 (0x07 << 0)
29.
30. #define S3C64XX_GPM1_HOSTIF_CS_M (0x02 << 0)
31. #define S3C64XX_GPM1_EINT24 (0x03 << 0)
32. #define S3C64XX_GPM1_RESERVED1 (0x04 << 0)
33. #define S3C64XX_GPM1_DATA_CF11 (0x05 << 0)
34. #define S3C64XX_GPM1_CE_CF1 (0x06 << 0)
35. #define S3C64XX_GPM1_RESERVED2 (0x07 << 0)
36.
37. #define S3C64XX_GPM2_HOSTIF_IF_CS_S (0x02 << 0)
38. #define S3C64XX_GPM2_EINT25 (0x03 << 0)
39. #define S3C64XX_GPM2_HOSTIF_MDP_VSYNC (0x04 << 0)
40. #define S3C64XX_GPM2_DATA_CF12 (0x05 << 0)
41. #define S3C64XX_GPM2_IORD_CF (0x06 << 0)
42. #define S3C64XX_GPM2_RESERVED2 (0x07 << 0)
43.
44. #define S3C64XX_GPM3_HOSTIF_WE (0x02 << 0)
45. #define S3C64XX_GPM3_EINT26 (0x03 << 0)
46. #define S3C64XX_GPM3_RESERVED1 (0x04 << 0)
47. #define S3C64XX_GPM3_DATA_CF13 (0x05 << 0)
48. #define S3C64XX_GPM3_IOWR_CF (0x06 << 0)
49. #define S3C64XX_GPM3_RESERVED2 (0x07 << 0)
50.
51. #define S3C64XX_GPM4_HOSTIF_OE (0x02 << 0)
52. #define S3C64XX_GPM4_EINT27 (0x03 << 0)
53. #define S3C64XX_GPM4_RESERVED1 (0x04 << 0)
54. #define S3C64XX_GPM4_DATA_CF14 (0x05 << 0)
55. #define S3C64XX_GPM4_IORDY_CF (0x06 << 0)
56. #define S3C64XX_GPM4_RESERVED2 (0x07 << 0)
57.
58. #define S3C64XX_GPM5_HOSTIF_INTR (0x02 << 0)
59. #define S3C64XX_GPM5_CF_DATA_DIR (0x03 << 0)
60. #define S3C64XX_GPM5_RESERVED1 (0x04 << 0)
61. #define S3C64XX_GPM5_DATA_CF15 (0x05 << 0)
62. #define S3C64XX_GPM5_RESERVED2 (0x06 << 0)
63. #define S3C64XX_GPM5_RESERVED3 (0x07 << 0)
3、#include <plat/gpio-cfg.h>:此头文件包含了GPIO的各种配置函数,例如设置输入输出方式,上拉电阻使能等等:
[cpp] view plaincopy
1. /* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h
2. *
3. * Copyright 2008 Openmoko, Inc.
4. * Copyright 2008 Simtec Electronics
5. * http://armlinux.simtec.co.uk/
6. * Ben Dooks <ben@simtec.co.uk>
7. *
8. * S3C Platform - GPIO pin configuration
9. *
10. * This program is free software; you can redistribute it and/or modify
11. * it under the terms of the GNU General Public License version 2 as
12. * published by the Free Software Foundation.
13. */
14.
15. /* This file contains the necessary definitions to get the basic gpio
16. * pin configuration done such as setting a pin to input or output or
17. * changing the pull-{up,down} configurations.
18. */
19.
20. /* Note, this interface is being added to the s3c64xx arch first and will
21. * be added to the s3c24xx systems later.
22. */
23.
24. #ifndef __PLAT_GPIO_CFG_H
25. #define __PLAT_GPIO_CFG_H __FILE__
26.
27. typedef unsigned int __bitwise__ s3c_gpio_pull_t;
28.
29. /* forward declaration if gpio-core.h hasn't been included */
30. struct s3c_gpio_chip;
31.
32. /**
33. * struct s3c_gpio_cfg GPIO configuration
34. * @cfg_eint: Configuration setting when used for external interrupt source
35. * @get_pull: Read the current pull configuration for the GPIO
36. * @set_pull: Set the current pull configuraiton for the GPIO
37. * @set_config: Set the current configuration for the GPIO
38. * @get_config: Read the current configuration for the GPIO
39. *
40. * Each chip can have more than one type of GPIO bank available and some
41. * have different capabilites even when they have the same control register
42. * layouts. Provide an point to vector control routine and provide any
43. * per-bank configuration information that other systems such as the
44. * external interrupt code will need.
45. */
46. struct s3c_gpio_cfg {
47. unsigned int cfg_eint;
48.
49. s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);
50. int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
51. s3c_gpio_pull_t pull);
52.
53. unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
54. int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
55. unsigned config);
56. };
57.
58. #define S3C_GPIO_SPECIAL_MARK (0xfffffff0)
59. #define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x))
60.
61. /* Defines for generic pin configurations */
62. #define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0))
63. #define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))
64. #define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))
65.
66. #define s3c_gpio_is_cfg_special(_cfg) \
67. (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
68.
69. /**
70. * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
71. * @pin pin The pin number to configure.
72. * @pin to The configuration for the pin's function.
73. *
74. * Configure which function is actually connected to the external
75. * pin, such as an gpio input, output or some form of special function
76. * connected to an internal peripheral block.
77. */
78. extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
79.
80. /* Define values for the pull-{up,down} available for each gpio pin.
81. *
82. * These values control the state of the weak pull-{up,down} resistors
83. * available on most pins on the S3C series. Not all chips support both
84. * up or down settings, and it may be dependant on the chip that is being
85. * used to whether the particular mode is available.
86. */
87. #define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
88. #define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
89. #define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02)
90.
91. /**
92. * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
93. * @pin: The pin number to configure the pull resistor.
94. * @pull: The configuration for the pull resistor.
95. *
96. * This function sets the state of the pull-{up,down} resistor for the
97. * specified pin. It will return 0 if successfull, or a negative error
98. * code if the pin cannot support the requested pull setting.
99. */
100. extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
101.
102. /**
103. * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
104. * @pin: The pin number to get the settings for
105. *
106. * Read the pull resistor value for the specified pin.
107. */
108. extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
109.
110. #endif /* __PLAT_GPIO_CFG_H */