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