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

Revision 3421, 5.9 KB (checked in by frodo, 14 years ago)

CVS IDs in comments all-over.

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