Root/
1 | /* linux/drivers/char/scx200_gpio.c |
2 | |
3 | National Semiconductor SCx200 GPIO driver. Allows a user space |
4 | process to play with the GPIO pins. |
5 | |
6 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */ |
7 | |
8 | #include <linux/device.h> |
9 | #include <linux/fs.h> |
10 | #include <linux/module.h> |
11 | #include <linux/errno.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/init.h> |
14 | #include <linux/platform_device.h> |
15 | #include <asm/uaccess.h> |
16 | #include <asm/io.h> |
17 | |
18 | #include <linux/types.h> |
19 | #include <linux/cdev.h> |
20 | |
21 | #include <linux/scx200_gpio.h> |
22 | #include <linux/nsc_gpio.h> |
23 | |
24 | #define DRVNAME "scx200_gpio" |
25 | |
26 | static struct platform_device *pdev; |
27 | |
28 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); |
29 | MODULE_DESCRIPTION("NatSemi/AMD SCx200 GPIO Pin Driver"); |
30 | MODULE_LICENSE("GPL"); |
31 | |
32 | static int major = 0; /* default to dynamic major */ |
33 | module_param(major, int, 0); |
34 | MODULE_PARM_DESC(major, "Major device number"); |
35 | |
36 | #define MAX_PINS 32 /* 64 later, when known ok */ |
37 | |
38 | struct nsc_gpio_ops scx200_gpio_ops = { |
39 | .owner = THIS_MODULE, |
40 | .gpio_config = scx200_gpio_configure, |
41 | .gpio_dump = nsc_gpio_dump, |
42 | .gpio_get = scx200_gpio_get, |
43 | .gpio_set = scx200_gpio_set, |
44 | .gpio_change = scx200_gpio_change, |
45 | .gpio_current = scx200_gpio_current |
46 | }; |
47 | EXPORT_SYMBOL_GPL(scx200_gpio_ops); |
48 | |
49 | static int scx200_gpio_open(struct inode *inode, struct file *file) |
50 | { |
51 | unsigned m = iminor(inode); |
52 | file->private_data = &scx200_gpio_ops; |
53 | |
54 | if (m >= MAX_PINS) |
55 | return -EINVAL; |
56 | return nonseekable_open(inode, file); |
57 | } |
58 | |
59 | static int scx200_gpio_release(struct inode *inode, struct file *file) |
60 | { |
61 | return 0; |
62 | } |
63 | |
64 | static const struct file_operations scx200_gpio_fileops = { |
65 | .owner = THIS_MODULE, |
66 | .write = nsc_gpio_write, |
67 | .read = nsc_gpio_read, |
68 | .open = scx200_gpio_open, |
69 | .release = scx200_gpio_release, |
70 | .llseek = no_llseek, |
71 | }; |
72 | |
73 | static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */ |
74 | |
75 | static int __init scx200_gpio_init(void) |
76 | { |
77 | int rc; |
78 | dev_t devid; |
79 | |
80 | if (!scx200_gpio_present()) { |
81 | printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n"); |
82 | return -ENODEV; |
83 | } |
84 | |
85 | /* support dev_dbg() with pdev->dev */ |
86 | pdev = platform_device_alloc(DRVNAME, 0); |
87 | if (!pdev) |
88 | return -ENOMEM; |
89 | |
90 | rc = platform_device_add(pdev); |
91 | if (rc) |
92 | goto undo_malloc; |
93 | |
94 | /* nsc_gpio uses dev_dbg(), so needs this */ |
95 | scx200_gpio_ops.dev = &pdev->dev; |
96 | |
97 | if (major) { |
98 | devid = MKDEV(major, 0); |
99 | rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio"); |
100 | } else { |
101 | rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio"); |
102 | major = MAJOR(devid); |
103 | } |
104 | if (rc < 0) { |
105 | dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); |
106 | goto undo_platform_device_add; |
107 | } |
108 | |
109 | cdev_init(&scx200_gpio_cdev, &scx200_gpio_fileops); |
110 | cdev_add(&scx200_gpio_cdev, devid, MAX_PINS); |
111 | |
112 | return 0; /* succeed */ |
113 | |
114 | undo_platform_device_add: |
115 | platform_device_del(pdev); |
116 | undo_malloc: |
117 | platform_device_put(pdev); |
118 | |
119 | return rc; |
120 | } |
121 | |
122 | static void __exit scx200_gpio_cleanup(void) |
123 | { |
124 | cdev_del(&scx200_gpio_cdev); |
125 | /* cdev_put(&scx200_gpio_cdev); */ |
126 | |
127 | unregister_chrdev_region(MKDEV(major, 0), MAX_PINS); |
128 | platform_device_unregister(pdev); |
129 | } |
130 | |
131 | module_init(scx200_gpio_init); |
132 | module_exit(scx200_gpio_cleanup); |
133 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9