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 adapter->adapter.id = I2C_HW_B_LP;
>> 168 strlcpy(adapter->adapter.name, "Parallel port adapter",
>> 169 sizeof(adapter->adapter.name));
176 adapter->algo_data = parport_algo_data 170 adapter->algo_data = parport_algo_data;
177 if (!adapter_parm[type].getscl.val) !! 171 /* Slow down if we can't sense SCL */
>> 172 if (!adapter_parm[type].getscl.val) {
178 adapter->algo_data.getscl = NU 173 adapter->algo_data.getscl = NULL;
>> 174 adapter->algo_data.udelay = 50; /* ~10 kbps */
>> 175 }
179 adapter->algo_data.data = port; 176 adapter->algo_data.data = port;
180 adapter->adapter.algo_data = &adapter- 177 adapter->adapter.algo_data = &adapter->algo_data;
>> 178 adapter->adapter.dev.parent = port->physport->dev;
181 179
182 if (parport_claim_or_block(adapter->pd 180 if (parport_claim_or_block(adapter->pdev) < 0) {
183 printk(KERN_ERR "i2c-parport: 181 printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
184 goto ERROR1; 182 goto ERROR1;
185 } 183 }
186 184
187 /* Reset hardware to a sane state (SCL 185 /* Reset hardware to a sane state (SCL and SDA high) */
188 parport_setsda(port, 1); 186 parport_setsda(port, 1);
189 parport_setscl(port, 1); 187 parport_setscl(port, 1);
190 /* Other init if needed (power on...) 188 /* Other init if needed (power on...) */
191 if (adapter_parm[type].init.val) 189 if (adapter_parm[type].init.val)
192 line_set(port, 1, &adapter_par 190 line_set(port, 1, &adapter_parm[type].init);
193 191
194 parport_release(adapter->pdev); 192 parport_release(adapter->pdev);
195 193
196 if (i2c_bit_add_bus(&adapter->adapter) 194 if (i2c_bit_add_bus(&adapter->adapter) < 0) {
197 printk(KERN_ERR "i2c-parport: 195 printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
198 goto ERROR1; 196 goto ERROR1;
199 } 197 }
200 198
201 /* Add the new adapter to the list */ 199 /* Add the new adapter to the list */
202 adapter->next = adapter_list; 200 adapter->next = adapter_list;
203 adapter_list = adapter; 201 adapter_list = adapter;
204 return; 202 return;
205 203
206 ERROR1: 204 ERROR1:
207 parport_unregister_device(adapter->pde 205 parport_unregister_device(adapter->pdev);
208 ERROR0: 206 ERROR0:
209 kfree(adapter); 207 kfree(adapter);
210 } 208 }
211 209
212 static void i2c_parport_detach (struct parport 210 static void i2c_parport_detach (struct parport *port)
213 { 211 {
214 struct i2c_par *adapter, *prev; 212 struct i2c_par *adapter, *prev;
215 213
216 /* Walk the list */ 214 /* Walk the list */
217 for (prev = NULL, adapter = adapter_li 215 for (prev = NULL, adapter = adapter_list; adapter;
218 prev = adapter, adapter = adapter 216 prev = adapter, adapter = adapter->next) {
219 if (adapter->pdev->port == por 217 if (adapter->pdev->port == port) {
>> 218 i2c_del_adapter(&adapter->adapter);
>> 219
220 /* Un-init if needed ( 220 /* Un-init if needed (power off...) */
221 if (adapter_parm[type] 221 if (adapter_parm[type].init.val)
222 line_set(port, 222 line_set(port, 0, &adapter_parm[type].init);
223 223
224 i2c_bit_del_bus(&adapt <<
225 parport_unregister_dev 224 parport_unregister_device(adapter->pdev);
226 if (prev) 225 if (prev)
227 prev->next = a 226 prev->next = adapter->next;
228 else 227 else
229 adapter_list = 228 adapter_list = adapter->next;
230 kfree(adapter); 229 kfree(adapter);
231 return; 230 return;
232 } 231 }
233 } 232 }
234 } 233 }
235 234
236 static struct parport_driver i2c_driver = { !! 235 static struct parport_driver i2c_parport_driver = {
237 .name = "i2c-parport", 236 .name = "i2c-parport",
238 .attach = i2c_parport_attach, 237 .attach = i2c_parport_attach,
239 .detach = i2c_parport_detach, 238 .detach = i2c_parport_detach,
240 }; 239 };
241 240
242 /* ----- Module loading, unloading and informa 241 /* ----- Module loading, unloading and information ------------------------ */
243 242
244 static int __init i2c_parport_init(void) 243 static int __init i2c_parport_init(void)
245 { 244 {
246 int type_count; !! 245 if (type < 0) {
>> 246 printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
>> 247 return -ENODEV;
>> 248 }
247 249
248 type_count = sizeof(adapter_parm)/size !! 250 if (type >= ARRAY_SIZE(adapter_parm)) {
249 if (type < 0 || type >= type_count) { <<
250 printk(KERN_WARNING "i2c-parpo 251 printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
251 type = 0; !! 252 return -ENODEV;
252 } 253 }
253 !! 254
254 return parport_register_driver(&i2c_dr !! 255 return parport_register_driver(&i2c_parport_driver);
255 } 256 }
256 257
257 static void __exit i2c_parport_exit(void) 258 static void __exit i2c_parport_exit(void)
258 { 259 {
259 parport_unregister_driver(&i2c_driver) !! 260 parport_unregister_driver(&i2c_parport_driver);
260 } 261 }
261 262
262 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.or 263 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
263 MODULE_DESCRIPTION("I2C bus over parallel port 264 MODULE_DESCRIPTION("I2C bus over parallel port");
264 MODULE_LICENSE("GPL"); 265 MODULE_LICENSE("GPL");
265 266
266 module_init(i2c_parport_init); 267 module_init(i2c_parport_init);
267 module_exit(i2c_parport_exit); 268 module_exit(i2c_parport_exit);
268 269
|
This page was automatically generated by the
LXR engine.
|