special usb hub handling, IDE disks, and retries all over the place
[linux-2.4.git] / drivers / i2c / i2c-philips-par.c
1 /* ------------------------------------------------------------------------- */
2 /* i2c-philips-par.c i2c-hw access for philips style parallel port adapters  */
3 /* ------------------------------------------------------------------------- */
4 /*   Copyright (C) 1995-2000 Simon G. Vogl
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
19 /* ------------------------------------------------------------------------- */ 
20
21 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
22    Frodo Looijaard <frodol@dds.nl> */
23
24 /* $Id: i2c-philips-par.c,v 1.18 2000/07/06 19:21:49 frodo Exp $ */
25
26 #include <linux/kernel.h>
27 #include <linux/ioport.h>
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/stddef.h>
31 #include <linux/parport.h>
32
33 #include <linux/i2c.h>
34 #include <linux/i2c-algo-bit.h>
35
36 #ifndef __exit
37 #define __exit __init
38 #endif
39
40 static int type;
41
42 struct i2c_par
43 {
44         struct pardevice *pdev;
45         struct i2c_adapter adapter;
46         struct i2c_algo_bit_data bit_lp_data;
47         struct i2c_par *next;
48 };
49
50 static struct i2c_par *adapter_list;
51
52
53 /* ----- global defines ----------------------------------------------- */
54 #define DEB(x)          /* should be reasonable open, close &c.         */
55 #define DEB2(x)         /* low level debugging - very slow              */
56 #define DEBE(x) x       /* error messages                               */
57
58 /* ----- printer port defines ------------------------------------------*/
59                                         /* Pin Port  Inverted   name    */
60 #define I2C_ON          0x20            /* 12 status N  paper           */
61                                         /* ... only for phil. not used  */
62 #define I2C_SDA         0x80            /*  9 data   N  data7           */
63 #define I2C_SCL         0x08            /* 17 ctrl   N  dsel            */
64
65 #define I2C_SDAIN       0x80            /* 11 stat   Y  busy            */
66 #define I2C_SCLIN       0x08            /* 15 stat   Y  enable          */
67
68 #define I2C_DMASK       0x7f
69 #define I2C_CMASK       0xf7
70
71 /* ----- local functions ---------------------------------------------- */
72
73 static void bit_lp_setscl(void *data, int state)
74 {
75         /*be cautious about state of the control register - 
76                 touch only the one bit needed*/
77         if (state) {
78                 parport_write_control((struct parport *) data,
79                       parport_read_control((struct parport *) data)|I2C_SCL);
80         } else {
81                 parport_write_control((struct parport *) data,
82                       parport_read_control((struct parport *) data)&I2C_CMASK);
83         }
84 }
85
86 static void bit_lp_setsda(void *data, int state)
87 {
88         if (state) {
89                 parport_write_data((struct parport *) data, I2C_DMASK);
90         } else {
91                 parport_write_data((struct parport *) data, I2C_SDA);
92         }
93 }
94
95 static int bit_lp_getscl(void *data)
96 {
97         return parport_read_status((struct parport *) data) & I2C_SCLIN;
98 }
99
100 static int bit_lp_getsda(void *data)
101 {
102         return parport_read_status((struct parport *) data) & I2C_SDAIN;
103 }
104
105 static void bit_lp_setscl2(void *data, int state)
106 {
107         if (state) {
108                 parport_write_data((struct parport *) data,
109                       parport_read_data((struct parport *) data)|0x1);
110         } else {
111                 parport_write_data((struct parport *) data,
112                       parport_read_data((struct parport *) data)&0xfe);
113         }
114 }
115
116 static void bit_lp_setsda2(void *data, int state)
117 {
118         if (state) {
119                 parport_write_data((struct parport *) data,
120                       parport_read_data((struct parport *) data)|0x2);
121         } else {
122                 parport_write_data((struct parport *) data,
123                       parport_read_data((struct parport *) data)&0xfd);
124         }
125 }
126
127 static int bit_lp_getsda2(void *data)
128 {
129         return (parport_read_status((struct parport *) data) & 
130                                      PARPORT_STATUS_BUSY) ? 0 : 1;
131 }
132
133 static int bit_lp_reg(struct i2c_client *client)
134 {
135         return 0;
136 }
137
138 static int bit_lp_unreg(struct i2c_client *client)
139 {
140         return 0;
141 }
142
143 static void bit_lp_inc_use(struct i2c_adapter *adap)
144 {
145         MOD_INC_USE_COUNT;
146 }
147
148 static void bit_lp_dec_use(struct i2c_adapter *adap)
149 {
150         MOD_DEC_USE_COUNT;
151 }
152
153 /* ------------------------------------------------------------------------
154  * Encapsulate the above functions in the correct operations structure.
155  * This is only done when more than one hardware adapter is supported.
156  */
157  
158 static struct i2c_algo_bit_data bit_lp_data = {
159         .setsda         = bit_lp_setsda,
160         .setscl         = bit_lp_setscl,
161         .getsda         = bit_lp_getsda,
162         .getscl         = bit_lp_getscl,
163         .udelay         = 80,
164         .mdelay         = 80,
165         .timeout        = HZ
166 }; 
167
168 static struct i2c_algo_bit_data bit_lp_data2 = {
169         .setsda         = bit_lp_setsda2,
170         .setscl         = bit_lp_setscl2,
171         .getsda         = bit_lp_getsda2,
172         .udelay         = 80,
173         .mdelay         = 80,
174         .timeout        = HZ
175 }; 
176
177 static struct i2c_adapter bit_lp_ops = {
178         .name           = "Philips Parallel port adapter",
179         .id             = I2C_HW_B_LP,
180         .inc_use        = bit_lp_inc_use,
181         .dec_use        = bit_lp_dec_use,
182         .client_register = bit_lp_reg,
183         .client_unregister = bit_lp_unreg,
184 };
185
186 static void i2c_parport_attach (struct parport *port)
187 {
188         struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par),
189                                           GFP_KERNEL);
190         if (!adapter) {
191                 printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
192                 return;
193         }
194
195         printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
196
197         adapter->pdev = parport_register_device(port, "i2c-philips-par",
198                                                 NULL, NULL, NULL, 
199                                                 PARPORT_FLAG_EXCL,
200                                                 NULL);
201         if (!adapter->pdev) {
202                 printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
203                 return;
204         }
205
206         adapter->adapter = bit_lp_ops;
207         adapter->adapter.algo_data = &adapter->bit_lp_data;
208         adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data;
209         adapter->bit_lp_data.data = port;
210
211         /* reset hardware to sane state */
212         parport_claim_or_block(adapter->pdev);
213         adapter->bit_lp_data.setsda(port, 1);
214         adapter->bit_lp_data.setscl(port, 1);
215         parport_release(adapter->pdev);
216
217         if (i2c_bit_add_bus(&adapter->adapter) < 0)
218         {
219                 printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
220                 parport_unregister_device(adapter->pdev);
221                 kfree(adapter);
222                 return;         /* No good */
223         }
224
225         adapter->next = adapter_list;
226         adapter_list = adapter;
227 }
228
229 static void i2c_parport_detach (struct parport *port)
230 {
231         struct i2c_par *adapter, *prev = NULL;
232
233         for (adapter = adapter_list; adapter; adapter = adapter->next)
234         {
235                 if (adapter->pdev->port == port)
236                 {
237                         parport_unregister_device(adapter->pdev);
238                         i2c_bit_del_bus(&adapter->adapter);
239                         if (prev)
240                                 prev->next = adapter->next;
241                         else
242                                 adapter_list = adapter->next;
243                         kfree(adapter);
244                         return;
245                 }
246                 prev = adapter;
247         }
248 }
249
250
251 static struct parport_driver i2c_driver = {
252         "i2c-philips-par",
253         i2c_parport_attach,
254         i2c_parport_detach,
255         NULL
256 };
257
258 int __init i2c_bitlp_init(void)
259 {
260         printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
261
262         parport_register_driver(&i2c_driver);
263         
264         return 0;
265 }
266
267 void __exit i2c_bitlp_exit(void)
268 {
269         parport_unregister_driver(&i2c_driver);
270 }
271
272 EXPORT_NO_SYMBOLS;
273
274 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
275 MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter");
276 MODULE_LICENSE("GPL");
277
278 MODULE_PARM(type, "i");
279
280 #ifdef MODULE
281 int init_module(void)
282 {
283         return i2c_bitlp_init();
284 }
285
286 void cleanup_module(void)
287 {
288         i2c_bitlp_exit();
289 }
290 #endif