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

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

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

  1 /* ------------------------------------------------------------------------- */
  2 /* i2c-elv.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-elv.c,v 1.16 2000/01/18 23:54:07 frodo Exp $ */
 25 
 26 #include <linux/kernel.h>
 27 #include <linux/module.h>
 28 #include <linux/delay.h>
 29 #include <linux/malloc.h>
 30 #include <linux/version.h>
 31 #include <linux/init.h>
 32 
 33 #include <asm/uaccess.h>
 34 
 35 #include <linux/ioport.h>
 36 #include <asm/io.h>
 37 #include <linux/errno.h>
 38 #include <linux/i2c.h>
 39 #include <linux/i2c-algo-bit.h>
 40 
 41 #define DEFAULT_BASE 0x378
 42 static int base=0;
 43 static unsigned char PortData = 0;
 44 
 45 /* ----- global defines ----------------------------------------------- */
 46 #define DEB(x)          /* should be reasonable open, close &c.         */
 47 #define DEB2(x)         /* low level debugging - very slow              */
 48 #define DEBE(x) x       /* error messages                               */
 49 #define DEBINIT(x) x    /* detection status messages                    */
 50 
 51 /* --- Convenience defines for the parallel port:                       */
 52 #define BASE    (unsigned int)(data)
 53 #define DATA    BASE                    /* Centronics data port         */
 54 #define STAT    (BASE+1)                /* Centronics status port       */
 55 #define CTRL    (BASE+2)                /* Centronics control port      */
 56 
 57 
 58 /* ----- local functions ---------------------------------------------- */
 59 
 60 
 61 static void bit_elv_setscl(void *data, int state)
 62 {
 63         if (state) {
 64                 PortData &= 0xfe;
 65         } else {
 66                 PortData |=1;
 67         }
 68         outb(PortData, DATA);
 69 }
 70 
 71 static void bit_elv_setsda(void *data, int state)
 72 {
 73         if (state) {
 74                 PortData &=0xfd;
 75         } else {
 76                 PortData |=2;
 77         }
 78         outb(PortData, DATA);
 79 } 
 80 
 81 static int bit_elv_getscl(void *data)
 82 {
 83         return ( 0 == ( (inb_p(STAT)) & 0x08 ) );
 84 }
 85 
 86 static int bit_elv_getsda(void *data)
 87 {
 88         return ( 0 == ( (inb_p(STAT)) & 0x40 ) );
 89 }
 90 
 91 static int bit_elv_init(void)
 92 {
 93         if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
 94                 return -ENODEV; 
 95         } else {
 96                                                 /* test for ELV adap.   */
 97                 if (inb(base+1) & 0x80) {       /* BUSY should be high  */
 98                         DEBINIT(printk("i2c-elv.o: Busy was low.\n"));
 99                         return -ENODEV;
100                 } else {
101                         outb(0x0c,base+2);      /* SLCT auf low         */
102                         udelay(400);
103                         if ( !(inb(base+1) && 0x10) ) {
104                                 outb(0x04,base+2);
105                                 DEBINIT(printk("i2c-elv.o: Select was high.\n"));
106                                 return -ENODEV;
107                         }
108                 }
109                 request_region(base,(base == 0x3bc)? 3 : 8,
110                         "i2c (ELV adapter)");
111                 PortData = 0;
112                 bit_elv_setsda((void*)base,1);
113                 bit_elv_setscl((void*)base,1);
114         }
115         return 0;
116 }
117 
118 static void bit_elv_exit(void)
119 {
120         release_region( base , (base == 0x3bc)? 3 : 8 );
121 }
122 
123 static int bit_elv_reg(struct i2c_client *client)
124 {
125         return 0;
126 }
127 
128 static int bit_elv_unreg(struct i2c_client *client)
129 {
130         return 0;
131 }
132 
133 static void bit_elv_inc_use(struct i2c_adapter *adap)
134 {
135 #ifdef MODULE
136         MOD_INC_USE_COUNT;
137 #endif
138 }
139 
140 static void bit_elv_dec_use(struct i2c_adapter *adap)
141 {
142 #ifdef MODULE
143         MOD_DEC_USE_COUNT;
144 #endif
145 }
146 
147 /* ------------------------------------------------------------------------
148  * Encapsulate the above functions in the correct operations structure.
149  * This is only done when more than one hardware adapter is supported.
150  */
151 static struct i2c_algo_bit_data bit_elv_data = {
152         NULL,
153         bit_elv_setsda,
154         bit_elv_setscl,
155         bit_elv_getsda,
156         bit_elv_getscl,
157         80, 80, 100,            /*      waits, timeout */
158 };
159 
160 static struct i2c_adapter bit_elv_ops = {
161         "ELV Parallel port adaptor",
162         I2C_HW_B_ELV,
163         NULL,
164         &bit_elv_data,
165         bit_elv_inc_use,
166         bit_elv_dec_use,
167         bit_elv_reg,
168         bit_elv_unreg,  
169 };
170 
171 int __init i2c_bitelv_init(void)
172 {
173         printk("i2c-elv.o: i2c ELV parallel port adapter module\n");
174         if (base==0) {
175                 /* probe some values */
176                 base=DEFAULT_BASE;
177                 bit_elv_data.data=(void*)DEFAULT_BASE;
178                 if (bit_elv_init()==0) {
179                         if(i2c_bit_add_bus(&bit_elv_ops) < 0)
180                                 return -ENODEV;
181                 } else {
182                         return -ENODEV;
183                 }
184         } else {
185                 bit_elv_ops.data=(void*)base;
186                 if (bit_elv_init()==0) {
187                         if(i2c_bit_add_bus(&bit_elv_ops) < 0)
188                                 return -ENODEV;
189                 } else {
190                         return -ENODEV;
191                 }
192         }
193         printk("i2c-elv.o: found device at %#x.\n",base);
194         return 0;
195 }
196 
197 
198 EXPORT_NO_SYMBOLS;
199 
200 #ifdef MODULE
201 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
202 MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter")
203 ;
204 
205 MODULE_PARM(base, "i");
206 
207 int init_module(void)
208 {
209         return i2c_bitelv_init();
210 }
211 
212 void cleanup_module(void)
213 {
214         i2c_bit_del_bus(&bit_elv_ops);
215         bit_elv_exit();
216 }
217 
218 #endif
219 

~ [ 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.