[<<][am335x][>>][..]
Tue Jun 12 19:40:08 EDT 2018

back to driver

Threaded irq?
Avoids top/bottom half.
https://www.quora.com/What-is-the-advantage-of-new-request_threaded_irq-over-request_irq

Why is it checking this based on version?
[    0.724262] omap_i2c 4819c000.i2c: request_threaded_irq: 5040000b

omap_i2c_isr_thread(int this_irq, void *dev_id)


Debug messages are used:
dev_dbg(omap->dev, "IRQ (ISR = 0x%04x)\n", stat);
How to enable them?

https://www.kernel.org/doc/html/v4.11/admin-guide/dynamic-debug-howto.html

Enable per callsite.  This is quite neat!

# echo 'file svcsock.c line 1603 +p' >debugfs/dynamic_debug/control
# cat debugfs/dynamic_debug/control


To add slave support, focus first on the STAT and IE registers

		bits = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG);
		stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);


/* I2C Status Register (OMAP_I2C_STAT): */
#define OMAP_I2C_STAT_XDR	(1 << 14)	/* TX Buffer draining */
#define OMAP_I2C_STAT_RDR	(1 << 13)	/* RX Buffer draining */
#define OMAP_I2C_STAT_BB	(1 << 12)	/* Bus busy */
#define OMAP_I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
#define OMAP_I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
#define OMAP_I2C_STAT_AAS	(1 << 9)	/* Address as slave */
#define OMAP_I2C_STAT_BF	(1 << 8)	/* Bus Free */
#define OMAP_I2C_STAT_XRDY	(1 << 4)	/* Transmit data ready */
#define OMAP_I2C_STAT_RRDY	(1 << 3)	/* Receive data ready */
#define OMAP_I2C_STAT_ARDY	(1 << 2)	/* Register access ready */
#define OMAP_I2C_STAT_NACK	(1 << 1)	/* No ack interrupt enable */
#define OMAP_I2C_STAT_AL	(1 << 0)	/* Arbitration lost int ena */

OMAP_I2C_STAT_REG at 0x28 for v2.
21.4.1.5 I2C_IRQSTATUS Register (offset = 28h) [reset = 0h]


#define OMAP_I2C_STAT_AAS	(1 << 9)	/* Address as slave */

IE reg is written from omap->iestate


Set in 
static int omap_i2c_init(struct omap_i2c_dev *omap)

	omap->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
			OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
			OMAP_I2C_IE_AL)  | ((omap->fifo_size) ?
				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);


/* I2C Interrupt Enable Register (OMAP_I2C_IE): */
#define OMAP_I2C_IE_XDR		(1 << 14)	/* TX Buffer drain int enable */
#define OMAP_I2C_IE_RDR		(1 << 13)	/* RX Buffer drain int enable */
#define OMAP_I2C_IE_XRDY	(1 << 4)	/* TX data ready int enable */
#define OMAP_I2C_IE_RRDY	(1 << 3)	/* RX data ready int enable */
#define OMAP_I2C_IE_ARDY	(1 << 2)	/* Access ready int enable */
#define OMAP_I2C_IE_NACK	(1 << 1)	/* No ack interrupt enable */
#define OMAP_I2C_IE_AL		(1 << 0)	/* Arbitration lost int ena */

IE reg is at 0x2C

So the ones that are ignored (not defined in source)
#define OMAP_I2C_IE_AAS         (1 << 9)	/* Addressed as slave */

Other, unused interrupts
7: AERR access error
6: STC  start condition
5: GC   general call




So, assumption is that if I2C_OA is set, slave mode is enabled.
 
21.4.1.20 I2C_OA Register (offset = A8h) [reset = 0h]


Active transfer phase: between STT having been set to 1 and reception of ARDY.

I2C mode register (I2C_CON) 0xA4
MST=1 : master mode
automatically cleared at STOP
set in omap_i2c_xfer_msg()

So with this, look at the code again.

I expect:
- AAS   slave access
- RRDY  receive data ready
- XRDY  transmit ready

Does master turn off power?  Check this again later.  There's a
timeout set: that would be the first thing to mess with.

My main concern in the way the framework is implemented, is that the
reads cannot be buffered easily.  There isn't a lot of time between
the read bit which likely causes the interrupt, and the byte being
clocked out.

At 10kHz, and in interrupt context, this should be fine though.

Let's look at the actual case:
- address received
- command received
- data reply

When command is received, immediately the fifo can be filled.  But the
slave mode doesn't really allow for this.

Maybe best to first hack it into the driver directly?



[Reply][About]
[<<][am335x][>>][..]