Diff markup
1 /* ------------------------------------------- 1 /* ------------------------------------------------------------------------ *
2 * i2c-parport.c I2C bus over parallel port 2 * i2c-parport.c I2C bus over parallel port *
3 * ------------------------------------------- 3 * ------------------------------------------------------------------------ *
4 Copyright (C) 2003-2004 Jean Delvare <khali !! 4 Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
5 5
6 Based on older i2c-philips-par.c driver 6 Based on older i2c-philips-par.c driver
7 Copyright (C) 1995-2000 Simon G. Vogl 7 Copyright (C) 1995-2000 Simon G. Vogl
8 With some changes from: 8 With some changes from:
9 Frodo Looijaard <frodol@dds.nl> 9 Frodo Looijaard <frodol@dds.nl>
10 Kyösti Mälkki <kmalkki@cc.hut.fi> !! 10 Kyösti Mälkki <kmalkki@cc.hut.fi>
11 11
12 This program is free software; you can redi 12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Publi 13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either versio 14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version. 15 (at your option) any later version.
16 16
17 This program is distributed in the hope tha 17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the 18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details 20 GNU General Public License for more details.
21 21
22 You should have received a copy of the GNU 22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to t 23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, 24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * ------------------------------------------- 25 * ------------------------------------------------------------------------ */
26 26
27 #include <linux/config.h> <<
28 #include <linux/kernel.h> 27 #include <linux/kernel.h>
29 #include <linux/module.h> 28 #include <linux/module.h>
30 #include <linux/init.h> 29 #include <linux/init.h>
31 #include <linux/parport.h> 30 #include <linux/parport.h>
32 #include <linux/i2c.h> 31 #include <linux/i2c.h>
33 #include <linux/i2c-algo-bit.h> 32 #include <linux/i2c-algo-bit.h>
34 #include "i2c-parport.h" 33 #include "i2c-parport.h"
35 34
36 /* ----- Device list ------------------------- 35 /* ----- Device list ------------------------------------------------------ */
37 36
38 struct i2c_par { 37 struct i2c_par {
39 struct pardevice *pdev; 38 struct pardevice *pdev;
40 struct i2c_adapter adapter; 39 struct i2c_adapter adapter;
41 struct i2c_algo_bit_data algo_data; 40 struct i2c_algo_bit_data algo_data;
42 struct i2c_par *next; 41 struct i2c_par *next;
43 }; 42 };
44 43
45 static struct i2c_par *adapter_list; 44 static struct i2c_par *adapter_list;
46 45
47 /* ----- Low-level parallel port access ------ 46 /* ----- Low-level parallel port access ----------------------------------- */
48 47
49 static void port_write_data(struct parport *p, 48 static void port_write_data(struct parport *p, unsigned char d)
50 { 49 {
51 parport_write_data(p, d); 50 parport_write_data(p, d);
52 } 51 }
53 52
54 static void port_write_control(struct parport 53 static void port_write_control(struct parport *p, unsigned char d)
55 { 54 {
56 parport_write_control(p, d); 55 parport_write_control(p, d);
57 } 56 }
58 57
59 static unsigned char port_read_data(struct par 58 static unsigned char port_read_data(struct parport *p)
60 { 59 {
61 return parport_read_data(p); 60 return parport_read_data(p);
62 } 61 }
63 62
64 static unsigned char port_read_status(struct p 63 static unsigned char port_read_status(struct parport *p)
65 { 64 {
66 return parport_read_status(p); 65 return parport_read_status(p);
67 } 66 }
68 67
69 static unsigned char port_read_control(struct 68 static unsigned char port_read_control(struct parport *p)
70 { 69 {
71 return parport_read_control(p); 70 return parport_read_control(p);
72 } 71 }
73 72
74 static void (*port_write[])(struct parport *, 73 static void (*port_write[])(struct parport *, unsigned char) = {
75 port_write_data, 74 port_write_data,
76 NULL, 75 NULL,
77 port_write_control, 76 port_write_control,
78 }; 77 };
79 78
80 static unsigned char (*port_read[])(struct par 79 static unsigned char (*port_read[])(struct parport *) = {
81 port_read_data, 80 port_read_data,
82 port_read_status, 81 port_read_status,
83 port_read_control, 82 port_read_control,
84 }; 83 };
85 84
86 /* ----- Unified line operation functions ---- 85 /* ----- Unified line operation functions --------------------------------- */
87 86
88 static inline void line_set(struct parport *da 87 static inline void line_set(struct parport *data, int state,
89 const struct lineop *op) 88 const struct lineop *op)
90 { 89 {
91 u8 oldval = port_read[op->port](data); 90 u8 oldval = port_read[op->port](data);
92 91
93 /* Touch only the bit(s) needed */ 92 /* Touch only the bit(s) needed */
94 if ((op->inverted && !state) || (!op-> 93 if ((op->inverted && !state) || (!op->inverted && state))
95 port_write[op->port](data, old 94 port_write[op->port](data, oldval | op->val);
96 else 95 else
97 port_write[op->port](data, old 96 port_write[op->port](data, oldval & ~op->val);
98 } 97 }
99 98
100 static inline int line_get(struct parport *dat 99 static inline int line_get(struct parport *data,
101 const struct lineop *op) 100 const struct lineop *op)
102 { 101 {
103 u8 oldval = port_read[op->port](data); 102 u8 oldval = port_read[op->port](data);
104 103
105 return ((op->inverted && (oldval & op- 104 return ((op->inverted && (oldval & op->val) != op->val)
106 || (!op->inverted && (oldval & op- 105 || (!op->inverted && (oldval & op->val) == op->val));
107 } 106 }
108 107
109 /* ----- I2C algorithm call-back functions and 108 /* ----- I2C algorithm call-back functions and structures ----------------- */
110 109
111 static void parport_setscl(void *data, int sta 110 static void parport_setscl(void *data, int state)
112 { 111 {
113 line_set((struct parport *) data, stat 112 line_set((struct parport *) data, state, &adapter_parm[type].setscl);
114 } 113 }
115 114
116 static void parport_setsda(void *data, int sta 115 static void parport_setsda(void *data, int state)
117 { 116 {
118 line_set((struct parport *) data, stat 117 line_set((struct parport *) data, state, &adapter_parm[type].setsda);
119 } 118 }
120 119
121 static int parport_getscl(void *data) 120 static int parport_getscl(void *data)
122 { 121 {
123 return line_get((struct parport *) dat 122 return line_get((struct parport *) data, &adapter_parm[type].getscl);
124 } 123 }
125 124
126 static int parport_getsda(void *data) 125 static int parport_getsda(void *data)
127 { 126 {
128 return line_get((struct parport *) dat 127 return line_get((struct parport *) data, &adapter_parm[type].getsda);
129 } 128 }
130 129
131 /* Encapsulate the functions above in the corr 130 /* Encapsulate the functions above in the correct structure.
132 Note that this is only a template, from whi 131 Note that this is only a template, from which the real structures are
133 copied. The attaching code will set getscl 132 copied. The attaching code will set getscl to NULL for adapters that
134 cannot read SCL back, and will also make th !! 133 cannot read SCL back, and will also make the data field point to
135 the parallel port structure. */ 134 the parallel port structure. */
136 static struct i2c_algo_bit_data parport_algo_d 135 static struct i2c_algo_bit_data parport_algo_data = {
137 .setsda = parport_setsda, 136 .setsda = parport_setsda,
138 .setscl = parport_setscl, 137 .setscl = parport_setscl,
139 .getsda = parport_getsda, 138 .getsda = parport_getsda,
140 .getscl = parport_getscl, 139 .getscl = parport_getscl,
141 .udelay = 60, !! 140 .udelay = 10, /* ~50 kbps */
142 .mdelay = 60, <<
143 .timeout = HZ, 141 .timeout = HZ,
144 }; 142 };
145 143
146 /* ----- I2c and parallel port call-back funct 144 /* ----- I2c and parallel port call-back functions and structures --------- */
147 145
148 static struct i2c_adapter parport_adapter = { <<
149 .owner = THIS_MODULE, <<
150 .class = I2C_CLASS_HWMON, <<
151 .id = I2C_HW_B_LP, <<
152 .name = "Parallel port adapt <<
153 }; <<
154 <<
155 static void i2c_parport_attach (struct parport 146 static void i2c_parport_attach (struct parport *port)
156 { 147 {
157 struct i2c_par *adapter; 148 struct i2c_par *adapter;
158 149
159 adapter = kmalloc(sizeof(struct i2c_pa !! 150 adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL);
160 if (adapter == NULL) { 151 if (adapter == NULL) {
161 printk(KERN_ERR "i2c-parport: !! 152 printk(KERN_ERR "i2c-parport: Failed to kzalloc\n");
162 return; 153 return;
163 } 154 }
164 memset(adapter, 0x00, sizeof(struct i2 <<
165 155
166 pr_debug("i2c-parport: attaching to %s 156 pr_debug("i2c-parport: attaching to %s\n", port->name);
167 adapter->pdev = parport_register_devic 157 adapter->pdev = parport_register_device(port, "i2c-parport",
168 NULL, NULL, NULL, PARPORT_FLAG 158 NULL, NULL, NULL, PARPORT_FLAG_EXCL, NULL);
169 if (!adapter->pdev) { 159 if (!adapter->pdev) {
170 printk(KERN_ERR "i2c-parport: 160 printk(KERN_ERR "i2c-parport: Unable to register with parport\n");
171 goto ERROR0; 161 goto ERROR0;
172 } 162 }
173 163
174 /* Fill the rest of the structure */ 164 /* Fill the rest of the structure */
175 adapter->adapter = parport_adapter; !! 165 adapter->adapter.owner = THIS_MODULE;
>> 166 adapter->adapter.class = I2C_CLASS_HWMON;
>> 167 strlcpy(adapter->adapter.name, "Parallel port adapter",
>> 168 sizeof(adapter->adapter.name));
176 adapter->algo_data = parport_algo_data 169 adapter->algo_data = parport_algo_data;
177 if (!adapter_parm[type].getscl.val) !! 170 /* Slow down if we can't sense SCL */
>> 171 if (!adapter_parm[type].getscl.val) {
178 adapter->algo_data.getscl = NU 172 adapter->algo_data.getscl = NULL;
>> 173 adapter->algo_data.udelay = 50; /* ~10 kbps */
>> 174 }
179 adapter->algo_data.data = port; 175 adapter->algo_data.data = port;
180 adapter->adapter.algo_data = &adapter- 176 adapter->adapter.algo_data = &adapter->algo_data;
>> 177 adapter->adapter.dev.parent = port->physport->dev;
181 178
182 if (parport_claim_or_block(adapter->pd 179 if (parport_claim_or_block(adapter->pdev) < 0) {
183 printk(KERN_ERR "i2c-parport: 180 printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
184 goto ERROR1; 181 goto ERROR1;
185 } 182 }
186 183
187 /* Reset hardware to a sane state (SCL 184 /* Reset hardware to a sane state (SCL and SDA high) */
188 parport_setsda(port, 1); 185 parport_setsda(port, 1);
189 parport_setscl(port, 1); 186 parport_setscl(port, 1);
190 /* Other init if needed (power on...) 187 /* Other init if needed (power on...) */
191 if (adapter_parm[type].init.val) 188 if (adapter_parm[type].init.val)
192 line_set(port, 1, &adapter_par 189 line_set(port, 1, &adapter_parm[type].init);
193 190
194 parport_release(adapter->pdev); <<
195 <<
196 if (i2c_bit_add_bus(&adapter->adapter) 191 if (i2c_bit_add_bus(&adapter->adapter) < 0) {
197 printk(KERN_ERR "i2c-parport: 192 printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
198 goto ERROR1; 193 goto ERROR1;
199 } 194 }
200 195
201 /* Add the new adapter to the list */ 196 /* Add the new adapter to the list */
202 adapter->next = adapter_list; 197 adapter->next = adapter_list;
203 adapter_list = adapter; 198 adapter_list = adapter;
204 return; 199 return;
205 200
206 ERROR1: 201 ERROR1:
>> 202 parport_release(adapter->pdev);
207 parport_unregister_device(adapter->pde 203 parport_unregister_device(adapter->pdev);
208 ERROR0: 204 ERROR0:
209 kfree(adapter); 205 kfree(adapter);
210 } 206 }
211 207
212 static void i2c_parport_detach (struct parport 208 static void i2c_parport_detach (struct parport *port)
213 { 209 {
214 struct i2c_par *adapter, *prev; 210 struct i2c_par *adapter, *prev;
215 211
216 /* Walk the list */ 212 /* Walk the list */
217 for (prev = NULL, adapter = adapter_li 213 for (prev = NULL, adapter = adapter_list; adapter;
218 prev = adapter, adapter = adapter 214 prev = adapter, adapter = adapter->next) {
219 if (adapter->pdev->port == por 215 if (adapter->pdev->port == port) {
>> 216 i2c_del_adapter(&adapter->adapter);
>> 217
220 /* Un-init if needed ( 218 /* Un-init if needed (power off...) */
221 if (adapter_parm[type] 219 if (adapter_parm[type].init.val)
222 line_set(port, 220 line_set(port, 0, &adapter_parm[type].init);
223 221
224 i2c_bit_del_bus(&adapt !! 222 parport_release(adapter->pdev);
225 parport_unregister_dev 223 parport_unregister_device(adapter->pdev);
226 if (prev) 224 if (prev)
227 prev->next = a 225 prev->next = adapter->next;
228 else 226 else
229 adapter_list = 227 adapter_list = adapter->next;
230 kfree(adapter); 228 kfree(adapter);
231 return; 229 return;
232 } 230 }
233 } 231 }
234 } 232 }
235 233
236 static struct parport_driver i2c_driver = { !! 234 static struct parport_driver i2c_parport_driver = {
237 .name = "i2c-parport", 235 .name = "i2c-parport",
238 .attach = i2c_parport_attach, 236 .attach = i2c_parport_attach,
239 .detach = i2c_parport_detach, 237 .detach = i2c_parport_detach,
240 }; 238 };
241 239
242 /* ----- Module loading, unloading and informa 240 /* ----- Module loading, unloading and information ------------------------ */
243 241
244 static int __init i2c_parport_init(void) 242 static int __init i2c_parport_init(void)
245 { 243 {
246 int type_count; !! 244 if (type < 0) {
>> 245 printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
>> 246 return -ENODEV;
>> 247 }
247 248
248 type_count = sizeof(adapter_parm)/size !! 249 if (type >= ARRAY_SIZE(adapter_parm)) {
249 if (type < 0 || type >= type_count) { <<
250 printk(KERN_WARNING "i2c-parpo 250 printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
251 type = 0; !! 251 return -ENODEV;
252 } 252 }
253 !! 253
254 return parport_register_driver(&i2c_dr !! 254 return parport_register_driver(&i2c_parport_driver);
255 } 255 }
256 256
257 static void __exit i2c_parport_exit(void) 257 static void __exit i2c_parport_exit(void)
258 { 258 {
259 parport_unregister_driver(&i2c_driver) !! 259 parport_unregister_driver(&i2c_parport_driver);
260 } 260 }
261 261
262 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.or 262 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
263 MODULE_DESCRIPTION("I2C bus over parallel port 263 MODULE_DESCRIPTION("I2C bus over parallel port");
264 MODULE_LICENSE("GPL"); 264 MODULE_LICENSE("GPL");
265 265
266 module_init(i2c_parport_init); 266 module_init(i2c_parport_init);
267 module_exit(i2c_parport_exit); 267 module_exit(i2c_parport_exit);
268 268
|
This page was automatically generated by the
LXR engine.
|