1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/parport.h>
32#include <linux/i2c.h>
33#include <linux/i2c-algo-bit.h>
34#include <linux/i2c-smbus.h>
35#include <linux/slab.h>
36#include <linux/list.h>
37#include <linux/mutex.h>
38#include "i2c-parport.h"
39
40
41
42struct i2c_par {
43 struct pardevice *pdev;
44 struct i2c_adapter adapter;
45 struct i2c_algo_bit_data algo_data;
46 struct i2c_smbus_alert_setup alert_data;
47 struct i2c_client *ara;
48 struct list_head node;
49};
50
51static LIST_HEAD(adapter_list);
52static DEFINE_MUTEX(adapter_list_lock);
53
54
55
56static void port_write_data(struct parport *p, unsigned char d)
57{
58 parport_write_data(p, d);
59}
60
61static void port_write_control(struct parport *p, unsigned char d)
62{
63 parport_write_control(p, d);
64}
65
66static unsigned char port_read_data(struct parport *p)
67{
68 return parport_read_data(p);
69}
70
71static unsigned char port_read_status(struct parport *p)
72{
73 return parport_read_status(p);
74}
75
76static unsigned char port_read_control(struct parport *p)
77{
78 return parport_read_control(p);
79}
80
81static void (*port_write[])(struct parport *, unsigned char) = {
82 port_write_data,
83 NULL,
84 port_write_control,
85};
86
87static unsigned char (*port_read[])(struct parport *) = {
88 port_read_data,
89 port_read_status,
90 port_read_control,
91};
92
93
94
95static inline void line_set(struct parport *data, int state,
96 const struct lineop *op)
97{
98 u8 oldval = port_read[op->port](data);
99
100
101 if ((op->inverted && !state) || (!op->inverted && state))
102 port_write[op->port](data, oldval | op->val);
103 else
104 port_write[op->port](data, oldval & ~op->val);
105}
106
107static inline int line_get(struct parport *data,
108 const struct lineop *op)
109{
110 u8 oldval = port_read[op->port](data);
111
112 return ((op->inverted && (oldval & op->val) != op->val)
113 || (!op->inverted && (oldval & op->val) == op->val));
114}
115
116
117
118static void parport_setscl(void *data, int state)
119{
120 line_set((struct parport *) data, state, &adapter_parm[type].setscl);
121}
122
123static void parport_setsda(void *data, int state)
124{
125 line_set((struct parport *) data, state, &adapter_parm[type].setsda);
126}
127
128static int parport_getscl(void *data)
129{
130 return line_get((struct parport *) data, &adapter_parm[type].getscl);
131}
132
133static int parport_getsda(void *data)
134{
135 return line_get((struct parport *) data, &adapter_parm[type].getsda);
136}
137
138
139
140
141
142
143static const struct i2c_algo_bit_data parport_algo_data = {
144 .setsda = parport_setsda,
145 .setscl = parport_setscl,
146 .getsda = parport_getsda,
147 .getscl = parport_getscl,
148 .udelay = 10,
149 .timeout = HZ,
150};
151
152
153
154void i2c_parport_irq(void *data)
155{
156 struct i2c_par *adapter = data;
157 struct i2c_client *ara = adapter->ara;
158
159 if (ara) {
160 dev_dbg(&ara->dev, "SMBus alert received\n");
161 i2c_handle_smbus_alert(ara);
162 } else
163 dev_dbg(&adapter->adapter.dev,
164 "SMBus alert received but no ARA client!\n");
165}
166
167static void i2c_parport_attach (struct parport *port)
168{
169 struct i2c_par *adapter;
170
171 adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL);
172 if (adapter == NULL) {
173 printk(KERN_ERR "i2c-parport: Failed to kzalloc\n");
174 return;
175 }
176
177 pr_debug("i2c-parport: attaching to %s\n", port->name);
178 parport_disable_irq(port);
179 adapter->pdev = parport_register_device(port, "i2c-parport",
180 NULL, NULL, i2c_parport_irq, PARPORT_FLAG_EXCL, adapter);
181 if (!adapter->pdev) {
182 printk(KERN_ERR "i2c-parport: Unable to register with parport\n");
183 goto ERROR0;
184 }
185
186
187 adapter->adapter.owner = THIS_MODULE;
188 adapter->adapter.class = I2C_CLASS_HWMON;
189 strlcpy(adapter->adapter.name, "Parallel port adapter",
190 sizeof(adapter->adapter.name));
191 adapter->algo_data = parport_algo_data;
192
193 if (!adapter_parm[type].getscl.val) {
194 adapter->algo_data.getscl = NULL;
195 adapter->algo_data.udelay = 50;
196 }
197 adapter->algo_data.data = port;
198 adapter->adapter.algo_data = &adapter->algo_data;
199 adapter->adapter.dev.parent = port->physport->dev;
200
201 if (parport_claim_or_block(adapter->pdev) < 0) {
202 printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
203 goto ERROR1;
204 }
205
206
207 parport_setsda(port, 1);
208 parport_setscl(port, 1);
209
210 if (adapter_parm[type].init.val) {
211 line_set(port, 1, &adapter_parm[type].init);
212
213 msleep(100);
214 }
215
216 if (i2c_bit_add_bus(&adapter->adapter) < 0) {
217 printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
218 goto ERROR1;
219 }
220
221
222 if (adapter_parm[type].smbus_alert) {
223 adapter->alert_data.alert_edge_triggered = 1;
224 adapter->ara = i2c_setup_smbus_alert(&adapter->adapter,
225 &adapter->alert_data);
226 if (adapter->ara)
227 parport_enable_irq(port);
228 else
229 printk(KERN_WARNING "i2c-parport: Failed to register "
230 "ARA client\n");
231 }
232
233
234 mutex_lock(&adapter_list_lock);
235 list_add_tail(&adapter->node, &adapter_list);
236 mutex_unlock(&adapter_list_lock);
237 return;
238
239ERROR1:
240 parport_release(adapter->pdev);
241 parport_unregister_device(adapter->pdev);
242ERROR0:
243 kfree(adapter);
244}
245
246static void i2c_parport_detach (struct parport *port)
247{
248 struct i2c_par *adapter, *_n;
249
250
251 mutex_lock(&adapter_list_lock);
252 list_for_each_entry_safe(adapter, _n, &adapter_list, node) {
253 if (adapter->pdev->port == port) {
254 if (adapter->ara) {
255 parport_disable_irq(port);
256 i2c_unregister_device(adapter->ara);
257 }
258 i2c_del_adapter(&adapter->adapter);
259
260
261 if (adapter_parm[type].init.val)
262 line_set(port, 0, &adapter_parm[type].init);
263
264 parport_release(adapter->pdev);
265 parport_unregister_device(adapter->pdev);
266 list_del(&adapter->node);
267 kfree(adapter);
268 }
269 }
270 mutex_unlock(&adapter_list_lock);
271}
272
273static struct parport_driver i2c_parport_driver = {
274 .name = "i2c-parport",
275 .attach = i2c_parport_attach,
276 .detach = i2c_parport_detach,
277};
278
279
280
281static int __init i2c_parport_init(void)
282{
283 if (type < 0) {
284 printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
285 return -ENODEV;
286 }
287
288 if (type >= ARRAY_SIZE(adapter_parm)) {
289 printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
290 return -ENODEV;
291 }
292
293 return parport_register_driver(&i2c_parport_driver);
294}
295
296static void __exit i2c_parport_exit(void)
297{
298 parport_unregister_driver(&i2c_parport_driver);
299}
300
301MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
302MODULE_DESCRIPTION("I2C bus over parallel port");
303MODULE_LICENSE("GPL");
304
305module_init(i2c_parport_init);
306module_exit(i2c_parport_exit);
307