root/dev/i2c/i2c_bitbang.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. i2c_bitbang_send_start
  2. i2c_bitbang_send_stop
  3. i2c_bitbang_initiate_xfer
  4. i2c_bitbang_read_byte
  5. i2c_bitbang_write_byte

    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 }

/* [<][>][^][v][top][bottom][index][help] */