1
0
Fork 0

Merge branch 'for-wolfram' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio into i2c/for-4.15

Refactor i2c-gpio and its users to use gpiod. Done by GPIO maintainer
LinusW.
hifive-unleashed-5.1
Wolfram Sang 2017-11-01 23:44:52 +01:00
commit 4ee045f4e9
29 changed files with 422 additions and 288 deletions

View File

@ -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@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>;

View File

@ -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,47 @@ 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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("G", 0, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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);
}

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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));

View File

@ -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();

View File

@ -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));

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", AVILA_SCL_PIN,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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);

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", DSMG600_SCL_PIN,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", FSG_SCL_PIN,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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");

View File

@ -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/rawnand.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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", IXDP425_SCL_PIN,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));
}

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", NAS100D_SCL_PIN,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", NSLU2_SCL_PIN,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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,17 @@
#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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("KS8695", 5, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = {
.sda_pin = 4,
.scl_pin = 5,
.udelay = 10,
};
@ -95,6 +103,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,

View File

@ -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,17 @@ 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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("gpio-pxa", 117, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
.sda_pin = 118,
.scl_pin = 117,
.udelay = 10,
.timeout = 100,
};
@ -369,6 +378,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);
}

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("gpio-pxa", VIPER_RTC_I2C_SCL_GPIO,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("gpio-pxa", VIPER_TPM_I2C_SCL_GPIO,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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,17 @@ 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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("gpio", GPIO_GPIO25, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
static struct i2c_gpio_platform_data simpad_i2c_data = {
.sda_pin = GPIO_GPIO21,
.scl_pin = GPIO_GPIO25,
.udelay = 10,
.timeout = HZ,
};
@ -380,6 +389,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");

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("BFIN-GPIO", GPIO_PF9, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("BFIN-GPIO", GPIO_PF0, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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,

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("BFIN-GPIO", GPIO_PF3, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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));

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("BFIN-GPIO", GPIO_PF0, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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;

View File

@ -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,27 @@ 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,
/*
* The open drain mode is hardwired somewhere or an electrical
* property of the alchemy GPIO controller.
*/
.sda_is_open_drain = 1,
.scl_pin = 210,
.scl_is_open_drain = 1,
.udelay = 2, /* ~100 kHz */
.timeout = HZ,
@ -295,6 +313,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));

View File

@ -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_OPEN_DRAIN),
GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SCL,
NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
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);

View File

@ -3264,8 +3264,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)

View File

@ -14,27 +14,17 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
struct i2c_gpio_private_data {
struct gpio_desc *sda;
struct gpio_desc *scl;
struct i2c_adapter adap;
struct i2c_algo_bit_data bit_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_platform_data *pdata = data;
if (state)
gpio_direction_input(pdata->sda_pin);
else
gpio_direction_output(pdata->sda_pin, 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
@ -42,20 +32,9 @@ static void i2c_gpio_setsda_dir(void *data, int state)
*/
static void i2c_gpio_setsda_val(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
struct i2c_gpio_private_data *priv = data;
gpio_set_value(pdata->sda_pin, state);
}
/* Toggle SCL by changing the direction of the pin. */
static void i2c_gpio_setscl_dir(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
if (state)
gpio_direction_input(pdata->scl_pin);
else
gpio_direction_output(pdata->scl_pin, 0);
gpiod_set_value(priv->sda, state);
}
/*
@ -66,44 +45,23 @@ static void i2c_gpio_setscl_dir(void *data, int state)
*/
static void i2c_gpio_setscl_val(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
struct i2c_gpio_private_data *priv = data;
gpio_set_value(pdata->scl_pin, state);
gpiod_set_value(priv->scl, state);
}
static int i2c_gpio_getsda(void *data)
{
struct i2c_gpio_platform_data *pdata = data;
struct i2c_gpio_private_data *priv = data;
return gpio_get_value(pdata->sda_pin);
return gpiod_get_value(priv->sda);
}
static int i2c_gpio_getscl(void *data)
{
struct i2c_gpio_platform_data *pdata = data;
struct i2c_gpio_private_data *priv = data;
return gpio_get_value(pdata->scl_pin);
}
static int of_i2c_gpio_get_pins(struct device_node *np,
unsigned int *sda_pin, unsigned int *scl_pin)
{
if (of_gpio_count(np) < 2)
return -ENODEV;
*sda_pin = of_get_gpio(np, 0);
*scl_pin = of_get_gpio(np, 1);
if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) {
pr_err("%pOF: invalid GPIO pins, sda=%d/scl=%d\n",
np, *sda_pin, *scl_pin);
return -ENODEV;
}
return 0;
return gpiod_get_value(priv->scl);
}
static void of_i2c_gpio_get_props(struct device_node *np,
@ -124,72 +82,105 @@ 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: %d\n", ret);
return retdesc;
}
static int i2c_gpio_probe(struct platform_device *pdev)
{
struct i2c_gpio_private_data *priv;
struct i2c_gpio_platform_data *pdata;
struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap;
unsigned int sda_pin, scl_pin;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
enum gpiod_flags gflags;
int ret;
/* First get the GPIO pins; if it fails, we'll defer the probe. */
if (pdev->dev.of_node) {
ret = of_i2c_gpio_get_pins(pdev->dev.of_node,
&sda_pin, &scl_pin);
if (ret)
return ret;
} else {
if (!dev_get_platdata(&pdev->dev))
return -ENXIO;
pdata = dev_get_platdata(&pdev->dev);
sda_pin = pdata->sda_pin;
scl_pin = pdata->scl_pin;
}
ret = devm_gpio_request(&pdev->dev, sda_pin, "sda");
if (ret) {
if (ret == -EINVAL)
ret = -EPROBE_DEFER; /* Try again later */
return ret;
}
ret = devm_gpio_request(&pdev->dev, scl_pin, "scl");
if (ret) {
if (ret == -EINVAL)
ret = -EPROBE_DEFER; /* Try again later */
return ret;
}
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
adap = &priv->adap;
bit_data = &priv->bit_data;
pdata = &priv->pdata;
if (pdev->dev.of_node) {
pdata->sda_pin = sda_pin;
pdata->scl_pin = scl_pin;
of_i2c_gpio_get_props(pdev->dev.of_node, pdata);
if (np) {
of_i2c_gpio_get_props(np, pdata);
} else {
memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata));
/*
* If all platform data settings are zero it is OK
* to not provide any platform data from the board.
*/
if (dev_get_platdata(dev))
memcpy(pdata, dev_get_platdata(dev), sizeof(*pdata));
}
if (pdata->sda_is_open_drain) {
gpio_direction_output(pdata->sda_pin, 1);
bit_data->setsda = i2c_gpio_setsda_val;
} else {
gpio_direction_input(pdata->sda_pin);
bit_data->setsda = i2c_gpio_setsda_dir;
}
/*
* 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)
gflags = GPIOD_OUT_HIGH;
else
gflags = GPIOD_OUT_HIGH_OPEN_DRAIN;
priv->sda = i2c_gpio_get_desc(dev, "sda", 0, gflags);
if (IS_ERR(priv->sda))
return PTR_ERR(priv->sda);
if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
gpio_direction_output(pdata->scl_pin, 1);
bit_data->setscl = i2c_gpio_setscl_val;
} else {
gpio_direction_input(pdata->scl_pin);
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 = 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;
if (!pdata->scl_is_output_only)
bit_data->getscl = i2c_gpio_getscl;
@ -207,18 +198,18 @@ static int i2c_gpio_probe(struct platform_device *pdev)
else
bit_data->timeout = HZ / 10; /* 100 ms */
bit_data->data = pdata;
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);
@ -227,8 +218,13 @@ static int i2c_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
pdata->sda_pin, pdata->scl_pin,
/*
* FIXME: using global GPIO numbers is not helpful. If/when we
* get accessors to get the actual name of the GPIO line,
* from the descriptor, then provide that instead.
*/
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" : "");

View File

@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/i2c-gpio.h>
#include <linux/gpio/machine.h>
#include <linux/slab.h>
#include <linux/sm501.h>
@ -1107,14 +1108,6 @@ static void sm501_gpio_remove(struct sm501_devdata *sm)
kfree(gpio->regs_res);
}
static inline int sm501_gpio_pin2nr(struct sm501_devdata *sm, unsigned int pin)
{
struct sm501_gpio *gpio = &sm->gpio;
int base = (pin < 32) ? gpio->low.gpio.base : gpio->high.gpio.base;
return (pin % 32) + base;
}
static inline int sm501_gpio_isregistered(struct sm501_devdata *sm)
{
return sm->gpio.registered;
@ -1129,11 +1122,6 @@ static inline void sm501_gpio_remove(struct sm501_devdata *sm)
{
}
static inline int sm501_gpio_pin2nr(struct sm501_devdata *sm, unsigned int pin)
{
return -1;
}
static inline int sm501_gpio_isregistered(struct sm501_devdata *sm)
{
return 0;
@ -1145,20 +1133,37 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm,
{
struct i2c_gpio_platform_data *icd;
struct platform_device *pdev;
struct gpiod_lookup_table *lookup;
pdev = sm501_create_subdev(sm, "i2c-gpio", 0,
sizeof(struct i2c_gpio_platform_data));
if (!pdev)
return -ENOMEM;
/* Create a gpiod lookup using gpiochip-local offsets */
lookup = devm_kzalloc(&pdev->dev,
sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup),
GFP_KERNEL);
lookup->dev_id = "i2c-gpio";
if (iic->pin_sda < 32)
lookup->table[0].chip_label = "SM501-LOW";
else
lookup->table[0].chip_label = "SM501-HIGH";
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 | GPIO_OPEN_DRAIN;
if (iic->pin_scl < 32)
lookup->table[1].chip_label = "SM501-LOW";
else
lookup->table[1].chip_label = "SM501-HIGH";
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 | GPIO_OPEN_DRAIN;
gpiod_add_lookup_table(lookup);
icd = dev_get_platdata(&pdev->dev);
/* We keep the pin_sda and pin_scl fields relative in case the
* same platform data is passed to >1 SM501.
*/
icd->sda_pin = sm501_gpio_pin2nr(sm, iic->pin_sda);
icd->scl_pin = sm501_gpio_pin2nr(sm, iic->pin_scl);
icd->timeout = iic->timeout;
icd->udelay = iic->udelay;
@ -1170,9 +1175,9 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm,
pdev->id = iic->bus_num;
dev_info(sm->dev, "registering i2c-%d: sda=%d (%d), scl=%d (%d)\n",
dev_info(sm->dev, "registering i2c-%d: sda=%d, scl=%d\n",
iic->bus_num,
icd->sda_pin, iic->pin_sda, icd->scl_pin, iic->pin_scl);
iic->pin_sda, iic->pin_scl);
return sm501_register_device(sm, pdev);
}

View File

@ -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

View File

@ -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;