root/i2c/trunk/kernel/i2c-elv.c @ 3560

Revision 3560, 5.0 KB (checked in by mds, 13 years ago)

Belatedly sync with kernel 2.4.2 (malloc.h -> slab.h)

Should be ok for 2.2 kernels also.
Thanks J . A . Magallon <jamagallon@…>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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$ */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/delay.h>
29#include <linux/slab.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 "i2c.h"
39#include "i2c-algo-bit.h"
40
41#define DEFAULT_BASE 0x378
42static int base=0;
43static 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
61static 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
71static 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
81static int bit_elv_getscl(void *data)
82{
83        return ( 0 == ( (inb_p(STAT)) & 0x08 ) );
84}
85
86static int bit_elv_getsda(void *data)
87{
88        return ( 0 == ( (inb_p(STAT)) & 0x40 ) );
89}
90
91static 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
118static void bit_elv_exit(void)
119{
120        release_region( base , (base == 0x3bc)? 3 : 8 );
121}
122
123static int bit_elv_reg(struct i2c_client *client)
124{
125        return 0;
126}
127
128static int bit_elv_unreg(struct i2c_client *client)
129{
130        return 0;
131}
132
133static void bit_elv_inc_use(struct i2c_adapter *adap)
134{
135#ifdef MODULE
136        MOD_INC_USE_COUNT;
137#endif
138}
139
140static 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 */
151static 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
160static 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
171int __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
198EXPORT_NO_SYMBOLS;
199
200#ifdef MODULE
201MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
202MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter")
203;
204
205MODULE_PARM(base, "i");
206
207int init_module(void)
208{
209        return i2c_bitelv_init();
210}
211
212void cleanup_module(void)
213{
214        i2c_bit_del_bus(&bit_elv_ops);
215        bit_elv_exit();
216}
217
218#endif
Note: See TracBrowser for help on using the browser.