root/i2c/trunk/kernel/i2c-velleman.c @ 3330

Revision 3330, 5.0 KB (checked in by kmalkki, 15 years ago)

(Kyösti)

  • Changed the way i2c_adapter extends for different algorithms

Algorithm low-level data is now accessed via i2c_adapter->algo_data.

  • Removed client_(un)register hooks in algorithm struct and drivers
  • Added client_(un)register to adapter struct
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* ------------------------------------------------------------------------- */
2/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters                  */
3/* ------------------------------------------------------------------------- */
4/*   Copyright (C) 1995-96 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/* -------------------------------------------------------------------------
20static char rcsid[] = "$Id$";
21  ------------------------------------------------------------------------- */
22
23#include <linux/kernel.h>
24#include <linux/ioport.h>
25#include <linux/module.h>
26#if LINUX_VERSION_CODE >= 0x020135
27#include <linux/init.h>
28#else
29#define __init
30#endif
31#include <linux/string.h>  /* for 2.0 kernels to get NULL   */
32#include <asm/errno.h>     /* for 2.0 kernels to get ENODEV */
33#include <asm/io.h>
34
35#include "i2c.h"
36#include "i2c-algo-bit.h"
37
38/* ----- global defines ----------------------------------------------- */
39#define DEB(x)          /* should be reasonable open, close &c.         */
40#define DEB2(x)         /* low level debugging - very slow              */
41#define DEBE(x) x       /* error messages                               */
42
43                                        /* Pin Port  Inverted   name    */
44#define I2C_SDA         0x02            /*  ctrl bit 1  (inv)   */
45#define I2C_SCL         0x08            /*  ctrl bit 3  (inv)   */
46
47#define I2C_SDAIN       0x10            /* stat bit 4           */
48#define I2C_SCLIN       0x08            /*  ctrl bit 3 (inv) (reads own output) */
49
50#define I2C_DMASK       0xfd
51#define I2C_CMASK       0xf7
52
53
54/* --- Convenience defines for the parallel port:                       */
55#define BASE    (unsigned int)(data)
56#define DATA    BASE                    /* Centronics data port         */
57#define STAT    (BASE+1)                /* Centronics status port       */
58#define CTRL    (BASE+2)                /* Centronics control port      */
59
60#define DEFAULT_BASE 0x378
61static int base=0;
62
63/* ----- local functions --------------------------------------------------- */
64
65static void bit_velle_setscl(void *data, int state)
66{
67        if (state) {
68                outb(inb(CTRL) & I2C_CMASK,   CTRL);
69        } else {
70                outb(inb(CTRL) | I2C_SCL, CTRL);
71        }
72       
73}
74
75static void bit_velle_setsda(void *data, int state)
76{
77        if (state) {
78                outb(inb(CTRL) & I2C_DMASK , CTRL);
79        } else {
80                outb(inb(CTRL) | I2C_SDA, CTRL);
81        }
82       
83} 
84
85static int bit_velle_getscl(void *data)
86{
87        return ( 0 == ( (inb(CTRL)) & I2C_SCLIN ) );
88}
89
90static int bit_velle_getsda(void *data)
91{
92        return ( 0 != ( (inb(STAT)) & I2C_SDAIN ) );
93}
94
95static int bit_velle_init(void)
96{
97        if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
98                DEBE(printk("i2c_init: Port %#x already in use.\n", base));
99                return -ENODEV;
100        } else {
101                request_region(base, (base == 0x3bc)? 3 : 8, 
102                        "i2c (Vellemann adapter)");
103                bit_velle_setsda((void*)base,1);
104                bit_velle_setscl((void*)base,1);
105        }
106        return 0;
107}
108
109static void bit_velle_exit(void)
110{       
111        release_region( base , (base == 0x3bc)? 3 : 8 );
112}
113
114
115static int bit_velle_reg(struct i2c_client *client)
116{
117        return 0;
118}
119
120static int bit_velle_unreg(struct i2c_client *client)
121{
122        return 0;
123}
124
125static void bit_velle_inc_use(struct i2c_adapter *adap)
126{
127#ifdef MODULE
128        MOD_INC_USE_COUNT;
129#endif
130}
131
132static void bit_velle_dec_use(struct i2c_adapter *adap)
133{
134#ifdef MODULE
135        MOD_DEC_USE_COUNT;
136#endif
137}
138
139/* ------------------------------------------------------------------------
140 * Encapsulate the above functions in the correct operations structure.
141 * This is only done when more than one hardware adapter is supported.
142 */
143
144static struct i2c_algo_bit_data bit_velle_data = {
145        NULL,
146        bit_velle_setsda,
147        bit_velle_setscl,
148        bit_velle_getsda,
149        bit_velle_getscl,
150        10, 10, 100,            /*      waits, timeout */
151};
152
153static struct i2c_adapter bit_velle_ops = {
154        "Philips Parallel port adapter",
155        I2C_HW_B_LP,
156        NULL,
157        &bit_velle_data,
158        bit_velle_inc_use,
159        bit_velle_dec_use,
160        bit_velle_reg,
161        bit_velle_unreg,
162};
163
164int __init  i2c_bitvelle_init(void)
165{
166        if (base==0) {
167                /* probe some values */
168                base=DEFAULT_BASE;
169                bit_velle_data.data=(void*)DEFAULT_BASE;
170                if (bit_velle_init()==0) {
171                        i2c_bit_add_bus(&bit_velle_ops);
172                } else {
173                        return -ENODEV;
174                }
175        } else {
176                bit_velle_data.data=(void*)base;
177                if (bit_velle_init()==0) {
178                        i2c_bit_add_bus(&bit_velle_ops);
179                } else {
180                        return -ENODEV;
181                }
182        }
183        printk("bit_velle: found device at %#x.\n",base);
184        return 0;
185}
186
187
188#ifdef MODULE
189MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
190MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K9000 adapter");
191
192MODULE_PARM(base, "i");
193
194int init_module(void) 
195{
196        return i2c_bitvelle_init();
197}
198
199void cleanup_module(void) 
200{
201        i2c_bit_del_bus(&bit_velle_ops);
202        bit_velle_exit();
203}
204
205#endif
206
207
208
Note: See TracBrowser for help on using the browser.