Annotation of sys/dev/i2c/i2c_bitbang.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: i2c_bitbang.c,v 1.3 2006/01/13 23:56:46 grange Exp $ */
2: /* $NetBSD: i2c_bitbang.c,v 1.1 2003/09/30 00:35:31 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 2003 Wasabi Systems, Inc.
6: * All rights reserved.
7: *
8: * Written by Jason R. Thorpe for Wasabi Systems, Inc.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed for the NetBSD Project by
21: * Wasabi Systems, Inc.
22: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23: * or promote products derived from this software without specific prior
24: * written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: /*
40: * Common module for bit-bang'ing an I2C bus.
41: */
42:
43: #include <sys/param.h>
44:
45: #include <dev/i2c/i2cvar.h>
46: #include <dev/i2c/i2c_bitbang.h>
47:
48: #define BB_SET(x) ops->ibo_set_bits(v, (x))
49: #define BB_DIR(x) ops->ibo_set_dir(v, (x))
50: #define BB_READ ops->ibo_read_bits(v)
51:
52: #define SDA ops->ibo_bits[I2C_BIT_SDA] /* i2c signal */
53: #define SCL ops->ibo_bits[I2C_BIT_SCL] /* i2c signal */
54: #define OUTPUT ops->ibo_bits[I2C_BIT_OUTPUT] /* SDA is output */
55: #define INPUT ops->ibo_bits[I2C_BIT_INPUT] /* SDA is input */
56:
57: /*ARGSUSED*/
58: int
59: i2c_bitbang_send_start(void *v, int flags, i2c_bitbang_ops_t ops)
60: {
61:
62: BB_DIR(OUTPUT);
63:
64: BB_SET(SDA | SCL);
65: delay(5); /* bus free time (4.7 uS) */
66: BB_SET( SCL);
67: delay(4); /* start hold time (4.0 uS) */
68: BB_SET( 0);
69: delay(5); /* clock low time (4.7 uS) */
70:
71: return (0);
72: }
73:
74: /*ARGSUSED*/
75: int
76: i2c_bitbang_send_stop(void *v, int flags, i2c_bitbang_ops_t ops)
77: {
78:
79: BB_DIR(OUTPUT);
80:
81: BB_SET( SCL);
82: delay(4); /* stop setup time (4.0 uS) */
83: BB_SET(SDA | SCL);
84:
85: return (0);
86: }
87:
88: int
89: i2c_bitbang_initiate_xfer(void *v, i2c_addr_t addr, int flags,
90: i2c_bitbang_ops_t ops)
91: {
92: int i2caddr;
93:
94: /* XXX Only support 7-bit addressing for now. */
95: if ((addr & 0x78) == 0x78)
96: return (EINVAL);
97:
98: i2caddr = (addr << 1) | ((flags & I2C_F_READ) ? 1 : 0);
99:
100: (void) i2c_bitbang_send_start(v, flags, ops);
101: return (i2c_bitbang_write_byte(v, i2caddr, flags & ~I2C_F_STOP, ops));
102: }
103:
104: int
105: i2c_bitbang_read_byte(void *v, uint8_t *valp, int flags,
106: i2c_bitbang_ops_t ops)
107: {
108: int i;
109: uint8_t val = 0;
110: uint32_t bit;
111:
112: BB_DIR(INPUT);
113: BB_SET(SDA );
114:
115: for (i = 0; i < 8; i++) {
116: val <<= 1;
117: BB_SET(SDA | SCL);
118: delay(4); /* clock high time (4.0 uS) */
119: if (BB_READ & SDA)
120: val |= 1;
121: BB_SET(SDA );
122: delay(5); /* clock low time (4.7 uS) */
123: }
124:
125: bit = (flags & I2C_F_LAST) ? SDA : 0;
126: BB_DIR(OUTPUT);
127: BB_SET(bit );
128: delay(1); /* data setup time (250 nS) */
129: BB_SET(bit | SCL);
130: delay(4); /* clock high time (4.0 uS) */
131: BB_SET(bit );
132: delay(5); /* clock low time (4.7 uS) */
133:
134: BB_DIR(INPUT);
135: BB_SET(SDA );
136: delay(5);
137:
138: if ((flags & (I2C_F_STOP | I2C_F_LAST)) == (I2C_F_STOP | I2C_F_LAST))
139: (void) i2c_bitbang_send_stop(v, flags, ops);
140:
141: *valp = val;
142: return (0);
143: }
144:
145: int
146: i2c_bitbang_write_byte(void *v, uint8_t val, int flags,
147: i2c_bitbang_ops_t ops)
148: {
149: uint32_t bit;
150: uint8_t mask;
151: int error;
152:
153: BB_DIR(OUTPUT);
154:
155: for (mask = 0x80; mask != 0; mask >>= 1) {
156: bit = (val & mask) ? SDA : 0;
157: BB_SET(bit );
158: delay(1); /* data setup time (250 nS) */
159: BB_SET(bit | SCL);
160: delay(4); /* clock high time (4.0 uS) */
161: BB_SET(bit );
162: delay(5); /* clock low time (4.7 uS) */
163: }
164:
165: BB_DIR(INPUT);
166:
167: BB_SET(SDA );
168: delay(5);
169: BB_SET(SDA | SCL);
170: delay(4);
171: error = (BB_READ & SDA) ? EIO : 0;
172: BB_SET(SDA );
173: delay(5);
174:
175: if (flags & I2C_F_STOP)
176: (void) i2c_bitbang_send_stop(v, flags, ops);
177:
178: return (error);
179: }
CVSweb