I2C GPIO to use gpiolibs open drain
Subsystems (11)
cover I2C GPIO to use gpiolibs open drain
This augments the I2C GPIO driver to use open drain emulation or hardware support for open drain from the GPIO driver.
This version layers Geert Uytterhoeven's idea to use explicit sda-gpios and scl-gpios for the GPIO lines, and strongly encourage the (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) flags to be used in all device trees.
We have collected ACKs from the ARM SoC maintainers and the MFD maintainer and are looking for testers to try this out.
Geert Uytterhoeven (1):
dt-bindings: i2c: i2c-gpio: Add support for named gpios
Linus Walleij (6):
i2c: gpio: Convert to use descriptors
gpio: Make it possible for consumers to enforce open drain
i2c: gpio: Enforce open drain through gpiolib
i2c: gpio: Augment all boardfiles to use open drain
i2c: gpio: Local vars in probe
i2c: gpio: Add support for named gpios in DT
Documentation/devicetree/bindings/i2c/i2c-gpio.txt | 32 +++- arch/arm/mach-ep93xx/core.c | 41 ++-- arch/arm/mach-ep93xx/edb93xx.c | 15 +- arch/arm/mach-ep93xx/include/mach/platform.h | 4 +- arch/arm/mach-ep93xx/simone.c | 12 +- arch/arm/mach-ep93xx/snappercl15.c | 12 +- arch/arm/mach-ep93xx/vision_ep9307.c | 7 +- arch/arm/mach-ixp4xx/avila-setup.c | 17 +- arch/arm/mach-ixp4xx/dsmg600-setup.c | 16 +- arch/arm/mach-ixp4xx/fsg-setup.c | 16 +- arch/arm/mach-ixp4xx/goramo_mlr.c | 24 +-- arch/arm/mach-ixp4xx/ixdp425-setup.c | 16 +- arch/arm/mach-ixp4xx/nas100d-setup.c | 16 +- arch/arm/mach-ixp4xx/nslu2-setup.c | 16 +- arch/arm/mach-ks8695/board-acs5k.c | 15 +- arch/arm/mach-pxa/palmz72.c | 14 +- arch/arm/mach-pxa/viper.c | 27 ++- arch/arm/mach-sa1100/simpad.c | 14 +- arch/blackfin/mach-bf533/boards/blackstamp.c | 19 +- arch/blackfin/mach-bf533/boards/ezkit.c | 18 +- arch/blackfin/mach-bf533/boards/stamp.c | 18 +- arch/blackfin/mach-bf561/boards/ezkit.c | 18 +- arch/mips/alchemy/board-gpr.c | 23 ++- arch/mips/ath79/mach-pb44.c | 16 +- drivers/gpio/gpiolib.c | 13 ++ drivers/i2c/busses/i2c-gpio.c | 213 ++++++++++----------- drivers/mfd/sm501.c | 49 ++--- include/linux/gpio/consumer.h | 6 + include/linux/i2c-gpio.h | 4 - 29 files changed, 423 insertions(+), 288 deletions(-)
Signature · 1 line
2.13.5
PATCH 1/7 i2c: gpio: Convert to use descriptors
This converts the GPIO-based I2C-driver to using GPIO descriptors instead of the old global numberspace-based GPIO interface. We:
- Convert the driver to unconditionally grab two GPIOs from the device by index 0 (SDA) and 1 (SCL) which will work fine with device tree and descriptor tables. The existing device trees will continue to work just like before, but without any roundtrip through the global numberspace.
- Brutally convert all boardfiles still passing global GPIOs by registering descriptor tables associated with the devices instead so this driver does not need to keep supporting passing any GPIO numbers as platform data.
There is no stepwise approach as elegant as this, I strongly prefer this big hammer over any antsteps for this conversion. This way the old GPIO numbers go away and NEVER COME BACK.
Special conversion for the different boards utilizing I2C-GPIO:
- EP93xx (arch/arm/mach-ep93xx): pretty straight forward as all boards were using the same two GPIO lines, just define these two in a lookup table for "i2c-gpio" and register these along with the device. None of them define any other platform data so just pass NULL as platform data. This platform selects GPIOLIB so all should be smooth. The pins appear on a gpiochip for bank "G" as pins 1 (SDA) and 0 (SCL).
- IXP4 (arch/arm/mach-ixp4): descriptor tables have to be registered for each board separately. They all use "IXP4XX_GPIO_CHIP" so it is pretty straight forward. Most board define no other platform data than SCL/SDA so they can drop the #include of <linux/i2c-gpio.h> and assign NULL to platform data.
The "goramo_mlr" (Goramo Multilink Router) board is a bit
worrisome: it implements its own I2C bit-banging in the board file, and optionally registers an I2C serial port, but claims the same GPIO lines for itself in the board file. This is not going to work: there will be competition for the GPIO lines, so delete the optional extra I2C bus instead, no I2C devices are registered on it anyway, there are just hints that it may contain an EEPROM that may be accessed from userspace. This needs to be fixed up properly by the serial clock using I2C emulation so drop a note in the code.
- KS8695 board acs5k (arch/arm/mach-ks8695/board-acs5.c) has some platform data in addition to the pins so it needs to be kept around sans GPIO lines. Its GPIO chip is named "KS8695" and the arch selects GPIOLIB.
- PXA boards (arch/arm/mach-pxa/*) use some of the platform data so it needs to be preserved here. The viper board even registers two GPIO I2Cs. The gpiochip is named "gpio-pxa" and the arch selects GPIOLIB.
- SA1100 Simpad (arch/arm/mach-sa1100/simpad.c) defines a GPIO I2C bus, and the arch selects GPIOLIB.
- Blackfin boards (arch/blackfin/bf533 etc) for these I assume their I2C GPIOs refer to the local gpiochip defined in arch/blackfin/kernel/bfin_gpio.c names "BFIN-GPIO". The arch selects GPIOLIB. The boards get spiked with IF_ENABLED(I2C_GPIO) but that is a side effect of it being like that already (I would just have Kconfig select I2C_GPIO and get rid of them all.) I also delete any platform data set to 0 as it will get that value anyway from static declartions of platform data.
- The MIPS selects GPIOLIB and the Alchemy machine is using two local GPIO chips, one of them has a GPIO I2C. We need to adjust the local offset from the global number space here. The ATH79 has a proper GPIO driver in drivers/gpio/gpio-ath79.c and AFAICT the chip is named "ath79-gpio" and the PB44 PCF857x expander spawns from this on GPIO 1 and 0. The latter board only use the platform data to specify pins so it can be cut altogether after this.
- The MFD Silicon Motion SM501 is a special case. It dynamically spawns an I2C bus off the MFD using sm501_create_subdev(). We use an approach to dynamically create a machine descriptor table and attach this to the "SM501-LOW" or "SM501-HIGH" gpiochip. We use chip-local offsets to grab the right lines. We can get rid of two local static inline helpers as part of this refactoring.
---
ChangeLog v1->v2:
- Fix a minor typo in error path (scl was sda from copy-paste)
- Collected Olof's ACK
Steven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
Lee: requesting ACK for Wolfram to take this patch. SM501 users: requesting Tested-by on this patch.
--- arch/arm/mach-ep93xx/core.c | 39 ++++---- arch/arm/mach-ep93xx/edb93xx.c | 15 +-- arch/arm/mach-ep93xx/include/mach/platform.h | 4 +- arch/arm/mach-ep93xx/simone.c | 12 +-- arch/arm/mach-ep93xx/snappercl15.c | 12 +-- arch/arm/mach-ep93xx/vision_ep9307.c | 7 +- arch/arm/mach-ixp4xx/avila-setup.c | 17 +++- arch/arm/mach-ixp4xx/dsmg600-setup.c | 16 +++- arch/arm/mach-ixp4xx/fsg-setup.c | 16 +++- arch/arm/mach-ixp4xx/goramo_mlr.c | 24 ++--- arch/arm/mach-ixp4xx/ixdp425-setup.c | 16 +++- arch/arm/mach-ixp4xx/nas100d-setup.c | 16 +++- arch/arm/mach-ixp4xx/nslu2-setup.c | 16 +++- arch/arm/mach-ks8695/board-acs5k.c | 13 ++- arch/arm/mach-pxa/palmz72.c | 12 ++- arch/arm/mach-pxa/viper.c | 27 +++++- arch/arm/mach-sa1100/simpad.c | 12 ++- arch/blackfin/mach-bf533/boards/blackstamp.c | 19 +++- arch/blackfin/mach-bf533/boards/ezkit.c | 18 +++- arch/blackfin/mach-bf533/boards/stamp.c | 18 +++- arch/blackfin/mach-bf561/boards/ezkit.c | 18 +++- arch/mips/alchemy/board-gpr.c | 19 +++- arch/mips/ath79/mach-pb44.c | 16 +++- drivers/i2c/busses/i2c-gpio.c | 134 +++++++++++++-------------- drivers/mfd/sm501.c | 49 +++++----- include/linux/i2c-gpio.h | 4 - 26 files changed, 327 insertions(+), 242 deletions(-)
arch/arm/mach-ep93xx/core.c +21 -18
@@ -31,7 +31,7 @@#include <linux/amba/serial.h> #include <linux/mtd/physmap.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/spi/spi.h> #include <linux/export.h> #include <linux/irqchip/arm-vic.h>
@@ -320,42 +320,45 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)/************************************************************************* * EP93xx i2c peripheral handling *************************************************************************/ -static struct i2c_gpio_platform_data ep93xx_i2c_data; + +/* All EP93xx devices use the same two GPIO pins for I2C bit-banging */ +static struct gpiod_lookup_table ep93xx_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +/* Use local offsets on gpiochip/port "G" */ +GPIO_LOOKUP_IDX ("G" ,1 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("G" ,0 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, +};static struct platform_device ep93xx_i2c_device = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &ep93xx_i2c_data, + .platform_data =NULL , }, };/** * ep93xx_register_i2c - Register the i2c platform device. -* @data: platform specific i2c-gpio configuration (__initdata) * @devices: platform specific i2c bus device information (__initdata) * @num: the number of devices on the i2c bus */ -void __init ep93xx_register_i2c (struct i2c_gpio_platform_data *data, -struct i2c_board_info *devices,int num) +void __init ep93xx_register_i2c (struct i2c_board_info *devices,int num) {/* -* Set the EEPROM interface pin drive type control. -* Defines the driver type for the EECLK and EEDAT pins as either -* open drain, which will require an external pull-up, or a normal -* CMOS driver. +* FIXME: this just sets the two pins as non-opendrain, as no +* platforms tries to do that anyway. Flag the applicable lines +* as open drain in the GPIO_LOOKUP above and the driver or +* gpiolib will handle open drain/open drain emulation as need +* be. Right now i2c-gpio emulates open drain which is not +* optimal. */ -if (data->sda_is_open_drain && data->sda_pin !=EP93XX_GPIO_LINE_EEDAT ) -pr_warning ("sda != EEDAT, open drain has no effect\n" ); -if (data->scl_is_open_drain && data->scl_pin !=EP93XX_GPIO_LINE_EECLK ) -pr_warning ("scl != EECLK, open drain has no effect\n" ); - -__raw_writel ((data->sda_is_open_drain <<1 ) | - (data->scl_is_open_drain <<0 ), +__raw_writel ((0 <<1 ) | (0 <<0 ),EP93XX_GPIO_EEDRIVE ); - ep93xx_i2c_data = *data;i2c_register_board_info (0 , devices, num); +gpiod_add_lookup_table (&ep93xx_i2c_gpiod_table);platform_device_register (&ep93xx_i2c_device); }
arch/arm/mach-ep93xx/edb93xx.c +2 -13
@@ -28,7 +28,6 @@#include <linux/init.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> #include <linux/spi/spi.h> #include <sound/cs4271.h>
@@ -61,14 +60,6 @@ static struct ep93xx_eth_data __initdata edb93xx_eth_data = {/************************************************************************* * EDB93xx i2c peripheral handling *************************************************************************/ -static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = { - .sda_pin =EP93XX_GPIO_LINE_EEDAT , - .sda_is_open_drain =0 , - .scl_pin =EP93XX_GPIO_LINE_EECLK , - .scl_is_open_drain =0 , - .udelay =0 ,/* default to 100 kHz */ - .timeout =0 ,/* default to 100 ms */ -};static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = { {
@@ -86,13 +77,11 @@ static void __init edb93xx_register_i2c(void) {if (machine_is_edb9302a () ||machine_is_edb9307a () ||machine_is_edb9315a ()) { -ep93xx_register_i2c (&edb93xx_i2c_gpio_data, - edb93xxa_i2c_board_info, +ep93xx_register_i2c (edb93xxa_i2c_board_info,ARRAY_SIZE (edb93xxa_i2c_board_info)); }else if (machine_is_edb9302 () ||machine_is_edb9307 () ||machine_is_edb9312 () ||machine_is_edb9315 ()) { -ep93xx_register_i2c (&edb93xx_i2c_gpio_data, - edb93xx_i2c_board_info, +ep93xx_register_i2c (edb93xx_i2c_board_info,ARRAY_SIZE (edb93xx_i2c_board_info)); } }
arch/arm/mach-ep93xx/include/mach/platform.h +1 -3
@@ -7,7 +7,6 @@#include <linux/reboot.h> struct device ; -struct i2c_gpio_platform_data ;struct i2c_board_info ;struct spi_board_info ;struct platform_device ;
@@ -36,8 +35,7 @@ void ep93xx_register_flash(unsigned int width, resource_size_t start, resource_size_t size);void ep93xx_register_eth (struct ep93xx_eth_data *data,int copy_addr); -void ep93xx_register_i2c (struct i2c_gpio_platform_data *data, -struct i2c_board_info *devices,int num); +void ep93xx_register_i2c (struct i2c_board_info *devices,int num);void ep93xx_register_spi (struct ep93xx_spi_info *info,struct spi_board_info *devices,int num);void ep93xx_register_fb (struct ep93xxfb_mach_info *data);
arch/arm/mach-ep93xx/simone.c +1 -11
@@ -19,7 +19,6 @@#include <linux/init.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> #include <linux/mmc/host.h> #include <linux/spi/spi.h> #include <linux/spi/mmc_spi.h>
@@ -129,15 +128,6 @@ static struct ep93xx_spi_info simone_spi_info __initdata = { .use_dma = 1, }; -static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { - .sda_pin =EP93XX_GPIO_LINE_EEDAT , - .sda_is_open_drain =0 , - .scl_pin =EP93XX_GPIO_LINE_EECLK , - .scl_is_open_drain =0 , - .udelay =0 , - .timeout =0 , -}; -static struct i2c_board_info __initdata simone_i2c_board_info[] = { {I2C_BOARD_INFO ("ds1337" ,0x68 ),
@@ -161,7 +151,7 @@ static void __init simone_init_machine(void)ep93xx_register_flash (2 ,EP93XX_CS6_PHYS_BASE ,SZ_8M );ep93xx_register_eth (&simone_eth_data,1 );ep93xx_register_fb (&simone_fb_info); -ep93xx_register_i2c (&simone_i2c_gpio_data, simone_i2c_board_info, +ep93xx_register_i2c (simone_i2c_board_info,ARRAY_SIZE (simone_i2c_board_info));ep93xx_register_spi (&simone_spi_info, simone_spi_devices,ARRAY_SIZE (simone_spi_devices));
arch/arm/mach-ep93xx/snappercl15.c +1 -11
@@ -21,7 +21,6 @@#include <linux/init.h> #include <linux/io.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> #include <linux/fb.h> #include <linux/mtd/partitions.h>
@@ -127,15 +126,6 @@ static struct ep93xx_eth_data __initdata snappercl15_eth_data = { .phy_id = 1, }; -static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = { - .sda_pin =EP93XX_GPIO_LINE_EEDAT , - .sda_is_open_drain =0 , - .scl_pin =EP93XX_GPIO_LINE_EECLK , - .scl_is_open_drain =0 , - .udelay =0 , - .timeout =0 , -}; -static struct i2c_board_info __initdata snappercl15_i2c_data[] = { {/* Audio codec */
@@ -161,7 +151,7 @@ static void __init snappercl15_init_machine(void) {ep93xx_init_devices ();ep93xx_register_eth (&snappercl15_eth_data,1 ); -ep93xx_register_i2c (&snappercl15_i2c_gpio_data, snappercl15_i2c_data, +ep93xx_register_i2c (snappercl15_i2c_data,ARRAY_SIZE (snappercl15_i2c_data));ep93xx_register_fb (&snappercl15_fb_info);snappercl15_register_audio ();
arch/arm/mach-ep93xx/vision_ep9307.c +1 -6
@@ -22,7 +22,6 @@#include <linux/io.h> #include <linux/mtd/partitions.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> #include <linux/platform_data/pca953x.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h>
@@ -144,10 +143,6 @@ static struct pca953x_platform_data pca953x_77_gpio_data = {/************************************************************************* * I2C Bus *************************************************************************/ -static struct i2c_gpio_platform_data vision_i2c_gpio_data__initdata = { - .sda_pin =EP93XX_GPIO_LINE_EEDAT , - .scl_pin =EP93XX_GPIO_LINE_EECLK , -};static struct i2c_board_info vision_i2c_info[]__initdata = { {
@@ -289,7 +284,7 @@ static void __init vision_init_machine(void) vision_i2c_info[1 ].irq =gpio_to_irq (EP93XX_GPIO_LINE_F (7 )); -ep93xx_register_i2c (&vision_i2c_gpio_data, vision_i2c_info, +ep93xx_register_i2c (vision_i2c_info,ARRAY_SIZE (vision_i2c_info));ep93xx_register_spi (&vision_spi_master, vision_spi_board_info,ARRAY_SIZE (vision_spi_board_info));
arch/arm/mach-ixp4xx/avila-setup.c +12 -5
@@ -17,7 +17,7 @@#include <linux/serial.h> #include <linux/tty.h> #include <linux/serial_8250.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <asm/types.h> #include <asm/setup.h> #include <asm/memory.h>
@@ -49,16 +49,21 @@ static struct platform_device avila_flash = { .resource = &avila_flash_resource, }; -static struct i2c_gpio_platform_data avila_i2c_gpio_data = { - .sda_pin =AVILA_SDA_PIN , - .scl_pin =AVILA_SCL_PIN , +static struct gpiod_lookup_table avila_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,AVILA_SDA_PIN , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,AVILA_SCL_PIN , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct platform_device avila_i2c_gpio = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &avila_i2c_gpio_data, + .platform_data =NULL , }, };
@@ -147,6 +152,8 @@ static void __init avila_init(void) avila_flash_resource.end =IXP4XX_EXP_BUS_BASE (0 ) + ixp4xx_exp_bus_size -1 ; +gpiod_add_lookup_table (&avila_i2c_gpiod_table); +platform_add_devices (avila_devices,ARRAY_SIZE (avila_devices)); avila_pata_resources[0 ].start =IXP4XX_EXP_BUS_BASE (1 );
arch/arm/mach-ixp4xx/dsmg600-setup.c +11 -5
@@ -25,7 +25,7 @@#include <linux/leds.h> #include <linux/reboot.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h>
@@ -68,16 +68,21 @@ static struct platform_device dsmg600_flash = { .resource = &dsmg600_flash_resource, }; -static struct i2c_gpio_platform_data dsmg600_i2c_gpio_data = { - .sda_pin =DSMG600_SDA_PIN , - .scl_pin =DSMG600_SCL_PIN , +static struct gpiod_lookup_table dsmg600_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,DSMG600_SDA_PIN , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,DSMG600_SCL_PIN , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct platform_device dsmg600_i2c_gpio = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &dsmg600_i2c_gpio_data, + .platform_data =NULL , }, };
@@ -269,6 +274,7 @@ static void __init dsmg600_init(void) dsmg600_flash_resource.end =IXP4XX_EXP_BUS_BASE (0 ) + ixp4xx_exp_bus_size -1 ; +gpiod_add_lookup_table (&dsmg600_i2c_gpiod_table);i2c_register_board_info (0 , dsmg600_i2c_board_info,ARRAY_SIZE (dsmg600_i2c_board_info));
arch/arm/mach-ixp4xx/fsg-setup.c +11 -5
@@ -22,7 +22,7 @@#include <linux/leds.h> #include <linux/reboot.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/io.h> #include <asm/mach-types.h> #include <asm/mach/arch.h>
@@ -54,16 +54,21 @@ static struct platform_device fsg_flash = { .resource = &fsg_flash_resource, }; -static struct i2c_gpio_platform_data fsg_i2c_gpio_data = { - .sda_pin =FSG_SDA_PIN , - .scl_pin =FSG_SCL_PIN , +static struct gpiod_lookup_table fsg_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,FSG_SDA_PIN , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,FSG_SCL_PIN , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct platform_device fsg_i2c_gpio = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &fsg_i2c_gpio_data, + .platform_data =NULL , }, };
@@ -196,6 +201,7 @@ static void __init fsg_init(void)/* Configure CS2 for operation, 8bit and writable */ *IXP4XX_EXP_CS2 =0xbfff0002 ; +gpiod_add_lookup_table (&fsg_i2c_gpiod_table);i2c_register_board_info (0 , fsg_i2c_board_info,ARRAY_SIZE (fsg_i2c_board_info));
arch/arm/mach-ixp4xx/goramo_mlr.c +6 -18
@@ -6,7 +6,6 @@#include <linux/delay.h> #include <linux/gpio.h> #include <linux/hdlc.h> -#include <linux/i2c-gpio.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/kernel.h>
@@ -78,6 +77,12 @@static u32 hw_bits =0xFFFFFFFD ;/* assume all hardware present */ ;static u8 control_value; +/* +* FIXME: this is reimplementing I2C bit-bangining. Move this +* over to using driver/i2c/busses/i2c-gpio.c like all other boards +* and register proper I2C device(s) on the bus for this. (See +* other IXP4xx boards for examples.) +*/ static void set_scl (u8 value) {gpio_set_value (GPIO_SCL , !!value);
@@ -216,20 +221,6 @@ static struct platform_device device_flash = { .resource = &flash_resource, }; - -/* I^2C interface */ -static struct i2c_gpio_platform_data i2c_data = { - .sda_pin =GPIO_SDA , - .scl_pin =GPIO_SCL , -}; - -static struct platform_device device_i2c = { - .name ="i2c-gpio" , - .id =0 , - .dev = { .platform_data = &i2c_data }, -}; - -/* IXP425 2 UART ports */ static struct resource uart_resources[] = { {
@@ -411,9 +402,6 @@ static void __init gmlr_init(void)if (hw_bits &CFG_HW_HAS_HSS1 ) device_tab[devices++] = &device_hss_tab[1 ];/* max index 5 */ -if (hw_bits &CFG_HW_HAS_EEPROM ) - device_tab[devices++] = &device_i2c;/* max index 6 */ -gpio_request (GPIO_SCL ,"SCL/clock" );gpio_request (GPIO_SDA ,"SDA/data" );gpio_request (GPIO_STR ,"strobe" );
arch/arm/mach-ixp4xx/ixdp425-setup.c +11 -5
@@ -14,7 +14,7 @@#include <linux/serial.h> #include <linux/tty.h> #include <linux/serial_8250.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/io.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h>
@@ -122,16 +122,21 @@ static struct platform_device ixdp425_flash_nand = { };#endif /* CONFIG_MTD_NAND_PLATFORM */ -static struct i2c_gpio_platform_data ixdp425_i2c_gpio_data = { - .sda_pin =IXDP425_SDA_PIN , - .scl_pin =IXDP425_SCL_PIN , +static struct gpiod_lookup_table ixdp425_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,IXDP425_SDA_PIN , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,IXDP425_SCL_PIN , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct platform_device ixdp425_i2c_gpio = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &ixdp425_i2c_gpio_data, + .platform_data =NULL , }, };
@@ -245,6 +250,7 @@ static void __init ixdp425_init(void) ixdp425_uart_data[1 ].flags =0 ; } +gpiod_add_lookup_table (&ixdp425_i2c_gpiod_table);platform_add_devices (ixdp425_devices,ARRAY_SIZE (ixdp425_devices)); }
arch/arm/mach-ixp4xx/nas100d-setup.c +11 -5
@@ -27,7 +27,7 @@#include <linux/leds.h> #include <linux/reboot.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/io.h> #include <asm/mach-types.h> #include <asm/mach/arch.h>
@@ -100,16 +100,21 @@ static struct platform_device nas100d_leds = { .dev.platform_data = &nas100d_led_data, }; -static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = { - .sda_pin =NAS100D_SDA_PIN , - .scl_pin =NAS100D_SCL_PIN , +static struct gpiod_lookup_table nas100d_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NAS100D_SDA_PIN , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NAS100D_SCL_PIN , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct platform_device nas100d_i2c_gpio = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &nas100d_i2c_gpio_data, + .platform_data =NULL , }, };
@@ -280,6 +285,7 @@ static void __init nas100d_init(void) nas100d_flash_resource.end =IXP4XX_EXP_BUS_BASE (0 ) + ixp4xx_exp_bus_size -1 ; +gpiod_add_lookup_table (&nas100d_i2c_gpiod_table);i2c_register_board_info (0 , nas100d_i2c_board_info,ARRAY_SIZE (nas100d_i2c_board_info));
arch/arm/mach-ixp4xx/nslu2-setup.c +11 -5
@@ -24,7 +24,7 @@#include <linux/leds.h> #include <linux/reboot.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/io.h> #include <asm/mach-types.h> #include <asm/mach/arch.h>
@@ -68,9 +68,14 @@ static struct platform_device nslu2_flash = { .resource = &nslu2_flash_resource, }; -static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = { - .sda_pin =NSLU2_SDA_PIN , - .scl_pin =NSLU2_SCL_PIN , +static struct gpiod_lookup_table nslu2_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NSLU2_SDA_PIN , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NSLU2_SCL_PIN , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
@@ -115,7 +120,7 @@ static struct platform_device nslu2_i2c_gpio = { .name = "i2c-gpio", .id = 0, .dev = { - .platform_data = &nslu2_i2c_gpio_data, + .platform_data = NULL, }, };
@@ -250,6 +255,7 @@ static void __init nslu2_init(void) nslu2_flash_resource.end =IXP4XX_EXP_BUS_BASE (0 ) + ixp4xx_exp_bus_size -1 ; +gpiod_add_lookup_table (&nslu2_i2c_gpiod_table);i2c_register_board_info (0 , nslu2_i2c_board_info,ARRAY_SIZE (nslu2_i2c_board_info));
arch/arm/mach-ks8695/board-acs5k.c +10 -3
@@ -16,7 +16,7 @@#include <linux/interrupt.h> #include <linux/init.h> #include <linux/platform_device.h> - +#include <linux/gpio/machine.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include <linux/i2c-gpio.h>
@@ -38,9 +38,15 @@#include "generic.h" +static struct gpiod_lookup_table acs5k_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("KS8695" ,4 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("KS8695" ,5 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = { - .sda_pin =4 , - .scl_pin =5 , .udelay =10 , };
@@ -95,6 +101,7 @@ static struct i2c_board_info acs5k_i2c_devs[] __initdata = {static void acs5k_i2c_init (void ) {/* The gpio interface */ +gpiod_add_lookup_table (&acs5k_i2c_gpiod_table);platform_device_register (&acs5k_i2c_device);/* I2C devices */ i2c_register_board_info(0, acs5k_i2c_devs,
arch/arm/mach-pxa/palmz72.c +10 -2
@@ -31,6 +31,7 @@#include <linux/power_supply.h> #include <linux/usb/gpio_vbus.h> #include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <asm/mach-types.h> #include <asm/suspend.h>
@@ -320,9 +321,15 @@ static struct soc_camera_link palmz72_iclink = { .flags = SOCAM_DATAWIDTH_8, }; +static struct gpiod_lookup_table palmz72_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("gpio-pxa" ,118 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("gpio-pxa" ,117 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data palmz72_i2c_bus_data = { - .sda_pin =118 , - .scl_pin =117 , .udelay =10 , .timeout =100 , };
@@ -369,6 +376,7 @@ static void __init palmz72_camera_init(void) {palmz72_cam_gpio_init ();pxa_set_camera_info (&palmz72_pxacamera_platform_data); +gpiod_add_lookup_table (&palmz72_i2c_gpiod_table);platform_device_register (&palmz72_i2c_bus_device);platform_device_register (&palmz72_camera); }
arch/arm/mach-pxa/viper.c +23 -4
@@ -36,6 +36,7 @@#include <linux/gpio.h> #include <linux/jiffies.h> #include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/i2c/pxa-i2c.h> #include <linux/serial_8250.h> #include <linux/smc91x.h>
@@ -458,9 +459,17 @@ static struct platform_device smc91x_device = { };/* i2c */ +static struct gpiod_lookup_table viper_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_RTC_I2C_SDA_GPIO , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_RTC_I2C_SCL_GPIO , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data i2c_bus_data = { - .sda_pin =VIPER_RTC_I2C_SDA_GPIO , - .scl_pin =VIPER_RTC_I2C_SCL_GPIO , .udelay =10 , .timeout =HZ , };
@@ -779,12 +788,20 @@ static int __init viper_tpm_setup(char *str)__setup ("tpm=" , viper_tpm_setup); +struct gpiod_lookup_table viper_tpm_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_TPM_I2C_SDA_GPIO , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_TPM_I2C_SCL_GPIO , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, +}; +static void __init viper_tpm_init (void ) {struct platform_device *tpm_device;struct i2c_gpio_platform_data i2c_tpm_data = { - .sda_pin =VIPER_TPM_I2C_SDA_GPIO , - .scl_pin =VIPER_TPM_I2C_SCL_GPIO , .udelay =10 , .timeout =HZ , };
@@ -794,6 +811,7 @@ static void __init viper_tpm_init(void)if (!viper_tpm)return ; +gpiod_add_lookup_table (&viper_tpm_i2c_gpiod_table); tpm_device =platform_device_alloc ("i2c-gpio" ,2 ); if (tpm_device) { if (!platform_device_add_data(tpm_device,
@@ -943,6 +961,7 @@ static void __init viper_init(void) smc91x_device.num_resources--;pxa_set_i2c_info (NULL ); +gpiod_add_lookup_table (&viper_i2c_gpiod_table);pwm_add_table (viper_pwm_lookup,ARRAY_SIZE (viper_pwm_lookup));platform_add_devices (viper_devs,ARRAY_SIZE (viper_devs));
arch/arm/mach-sa1100/simpad.c +10 -2
@@ -16,6 +16,7 @@#include <linux/mtd/partitions.h> #include <linux/io.h> #include <linux/gpio/driver.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <asm/setup.h>
@@ -323,9 +324,15 @@ static struct platform_device simpad_gpio_leds = {/* * i2c */ +static struct gpiod_lookup_table simpad_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("gpio" ,GPIO_GPIO21 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("gpio" ,GPIO_GPIO25 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data simpad_i2c_data = { - .sda_pin =GPIO_GPIO21 , - .scl_pin =GPIO_GPIO25 , .udelay =10 , .timeout =HZ , };
@@ -380,6 +387,7 @@ static int __init simpad_init(void) ARRAY_SIZE(simpad_flash_resources));sa11x0_register_mcp (&simpad_mcp_data); +gpiod_add_lookup_table (&simpad_i2c_gpiod_table); ret =platform_add_devices (devices,ARRAY_SIZE (devices));if (ret)printk (KERN_WARNING "simpad: Unable to register mq200 framebuffer device" );
arch/blackfin/mach-bf533/boards/blackstamp.c +14 -5
@@ -22,6 +22,7 @@#include <linux/irq.h> #include <linux/gpio.h> #include <linux/i2c.h> +#include <linux/gpio/machine.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> #include <asm/portmux.h>
@@ -362,11 +363,17 @@ static struct platform_device bfin_device_gpiokeys = {#if IS_ENABLED (CONFIG_I2C_GPIO )#include <linux/i2c-gpio.h> +static struct gpiod_lookup_table bfin_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF8 ,NULL ,0 , +GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF9 ,NULL ,1 , +GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin =GPIO_PF8 , - .scl_pin =GPIO_PF9 , - .sda_is_open_drain =0 , - .scl_is_open_drain =0 , .udelay =40 , };/* This hasn't actually been used these pins * are (currently) free pins on the expansion connector */
@@ -462,7 +469,9 @@ static int __init blackstamp_init(void)int ret;printk (KERN_INFO "%s(): registering device resources\n" , __func__); - +#if IS_ENABLED (CONFIG_I2C_GPIO ) +gpiod_add_lookup_table (&bfin_i2c_gpiod_table); +#endif i2c_register_board_info (0 , bfin_i2c_board_info,ARRAY_SIZE (bfin_i2c_board_info));
arch/blackfin/mach-bf533/boards/ezkit.c +14 -4
@@ -19,6 +19,7 @@#endif #include <linux/irq.h> #include <linux/i2c.h> +#include <linux/gpio/machine.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> #include <asm/portmux.h>
@@ -390,11 +391,17 @@ static struct platform_device bfin_device_gpiokeys = {#if IS_ENABLED (CONFIG_I2C_GPIO )#include <linux/i2c-gpio.h> +static struct gpiod_lookup_table bfin_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF1 ,NULL ,0 , +GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF0 ,NULL ,1 , +GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin =GPIO_PF1 , - .scl_pin =GPIO_PF0 , - .sda_is_open_drain =0 , - .scl_is_open_drain =0 , .udelay =40 , };
@@ -516,6 +523,9 @@ static struct platform_device *ezkit_devices[] __initdata = {static int __init ezkit_init (void ) {printk (KERN_INFO "%s(): registering device resources\n" , __func__); +#if IS_ENABLED (CONFIG_I2C_GPIO ) +gpiod_add_lookup_table (&bfin_i2c_gpiod_table); +#endif platform_add_devices (ezkit_devices,ARRAY_SIZE (ezkit_devices));spi_register_board_info (bfin_spi_board_info,ARRAY_SIZE (bfin_spi_board_info)); i2c_register_board_info(0, bfin_i2c_board_info,
arch/blackfin/mach-bf533/boards/stamp.c +14 -4
@@ -21,6 +21,7 @@#include <linux/gpio.h> #include <linux/irq.h> #include <linux/i2c.h> +#include <linux/gpio/machine.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> #include <asm/reboot.h>
@@ -512,11 +513,17 @@ static struct platform_device bfin_device_gpiokeys = {#if IS_ENABLED (CONFIG_I2C_GPIO )#include <linux/i2c-gpio.h> +static struct gpiod_lookup_table bfin_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF2 ,NULL ,0 , +GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF3 ,NULL ,1 , +GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin =GPIO_PF2 , - .scl_pin =GPIO_PF3 , - .sda_is_open_drain =0 , - .scl_is_open_drain =0 , .udelay =10 , };
@@ -848,6 +855,9 @@ static int __init stamp_init(void)printk (KERN_INFO "%s(): registering device resources\n" , __func__); +#if IS_ENABLED (CONFIG_I2C_GPIO ) +gpiod_add_lookup_table (&bfin_i2c_gpiod_table); +#endif i2c_register_board_info (0 , bfin_i2c_board_info,ARRAY_SIZE (bfin_i2c_board_info));
arch/blackfin/mach-bf561/boards/ezkit.c +14 -4
@@ -16,6 +16,7 @@#include <linux/interrupt.h> #include <linux/gpio.h> #include <linux/delay.h> +#include <linux/gpio/machine.h> #include <asm/dma.h> #include <asm/bfin5xx_spi.h> #include <asm/portmux.h>
@@ -379,11 +380,17 @@ static struct platform_device bfin_device_gpiokeys = {#if IS_ENABLED (CONFIG_I2C_GPIO )#include <linux/i2c-gpio.h> +static struct gpiod_lookup_table bfin_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF1 ,NULL ,0 , +GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF0 ,NULL ,1 , +GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin =GPIO_PF1 , - .scl_pin =GPIO_PF0 , - .sda_is_open_drain =0 , - .scl_is_open_drain =0 , .udelay =10 , };
@@ -633,6 +640,9 @@ static int __init ezkit_init(void)printk (KERN_INFO "%s(): registering device resources\n" , __func__); +#if IS_ENABLED (CONFIG_I2C_GPIO ) +gpiod_add_lookup_table (&bfin_i2c_gpiod_table); +#endif ret =platform_add_devices (ezkit_devices,ARRAY_SIZE (ezkit_devices));if (ret <0 )return ret;
arch/mips/alchemy/board-gpr.c +17 -2
@@ -30,6 +30,7 @@#include <linux/gpio.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <asm/bootinfo.h> #include <asm/idle.h> #include <asm/reboot.h>
@@ -218,10 +219,23 @@ static struct platform_device gpr_led_devices = {/* * I2C */ +static struct gpiod_lookup_table gpr_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +/* +* This should be on "GPIO2" which has base at 200 so +* the global numbers 209 and 210 should correspond to +* local offsets 9 and 10. +*/ +GPIO_LOOKUP_IDX ("alchemy-gpio2" ,9 ,NULL ,0 , +GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("alchemy-gpio2" ,10 ,NULL ,1 , +GPIO_ACTIVE_HIGH ), + }, +}; +static struct i2c_gpio_platform_data gpr_i2c_data = { - .sda_pin =209 , .sda_is_open_drain =1 , - .scl_pin =210 , .scl_is_open_drain =1 , .udelay =2 ,/* ~100 kHz */ .timeout =HZ ,
@@ -295,6 +309,7 @@ arch_initcall(gpr_pci_init);static int __init gpr_dev_init (void ) { +gpiod_add_lookup_table (&gpr_i2c_gpiod_table);i2c_register_board_info (0 , gpr_i2c_info,ARRAY_SIZE (gpr_i2c_info));return platform_add_devices (gpr_devices,ARRAY_SIZE (gpr_devices));
arch/mips/ath79/mach-pb44.c +11 -5
@@ -11,7 +11,7 @@#include <linux/init.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/i2c-gpio.h> +#include <linux/gpio/machine.h> #include <linux/platform_data/pcf857x.h> #include "machtypes.h"
@@ -33,16 +33,21 @@#define PB44_KEYS_POLL_INTERVAL 20/* msecs */ #define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL) -static struct i2c_gpio_platform_data pb44_i2c_gpio_data = { - .sda_pin =PB44_GPIO_I2C_SDA , - .scl_pin =PB44_GPIO_I2C_SCL , +static struct gpiod_lookup_table pb44_i2c_gpiod_table = { + .dev_id ="i2c-gpio" , + .table = { +GPIO_LOOKUP_IDX ("ath79-gpio" ,PB44_GPIO_I2C_SDA , +NULL ,0 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("ath79-gpio" ,PB44_GPIO_I2C_SCL , +NULL ,1 ,GPIO_ACTIVE_HIGH ), + }, };static struct platform_device pb44_i2c_gpio_device = { .name ="i2c-gpio" , .id =0 , .dev = { - .platform_data = &pb44_i2c_gpio_data, + .platform_data =NULL , } };
@@ -103,6 +108,7 @@ static struct ath79_spi_platform_data pb44_spi_data = {static void __init pb44_init (void ) { +gpiod_add_lookup_table (&pb44_i2c_gpiod_table);i2c_register_board_info (0 , pb44_i2c_board_info,ARRAY_SIZE (pb44_i2c_board_info));platform_device_register (&pb44_i2c_gpio_device);
drivers/i2c/busses/i2c-gpio.c +63 -71
229 lines not on this page · raw message
drivers/mfd/sm501.c +27 -22
87 lines not on this page · raw message
include/linux/i2c-gpio.h +0 -4
@@ -12,8 +12,6 @@/** * struct i2c_gpio_platform_data - Platform-dependent data for i2c-gpio -* @sda_pin: GPIO pin ID to use for SDA -* @scl_pin: GPIO pin ID to use for SCL * @udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz * @timeout: clock stretching timeout in jiffies. If the slave keeps * SCL low for longer than this, the transfer will time out.
@@ -26,8 +24,6 @@* @scl_is_output_only: SCL output drivers cannot be turned off. */ struct i2c_gpio_platform_data { -unsigned int sda_pin; -unsigned int scl_pin;int udelay;int timeout;unsigned int sda_is_open_drain:1 ;
Signature · 1 line
2.13.5
PATCH 1/7 i2c: gpio: Convert to use descriptors
Quoted 3 lines · Linus Walleij
This converts the GPIO-based I2C-driver to using GPIO descriptors instead of the old global numberspace-based GPIO interface. We:
[STUFF]
Quoted 18 lines
- The MFD Silicon Motion SM501 is a special case. It dynamically spawns an I2C bus off the MFD using
sm501_create_subdev(). We use an approach to dynamically create a machine descriptor table and attach this to the "SM501-LOW" or "SM501-HIGH" gpiochip. We use chip-local offsets to grab the right lines. We can get rid of two local static inline helpers as part of this refactoring.Cc Steven Miao <[email protected]>Cc Ralf Baechle <[email protected]>Cc Lee Jones <[email protected]>Cc Guenter Roeck <[email protected]>Cc Ville Syrj?l? <[email protected]>Cc Magnus Damm <[email protected]>Cc Ben Dooks <[email protected]>Cc Heiko Schocher <[email protected]>Acked-by Olof Johansson <[email protected]>Signed-off-by Linus Walleij <[email protected]>
Quoted 8 lines
---
ChangeLogv1->v2:
- Fix a minor typo in error path (scl was sda from copy-paste)
- Collected Olof's ACKSteven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
Lee: requesting ACK for Wolfram to take this patch.
This ...
Quoted 1 line
SM501 users: requesting Tested-by on this patch.
... loosely depends on this (until it doesn't).
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH 1/7 i2c: gpio: Convert to use descriptors
Quoted 9 lines · Lee Jones
Quoted 1 line · Linus Walleij
Lee: requesting ACK for Wolfram to take this patch.
This ...
Quoted 1 line
SM501 users: requesting Tested-by on this patch.
... loosely depends on this (until it doesn't).
Yeah I did my best to scout around the commit logs to figure out who's been contributing to the SM501 and using it, I hope someone will step up and test it.
Linus
PATCH 1/7 i2c: gpio: Convert to use descriptors
Quoted 7 lines · Linus Walleij
Quoted 6 lines · Lee Jones
Quoted 1 line · Linus Walleij
Lee: requesting ACK for Wolfram to take this patch.
This ...
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
SM501 users: requesting Tested-by on this patch.
... loosely depends on this (until it doesn't).
Yeah I did my best to scout around the commit logs to figure out who's been contributing to the SM501 and using it, I hope someone will step up and test it.
I don't know if anything I have available working has an SM501 on it. We did a couple of boards with S3C2440 and an SM501 connected via external IO. However these have not been supported in years (since Simtec)
I don't even think I have the PCI SM501 kit, that may have ended up either at Simtec or one of the other engineers.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
PATCH 1/7 i2c: gpio: Convert to use descriptors
In reply to Linus WalleijQuoted 7 lines · Linus Walleij
- The MFD Silicon Motion SM501 is a special case. It dynamically spawns an I2C bus off the MFD using
sm501_create_subdev(). We use an approach to dynamically create a machine descriptor table and attach this to the "SM501-LOW" or "SM501-HIGH" gpiochip. We use chip-local offsets to grab the right lines. We can get rid of two local static inline helpers as part of this refactoring.
(...)
Quoted 1 line
SM501 users: requesting Tested-by on this patch.
Paging Simtec (if it reaches anyone), Vincent Sanders, Teddy Wang at Silicon Motion:
Does any of you have an "Anubis" board so you can test GPIO on this board before/after this patch and see if it checks out right?
I guess it's this board:
http://www.simtec.co.uk/products/BBD20EUROA/
Does anyone know of a commercially obtainable product using SM501 with reasonable mainline Linux support so I can test it myself?
Getting a bit desperate...
Yours,
Linus Walleij
PATCH 1/7 i2c: gpio: Convert to use descriptors
Quoted 10 lines · Linus Walleij
Quoted 7 lines · Linus Walleij
- The MFD Silicon Motion SM501 is a special case. It dynamically spawns an I2C bus off the MFD using
sm501_create_subdev(). We use an approach to dynamically create a machine descriptor table and attach this to the "SM501-LOW" or "SM501-HIGH" gpiochip. We use chip-local offsets to grab the right lines. We can get rid of two local static inline helpers as part of this refactoring.
Quoted 5 lines
(...)
Quoted 1 line
SM501 users: requesting Tested-by on this patch.
Paging Simtec (if it reaches anyone), Vincent Sanders, Teddy Wang at Silicon Motion:
I'm fairly sure Simtec is not currently active. See below. I have no idea if the SM501 is even available for current designs.
Quoted 5 lines
Does any of you have an "Anubis" board so you can test GPIO on this board before/after this patch and see if it checks out right?
I guess it's this board:
http://www.simtec.co.uk/products/BBD20EUROA/
I think that's fairly close.
We did have a couple of other designs done for clients, but they may not have been available to the general public.
Quoted 5 lines
Does anyone know of a commercially obtainable product using SM501 with reasonable mainline Linux support so I can test it myself?
Getting a bit desperate...
At the moment I have no time to go through the boxes of ex-Simtec stuff that I still have... quite a lot of my old Simtec stuff has already been recycled as it has been over five years since leaving.
Quoted 3 lines
Yours,
Linus Walleij
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
PATCH 1/7 i2c: gpio: Convert to use descriptors
In reply to Linus WalleijQuoted 128 lines · Linus Walleij
This converts the GPIO-based I2C-driver to using GPIO descriptors instead of the old global numberspace-based GPIO interface. We:
- Convert the driver to unconditionally grab two GPIOs from the device by index 0 (SDA) and 1 (SCL) which will work fine with device tree and descriptor tables. The existing device trees will continue to work just like before, but without any roundtrip through the global numberspace.
- Brutally convert all boardfiles still passing global GPIOs by registering descriptor tables associated with the devices instead so this driver does not need to keep supporting passing any GPIO numbers as platform data.
There is no stepwise approach as elegant as this, I strongly prefer this big hammer over any antsteps for this conversion. This way the old GPIO numbers go away and NEVER COME BACK.
Special conversion for the different boards utilizing I2C-GPIO:
- EP93xx (
arch/arm/mach-ep93xx): pretty straight forward as all boards were using the same two GPIO lines, just define these two in a lookup table for "i2c-gpio" and register these along with the device. None of them define any other platform data so just pass NULL as platform data. This platform selects GPIOLIB so all should be smooth. The pins appear on a gpiochip for bank "G" as pins 1 (SDA) and 0 (SCL).- IXP4 (
arch/arm/mach-ixp4): descriptor tables have to be registered for each board separately. They all use "IXP4XX_GPIO_CHIP" so it is pretty straight forward. Most board define no other platform data than SCL/SDA so they can drop the #include of <linux/i2c-gpio.h> and assign NULL to platform data.The "
goramo_mlr" (Goramo Multilink Router) board is a bit
worrisome: it implements its own I2C bit-banging in the board file, and optionally registers an I2C serial port, but claims the same GPIO lines for itself in the board file. This is not going to work: there will be competition for the GPIO lines, so delete the optional extra I2C bus instead, no I2C devices are registered on it anyway, there are just hints that it may contain an EEPROM that may be accessed from userspace. This needs to be fixed up properly by the serial clock using I2C emulation so drop a note in the code.- KS8695 board acs5k (
arch/arm/mach-ks8695/board-acs5.c) has some platform data in addition to the pins so it needs to be kept around sans GPIO lines. Its GPIO chip is named "KS8695" and the arch selects GPIOLIB.- PXA boards (
arch/arm/mach-pxa/*) use some of the platform data so it needs to be preserved here. The viper board even registers two GPIO I2Cs. The gpiochip is named "gpio-pxa" and the arch selects GPIOLIB.- SA1100 Simpad (
arch/arm/mach-sa1100/simpad.c) defines a GPIO I2C bus, and the arch selects GPIOLIB.- Blackfin boards (
arch/blackfin/bf533etc) for these I assume their I2C GPIOs refer to the local gpiochip defined inarch/blackfin/kernel/bfin_gpio.cnames "BFIN-GPIO". The arch selects GPIOLIB. The boards get spiked withIF_ENABLED(I2C_GPIO)but that is a side effect of it being like that already (I would just haveKconfigselectI2C_GPIOand get rid of them all.) I also delete any platform data set to 0 as it will get that value anyway from static declartions of platform data.- The MIPS selects GPIOLIB and the Alchemy machine is using two local GPIO chips, one of them has a GPIO I2C. We need to adjust the local offset from the global number space here. The ATH79 has a proper GPIO driver in
drivers/gpio/gpio-ath79.cand AFAICT the chip is named "ath79-gpio" and the PB44 PCF857x expander spawns from this on GPIO 1 and 0. The latter board only use the platform data to specify pins so it can be cut altogether after this.- The MFD Silicon Motion SM501 is a special case. It dynamically spawns an I2C bus off the MFD using
sm501_create_subdev(). We use an approach to dynamically create a machine descriptor table and attach this to the "SM501-LOW" or "SM501-HIGH" gpiochip. We use chip-local offsets to grab the right lines. We can get rid of two local static inline helpers as part of this refactoring.Cc Steven Miao <[email protected]>Cc Ralf Baechle <[email protected]>Cc Lee Jones <[email protected]>Cc Guenter Roeck <[email protected]>Cc Ville Syrj?l? <[email protected]>Cc Magnus Damm <[email protected]>Cc Ben Dooks <[email protected]>Cc Heiko Schocher <[email protected]>Acked-by Olof Johansson <[email protected]>Signed-off-by Linus Walleij <[email protected]>---
ChangeLogv1->v2:
- Fix a minor typo in error path (scl was sda from copy-paste)
- Collected Olof's ACKSteven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
Lee: requesting ACK for Wolfram to take this patch. SM501 users: requesting Tested-by on this patch.--- arch/arm/mach-ep93xx/core.c | 39 ++++---- arch/arm/mach-ep93xx/edb93xx.c | 15 +-- arch/arm/mach-ep93xx/include/mach/platform.h | 4 +- arch/arm/mach-ep93xx/simone.c | 12 +-- arch/arm/mach-ep93xx/snappercl15.c | 12 +-- arch/arm/mach-ep93xx/vision_ep9307.c | 7 +- arch/arm/mach-ixp4xx/avila-setup.c | 17 +++- arch/arm/mach-ixp4xx/dsmg600-setup.c | 16 +++- arch/arm/mach-ixp4xx/fsg-setup.c | 16 +++- arch/arm/mach-ixp4xx/goramo_mlr.c | 24 ++--- arch/arm/mach-ixp4xx/ixdp425-setup.c | 16 +++- arch/arm/mach-ixp4xx/nas100d-setup.c | 16 +++- arch/arm/mach-ixp4xx/nslu2-setup.c | 16 +++- arch/arm/mach-ks8695/board-acs5k.c | 13 ++- arch/arm/mach-pxa/palmz72.c | 12 ++- arch/arm/mach-pxa/viper.c | 27 +++++- arch/arm/mach-sa1100/simpad.c | 12 ++-
Quoted 8 lines
arch/blackfin/mach-bf533/boards/blackstamp.c | 19 +++- arch/blackfin/mach-bf533/boards/ezkit.c | 18 +++- arch/blackfin/mach-bf533/boards/stamp.c | 18 +++- arch/blackfin/mach-bf561/boards/ezkit.c | 18 +++- arch/mips/alchemy/board-gpr.c | 19 +++- arch/mips/ath79/mach-pb44.c | 16 +++- drivers/i2c/busses/i2c-gpio.c | 134 +++++++++++++-------------- drivers/mfd/sm501.c | 49 +++++-----
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH 1/7 i2c: gpio: Convert to use descriptors
In reply to Linus WalleijQuoted 126 lines · Linus Walleij
This converts the GPIO-based I2C-driver to using GPIO descriptors instead of the old global numberspace-based GPIO interface. We:
- Convert the driver to unconditionally grab two GPIOs from the device by index 0 (SDA) and 1 (SCL) which will work fine with device tree and descriptor tables. The existing device trees will continue to work just like before, but without any roundtrip through the global numberspace.
- Brutally convert all boardfiles still passing global GPIOs by registering descriptor tables associated with the devices instead so this driver does not need to keep supporting passing any GPIO numbers as platform data.
There is no stepwise approach as elegant as this, I strongly prefer this big hammer over any antsteps for this conversion. This way the old GPIO numbers go away and NEVER COME BACK.
Special conversion for the different boards utilizing I2C-GPIO:
- EP93xx (
arch/arm/mach-ep93xx): pretty straight forward as all boards were using the same two GPIO lines, just define these two in a lookup table for "i2c-gpio" and register these along with the device. None of them define any other platform data so just pass NULL as platform data. This platform selects GPIOLIB so all should be smooth. The pins appear on a gpiochip for bank "G" as pins 1 (SDA) and 0 (SCL).- IXP4 (
arch/arm/mach-ixp4): descriptor tables have to be registered for each board separately. They all use "IXP4XX_GPIO_CHIP" so it is pretty straight forward. Most board define no other platform data than SCL/SDA so they can drop the #include of <linux/i2c-gpio.h> and assign NULL to platform data.The "
goramo_mlr" (Goramo Multilink Router) board is a bit
worrisome: it implements its own I2C bit-banging in the board file, and optionally registers an I2C serial port, but claims the same GPIO lines for itself in the board file. This is not going to work: there will be competition for the GPIO lines, so delete the optional extra I2C bus instead, no I2C devices are registered on it anyway, there are just hints that it may contain an EEPROM that may be accessed from userspace. This needs to be fixed up properly by the serial clock using I2C emulation so drop a note in the code.- KS8695 board acs5k (
arch/arm/mach-ks8695/board-acs5.c) has some platform data in addition to the pins so it needs to be kept around sans GPIO lines. Its GPIO chip is named "KS8695" and the arch selects GPIOLIB.- PXA boards (
arch/arm/mach-pxa/*) use some of the platform data so it needs to be preserved here. The viper board even registers two GPIO I2Cs. The gpiochip is named "gpio-pxa" and the arch selects GPIOLIB.- SA1100 Simpad (
arch/arm/mach-sa1100/simpad.c) defines a GPIO I2C bus, and the arch selects GPIOLIB.- Blackfin boards (
arch/blackfin/bf533etc) for these I assume their I2C GPIOs refer to the local gpiochip defined inarch/blackfin/kernel/bfin_gpio.cnames "BFIN-GPIO". The arch selects GPIOLIB. The boards get spiked withIF_ENABLED(I2C_GPIO)but that is a side effect of it being like that already (I would just haveKconfigselectI2C_GPIOand get rid of them all.) I also delete any platform data set to 0 as it will get that value anyway from static declartions of platform data.- The MIPS selects GPIOLIB and the Alchemy machine is using two local GPIO chips, one of them has a GPIO I2C. We need to adjust the local offset from the global number space here. The ATH79 has a proper GPIO driver in
drivers/gpio/gpio-ath79.cand AFAICT the chip is named "ath79-gpio" and the PB44 PCF857x expander spawns from this on GPIO 1 and 0. The latter board only use the platform data to specify pins so it can be cut altogether after this.- The MFD Silicon Motion SM501 is a special case. It dynamically spawns an I2C bus off the MFD using
sm501_create_subdev(). We use an approach to dynamically create a machine descriptor table and attach this to the "SM501-LOW" or "SM501-HIGH" gpiochip. We use chip-local offsets to grab the right lines. We can get rid of two local static inline helpers as part of this refactoring.Cc Steven Miao <[email protected]>Cc Ralf Baechle <[email protected]>Cc Lee Jones <[email protected]>Cc Guenter Roeck <[email protected]>Cc Ville Syrj?l? <[email protected]>Cc Magnus Damm <[email protected]>Cc Ben Dooks <[email protected]>Cc Heiko Schocher <[email protected]>Acked-by Olof Johansson <[email protected]>Signed-off-by Linus Walleij <[email protected]>---
ChangeLogv1->v2:
- Fix a minor typo in error path (scl was sda from copy-paste)
- Collected Olof's ACKSteven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
Lee: requesting ACK for Wolfram to take this patch. SM501 users: requesting Tested-by on this patch.--- arch/arm/mach-ep93xx/core.c | 39 ++++---- arch/arm/mach-ep93xx/edb93xx.c | 15 +-- arch/arm/mach-ep93xx/include/mach/platform.h | 4 +- arch/arm/mach-ep93xx/simone.c | 12 +-- arch/arm/mach-ep93xx/snappercl15.c | 12 +-- arch/arm/mach-ep93xx/vision_ep9307.c | 7 +- arch/arm/mach-ixp4xx/avila-setup.c | 17 +++- arch/arm/mach-ixp4xx/dsmg600-setup.c | 16 +++- arch/arm/mach-ixp4xx/fsg-setup.c | 16 +++- arch/arm/mach-ixp4xx/goramo_mlr.c | 24 ++--- arch/arm/mach-ixp4xx/ixdp425-setup.c | 16 +++- arch/arm/mach-ixp4xx/nas100d-setup.c | 16 +++- arch/arm/mach-ixp4xx/nslu2-setup.c | 16 +++- arch/arm/mach-ks8695/board-acs5k.c | 13 ++- arch/arm/mach-pxa/palmz72.c | 12 ++-
Quoted 8 lines
arch/arm/mach-pxa/viper.c | 27 +++++- arch/arm/mach-sa1100/simpad.c | 12 ++- arch/blackfin/mach-bf533/boards/blackstamp.c | 19 +++- arch/blackfin/mach-bf533/boards/ezkit.c | 18 +++- arch/blackfin/mach-bf533/boards/stamp.c | 18 +++- arch/blackfin/mach-bf561/boards/ezkit.c | 18 +++- arch/mips/alchemy/board-gpr.c | 19 +++- arch/mips/ath79/mach-pb44.c | 16 +++-
For MIPS:
Ralf
PATCH 2/7 gpio: Make it possible for consumers to enforce open drain
In reply to Linus WalleijSome busses, like I2C, strictly need to have the line handled as open drain, i.e. not actively driven high. For this reason the i2c-gpio.c bit-banged I2C driver is reimplementing open drain handling outside of gpiolib.
This is not very optimal. Instead make it possible for a consumer to explcitly express that the line must be handled as open drain instead of allowing local hacks papering over this issue.
The descriptor tables, whether DT, ACPI or board files, should of course have flagged these lines as open drain. E.g.:
enum gpio_lookup_flags GPIO_OPEN_DRAIN for a board file, or gpios = <&foo 42 GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN>; in a device tree using <dt-bindings/gpio/gpio.h>
But more often than not, these descriptors are wrong. So we need to make it possible for consumers to enforce this open drain behaviour.
We now have two new enumerated GPIO descriptor config flags:GPIOD_OUT_LOW_OPEN_DRAIN and GPIOD_OUT_HIGH_OPEN_DRAIN that will set up the lined enforced as open drain as output low or high, using open drain (if the driver supports it) or using open drain emulation (setting the line as input to drive it high) from the gpiolib core.
---
Obviously I authorize this patch to be applied directly to the I2C tree as part of the refactorings.
--- drivers/gpio/gpiolib.c | 13 +++++++++++++ include/linux/gpio/consumer.h | 6 ++++++ 2 files changed, 19 insertions(+)
drivers/gpio/gpiolib.c +13 -0
@@ -3228,8 +3228,21 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,if (lflags &GPIO_ACTIVE_LOW )set_bit (FLAG_ACTIVE_LOW , &desc->flags); +if (lflags &GPIO_OPEN_DRAIN )set_bit (FLAG_OPEN_DRAIN , &desc->flags); +else if (dflags &GPIOD_FLAGS_BIT_OPEN_DRAIN ) { +/* +* This enforces open drain mode from the consumer side. +* This is necessary for some busses like I2C, but the lookup +* should *REALLY* have specified them as open drain in the +* first place, so print a little warning here. +*/ +set_bit (FLAG_OPEN_DRAIN , &desc->flags); +gpiod_warn (desc, +"enforced open drain please flag it properly in DT/ACPI DSDT/board file\n" ); + } +if (lflags &GPIO_OPEN_SOURCE )set_bit (FLAG_OPEN_SOURCE , &desc->flags);if (lflags &GPIO_SLEEP_MAY_LOOSE_VALUE )
include/linux/gpio/consumer.h +6 -0
@@ -28,6 +28,7 @@ struct gpio_descs {#define GPIOD_FLAGS_BIT_DIR_SET BIT(0)#define GPIOD_FLAGS_BIT_DIR_OUT BIT(1)#define GPIOD_FLAGS_BIT_DIR_VAL BIT(2) +#define GPIOD_FLAGS_BIT_OPEN_DRAIN BIT(3)/** * Optional flags that can be passed to one of gpiod_* to configure direction
@@ -39,6 +40,11 @@ enum gpiod_flags {GPIOD_OUT_LOW =GPIOD_FLAGS_BIT_DIR_SET |GPIOD_FLAGS_BIT_DIR_OUT ,GPIOD_OUT_HIGH =GPIOD_FLAGS_BIT_DIR_SET |GPIOD_FLAGS_BIT_DIR_OUT |GPIOD_FLAGS_BIT_DIR_VAL , +GPIOD_OUT_LOW_OPEN_DRAIN =GPIOD_FLAGS_BIT_DIR_SET | +GPIOD_FLAGS_BIT_DIR_OUT |GPIOD_FLAGS_BIT_OPEN_DRAIN , +GPIOD_OUT_HIGH_OPEN_DRAIN =GPIOD_FLAGS_BIT_DIR_SET | +GPIOD_FLAGS_BIT_DIR_OUT |GPIOD_FLAGS_BIT_DIR_VAL | + GPIOD_FLAGS_BIT_OPEN_DRAIN, };#ifdef CONFIG_GPIOLIB
Signature · 1 line
2.13.5
PATCH 3/7 i2c: gpio: Enforce open drain through gpiolib
In reply to Linus WalleijThe I2C GPIO bitbang driver currently emulates open drain behaviour by implementing what the gpiolib already does:
not actively driving the line high, instead setting it to input.
This makes no sense. Use the new facility in gpiolib to request the lines enforced into open drain mode, and let the open drain emulation already present in the gpiolib kick in and handle this.
As a bonus: if the GPIO driver in the back-end actually supports open drain in hardware using the .set_config() callback, it will be utilized. That's correct: we never used that hardware feature before, instead relying on emulating open drain even if the GPIO controller could actually handle this for us.
Users will sometimes get messages like this:
gpio-485 (?): enforced open drain please flag it properly
in DT/ACPI DSDT/board file
gpio-486 (?): enforced open drain please flag it properly
in DT/ACPI DSDT/board file
i2c-gpio gpio-i2c: using lines 485 (SDA) and 486 (SCL)
Which is completely proper: since the line is used as open drain, it should actually be flagged properly with e.g.
gpios = <&gpio0 5 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>,
<&gpio0 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
Or similar facilities in board file descriptor tables or ACPI DSDT.
---
ChangeLog v1->v2:
- Fix a minor typo in error path (copy-paste scl was sda)
--- drivers/i2c/busses/i2c-gpio.c | 102 ++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 63 deletions(-)
drivers/i2c/busses/i2c-gpio.c +39 -63
@@ -25,23 +25,6 @@ struct i2c_gpio_private_data {struct i2c_gpio_platform_data pdata; }; -/* Toggle SDA by changing the direction of the pin */ -static void i2c_gpio_setsda_dir (void *data,int state) -{ -struct i2c_gpio_private_data *priv = data; - -/* -* This is a way of saying "do not drive -* me actively high" which means emulating open drain. -* The right way to do this is for gpiolib to -* handle this, by the function below. -*/ -if (state) -gpiod_direction_input (priv->sda); -else -gpiod_direction_output (priv->sda,0 ); -} -/* * Toggle SDA by changing the output value of the pin. This is only * valid for pins configured as open drain (i.e. setting the value
@@ -54,17 +37,6 @@ static void i2c_gpio_setsda_val(void *data, int state)gpiod_set_value (priv->sda, state); } -/* Toggle SCL by changing the direction of the pin. */ -static void i2c_gpio_setscl_dir (void *data,int state) -{ -struct i2c_gpio_private_data *priv = data; - -if (state) -gpiod_direction_input (priv->scl); -else -gpiod_direction_output (priv->scl,0 ); -} -/* * Toggle SCL by changing the output value of the pin. This is used * for pins that are configured as open drain and for output-only
@@ -116,30 +88,13 @@ static int i2c_gpio_probe(struct platform_device *pdev)struct i2c_gpio_platform_data *pdata;struct i2c_algo_bit_data *bit_data;struct i2c_adapter *adap; +enum gpiod_flags gflags;int ret; priv =devm_kzalloc (&pdev->dev,sizeof (*priv),GFP_KERNEL );if (!priv)return -ENOMEM ; -/* First get the GPIO pins; if it fails, we'll defer the probe. */ - priv->sda =devm_gpiod_get_index (&pdev->dev,NULL ,0 ,GPIOD_OUT_HIGH ); -if (IS_ERR (priv->sda)) { - ret =PTR_ERR (priv->sda); -/* FIXME: hack in the old code, is this really necessary? */ -if (ret == -EINVAL ) - ret = -EPROBE_DEFER ; -return ret; - } - priv->scl =devm_gpiod_get_index (&pdev->dev,NULL ,1 ,GPIOD_OUT_LOW ); -if (IS_ERR (priv->scl)) { - ret =PTR_ERR (priv->scl); -/* FIXME: hack in the old code, is this really necessary? */ -if (ret == -EINVAL ) - ret = -EPROBE_DEFER ; -return ret; - } - adap = &priv->adap; bit_data = &priv->bit_data; pdata = &priv->pdata;
@@ -157,27 +112,48 @@ static int i2c_gpio_probe(struct platform_device *pdev) }/* -* FIXME: this is a hack emulating the open drain emulation -* that gpiolib can already do for us. Make all clients properly -* flag their lines as open drain and get rid of this property -* and the special callback. +* First get the GPIO pins; if it fails, we'll defer the probe. +* If the SDA line is marked from platform data or device tree as +* "open drain" it means something outside of our control is making +* this line being handled as open drain, and we should just handle +* it as any other output. Else we enforce open drain as this is +* required for an I2C bus. */ -if (pdata->sda_is_open_drain) { -gpiod_direction_output (priv->sda,1 ); - bit_data->setsda = i2c_gpio_setsda_val; - }else { -gpiod_direction_input (priv->sda); - bit_data->setsda = i2c_gpio_setsda_dir; +if (pdata->sda_is_open_drain) + gflags =GPIOD_OUT_HIGH ; +else + gflags =GPIOD_OUT_HIGH_OPEN_DRAIN ; + priv->sda =devm_gpiod_get_index (&pdev->dev,NULL ,0 , gflags); +if (IS_ERR (priv->sda)) { + ret =PTR_ERR (priv->sda); +/* FIXME: hack in the old code, is this really necessary? */ +if (ret == -EINVAL ) + ret = -EPROBE_DEFER ; +return ret; } - -if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { -gpiod_direction_output (priv->scl,1 ); - bit_data->setscl = i2c_gpio_setscl_val; - }else { -gpiod_direction_input (priv->scl); - bit_data->setscl = i2c_gpio_setscl_dir; +/* +* If the SCL line is marked from platform data or device tree as +* "open drain" it means something outside of our control is making +* this line being handled as open drain, and we should just handle +* it as any other output. Else we enforce open drain as this is +* required for an I2C bus. +*/ +if (pdata->scl_is_open_drain) + gflags =GPIOD_OUT_LOW ; +else + gflags =GPIOD_OUT_LOW_OPEN_DRAIN ; + priv->scl =devm_gpiod_get_index (&pdev->dev,NULL ,1 , gflags); +if (IS_ERR (priv->scl)) { + ret =PTR_ERR (priv->scl); +/* FIXME: hack in the old code, is this really necessary? */ +if (ret == -EINVAL ) + ret = -EPROBE_DEFER ; +return ret; } + bit_data->setsda = i2c_gpio_setsda_val; + bit_data->setscl = i2c_gpio_setscl_val; +if (!pdata->scl_is_output_only) bit_data->getscl = i2c_gpio_getscl; bit_data->getsda = i2c_gpio_getsda;
Signature · 1 line
2.13.5
PATCH 4/7 i2c: gpio: Augment all boardfiles to use open drain
In reply to Linus WalleijWe now handle the open drain mode internally in the I2C GPIO driver, but we will get warnings from the gpiolib that we override the default mode of the line so it becomes open drain.
We can fix all in-kernel users by simply passing the right flag along in the descriptor table, and we already touched all of these files in the series so let's just tidy it up.
---
ChangeLog v1->v2:
- Collected ACKs.
Steven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
--- arch/arm/mach-ep93xx/core.c | 6 ++++-- arch/arm/mach-ixp4xx/avila-setup.c | 4 ++-- arch/arm/mach-ixp4xx/dsmg600-setup.c | 4 ++-- arch/arm/mach-ixp4xx/fsg-setup.c | 4 ++-- arch/arm/mach-ixp4xx/ixdp425-setup.c | 4 ++-- arch/arm/mach-ixp4xx/nas100d-setup.c | 4 ++-- arch/arm/mach-ixp4xx/nslu2-setup.c | 4 ++-- arch/arm/mach-ks8695/board-acs5k.c | 6 ++++-- arch/arm/mach-pxa/palmz72.c | 6 ++++-- arch/arm/mach-pxa/viper.c | 8 ++++---- arch/arm/mach-sa1100/simpad.c | 6 ++++-- arch/blackfin/mach-bf533/boards/blackstamp.c | 4 ++-- arch/blackfin/mach-bf533/boards/ezkit.c | 4 ++-- arch/blackfin/mach-bf533/boards/stamp.c | 4 ++-- arch/blackfin/mach-bf561/boards/ezkit.c | 4 ++-- arch/mips/alchemy/board-gpr.c | 4 ++++ arch/mips/ath79/mach-pb44.c | 4 ++-- drivers/mfd/sm501.c | 4 ++-- 18 files changed, 48 insertions(+), 36 deletions(-)
arch/arm/mach-ep93xx/core.c +4 -2
@@ -326,8 +326,10 @@ static struct gpiod_lookup_table ep93xx_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {/* Use local offsets on gpiochip/port "G" */ -GPIO_LOOKUP_IDX ("G" ,1 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), - GPIO_LOOKUP_IDX("G", 0, NULL, 1, GPIO_ACTIVE_HIGH), +GPIO_LOOKUP_IDX ("G" ,1 ,NULL ,0 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), +GPIO_LOOKUP_IDX ("G" ,0 ,NULL ,1 , + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ixp4xx/avila-setup.c +2 -2
@@ -53,9 +53,9 @@ static struct gpiod_lookup_table avila_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,AVILA_SDA_PIN , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,AVILA_SCL_PIN , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ixp4xx/dsmg600-setup.c +2 -2
@@ -72,9 +72,9 @@ static struct gpiod_lookup_table dsmg600_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,DSMG600_SDA_PIN , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,DSMG600_SCL_PIN , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ixp4xx/fsg-setup.c +2 -2
@@ -58,9 +58,9 @@ static struct gpiod_lookup_table fsg_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,FSG_SDA_PIN , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,FSG_SCL_PIN , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ixp4xx/ixdp425-setup.c +2 -2
@@ -126,9 +126,9 @@ static struct gpiod_lookup_table ixdp425_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,IXDP425_SDA_PIN , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,IXDP425_SCL_PIN , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ixp4xx/nas100d-setup.c +2 -2
@@ -104,9 +104,9 @@ static struct gpiod_lookup_table nas100d_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NAS100D_SDA_PIN , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NAS100D_SCL_PIN , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ixp4xx/nslu2-setup.c +2 -2
@@ -72,9 +72,9 @@ static struct gpiod_lookup_table nslu2_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NSLU2_SDA_PIN , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("IXP4XX_GPIO_CHIP" ,NSLU2_SCL_PIN , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-ks8695/board-acs5k.c +4 -2
@@ -41,8 +41,10 @@static struct gpiod_lookup_table acs5k_i2c_gpiod_table = { .dev_id ="i2c-gpio" , .table = { -GPIO_LOOKUP_IDX ("KS8695" ,4 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), -GPIO_LOOKUP_IDX ("KS8695" ,5 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("KS8695" ,4 ,NULL ,0 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), +GPIO_LOOKUP_IDX ("KS8695" ,5 ,NULL ,1 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), }, };
arch/arm/mach-pxa/palmz72.c +4 -2
@@ -324,8 +324,10 @@ static struct soc_camera_link palmz72_iclink = {static struct gpiod_lookup_table palmz72_i2c_gpiod_table = { .dev_id ="i2c-gpio" , .table = { -GPIO_LOOKUP_IDX ("gpio-pxa" ,118 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), -GPIO_LOOKUP_IDX ("gpio-pxa" ,117 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("gpio-pxa" ,118 ,NULL ,0 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), +GPIO_LOOKUP_IDX ("gpio-pxa" ,117 ,NULL ,1 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), }, };
arch/arm/mach-pxa/viper.c +4 -4
@@ -463,9 +463,9 @@ static struct gpiod_lookup_table viper_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_RTC_I2C_SDA_GPIO , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_RTC_I2C_SCL_GPIO , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
@@ -792,9 +792,9 @@ struct gpiod_lookup_table viper_tpm_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_TPM_I2C_SDA_GPIO , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("gpio-pxa" ,VIPER_TPM_I2C_SCL_GPIO , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/arm/mach-sa1100/simpad.c +4 -2
@@ -327,8 +327,10 @@ static struct platform_device simpad_gpio_leds = {static struct gpiod_lookup_table simpad_i2c_gpiod_table = { .dev_id ="i2c-gpio" , .table = { -GPIO_LOOKUP_IDX ("gpio" ,GPIO_GPIO21 ,NULL ,0 ,GPIO_ACTIVE_HIGH ), -GPIO_LOOKUP_IDX ("gpio" ,GPIO_GPIO25 ,NULL ,1 ,GPIO_ACTIVE_HIGH ), +GPIO_LOOKUP_IDX ("gpio" ,GPIO_GPIO21 ,NULL ,0 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), +GPIO_LOOKUP_IDX ("gpio" ,GPIO_GPIO25 ,NULL ,1 , +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ), }, };
arch/blackfin/mach-bf533/boards/blackstamp.c +2 -2
@@ -367,9 +367,9 @@ static struct gpiod_lookup_table bfin_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF8 ,NULL ,0 , -GPIO_ACTIVE_HIGH ), +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF9 ,NULL ,1 , - GPIO_ACTIVE_HIGH), + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/blackfin/mach-bf533/boards/ezkit.c +2 -2
@@ -395,9 +395,9 @@ static struct gpiod_lookup_table bfin_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF1 ,NULL ,0 , -GPIO_ACTIVE_HIGH ), +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF0 ,NULL ,1 , - GPIO_ACTIVE_HIGH), + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/blackfin/mach-bf533/boards/stamp.c +2 -2
@@ -517,9 +517,9 @@ static struct gpiod_lookup_table bfin_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF2 ,NULL ,0 , -GPIO_ACTIVE_HIGH ), +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF3 ,NULL ,1 , - GPIO_ACTIVE_HIGH), + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/blackfin/mach-bf561/boards/ezkit.c +2 -2
@@ -384,9 +384,9 @@ static struct gpiod_lookup_table bfin_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF1 ,NULL ,0 , -GPIO_ACTIVE_HIGH ), +GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("BFIN-GPIO" ,GPIO_PF0 ,NULL ,1 , - GPIO_ACTIVE_HIGH), + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
arch/mips/alchemy/board-gpr.c +4 -0
@@ -235,6 +235,10 @@ static struct gpiod_lookup_table gpr_i2c_gpiod_table = { };static struct i2c_gpio_platform_data gpr_i2c_data = { +/* +* The open drain mode is hardwired somewhere or an electrical +* property of the alchemy GPIO controller. +*/ .sda_is_open_drain =1 , .scl_is_open_drain =1 , .udelay =2 ,/* ~100 kHz */
arch/mips/ath79/mach-pb44.c +2 -2
@@ -37,9 +37,9 @@ static struct gpiod_lookup_table pb44_i2c_gpiod_table = { .dev_id = "i2c-gpio", .table = {GPIO_LOOKUP_IDX ("ath79-gpio" ,PB44_GPIO_I2C_SDA , -NULL ,0 ,GPIO_ACTIVE_HIGH ), +NULL ,0 ,GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ),GPIO_LOOKUP_IDX ("ath79-gpio" ,PB44_GPIO_I2C_SCL , - NULL, 1, GPIO_ACTIVE_HIGH), + NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, };
drivers/mfd/sm501.c +2 -2
@@ -1152,7 +1152,7 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm, lookup->table[0 ].chip_hwnum = iic->pin_sda %32 ; lookup->table[0 ].con_id =NULL ; lookup->table[0 ].idx =0 ; - lookup->table[0 ].flags =GPIO_ACTIVE_HIGH ; + lookup->table[0 ].flags =GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ;if (iic->pin_scl <32 ) lookup->table[1 ].chip_label ="SM501-LOW" ;else
@@ -1160,7 +1160,7 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm, lookup->table[1 ].chip_hwnum = iic->pin_scl %32 ; lookup->table[1 ].con_id =NULL ; lookup->table[1 ].idx =1 ; - lookup->table[1 ].flags =GPIO_ACTIVE_HIGH ; + lookup->table[1 ].flags =GPIO_ACTIVE_HIGH |GPIO_OPEN_DRAIN ;gpiod_add_lookup_table (lookup); icd =dev_get_platdata (&pdev->dev);
Signature · 1 line
2.13.5
Robert Jarzmik
maintainerPATCH 4/7 i2c: gpio: Augment all boardfiles to use open drain
Quoted 14 lines · Linus Walleij
We now handle the open drain mode internally in the I2C GPIO driver, but we will get warnings from the gpiolib that we override the default mode of the line so it becomes open drain.
We can fix all in-kernel users by simply passing the right flag along in the descriptor table, and we already touched all of these files in the series so let's just tidy it up.
Cc Steven Miao <[email protected]>Cc Ralf Baechle <[email protected]>Acked-by Olof Johansson <[email protected]>Acked-by Lee Jones <[email protected]>Signed-off-by Linus Walleij <[email protected]>
Quoted 6 lines
---
ChangeLogv1->v2:
- Collected ACKs.Steven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
For mach-pxa:
Cheers.
--
Robert
PATCH 4/7 i2c: gpio: Augment all boardfiles to use open drain
In reply to Linus WalleijQuoted 2 lines · Linus Walleij
Steven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
Ralf
PATCH 4/7 i2c: gpio: Augment all boardfiles to use open drain
Hi all,
Steven is no longer working on this for ADI. Acked by me if this works. Thanks.
Best regards,
Aaron Wu
Analog Devices Inc.
-----Original Message-----
From: Ralf Baechle [mailto:ralf at linux-mips.org]
Sent: Monday, October 09, 2017 10:28 PM
To: Linus Walleij <[email protected]>
Cc: linux-mips at linux-mips.org; Steven Miao <[email protected]>; adi-buildroot-devel at lists.sourceforge.net; Geert Uytterhoeven <[email protected]>; linux-i2c at vger.kernel.org; linux-arm-kernel at lists.infradead.org
Subject: Re: [Adi-buildroot-devel] [PATCH 4/7] i2c: gpio: Augment all boardfiles to use open drain
Quoted 2 lines · Linus Walleij
Steven (Blackfin): requesting ACK for Wolfram to take this patch. Ralf (MIPS): requesting ACK for Wolfram to take this patch.
Ralf
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Adi-buildroot-devel mailing list
Adi-buildroot-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/adi-buildroot-devel
PATCH 5/7 i2c: gpio: Local vars in probe
In reply to Linus WalleijBy creating local variables for *dev and *np, the code become much easier to read, in my opinion.
---
I put this at the end of the series because compared to the rest of the patches it is completely unimportant.
--- drivers/i2c/busses/i2c-gpio.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
drivers/i2c/busses/i2c-gpio.c +14 -12
@@ -88,10 +88,12 @@ static int i2c_gpio_probe(struct platform_device *pdev)struct i2c_gpio_platform_data *pdata;struct i2c_algo_bit_data *bit_data;struct i2c_adapter *adap; +struct device *dev = &pdev->dev; +struct device_node *np = dev->of_node;enum gpiod_flags gflags;int ret; - priv =devm_kzalloc (&pdev->dev,sizeof (*priv),GFP_KERNEL ); + priv =devm_kzalloc (dev,sizeof (*priv),GFP_KERNEL );if (!priv)return -ENOMEM ;
@@ -99,15 +101,15 @@ static int i2c_gpio_probe(struct platform_device *pdev) bit_data = &priv->bit_data; pdata = &priv->pdata; -if (pdev->dev.of_node) { -of_i2c_gpio_get_props (pdev->dev.of_node, pdata); +if (np) { +of_i2c_gpio_get_props (np, pdata); }else {/* * If all platform data settings are zero it is OK * to not provide any platform data from the board. */ -if (dev_get_platdata (&pdev->dev)) -memcpy (pdata,dev_get_platdata (&pdev->dev), +if (dev_get_platdata (dev)) +memcpy (pdata,dev_get_platdata (dev),sizeof (*pdata)); }
@@ -123,7 +125,7 @@ static int i2c_gpio_probe(struct platform_device *pdev) gflags =GPIOD_OUT_HIGH ; else gflags =GPIOD_OUT_HIGH_OPEN_DRAIN ; - priv->sda =devm_gpiod_get_index (&pdev->dev,NULL ,0 , gflags); + priv->sda =devm_gpiod_get_index (dev,NULL ,0 , gflags);if (IS_ERR (priv->sda)) { ret =PTR_ERR (priv->sda);/* FIXME: hack in the old code, is this really necessary? */
@@ -142,7 +144,7 @@ static int i2c_gpio_probe(struct platform_device *pdev) gflags =GPIOD_OUT_LOW ; else gflags =GPIOD_OUT_LOW_OPEN_DRAIN ; - priv->scl =devm_gpiod_get_index (&pdev->dev,NULL ,1 , gflags); + priv->scl =devm_gpiod_get_index (dev,NULL ,1 , gflags);if (IS_ERR (priv->scl)) { ret =PTR_ERR (priv->scl);/* FIXME: hack in the old code, is this really necessary? */
@@ -173,15 +175,15 @@ static int i2c_gpio_probe(struct platform_device *pdev) bit_data->data = priv; adap->owner =THIS_MODULE ; -if (pdev->dev.of_node) -strlcpy (adap->name,dev_name (&pdev->dev),sizeof (adap->name)); +if (np) +strlcpy (adap->name,dev_name (dev),sizeof (adap->name));else snprintf (adap->name,sizeof (adap->name),"i2c-gpio%d" , pdev->id); adap->algo_data = bit_data; adap->class =I2C_CLASS_HWMON |I2C_CLASS_SPD ; - adap->dev.parent = &pdev->dev; - adap->dev.of_node = pdev->dev.of_node; + adap->dev.parent = dev; + adap->dev.of_node = np; adap->nr = pdev->id; ret =i2c_bit_add_numbered_bus (adap);
@@ -195,7 +197,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)* get accessors to get the actual name of the GPIO line, * from the descriptor, then provide that instead. */ -dev_info (&pdev->dev,"using lines %u (SDA) and %u (SCL%s)\n" , +dev_info (dev,"using lines %u (SDA) and %u (SCL%s)\n" ,desc_to_gpio (priv->sda),desc_to_gpio (priv->scl), pdata->scl_is_output_only ?", no clock stretching" :"" );
Signature · 1 line
2.13.5
PATCH 5/7 i2c: gpio: Local vars in probe
Hi Linus,
Quoted 24 lines · Linus Walleij
By creating local variables for *dev and *np, the code become much easier to read, in my opinion.
Signed-off-by Linus Walleij <[email protected]>---
I put this at the end of the series because compared to the rest of the patches it is completely unimportant.--- drivers/i2c/busses/i2c-gpio.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)drivers/i2c/busses/i2c-gpio.c +2
-2@@ -99,15 +101,15 @@ static int i2c_gpio_probe(struct platform_device *pdev) bit_data = &priv->bit_data; pdata = &priv->pdata; -if (pdev->dev.of_node) { -of_i2c_gpio_get_props (pdev->dev.of_node, pdata); +if (np) { +of_i2c_gpio_get_props (np, pdata);
drivers/i2c/busses/i2c-gpio.c static int i2c_gpio_probe(struct platform_device *pdev) · line 113
Quoted 10 lines
drivers/i2c/busses/i2c-gpio.c +2
-2}else {/* * If all platform data settings are zero it is OK * to not provide any platform data from the board. */ -if (dev_get_platdata (&pdev->dev)) -memcpy (pdata,dev_get_platdata (&pdev->dev), +if (dev_get_platdata (dev)) +memcpy (pdata,dev_get_platdata (dev),sizeof (*pdata));
This fits on one line again (you have to do something to offset the LoC increase 14 insertions(+), 12 deletions(-) ;-)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
PATCH 6/7 dt-bindings: i2c: i2c-gpio: Add support for named gpios
In reply to Linus WalleijFrom: Geert Uytterhoeven <geert+renesas () glider ! be>
The current i2c-gpio DT bindings use a single unnamed "gpios" property to refer to the SDA and SCL signal lines by index. This is error-prone for the casual DT writer and reviewer, as one has to look up the order in the DT bindings.
Fix this by amending the DT bindings to use two separate named gpios properties, and deprecate the old unnamed variant.
Take this opportunity to clearly deprecate the "i2c-gpio,sda-open-drain" and "i2c-gpio,scl-open-drain" flags as well. The commit describes in detail what these flags actually mean, and why they should not be used in new device trees.
---
ChangeLog v1->v2:
- Create a special section for the deprecated bindings
- Also deprecate the open drain bool properties
- Update the example to use the new style of bindings
--- Documentation/devicetree/bindings/i2c/i2c-gpio.txt | 32 ++++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-)
Documentation/devicetree/bindings/i2c/i2c-gpio.txt +23 -9
@@ -2,25 +2,39 @@ Device-Tree bindings for i2c gpio driver Required properties: - compatible = "i2c-gpio"; - - gpios: sda and scl gpio - + - sda-gpios: gpio used for the sda signal, this should be flagged as + active high using open drain with (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) + from <dt-bindings/gpio/gpio.h> since the signal is by definition + open drain. + - scl-gpios: gpio used for the scl signal, this should be flagged as + active high using open drain with (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) + from <dt-bindings/gpio/gpio.h> since the signal is by definition + open drain. Optional properties: - - i2c-gpio,sda-open-drain: sda as open drain - - i2c-gpio,scl-open-drain: scl as open drain - i2c-gpio,scl-output-only: scl as output only - i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform) - i2c-gpio,timeout-ms: timeout to get data +Deprecated properties, do not use in new device tree sources: + - gpios: sda and scl gpio, alternative for {sda,scl}-gpios + - i2c-gpio,sda-open-drain: this means that something outside of our + control has put the GPIO line used for SDA into open drain mode, and + that something is not the GPIO chip. It is essentially an + inconsistency flag. + - i2c-gpio,scl-open-drain: this means that something outside of our + control has put the GPIO line used for SCL into open drain mode, and + that something is not the GPIO chip. It is essentially an + inconsistency flag. + Example nodes: +#include <dt-bindings/gpio/gpio.h> + i2c at 0 { compatible = "i2c-gpio"; - gpios = <&pioA 23 0 /* sda */ - &pioA 24 0 /* scl */ - >; - i2c-gpio,sda-open-drain; - i2c-gpio,scl-open-drain; + sda-gpios = <&pioA 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + scl-gpios = <&pioA 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>;
Signature · 1 line
2.13.5
Rob Herring
maintainerPATCH 6/7 dt-bindings: i2c: i2c-gpio: Add support for named gpios
Quoted 19 lines · Linus Walleij
From: Geert Uytterhoeven <geert+renesas () glider ! be>
The current i2c-gpio DT bindings use a single unnamed "gpios" property to refer to the SDA and SCL signal lines by index. This is error-prone for the casual DT writer and reviewer, as one has to look up the order in the DT bindings.
Fix this by amending the DT bindings to use two separate named gpios properties, and deprecate the old unnamed variant.
Take this opportunity to clearly deprecate the "i2c-gpio,sda-open-drain" and "i2c-gpio,scl-open-drain" flags as well. The commit describes in detail what these flags actually mean, and why they should not be used in new device trees.
Cc devicetree at vger.kernel.orgSigned-off-by Geert Uytterhoeven <[email protected]>[Augmented to what I and Rob would like]Signed-off-by Linus Walleij <[email protected]>
Quoted 8 lines
---
ChangeLogv1->v2:
- Create a special section for the deprecated bindings
- Also deprecate the open drain bool properties
- Update the example to use the new style of bindings--- Documentation/devicetree/bindings/i2c/i2c-gpio.txt | 32 ++++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-)
PATCH 7/7 i2c: gpio: Add support for named gpios in DT
In reply to Linus WalleijThis adds support for using the "sda" and "scl" GPIOs in device tree instead of anonymously using index 0 and 1 of the "gpios" property.
We add a helper function to retrieve the GPIO descriptors and some explicit error handling since the probe may have to be deferred. At least this happened to me when moving to using named "sda" and "scl" lines (all of a sudden this started to probe before the GPIO driver) so we need to gracefully defer probe when we ge -ENOENT in the error pointer.
---
This is pretty much a rewrite of Geerts patch on top of my own changes to support descriptors.
--- drivers/i2c/busses/i2c-gpio.c | 59 +++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 16 deletions(-)
drivers/i2c/busses/i2c-gpio.c +43 -16
@@ -82,6 +82,42 @@ static void of_i2c_gpio_get_props(struct device_node *np,of_property_read_bool (np,"i2c-gpio,scl-output-only" ); } +static struct gpio_desc *i2c_gpio_get_desc (struct device *dev, +const char *con_id, +unsigned int index, +enum gpiod_flags gflags) +{ +struct gpio_desc *retdesc; +int ret; + + retdesc =devm_gpiod_get (dev, con_id, gflags); +if (!IS_ERR (retdesc)) { +dev_dbg (dev,"got GPIO from name %s\n" , con_id); +return retdesc; + } + + retdesc =devm_gpiod_get_index (dev,NULL , index, gflags); +if (!IS_ERR (retdesc)) { +dev_dbg (dev,"got GPIO from index %u\n" , index); +return retdesc; + } + + ret =PTR_ERR (retdesc); + +/* FIXME: hack in the old code, is this really necessary? */ +if (ret == -EINVAL ) + retdesc =ERR_PTR (-EPROBE_DEFER ); + +/* This happens if the GPIO driver is not yet probed, let's defer */ +if (ret == -ENOENT ) + retdesc =ERR_PTR (-EPROBE_DEFER ); + +if (ret != -EPROBE_DEFER ) +dev_err (dev,"error trying to get descriptor: %ld\n" , ret); + +return retdesc; +} +static int i2c_gpio_probe (struct platform_device *pdev) {struct i2c_gpio_private_data *priv;
@@ -125,14 +161,10 @@ static int i2c_gpio_probe(struct platform_device *pdev) gflags =GPIOD_OUT_HIGH ; else gflags =GPIOD_OUT_HIGH_OPEN_DRAIN ; - priv->sda =devm_gpiod_get_index (dev,NULL ,0 , gflags); -if (IS_ERR (priv->sda)) { - ret =PTR_ERR (priv->sda); -/* FIXME: hack in the old code, is this really necessary? */ -if (ret == -EINVAL ) - ret = -EPROBE_DEFER ; -return ret; - } + priv->sda =i2c_gpio_get_desc (dev,"sda" ,0 , gflags); +if (IS_ERR (priv->sda)) +return PTR_ERR (priv->sda); +/* * If the SCL line is marked from platform data or device tree as * "open drain" it means something outside of our control is making
@@ -144,14 +176,9 @@ static int i2c_gpio_probe(struct platform_device *pdev) gflags =GPIOD_OUT_LOW ; else gflags =GPIOD_OUT_LOW_OPEN_DRAIN ; - priv->scl =devm_gpiod_get_index (dev,NULL ,1 , gflags); -if (IS_ERR (priv->scl)) { - ret =PTR_ERR (priv->scl); -/* FIXME: hack in the old code, is this really necessary? */ -if (ret == -EINVAL ) - ret = -EPROBE_DEFER ; -return ret; - } + priv->scl =i2c_gpio_get_desc (dev,"scl" ,1 , gflags); +if (IS_ERR (priv->scl)) +return PTR_ERR (priv->scl); bit_data->setsda = i2c_gpio_setsda_val; bit_data->setscl = i2c_gpio_setscl_val;
Signature · 1 line
2.13.5
PATCH 7/7 i2c: gpio: Add support for named gpios in DT
Quoted 10 lines · Linus Walleij
This adds support for using the "sda" and "scl" GPIOs in device tree instead of anonymously using index 0 and 1 of the "gpios" property.
We add a helper function to retrieve the GPIO descriptors and some explicit error handling since the probe may have to be deferred. At least this happened to me when moving to using named "sda" and "scl" lines (all of a sudden this started to probe before the GPIO driver) so we need to gracefully defer probe when we ge
-ENOENTin the error
get
Quoted 1 line
pointer.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
PATCH 7/7 i2c: gpio: Add support for named gpios in DT
In reply to Linus WalleijHi Linus,
Quoted 36 lines · Linus Walleij
This adds support for using the "sda" and "scl" GPIOs in device tree instead of anonymously using index 0 and 1 of the "gpios" property.
We add a helper function to retrieve the GPIO descriptors and some explicit error handling since the probe may have to be deferred. At least this happened to me when moving to using named "sda" and "scl" lines (all of a sudden this started to probe before the GPIO driver) so we need to gracefully defer probe when we ge
-ENOENTin the error pointer.Suggested-by Geert Uytterhoeven <[email protected]>Signed-off-by Linus Walleij <[email protected]>---
This is pretty much a rewrite of Geerts patch on top of my own changes to support descriptors.--- drivers/i2c/busses/i2c-gpio.c | 59 +++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 16 deletions(-)drivers/i2c/busses/i2c-gpio.c +7
-0@@ -82,6 +82,42 @@ static void of_i2c_gpio_get_props(struct device_node *np,of_property_read_bool (np,"i2c-gpio,scl-output-only" ); } +static struct gpio_desc *i2c_gpio_get_desc (struct device *dev, +const char *con_id, +unsigned int index, +enum gpiod_flags gflags) +{ +struct gpio_desc *retdesc; +int ret;
[...]
drivers/i2c/busses/i2c-gpio.c static void of_i2c_gpio_get_props(struct device_node *np, · line 116
Quoted 2 lines
drivers/i2c/busses/i2c-gpio.c +2
-0+if (ret != -EPROBE_DEFER ) +dev_err (dev,"error trying to get descriptor: %ld\n" , ret);
warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'int' [-Wformat=]
%d (0day busy?)
drivers/i2c/busses/i2c-gpio.c static void of_i2c_gpio_get_props(struct device_node *np, · line 97
Quoted 3 lines
drivers/i2c/busses/i2c-gpio.c +3
-0+ +return retdesc; +}
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
PATCH 7/7 i2c: gpio: Add support for named gpios in DT
Quoted 7 lines · Geert Uytterhoeven
drivers/i2c/busses/i2c-gpio.c static void of_i2c_gpio_get_props(struct device_node *np, · line 116
Quoted 2 lines
drivers/i2c/busses/i2c-gpio.c +2
-0+if (ret != -EPROBE_DEFER ) +dev_err (dev,"error trying to get descriptor: %ld\n" , ret);warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'int' [-Wformat=]
%d (0day busy?)
Bah haven't pushed it to the 0day builders yet. I'll do that tonight so I can drown in the build errors. :-D
Fixing it.
Yours,
Linus Walleij
cover I2C GPIO to use gpiolibs open drain
In reply to Linus WalleijHi Linus,
Quoted 14 lines · Linus Walleij
This augments the I2C GPIO driver to use open drain emulation or hardware support for open drain from the GPIO driver.
This version layers Geert Uytterhoeven's idea to use explicit sda-gpios and scl-gpios for the GPIO lines, and strongly encourage the (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) flags to be used in all device trees.
We have collected ACKs from the ARM SoC maintainers and the MFD maintainer and are looking for testers to try this out.
Geert Uytterhoeven (1):
dt-bindings: i2c: i2c-gpio: Add support for named gpios
Quoted 7 lines
Linus Walleij (6):
i2c: gpio: Convert to use descriptors
gpio: Make it possible for consumers to enforce open drain
i2c: gpio: Enforce open drain through gpiolib
i2c: gpio: Augment all boardfiles to use open drain
i2c: gpio: Local vars in probe
i2c: gpio: Add support for named gpios in DT
Thanks for doing this, and picking up my patch.
I gave this a try on r8a7740/armadillo800eva.
Without DT changes, the GPIO i2c bus still works fine, but a warning is printed, as expected:
gpio-208 (sda): enforced open drain please flag it properly in
DT/ACPI DSDT/board file
gpio-91 (scl): enforced open drain please flag it properly in
DT/ACPI DSDT/board file
After
- sda-gpios = <&pfc 208 GPIO_ACTIVE_HIGH>;
- scl-gpios = <&pfc 91 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&pfc 208 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&pfc 91 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
the warning is gone, and the GPIO i2c bus still works.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds