Subject: i2c 10-bit addressing
To: None <tech-kern@NetBSD.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: tech-kern
Date: 04/25/2006 13:52:57
This is a multi-part message in MIME format.
--------------010104000006020505040600
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

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.

-- 
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecomputer.com/
Phone: 951 325-2134  Fax: 951 325-2191


--------------010104000006020505040600
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 -r1.3 i2c_bitbang.c
91d90
< 	int i2caddr;
93,95c92,93
< 	/* XXX Only support 7-bit addressing for now. */
< 	if ((addr & 0x78) == 0x78)
< 		return (EINVAL);
---
> 	if (addr < 0x80) {
> 		uint8_t i2caddr;
97c95,120
< 	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));
99,100c122,123
< 	(void) i2c_bitbang_send_start(v, flags, ops);
< 	return (i2c_bitbang_write_byte(v, i2caddr, flags & ~I2C_F_STOP, ops));
---
> 	} else
> 		return EINVAL;

--------------010104000006020505040600--