drivers: i2c: gpio: convert to using devicetree for instances
Convert the GPIO bit banging I2C controller driver to use devicetree bindings for configuring instances. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
ea61a6e3fd
commit
911b6a0e9f
2 changed files with 68 additions and 173 deletions
|
@ -6,143 +6,3 @@ config I2C_GPIO
|
|||
select I2C_BITBANG
|
||||
help
|
||||
Enable software driven (bit banging) I2C support using GPIO pins
|
||||
|
||||
# ---------- Port 0 ----------
|
||||
|
||||
config I2C_GPIO_0
|
||||
bool "Enable GPIO Bit Bang I2C device 0"
|
||||
depends on I2C_GPIO
|
||||
help
|
||||
This tells the driver to configure the I2C device at boot, depending
|
||||
on the additional configuration options below.
|
||||
|
||||
if I2C_GPIO_0
|
||||
|
||||
config I2C_GPIO_0_NAME
|
||||
string "GPIO Bit Bang I2C device 0 device name"
|
||||
default "I2C_0"
|
||||
help
|
||||
This is the device name for the I2C device, and is included in the
|
||||
device struct.
|
||||
|
||||
config I2C_GPIO_0_GPIO
|
||||
string "Bit Bang I2C device 0 GPIO name"
|
||||
help
|
||||
This is the name of the GPIO device that controls the I2C lines.
|
||||
|
||||
config I2C_GPIO_0_SCL_PIN
|
||||
int "Bit Bang I2C device 0 GPIO pin number for SCL"
|
||||
help
|
||||
This is the GPIO pin number for the I2S SCL line
|
||||
|
||||
config I2C_GPIO_0_SDA_PIN
|
||||
int "Bit Bang I2C device 0 GPIO pin number for SDA"
|
||||
help
|
||||
This is the GPIO pin number for the I2S SDA line
|
||||
|
||||
endif # I2C_GPIO_0
|
||||
|
||||
# ---------- Port 1 ----------
|
||||
|
||||
config I2C_GPIO_1
|
||||
bool "Enable GPIO Bit Bang I2C device 1"
|
||||
depends on I2C_GPIO
|
||||
help
|
||||
This tells the driver to configure the I2C device at boot, depending
|
||||
on the additional configuration options below.
|
||||
|
||||
if I2C_GPIO_1
|
||||
|
||||
config I2C_GPIO_1_NAME
|
||||
string "Bit Bang I2C device 1 device name"
|
||||
default "I2C_1"
|
||||
help
|
||||
This is the device name for the I2C device, and is included in the
|
||||
device struct.
|
||||
|
||||
config I2C_GPIO_1_GPIO
|
||||
string "Bit Bang I2C device 1 GPIO name"
|
||||
help
|
||||
This is the name of the GPIO device that controls the I2C lines.
|
||||
|
||||
config I2C_GPIO_1_SCL_PIN
|
||||
int "Bit Bang I2C device 1 GPIO pin number for SCL"
|
||||
help
|
||||
This is the GPIO pin number for the I2S SCL line
|
||||
|
||||
config I2C_GPIO_1_SDA_PIN
|
||||
int "Bit Bang I2C device 1 GPIO pin number for SDA"
|
||||
help
|
||||
This is the GPIO pin number for the I2S SDA line
|
||||
|
||||
endif # I2C_GPIO_1
|
||||
|
||||
# ---------- Port 2 ----------
|
||||
|
||||
config I2C_GPIO_2
|
||||
bool "Enable GPIO Bit Bang I2C device 2"
|
||||
depends on I2C_GPIO
|
||||
help
|
||||
This tells the driver to configure the I2C device at boot, depending
|
||||
on the additional configuration options below.
|
||||
|
||||
if I2C_GPIO_2
|
||||
|
||||
config I2C_GPIO_2_NAME
|
||||
string "Bit Bang I2C device 2 device name"
|
||||
default "I2C_2"
|
||||
help
|
||||
This is the device name for the I2C device, and is included in the
|
||||
device struct.
|
||||
|
||||
config I2C_GPIO_2_GPIO
|
||||
string "Bit Bang I2C device 2 GPIO name"
|
||||
help
|
||||
This is the name of the GPIO device that controls the I2C lines.
|
||||
|
||||
config I2C_GPIO_2_SCL_PIN
|
||||
int "Bit Bang I2C device 2 GPIO pin number for SCL"
|
||||
help
|
||||
This is the GPIO pin number for the I2S SCL line
|
||||
|
||||
config I2C_GPIO_2_SDA_PIN
|
||||
int "Bit Bang I2C device 2 GPIO pin number for SDA"
|
||||
help
|
||||
This is the GPIO pin number for the I2S SDA line
|
||||
|
||||
endif # I2C_GPIO_2
|
||||
|
||||
# ---------- Port 3 ----------
|
||||
|
||||
config I2C_GPIO_3
|
||||
bool "Enable GPIO Bit Bang I2C device 3"
|
||||
depends on I2C_GPIO
|
||||
help
|
||||
This tells the driver to configure the I2C device at boot, depending
|
||||
on the additional configuration options below.
|
||||
|
||||
if I2C_GPIO_3
|
||||
|
||||
config I2C_GPIO_3_NAME
|
||||
string "Bit Bang I2C device 3 device name"
|
||||
default "I2C_3"
|
||||
help
|
||||
This is the device name for the I2C device, and is included in the
|
||||
device struct.
|
||||
|
||||
config I2C_GPIO_3_GPIO
|
||||
string "Bit Bang I2C device 3 GPIO name"
|
||||
help
|
||||
This is the name of the GPIO device that controls the I2C lines.
|
||||
|
||||
config I2C_GPIO_3_SCL_PIN
|
||||
int "Bit Bang I2C device 3 GPIO pin number for SCL"
|
||||
help
|
||||
This is the GPIO pin number for the I2C SCL line
|
||||
|
||||
config I2C_GPIO_3_SDA_PIN
|
||||
int "Bit Bang I2C device 3 GPIO pin number for SDA"
|
||||
help
|
||||
This is the GPIO pin number for the I2C SDA line
|
||||
|
||||
endif # I2C_GPIO_3
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vestas Wind Systems A/S
|
||||
* Copyright (c) 2017 Linaro Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT gpio_i2c
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Driver for software driven I2C using GPIO lines
|
||||
*
|
||||
* This driver implements an I2C interface by driving two GPIO lines under
|
||||
* software control. The GPIO pins used must be preconfigured to to a suitable
|
||||
* state, i.e. the SDA pin as open-colector/open-drain with a pull-up resistor
|
||||
* software control. The GPIO pins used must be configured (through devicetree and pinmux) with suitable
|
||||
* flags, i.e. the SDA pin as open-colector/open-drain with a pull-up resistor
|
||||
* (possibly as an external component attached to the pin). When the SDA pin
|
||||
* is read it must return the state of the physical hardware line, not just the
|
||||
* last state written to it for output.
|
||||
|
@ -24,41 +27,51 @@
|
|||
#include <errno.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <drivers/i2c.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(i2c_gpio);
|
||||
|
||||
#include "i2c-priv.h"
|
||||
#include "i2c_bitbang.h"
|
||||
|
||||
/* Driver config */
|
||||
struct i2c_gpio_config {
|
||||
char *gpio_name;
|
||||
u8_t scl_pin;
|
||||
u8_t sda_pin;
|
||||
const char *scl_gpio_name;
|
||||
const char *sda_gpio_name;
|
||||
gpio_pin_t scl_pin;
|
||||
gpio_pin_t sda_pin;
|
||||
gpio_dt_flags_t scl_flags;
|
||||
gpio_dt_flags_t sda_flags;
|
||||
u32_t bitrate;
|
||||
};
|
||||
|
||||
/* Driver instance data */
|
||||
struct i2c_gpio_context {
|
||||
struct i2c_bitbang bitbang; /* Bit-bang library data */
|
||||
struct device *gpio; /* GPIO used for I2C lines */
|
||||
u8_t scl_pin; /* Pin on gpio used for SCL line */
|
||||
u8_t sda_pin; /* Pin on gpio used for SDA line */
|
||||
struct device *scl_gpio; /* GPIO used for I2C SCL line */
|
||||
struct device *sda_gpio; /* GPIO used for I2C SDA line */
|
||||
gpio_pin_t scl_pin; /* Pin on gpio used for SCL line */
|
||||
gpio_pin_t sda_pin; /* Pin on gpio used for SDA line */
|
||||
};
|
||||
|
||||
static void i2c_gpio_set_scl(void *io_context, int state)
|
||||
{
|
||||
struct i2c_gpio_context *context = io_context;
|
||||
|
||||
gpio_pin_set(context->gpio, context->scl_pin, state);
|
||||
gpio_pin_set(context->scl_gpio, context->scl_pin, state);
|
||||
}
|
||||
|
||||
static void i2c_gpio_set_sda(void *io_context, int state)
|
||||
{
|
||||
struct i2c_gpio_context *context = io_context;
|
||||
|
||||
gpio_pin_set(context->gpio, context->sda_pin, state);
|
||||
gpio_pin_set(context->sda_gpio, context->sda_pin, state);
|
||||
}
|
||||
|
||||
static int i2c_gpio_get_sda(void *io_context)
|
||||
{
|
||||
struct i2c_gpio_context *context = io_context;
|
||||
int rc = gpio_pin_get(context->gpio, context->sda_pin);
|
||||
int rc = gpio_pin_get(context->sda_gpio, context->sda_pin);
|
||||
|
||||
/* Default high as that would be a NACK */
|
||||
return rc != 0;
|
||||
|
@ -83,7 +96,7 @@ static int i2c_gpio_transfer(struct device *dev, struct i2c_msg *msgs,
|
|||
struct i2c_gpio_context *context = dev->driver_data;
|
||||
|
||||
return i2c_bitbang_transfer(&context->bitbang, msgs, num_msgs,
|
||||
slave_address);
|
||||
slave_address);
|
||||
}
|
||||
|
||||
static struct i2c_driver_api api = {
|
||||
|
@ -95,16 +108,48 @@ static int i2c_gpio_init(struct device *dev)
|
|||
{
|
||||
struct i2c_gpio_context *context = dev->driver_data;
|
||||
const struct i2c_gpio_config *config = dev->config->config_info;
|
||||
u32_t bitrate_cfg;
|
||||
int err;
|
||||
|
||||
context->gpio = device_get_binding(config->gpio_name);
|
||||
if (!context->gpio) {
|
||||
context->scl_gpio = device_get_binding(config->scl_gpio_name);
|
||||
if (!context->scl_gpio) {
|
||||
LOG_ERR("failed to get SCL GPIO device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = gpio_config(context->scl_gpio, config->scl_pin,
|
||||
config->scl_flags | GPIO_OUTPUT_HIGH);
|
||||
if (err) {
|
||||
LOG_ERR("failed to configure SCL GPIO pin (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
context->sda_gpio = device_get_binding(config->sda_gpio_name);
|
||||
if (!context->sda_gpio) {
|
||||
LOG_ERR("failed to get SCL GPIO device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = gpio_config(context->sda_gpio, config->sda_pin,
|
||||
config->sda_flags | GPIO_OUTPUT_HIGH);
|
||||
if (err) {
|
||||
LOG_ERR("failed to configure SDA GPIO pin (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
context->sda_pin = config->sda_pin;
|
||||
context->scl_pin = config->scl_pin;
|
||||
|
||||
i2c_bitbang_init(&context->bitbang, &io_fns, context);
|
||||
|
||||
bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
|
||||
err = i2c_bitbang_configure(&context->bitbang,
|
||||
I2C_MODE_MASTER | bitrate_cfg);
|
||||
if (err) {
|
||||
LOG_ERR("failed to configure I2C bitbang (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -113,29 +158,19 @@ static int i2c_gpio_init(struct device *dev)
|
|||
static struct i2c_gpio_context i2c_gpio_dev_data_##_num; \
|
||||
\
|
||||
static const struct i2c_gpio_config i2c_gpio_dev_cfg_##_num = { \
|
||||
.gpio_name = CONFIG_I2C_GPIO_##_num##_GPIO, \
|
||||
.scl_pin = CONFIG_I2C_GPIO_##_num##_SCL_PIN, \
|
||||
.sda_pin = CONFIG_I2C_GPIO_##_num##_SDA_PIN, \
|
||||
.scl_gpio_name = DT_INST_GPIO_LABEL(_num, scl_gpios), \
|
||||
.sda_gpio_name = DT_INST_GPIO_LABEL(_num, sda_gpios), \
|
||||
.scl_pin = DT_INST_GPIO_PIN(_num, scl_gpios), \
|
||||
.sda_pin = DT_INST_GPIO_PIN(_num, sda_gpios), \
|
||||
.scl_flags = DT_INST_GPIO_FLAGS(_num, scl_gpios), \
|
||||
.sda_flags = DT_INST_GPIO_FLAGS(_num, sda_gpios), \
|
||||
.bitrate = DT_INST_PROP(_num, clock_frequency), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_AND_API_INIT(i2c_gpio_##_num, CONFIG_I2C_GPIO_##_num##_NAME, \
|
||||
DEVICE_AND_API_INIT(i2c_gpio_##_num, DT_INST_LABEL(_num), \
|
||||
i2c_gpio_init, \
|
||||
&i2c_gpio_dev_data_##_num, \
|
||||
&i2c_gpio_dev_cfg_##_num, \
|
||||
PRE_KERNEL_2, CONFIG_I2C_INIT_PRIORITY, &api)
|
||||
|
||||
#ifdef CONFIG_I2C_GPIO_0
|
||||
DEFINE_I2C_GPIO(0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_GPIO_1
|
||||
DEFINE_I2C_GPIO(1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_GPIO_2
|
||||
DEFINE_I2C_GPIO(2);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_GPIO_3
|
||||
DEFINE_I2C_GPIO(3);
|
||||
#endif
|
||||
DT_INST_FOREACH(DEFINE_I2C_GPIO)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue