[<<][am335x][>>][..]
Tue Jun 12 11:20:22 EDT 2018

drivers/i2c/busses/i2c-omap.c

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

static int __init
omap_i2c_init_driver(void)
{
	return platform_driver_register(&omap_i2c_driver);
}
subsys_initcall(omap_i2c_init_driver);


How does the kernel know to call that function?
https://stackoverflow.com/questions/8832114/what-does-init-mean-in-the-linux-kernel-code
include/linux/init.h

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
subsys_initcall(omap_i2c_init_driver);
https://stackoverflow.com/questions/15541290/what-is-the-difference-between-module-init-and-subsys-initcall-while-initializin

The next point is
platform_driver_register(&omap_i2c_driver);

  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_irq()
devm_kzalloc()
platform_get_resource(), devm_ioremap_resource()
of_match_device()
platform_set_drvdata()
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
pm_*()


QUESTIONS:

- completion?
  https://www.kernel.org/doc/Documentation/scheduler/completion.txt

- generic i2c driver documentation?

- do i know enough to start looking into slave mode?
  original slave mode patch:
  https://lwn.net/Articles/611332/
  How to look at this particular patch?


  slave eeprom:
  drivers/i2c/i2c-slave-eeprom.c
  drivers/i2c/i2c-core.c

- 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
https://www.youtube.com/watch?v=JdQ21jlwb58
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
- write: _WRITE_REQUESTED, _WRITE_RECEIVED, _STOP
- read: _READ_REQUESTED, _READ_PROCESSED, _STOP
- _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...



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