LEGO MINDSTORMS I2C support
Subsystems (2)
cover LEGO MINDSTORMS I2C support
I'm working on getting LEGO MINDSTORMS[1] support in the Linux kernel.
They have a system of modular sensors that are hot-plugable, some of which use I2C communications. Unfortunately, these don't necessary follow standard I2C conventions, but they do have a well-defined register layout, so they are easy to detect.
This set of patches addresses the hot-plugability of the sensors.
[1]: http://mindstorms.lego.com
David Lechner (3):
i2c: Add class for LEGO MINDSTORMS sensors
i2c: Add special case for detecting LEGO devices
i2c: expose adapter probe and remove probed functions
drivers/i2c/i2c-core.c | 62 ++++++++++++++++++++++++++++++++++++++------------ include/linux/i2c.h | 4 ++++ 2 files changed, 52 insertions(+), 14 deletions(-)
Signature · 1 line
2.7.4
PATCH 1/3 i2c: Add class for LEGO MINDSTORMS sensors
LEGO MINDSTORMS (robotics system from LEGO) has a number of sensors that use I2C communications. These sensors have a well-know register layout, so they are easily detected.
This class is being added so that future drivers for these sensors can be automatically detected.
--- include/linux/i2c.h | 1 + 1 file changed, 1 insertion(+)
include/linux/i2c.h +1 -0
@@ -638,6 +638,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)#define I2C_CLASS_DDC (1<<3)/* DDC bus on graphics adapters */ #define I2C_CLASS_SPD (1<<7)/* Memory modules */ #define I2C_CLASS_DEPRECATED (1<<8)/* Warn users that adapter will stop using classes */ +#define I2C_CLASS_LEGO (1<<9)/* LEGO MINDSTORMS sensors */ /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU
Signature · 1 line
2.7.4
Re: [PATCH 1/3] i2c: Add class for LEGO MINDSTORMS sensors
Hello David,
Quoted 1 line · David Lechner
that use I2C communications. These sensors have a well-know register
s/w/wn/
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ |
PATCH 2/3 i2c: Add special case for detecting LEGO devices
In reply to David LechnerLEGO chose to ignore the I2C specification and has created devices with I2C addresses of 0x01 and 0x02. i2c_check_7bit_addr_validity_strict() disallows these addresses, so we need a special case to skip this for LEGO sensors.
Furthermore, LEGO devices do not respond to i2c_default_probe(), so we skip this as a special case as well.
--- drivers/i2c/i2c-core.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/i2c/i2c-core.c +10 -7
@@ -2591,12 +2591,14 @@ static int i2c_detect_address(struct i2c_client *temp_client,int addr = temp_client->addr;int err; -/* Make sure the address is valid */ - err =i2c_check_7bit_addr_validity_strict (addr); -if (err) { -dev_warn (&adapter->dev,"Invalid probe address 0x%02x\n" , - addr); -return err; +/* Make sure the address is valid - LEGO devices break the rules */ +if (!(driver->class &I2C_CLASS_LEGO )) { + err =i2c_check_7bit_addr_validity_strict (addr); +if (err) { +dev_warn (&adapter->dev,"Invalid probe address 0x%02x\n" , + addr); +return err; + } }/* Skip if already in use (7 bit, no need to encode flags) */
@@ -2604,7 +2606,8 @@ static int i2c_detect_address(struct i2c_client *temp_client,return 0 ;/* Make sure there is something at this address */ -if (!i2c_default_probe (adapter, addr)) +if (!(driver->class &I2C_CLASS_LEGO ) && + !i2c_default_probe (adapter, addr))return 0 ;/* Finally call the custom detection function */
Signature · 1 line
2.7.4
PATCH 3/3 i2c: expose adapter probe and remove probed functions
In reply to David LechnerPublicly expose functions for detecting devices and removing detected devices.
Currently an i2c adapter only probes/detects new devices when the adapter is added or when a new i2c driver is added. This adds a new function, i2c_adapter_probe(), that allows detecting sensors at any time.
Furthermore, the function i2c_adapter_remove_probed() is added to remove the devices added by i2c_adapter_probe() at any time.
The intended use of these functions is for LEGO MINDSTORMS sensors. These are hot-plugable I2C devices. When a sensor is connected, i2c_adapter_probe() is called to automatically configure the sensor. When the sensor is disconnected, i2c_adapter_remove_probed() is called to remove the automatically configured device.
--- drivers/i2c/i2c-core.c | 45 ++++++++++++++++++++++++++++++++++++++------- include/linux/i2c.h | 3 +++ 2 files changed, 41 insertions(+), 7 deletions(-)
drivers/i2c/i2c-core.c +38 -7
@@ -1691,6 +1691,23 @@ static int __process_new_adapter(struct device_driver *d, void *data)return i2c_do_add_adapter (to_i2c_driver (d), data); } +/** +* i2c_adapter_probe - probe adapter for clients +* @adap: The i2c adapter. +* +* This calls the detect function of each driver that matches the class of the +* adapter. This function is called when an adapter is added, so there is no +* need to call this manually, unless you have hot-plugable i2c devices that +* are connected after the adapter is created. +*/ +void i2c_adapter_probe (struct i2c_adapter *adap) +{ +mutex_lock (&core_lock); +bus_for_each_drv (&i2c_bus_type,NULL , adap, __process_new_adapter); +mutex_unlock (&core_lock); +} +EXPORT_SYMBOL (i2c_adapter_probe); +static int i2c_register_adapter (struct i2c_adapter *adap) {int res = -EINVAL ;
@@ -1759,9 +1776,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)i2c_scan_static_board_info (adap);/* Notify drivers */ -mutex_lock (&core_lock); -bus_for_each_drv (&i2c_bus_type,NULL , adap, __process_new_adapter); -mutex_unlock (&core_lock); +i2c_adapter_probe (adap);return 0 ;
@@ -1904,6 +1919,25 @@ static int __process_removed_adapter(struct device_driver *d, void *data) }/** +* i2c_adapter_remove_probed - Remove clients that were automatically detected. +* @adap: The i2c adapter. +* +* This removes all i2c clients from this adapter that were added via driver +* detect() functions. This function is called when an adapter is removed, so +* there is no need to call this manually, unless you have hot-plugable i2c +* devices that are disconnected before the adapter is destroyed. +* +* Any clients that were added manually (e.g. via sysfs) are not removed. +*/ +void i2c_adapter_remove_probed (struct i2c_adapter *adap) +{ +mutex_lock (&core_lock); +bus_for_each_drv (&i2c_bus_type,NULL , adap, __process_removed_adapter); +mutex_unlock (&core_lock); +} +EXPORT_SYMBOL (i2c_adapter_remove_probed); + +/** * i2c_del_adapter - unregister I2C adapter * @adap: the adapter being unregistered * Context: can sleep
@@ -1927,10 +1961,7 @@ void i2c_del_adapter(struct i2c_adapter *adap)acpi_i2c_remove_space_handler (adap);/* Tell drivers about this removal */ -mutex_lock (&core_lock); -bus_for_each_drv (&i2c_bus_type,NULL , adap, - __process_removed_adapter); -mutex_unlock (&core_lock); +i2c_adapter_remove_probed (adap);/* Remove devices instantiated from sysfs */ mutex_lock_nested(&adap->userspace_clients_lock,
include/linux/i2c.h +3 -0
@@ -657,6 +657,9 @@ extern int i2c_add_adapter(struct i2c_adapter *);extern void i2c_del_adapter (struct i2c_adapter *);extern int i2c_add_numbered_adapter (struct i2c_adapter *); +extern void i2c_adapter_probe (struct i2c_adapter *adap); +extern void i2c_adapter_remove_probed (struct i2c_adapter *adap); +extern int i2c_register_driver (struct module *,struct i2c_driver *);extern void i2c_del_driver (struct i2c_driver *);
Signature · 1 line
2.7.4
Re: [PATCH 3/3] i2c: expose adapter probe and remove probed functions
Quoted 6 lines
The intended use of these functions is for LEGO MINDSTORMS sensors. These are hot-plugable I2C devices. When a sensor is connected,
i2c_adapter_probe()is called to automatically configure the sensor. When the sensor is disconnected,i2c_adapter_remove_probed()is called to remove the automatically configured device.
How do you detect the hot-plug events?
Re: [PATCH 3/3] i2c: expose adapter probe and remove probed functions
Quoted 9 lines · Wolfram Sang
Quoted 6 lines
The intended use of these functions is for LEGO MINDSTORMS sensors. These are hot-plugable I2C devices. When a sensor is connected,
i2c_adapter_probe()is called to automatically configure the sensor. When the sensor is disconnected,i2c_adapter_remove_probed()is called to remove the automatically configured device.How do you detect the hot-plug events?
There are "port" drivers that do this. An I2C adapter is assigned to each port via device-tree or platform data struct.
Port driver code if you are interested:
- https://github.com/ev3dev/lego-linux-drivers/blob/master/ev3/legoev3_ports_in.c
- https://github.com/ev3dev/lego-linux-drivers/blob/master/evb/evb_ports_in.c
In particular, here is where we call the new i2c_adapter_probe() function: https://github.com/ev3dev/lego-linux-drivers/blob/master/evb/evb_ports_in.c#L543
Quoted 10 lines · David Lechner
I'm working on getting LEGO MINDSTORMS[1] support in the Linux kernel.
They have a system of modular sensors that are hot-plugable, some of which use I2C communications. Unfortunately, these don't necessary follow standard I2C conventions, but they do have a well-defined register layout, so they are easy to detect.
This set of patches addresses the hot-plugability of the sensors.
Thanks!
For a review, I'd need users of this functionality. In this case, a master driver and probably a sensor driver. Can any regular I2C master talk to these devices if they support talking to addresses 0x00-0x7f? My first impression is that using a class is not the proper approach because classes were used to limit access to devices, not to extend. However, I'd need to see more code to check if that holds true.
Thanks,
Wolfram
Quoted 8 lines · Wolfram Sang
Quoted 7 lines · David Lechner
I'm working on getting LEGO MINDSTORMS[1] support in the Linux kernel.
They have a system of modular sensors that are hot-plugable, some of which use I2C communications. Unfortunately, these don't necessary follow standard I2C conventions, but they do have a well-defined register layout, so they are easy to detect.
Quoted 8 lines
Quoted 3 lines
This set of patches addresses the hot-plugability of the sensors.
Thanks!
For a review, I'd need users of this functionality. In this case, a master driver and probably a sensor driver.
Work in progress drivers:
master: https://github.com/ev3dev/lego-linux-drivers/blob/master/ev3/legoev3_i2c.c
master: https://github.com/ev3dev/lego-linux-drivers/blob/master/evb/evb_pru_i2c.c
sensor: https://github.com/ev3dev/lego-linux-drivers/blob/master/sensors/nxt_i2c_sensor_core.c
Quoted 2 lines
Can any regular I2C master
talk to these devices if they support talking to addresses 0x00-0x7f?
Yes. I've tested this with the SoC I2C on Raspberry Pi. There are several 3rd party LEGO MINDSTORMS compatible addon boards for RPi that use the SoC I2C with LEGO sensors, which is part of my motivation for this patchset.
Quoted 4 lines
My first impression is that using a class is not the proper approach because classes were used to limit access to devices, not to extend. However, I'd need to see more code to check if that holds true.
I'm certainly open to other suggestions. This just seemed like the obvious way to me.