root/i2c/trunk/kernel/i2c-pport.c @ 3765

Revision 3765, 5.2 KB (checked in by kmalkki, 12 years ago)

(Kyösti) More cleanups

Redo i2c-core locks.

No longer pass controlling_mod in i2cproc_register_entry, use
client->driver->owner instead.

Comment out or remove obsolete parts of mkpatch for 2.5.
Currently it does not touch kernel build/configure system at all.

Cleanup #include order. Note that kernel headers are not to be
included for userland utilities, to promote binary compatibility of
utilities across kernel versions.

Remove bus_scans. Remove empty and unused algo_control and
debugging code that would not compile if uncommented.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* ------------------------------------------------------------------------- */
2/* i2c-pport.c i2c-hw access  for primitive i2c par. port adapter            */
3/* ------------------------------------------------------------------------- */
4/*   Copyright (C) 2001    Daniel Smolik
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/*
22        See doc/i2c-pport for instructions on wiring to the
23        parallel port connector.
24
25        Cut & paste :-)  based on Velleman K9000 driver by Simon G. Vogl
26*/
27
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/init.h>
34#include <linux/ioport.h>
35#include <linux/errno.h>
36#include "i2c.h"
37#include "i2c-algo-bit.h"
38#include <asm/io.h>
39
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/* we will use SDA  - Auto Linefeed(14)   bit 1  POUT   */
58/* we will use SCL - Initialize printer(16)    BUSY bit 2*/
59
60#define  SET_SCL    | 0x04
61#define  CLR_SCL    & 0xFB
62
63
64
65
66#define  SET_SDA    & 0x04
67#define  CLR_SDA    | 0x02
68
69
70/* ----- local functions ---------------------------------------------- */
71
72
73static void bit_pport_setscl(void *data, int state)
74{
75        if (state) {
76                //high
77                PortData = PortData SET_SCL;
78        } else {
79                //low
80                PortData = PortData CLR_SCL; 
81        }
82        outb(PortData, CTRL);
83}
84
85static void bit_pport_setsda(void *data, int state)
86{
87        if (state) {
88               
89                PortData = PortData SET_SDA;
90        } else {
91
92                PortData = PortData CLR_SDA;
93        }
94        outb(PortData, CTRL);
95} 
96
97static int bit_pport_getscl(void *data)
98{
99
100        return ( 4 == ( (inb_p(CTRL)) & 0x04 ) );
101}
102
103static int bit_pport_getsda(void *data)
104{
105        return ( 0 == ( (inb_p(CTRL)) & 0x02 ) );
106}
107
108static int bit_pport_init(void)
109{
110        if (!request_region((base+2),1, "i2c (PPORT adapter)")) {
111                return -ENODEV; 
112        } else {
113                /* test for PPORT adap.         */
114       
115
116                PortData=inb(base+2);
117                PortData= (PortData SET_SDA) SET_SCL;
118                outb(PortData,base+2);                         
119
120                if (!(inb(base+2) | 0x06)) {    /* SDA and SCL will be high     */
121                        DEBINIT(printk("i2c-pport.o: SDA and SCL was low.\n"));
122                        return -ENODEV;
123                } else {
124               
125                        /*SCL high and SDA low*/
126                        PortData = PortData SET_SCL CLR_SDA;
127                        outb(PortData,base+2); 
128                        schedule_timeout(400);
129                        if ( !(inb(base+2) | 0x4) ) {
130                                //outb(0x04,base+2);
131                                DEBINIT(printk("i2c-port.o: SDA was high.\n"));
132                                return -ENODEV;
133                        }
134                }
135                bit_pport_setsda((void*)base,1);
136                bit_pport_setscl((void*)base,1);
137        }
138        return 0;
139}
140
141
142/* ------------------------------------------------------------------------
143 * Encapsulate the above functions in the correct operations structure.
144 * This is only done when more than one hardware adapter is supported.
145 */
146static struct i2c_algo_bit_data bit_pport_data = {
147        .setsda         = bit_pport_setsda,
148        .setscl         = bit_pport_setscl,
149        .getsda         = bit_pport_getsda,
150        .getscl         = bit_pport_getscl,
151        .udelay         = 40,
152        .mdelay         = 80,
153        .timeout        = HZ
154};
155
156static struct i2c_adapter bit_pport_ops = {
157        .owner          = THIS_MODULE,
158        .name           = "Primitive Parallel port adaptor",
159        .id             = I2C_HW_B_PPORT,
160        .algo_data      = &bit_pport_data,
161};
162
163int __init i2c_bitpport_init(void)
164{
165        printk("i2c-pport.o: i2c Primitive parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
166
167        if (base==0) {
168                /* probe some values */
169                base=DEFAULT_BASE;
170                bit_pport_data.data=(void*)DEFAULT_BASE;
171                if (bit_pport_init()==0) {
172                        if(i2c_bit_add_bus(&bit_pport_ops) < 0)
173                                return -ENODEV;
174                } else {
175                        return -ENODEV;
176                }
177        } else {
178                bit_pport_data.data=(void*)base;
179                if (bit_pport_init()==0) {
180                        if(i2c_bit_add_bus(&bit_pport_ops) < 0)
181                                return -ENODEV;
182                } else {
183                        return -ENODEV;
184                }
185        }
186        printk("i2c-pport.o: found device at %#x.\n",base);
187        return 0;
188}
189
190static void __exit i2c_bitpport_exit(void)
191{
192        i2c_bit_del_bus(&bit_pport_ops);
193        release_region((base+2),1);
194}
195
196EXPORT_NO_SYMBOLS;
197
198MODULE_AUTHOR("Daniel Smolik <marvin@sitour.cz>");
199MODULE_DESCRIPTION("I2C-Bus adapter routines for Primitive parallel port adapter");
200MODULE_LICENSE("GPL");
201
202MODULE_PARM(base, "i");
203
204module_init(i2c_bitpport_init);
205module_exit(i2c_bitpport_exit);
Note: See TracBrowser for help on using the browser.