~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/i2c/i2c-elektor.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* ------------------------------------------------------------------------- */
  2 /* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes             */
  3 /* ------------------------------------------------------------------------- */
  4 /*   Copyright (C) 1995-97 Simon G. Vogl
  5                    1998-99 Hans Berglund
  6 
  7     This program is free software; you can redistribute it and/or modify
  8     it under the terms of the GNU General Public License as published by
  9     the Free Software Foundation; either version 2 of the License, or
 10     (at your option) any later version.
 11 
 12     This program is distributed in the hope that it will be useful,
 13     but WITHOUT ANY WARRANTY; without even the implied warranty of
 14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15     GNU General Public License for more details.
 16 
 17     You should have received a copy of the GNU General Public License
 18     along with this program; if not, write to the Free Software
 19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
 20 /* ------------------------------------------------------------------------- */
 21 
 22 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
 23    Frodo Looijaard <frodol@dds.nl> */
 24 
 25 /* $Id: i2c-elektor.c,v 1.19 2000/07/25 23:52:17 frodo Exp $ */
 26 
 27 #include <linux/kernel.h>
 28 #include <linux/ioport.h>
 29 #include <linux/module.h>
 30 #include <linux/delay.h>
 31 #include <linux/malloc.h>
 32 #include <linux/version.h>
 33 #include <linux/init.h>
 34 #include <asm/irq.h>
 35 #include <asm/io.h>
 36 
 37 #include <linux/i2c.h>
 38 #include <linux/i2c-algo-pcf.h>
 39 #include <linux/i2c-elektor.h>
 40 #include "i2c-pcf8584.h"
 41 
 42 #define DEFAULT_BASE 0x300
 43 #define DEFAULT_IRQ      0
 44 #define DEFAULT_CLOCK 0x1c
 45 #define DEFAULT_OWN   0x55
 46 
 47 static int base  = 0;
 48 static int irq   = 0;
 49 static int clock = 0;
 50 static int own   = 0;
 51 static int i2c_debug=0;
 52 static struct i2c_pcf_isa gpi;
 53 #if (LINUX_VERSION_CODE < 0x020301)
 54 static struct wait_queue *pcf_wait = NULL;
 55 #else
 56 static wait_queue_head_t pcf_wait;
 57 #endif
 58 static int pcf_pending;
 59 
 60 /* ----- global defines ----------------------------------------------- */
 61 #define DEB(x)  if (i2c_debug>=1) x
 62 #define DEB2(x) if (i2c_debug>=2) x
 63 #define DEB3(x) if (i2c_debug>=3) x
 64 #define DEBE(x) x       /* error messages                               */
 65 
 66 
 67 /* --- Convenience defines for the i2c port:                    */
 68 #define BASE    ((struct i2c_pcf_isa *)(data))->pi_base
 69 #define DATA    BASE                    /* Adapter data port            */
 70 #define CTRL    (BASE+1)                /* Adapter control port         */
 71 
 72 /* ----- local functions ---------------------------------------------- */
 73 
 74 static void pcf_isa_setbyte(void *data, int ctl, int val)
 75 {
 76         unsigned long j = jiffies + 10;
 77 
 78         if (ctl) {
 79                 if (gpi.pi_irq > 0) {
 80                         DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n",
 81                              val|I2C_PCF_ENI));
 82                         DEB3({while (jiffies < j) schedule();})
 83                         outb(val | I2C_PCF_ENI, CTRL);
 84                 } else {
 85                          DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n", val|I2C_PCF_ENI));
 86                          DEB3({while (jiffies < j) schedule();})
 87                          outb(val|I2C_PCF_ENI, CTRL);
 88                 }
 89         } else {
 90                 DEB3(printk("i2c-elektor.o: Write Data 0x%02X\n", val&0xff));
 91                 DEB3({while (jiffies < j) schedule();})
 92                 outb(val, DATA);
 93         }
 94 }
 95 
 96 static int pcf_isa_getbyte(void *data, int ctl)
 97 {
 98         int val;
 99 
100         if (ctl) {
101                 val = inb(CTRL);
102                 DEB3(printk("i2c-elektor.o: Read Ctrl 0x%02X\n", val));
103         } else {
104                 val = inb(DATA);
105                 DEB3(printk("i2c-elektor.o: Read Data 0x%02X\n", val));
106         }
107         return (val);
108 }
109 
110 static int pcf_isa_getown(void *data)
111 {
112         return (gpi.pi_own);
113 }
114 
115 
116 static int pcf_isa_getclock(void *data)
117 {
118         return (gpi.pi_clock);
119 }
120 
121 
122 
123 #if 0
124 static void pcf_isa_sleep(unsigned long timeout)
125 {
126         schedule_timeout( timeout * HZ);
127 }
128 #endif
129 
130 
131 static void pcf_isa_waitforpin(void) {
132 
133         int timeout = 2;
134 
135         if (gpi.pi_irq > 0) {
136                 cli();
137         if (pcf_pending == 0) {
138                 interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
139         } else
140                 pcf_pending = 0;
141                 sti();
142         } else {
143                 udelay(100);
144         }
145 }
146 
147 
148 static void pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
149         pcf_pending = 1;
150         wake_up_interruptible(&pcf_wait);
151 }
152 
153 
154 static int pcf_isa_init(void)
155 {
156         if (check_region(gpi.pi_base, 2) < 0 ) {
157                 return -ENODEV;
158         } else {
159                 request_region(gpi.pi_base, 2, "i2c (isa bus adapter)");
160         }
161         if (gpi.pi_irq > 0) {
162                 if (request_irq(gpi.pi_irq, pcf_isa_handler, 0, "PCF8584", 0)
163                     < 0) {
164                 printk("i2c-elektor.o: Request irq%d failed\n", gpi.pi_irq);
165                 gpi.pi_irq = 0;
166         } else
167                 enable_irq(gpi.pi_irq);
168         }
169         return 0;
170 }
171 
172 
173 static void pcf_isa_exit(void)
174 {
175         if (gpi.pi_irq > 0) {
176                 disable_irq(gpi.pi_irq);
177                 free_irq(gpi.pi_irq, 0);
178         }
179         release_region(gpi.pi_base , 2);
180 }
181 
182 
183 static int pcf_isa_reg(struct i2c_client *client)
184 {
185         return 0;
186 }
187 
188 
189 static int pcf_isa_unreg(struct i2c_client *client)
190 {
191         return 0;
192 }
193 
194 static void pcf_isa_inc_use(struct i2c_adapter *adap)
195 {
196 #ifdef MODULE
197         MOD_INC_USE_COUNT;
198 #endif
199 }
200 
201 static void pcf_isa_dec_use(struct i2c_adapter *adap)
202 {
203 #ifdef MODULE
204         MOD_DEC_USE_COUNT;
205 #endif
206 }
207 
208 
209 /* ------------------------------------------------------------------------
210  * Encapsulate the above functions in the correct operations structure.
211  * This is only done when more than one hardware adapter is supported.
212  */
213 static struct i2c_algo_pcf_data pcf_isa_data = {
214         NULL,
215         pcf_isa_setbyte,
216         pcf_isa_getbyte,
217         pcf_isa_getown,
218         pcf_isa_getclock,
219         pcf_isa_waitforpin,
220         80, 80, 100,            /*      waits, timeout */
221 };
222 
223 static struct i2c_adapter pcf_isa_ops = {
224         "PCF8584 ISA adapter",
225         I2C_HW_P_ELEK,
226         NULL,
227         &pcf_isa_data,
228         pcf_isa_inc_use,
229         pcf_isa_dec_use,
230         pcf_isa_reg,
231         pcf_isa_unreg,
232 };
233 
234 int __init i2c_pcfisa_init(void) 
235 {
236 
237         struct i2c_pcf_isa *pisa = &gpi;
238 
239         printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n");
240         if (base == 0)
241                 pisa->pi_base = DEFAULT_BASE;
242         else
243                 pisa->pi_base = base;
244 
245         if (irq == 0)
246                 pisa->pi_irq = DEFAULT_IRQ;
247         else
248                 pisa->pi_irq = irq;
249 
250         if (clock == 0)
251                 pisa->pi_clock = DEFAULT_CLOCK;
252         else
253                 pisa->pi_clock = clock;
254 
255         if (own == 0)
256                 pisa->pi_own = DEFAULT_OWN;
257         else
258                 pisa->pi_own = own;
259 
260         pcf_isa_data.data = (void *)pisa;
261 #if (LINUX_VERSION_CODE >= 0x020301)
262         init_waitqueue_head(&pcf_wait);
263 #endif
264         if (pcf_isa_init() == 0) {
265                 if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
266                         return -ENODEV;
267         } else {
268                 return -ENODEV;
269         }
270         printk("i2c-elektor.o: found device at %#x.\n", pisa->pi_base);
271         return 0;
272 }
273 
274 
275 EXPORT_NO_SYMBOLS;
276 
277 #ifdef MODULE
278 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
279 MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
280 
281 MODULE_PARM(base, "i");
282 MODULE_PARM(irq, "i");
283 MODULE_PARM(clock, "i");
284 MODULE_PARM(own, "i");
285 MODULE_PARM(i2c_debug,"i");
286 
287 int init_module(void) 
288 {
289         return i2c_pcfisa_init();
290 }
291 
292 void cleanup_module(void) 
293 {
294         i2c_pcf_del_bus(&pcf_isa_ops);
295         pcf_isa_exit();
296 }
297 
298 #endif
299 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.