Annotation of sys/dev/i2c/i2c_bitbang.c, Revision 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