Tue Jun 12 11:20:22 EDT 2018


I need to start at the very beginning.  How does the driver get

static int __init
	return platform_driver_register(&omap_i2c_driver);

How does the kernel know to call that function?

So __init is just a marker to put code in a section that can later be discarded.

I think the real entry point is determined by

The next point is

  Platform devices are devices that typically appear as autonomous
  entities in the system. ... What they usually have in common is
  direct addressing from a CPU bus.

  Platform drivers follow the standard driver model convention, where
  discovery/enumeration is handled outside the drivers, and drivers
  provide probe() and remove() methods.  They support power management
  and shutdown notifications using the standard conventions.

It uses the structure:

struct platform_driver omap_i2c_driver = {
	.probe		= omap_i2c_probe,
	.remove		= omap_i2c_remove,
	.driver		= {
		.name	= "omap_i2c",
		.pm	= OMAP_I2C_PM_OPS,
		.of_match_table = of_match_ptr(omap_i2c_of_match),

Ignore PM for now, and assume that OF just gives the correct data.
Move on to:

omap_i2c_probe(struct platform_device *pdev)

platform_get_resource(), devm_ioremap_resource()
init_completion()  // synchronization infrastructure
pm_*() // power management calls.  do not touch.
readw_relaxed(omap->base + 0x04); // revision, scheme
omap->regs, omap->errata; // set based on revision, scheme
omap->fifo_size // read register BUFSTAT_REG 0x10 to deterimine fifo size (not clear)
omap_i2c_init() // reset hardware
devm_request_irq() or devm_request_threaded_irq()  // not clear which one
i2c_set_adapdata()  // hook up to i2c infrastructure?
adap->algo = &omap_i2c_algo; // omap_i2c_xfer, omap_i2c_func
adap->bus_recovery_info = &omap_i2c_bus_recovery_info; // ??? stuck bus stuff?
i2c_add_numbered_adapter() // get i2c bus number


- completion?

- generic i2c driver documentation?

- do i know enough to start looking into slave mode?
  original slave mode patch:
  How to look at this particular patch?

  slave eeprom:

- Documentation/i2c:
  drwxr-xr-x 1  446 May 17 17:32 busses
  -rw-r--r-- 1 8.7K Feb 21 16:20 dev-interface
  -rw-r--r-- 1 5.0K Feb 21 16:20 fault-codes
  -rw-r--r-- 1 6.0K Feb 21 16:20 functionality
  -rw-r--r-- 1 3.0K Feb 21 16:20 i2c-protocol
  -rw-r--r-- 1 2.3K Feb 21 16:20 i2c-stub
  -rw-r--r-- 1  15K Feb 21 16:20 i2c-topology
  -rw-r--r-- 1 9.6K Feb 21 16:20 instantiating-devices
  drwxr-xr-x 1   24 May 17 17:32 muxes
  -rw-r--r-- 1 1.9K Feb 21 16:20 old-module-parameters
  -rw-r--r-- 1  476 Feb 21 16:20 slave-eeprom-backend
  -rw-r--r-- 1 7.7K Feb 21 16:20 slave-interface
  -rw-r--r-- 1 9.3K Feb 21 16:20 smbus-protocol
  -rw-r--r-- 1 1.9K Feb 21 16:20 summary
  -rw-r--r-- 1 1.6K Feb 21 16:20 ten-bit-addresses
  -rw-r--r-- 1 6.8K Feb 21 16:20 upgrading-clients
  -rw-r--r-- 1  15K Feb 21 16:20 writing-clients

The slave-* documentation is at least a starting point.  Let's look at
the diff first.  Current gw_buildroot linux checkout does not have a
.git directory, so find that first maybe?

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git log |head
commit 960d4b4bc998942d0642df2246a79c6cd5e9eb5d
Author: Robert Nelson <robertcnelson@gmail.com>
Date:   Wed Feb 21 15:20:40 2018 -0600

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git blame Documentation/i2c/slave-eeprom-backend
Blaming lines: 100% (14/14), done.
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  1) Linux I2C slave eeprom backend
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  2) ==============================
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  3) 
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  4) by Wolfram Sang <wsa@sang-engineering.com> in 2014-15
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  5) 
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  6) This is a proof-of-concept backend which acts like an EEPROM on the connected
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  7) I2C bus. The memory contents can be modified from userspace via this file
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  8) located in sysfs:
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100  9) 
2e049d6132eb9 (Masanari Iida 2016-02-02 20:41:25 +0900 10) 	/sys/bus/i2c/devices/<device-directory>/slave-eeprom
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100 11) 
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100 12) As of 2015, Linux doesn't support poll on binary sysfs files, so there is no
2e049d6132eb9 (Masanari Iida 2016-02-02 20:41:25 +0900 13) notification when another master changed the content.
d0c892f59c918 (Wolfram Sang  2015-03-23 09:26:38 +0100 14) 

That main patch seems to be only documentation:

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git diff d0c892f59c918~1 d0c892f59c918
diff --git a/Documentation/i2c/slave-eeprom-backend b/Documentation/i2c/slave-eeprom-backend
new file mode 100644
index 000000000000..c8444ef82acf
--- /dev/null
+++ b/Documentation/i2c/slave-eeprom-backend
@@ -0,0 +1,14 @@
+Linux I2C slave eeprom backend
+by Wolfram Sang <wsa@sang-engineering.com> in 2014-15
+This is a proof-of-concept backend which acts like an EEPROM on the connected
+I2C bus. The memory contents can be modified from userspace via this file
+located in sysfs:
+	/sys/bus/i2c/devices/<device-direcory>/slave-eeprom
+As of 2015, Linux doesn't support poll on binary sysfs files, so there is no
+notfication when another master changed the content.

Let's look at the slave c file instead.

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git blame drivers/i2c/i2c-slave-eeprom.c
389be323cfac3 (Wolfram Sang 2014-11-18 17:04:54 +0100   1) /*

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git diff 389be323cfac3~1 389be323cfac3
That is just the eeprom.

Grepping... the following also includes noise.  Second one is better.

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ grep -re I2C_SLAVE .
tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ grep -re I2C_SLAVE_WRITE_REQUESTED .
./Documentation/i2c/slave-interface:* I2C_SLAVE_WRITE_REQUESTED (mandatory)
./drivers/i2c/busses/i2c-emev2.c:			i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED,
./drivers/i2c/busses/i2c-rcar.c:			i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
./drivers/i2c/i2c-slave-eeprom.c:	case I2C_SLAVE_WRITE_REQUESTED:
./include/linux/i2c.h:	I2C_SLAVE_WRITE_REQUESTED,

There is only this implementation:
rcar  Renesas RCar I2C unit
emev2 Renesas EMEV2 SoC

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git blame include/linux/i2c.h |grep I2C_SLAVE_WRITE
5b77d162a3d73 (Wolfram Sang         2015-03-23 09:26:36 +0100 268) 	I2C_SLAVE_WRITE_REQUESTED,
5b77d162a3d73 (Wolfram Sang         2015-03-23 09:26:36 +0100 270) 	I2C_SLAVE_WRITE_RECEIVED,

That's also just a minor patch.

What am I looking for then?

tom@buildroot:/i/buildroot/home/tom/cache/buildroot_dl/linux/git$ git log --pretty=oneline | grep "i2c: slave:"
b4cdaf32ce04366ec143c2255492918c35f58691 Documentation: i2c: slave: give proper example for pm usage
38fa8afff0a99fe8caabbde0d590df3067cf695a Documentation: i2c: slave: describe buffer problems a bit better
c6909d6f6f1082b8bb4c1b0ef3460a005c9dcb4d i2c: slave: print warning if slave flag not set
8366610283d08564f65a1af2ec8458df08418727 i2c: slave: fix the example how to instantiate from userspace
0c7cab96ec413a69af86965d94fb650f01c5887a i2c: slave: add error messages to slave core
976cf2056ccf1be1759f8c122d194c117c879e11 i2c: slave: docs: be more precise about the prerequsites
d0c892f59c918535f902caea63637af87d931d91 i2c: slave: add documentation for i2c-slave-eeprom
5b77d162a3d7359a8a8d83776720da065bf4e77b i2c: slave: rework the slave API

The Shiny New I2C Slave Framework - Wolfram Sang
Wolram is:
- I2C maintainer
- consultant
- part of Renesas kernel team
- There is support for multi-master.  It is tricky though.
- Probably best to just be slave.
- I2C slave events decouples backend (e.g. eeprom) from driver.
- PM: slave needs to be on to listen for address
- developed by shorting 2 busses, one master, one slave
- rcar_reg_slave() : driver support to register slave
- i2c_slave_event() : register backend to slave
- event handlers are called in interrupt context (callback)
- one event per data byte (no buffers)
- address phase is always acknowledged
- data phase ack depends on event handler return value
- assumes clock stretching for flow control
- _READ_PROCESSED is highlevel, so doesn't mean data went out.
- driver side: straightforward, based on what interrupts come in
- "somebody still using platform devices?"
- no use case for user space client events
- see i2c_slave_8bit_seconds_slave_cb,_probe,_remove example
- read pointer problem: if you get another read, the previous one is assumed to be ok
- some davinci code is in private somewhere...