Subject: Re: i2c 10-bit addressing
To: Garrett D'Amore <garrett_damore@tadpole.com>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: tech-kern
Date: 04/25/2006 13:55:20
This is a multi-part message in MIME format.
--------------000106030907080609000807
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Again, with diff -u for enhanced readability. Sorry.
-- Garrettt
Garrett D'Amore wrote:
> While working on a DDC driver, I wound up extending the I2C bit bang
> framework to support 10-bit addressing. (This is because I was under
> the *false* impression that DDC addresses were 0xA0, rather than 0x50.)
>
> Anyway, I've got the code, and at least the *7-bit* support works. I
> don't have any 10-bit ICs to test with.
>
> I'm attaching the patch, and if someone can test or wants to commit it
> (or wants me to commit) either do so or let me know.
>
>
> ------------------------------------------------------------------------
--------------000106030907080609000807
Content-Type: text/plain;
name="patch.i2c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="patch.i2c"
Index: i2c_bitbang.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/i2c_bitbang.c,v
retrieving revision 1.3
diff -u -r1.3 i2c_bitbang.c
--- i2c_bitbang.c 5 Mar 2006 17:33:33 -0000 1.3
+++ i2c_bitbang.c 25 Apr 2006 20:54:23 -0000
@@ -88,16 +88,39 @@
i2c_bitbang_initiate_xfer(void *v, i2c_addr_t addr, int flags,
i2c_bitbang_ops_t ops)
{
- int i2caddr;
- /* XXX Only support 7-bit addressing for now. */
- if ((addr & 0x78) == 0x78)
- return (EINVAL);
+ if (addr < 0x80) {
+ uint8_t i2caddr;
- i2caddr = (addr << 1) | ((flags & I2C_F_READ) ? 1 : 0);
+ /* disallow the 10-bit address prefix */
+ if ((addr & 0x78) == 0x78)
+ return EINVAL;
+ i2caddr = (addr << 1) | ((flags & I2C_F_READ) ? 1 : 0);
+ (void) i2c_bitbang_send_start(v, flags, ops);
+
+ return (i2c_bitbang_write_byte(v, i2caddr,
+ flags & ~I2C_F_STOP, ops));
+
+ } else if (addr < 0x400) {
+ uint16_t i2caddr;
+ int rv;
+
+ i2caddr = (addr << 1) | ((flags & I2C_F_READ) ? 1 : 0) |
+ 0xf000;
+
+ (void) i2c_bitbang_send_start(v, flags, ops);
+ rv = i2c_bitbang_write_byte(v, i2caddr >> 8,
+ flags & ~I2C_F_STOP, ops);
+ /* did a slave ack the 10-bit prefix? */
+ if (rv != 0)
+ return rv;
+
+ /* send the lower 7-bits (+ read/write mode) */
+ return (i2c_bitbang_write_byte(v, i2caddr & 0xff,
+ flags & ~I2C_F_STOP, ops));
- (void) i2c_bitbang_send_start(v, flags, ops);
- return (i2c_bitbang_write_byte(v, i2caddr, flags & ~I2C_F_STOP, ops));
+ } else
+ return EINVAL;
}
int
--------------000106030907080609000807--