diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index a3210df3135..e4ddf723df8 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -16,7 +16,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_LPC gpio_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MMIO32 gpio_mmio32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_XEC gpio_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NRFX gpio_nrfx.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_PCAL9535A gpio_pcal9535a.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_PCA95XX gpio_pca95xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_STM32 gpio_stm32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SAM0 gpio_sam0.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SAM gpio_sam.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4d0c3a6862f..e9b6be26d2e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -21,7 +21,7 @@ config GPIO_SHELL source "drivers/gpio/Kconfig.dw" -source "drivers/gpio/Kconfig.pcal9535a" +source "drivers/gpio/Kconfig.pca95xx" source "drivers/gpio/Kconfig.mcux" diff --git a/drivers/gpio/Kconfig.pca95xx b/drivers/gpio/Kconfig.pca95xx new file mode 100644 index 00000000000..e898c4ed3a2 --- /dev/null +++ b/drivers/gpio/Kconfig.pca95xx @@ -0,0 +1,148 @@ +# PCA95XX GPIO configuration options + +# Copyright (c) 2016 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_PCA95XX + bool "PCA95XX I2C-based GPIO chip" + depends on I2C + help + Enable driver for PCA95XX I2C-based GPIO chip. + +if GPIO_PCA95XX + +config GPIO_PCA95XX_INIT_PRIORITY + int "Init priority" + default 70 + help + Device driver initialization priority. + +config GPIO_PCA95XX_0 + bool "PCA95XX GPIO chip #0" + help + Enable config options for the PCA95XX I2C-based GPIO chip #0. + +config GPIO_PCA95XX_0_DEV_NAME + string "PCA95XX GPIO chip #0 Device Name" + depends on GPIO_PCA95XX_0 + default "GPIO_P0" + help + Specify the device name for the PCA95XX I2C-based GPIO chip #0. + +config GPIO_PCA95XX_0_I2C_ADDR + hex "PCA95XX GPIO chip #0 I2C slave address" + depends on GPIO_PCA95XX_0 + help + Specify the I2C slave address for the PCA95XX I2C-based GPIO chip #0. + +config GPIO_PCA95XX_0_I2C_MASTER_DEV_NAME + string "I2C Master where PCA95XX GPIO chip #0 is connected" + depends on GPIO_PCA95XX_0 + help + Specify the device name of the I2C master device to which this + PCA95XX chip #0 is binded. + +config GPIO_PCA95XX_0_HAS_PUD + bool "PCA95XX GPIO chip #0 supports pull-up/pull-down" + depends on GPIO_PCA95XX_0 + help + Enable if the PCA95XX I2C-based GPIO chip #0 supports + pull-up/pull-down. + +config GPIO_PCA95XX_1 + bool "PCA95XX GPIO chip #1" + help + Enable config options for the PCA95XX I2C-based GPIO chip #1. + +config GPIO_PCA95XX_1_DEV_NAME + string "PCA95XX GPIO chip #1 Device Name" + depends on GPIO_PCA95XX_1 + default "GPIO_P1" + help + Specify the device name for the PCA95XX I2C-based GPIO chip #1. + +config GPIO_PCA95XX_1_I2C_ADDR + hex "PCA95XX GPIO chip #1 I2C slave address" + depends on GPIO_PCA95XX_1 + help + Specify the I2C slave address for the PCA95XX I2C-based GPIO chip #1. + +config GPIO_PCA95XX_1_I2C_MASTER_DEV_NAME + string "I2C Master where PCA95XX GPIO chip #1 is connected" + depends on GPIO_PCA95XX_1 + help + Specify the device name of the I2C master device to which this + PCA95XX chip #1 is binded. + +config GPIO_PCA95XX_1_HAS_PUD + bool "PCA95XX GPIO chip #1 supports pull-up/pull-down" + depends on GPIO_PCA95XX_1 + help + Enable if the PCA95XX I2C-based GPIO chip #1 supports + pull-up/pull-down. + +config GPIO_PCA95XX_2 + bool "PCA95XX GPIO chip #2" + help + Enable config options for the PCA95XX I2C-based GPIO chip #2. + +config GPIO_PCA95XX_2_DEV_NAME + string "PCA95XX GPIO chip #2 Device Name" + depends on GPIO_PCA95XX_2 + default "GPIO_P2" + help + Specify the device name for the PCA95XX I2C-based GPIO chip #2. + +config GPIO_PCA95XX_2_I2C_ADDR + hex "PCA95XX GPIO chip #2 I2C slave address" + depends on GPIO_PCA95XX_2 + help + Specify the I2C slave address for the PCA95XX I2C-based GPIO chip #2. + +config GPIO_PCA95XX_2_I2C_MASTER_DEV_NAME + string "I2C Master where PCA95XX GPIO chip #2 is connected" + depends on GPIO_PCA95XX_2 + help + Specify the device name of the I2C master device to which this + PCA95XX chip #2 is binded. + +config GPIO_PCA95XX_2_HAS_PUD + bool "PCA95XX GPIO chip #2 supports pull-up/pull-down" + depends on GPIO_PCA95XX_2 + help + Enable if the PCA95XX I2C-based GPIO chip #2 supports + pull-up/pull-down. + +config GPIO_PCA95XX_3 + bool "PCA95XX GPIO chip #3" + help + Enable config options for the PCA95XX I2C-based GPIO chip #3. + +config GPIO_PCA95XX_3_DEV_NAME + string "PCA95XX GPIO chip #3 Device Name" + depends on GPIO_PCA95XX_3 + default "GPIO_P3" + help + Specify the device name for the PCA95XX I2C-based GPIO chip #3. + +config GPIO_PCA95XX_3_I2C_ADDR + hex "PCA95XX GPIO chip #3 I2C slave address" + depends on GPIO_PCA95XX_3 + help + Specify the I2C slave address for the PCA95XX I2C-based GPIO chip #3. + +config GPIO_PCA95XX_3_I2C_MASTER_DEV_NAME + string "I2C Master where PCA95XX GPIO chip #3 is connected" + depends on GPIO_PCA95XX_3 + help + Specify the device name of the I2C master device to which this + PCA95XX chip #3 is binded. + +config GPIO_PCA95XX_3_HAS_PUD + bool "PCA95XX GPIO chip #3 supports pull-up/pull-down" + depends on GPIO_PCA95XX_3 + help + Enable if the PCA95XX I2C-based GPIO chip #3 supports + pull-up/pull-down. + +endif # GPIO_PCA95XX diff --git a/drivers/gpio/Kconfig.pcal9535a b/drivers/gpio/Kconfig.pcal9535a deleted file mode 100644 index 7bd50b46771..00000000000 --- a/drivers/gpio/Kconfig.pcal9535a +++ /dev/null @@ -1,120 +0,0 @@ -# PCAL9535A GPIO configuration options - -# Copyright (c) 2016 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -menuconfig GPIO_PCAL9535A - bool "PCAL9535A I2C-based GPIO chip" - depends on I2C - help - Enable driver for PCAL9535A I2C-based GPIO chip. - -if GPIO_PCAL9535A - -config GPIO_PCAL9535A_INIT_PRIORITY - int "Init priority" - default 70 - help - Device driver initialization priority. - -config GPIO_PCAL9535A_0 - bool "PCAL9535A GPIO chip #0" - help - Enable config options for the PCAL9535A I2C-based GPIO chip #0. - -config GPIO_PCAL9535A_0_DEV_NAME - string "PCAL9535A GPIO chip #0 Device Name" - depends on GPIO_PCAL9535A_0 - default "GPIO_P0" - help - Specify the device name for the PCAL9535A I2C-based GPIO chip #0. - -config GPIO_PCAL9535A_0_I2C_ADDR - hex "PCAL9535A GPIO chip #0 I2C slave address" - depends on GPIO_PCAL9535A_0 - help - Specify the I2C slave address for the PCAL9535A I2C-based GPIO chip #0. - -config GPIO_PCAL9535A_0_I2C_MASTER_DEV_NAME - string "I2C Master where PCAL9535A GPIO chip #0 is connected" - depends on GPIO_PCAL9535A_0 - help - Specify the device name of the I2C master device to which this - PCAL9535A chip #0 is binded. - -config GPIO_PCAL9535A_1 - bool "PCAL9535A GPIO chip #1" - help - Enable config options for the PCAL9535A I2C-based GPIO chip #1. - -config GPIO_PCAL9535A_1_DEV_NAME - string "PCAL9535A GPIO chip #1 Device Name" - depends on GPIO_PCAL9535A_1 - default "GPIO_P1" - help - Specify the device name for the PCAL9535A I2C-based GPIO chip #1. - -config GPIO_PCAL9535A_1_I2C_ADDR - hex "PCAL9535A GPIO chip #1 I2C slave address" - depends on GPIO_PCAL9535A_1 - help - Specify the I2C slave address for the PCAL9535A I2C-based GPIO chip #1. - -config GPIO_PCAL9535A_1_I2C_MASTER_DEV_NAME - string "I2C Master where PCAL9535A GPIO chip #1 is connected" - depends on GPIO_PCAL9535A_1 - help - Specify the device name of the I2C master device to which this - PCAL9535A chip #1 is binded. - -config GPIO_PCAL9535A_2 - bool "PCAL9535A GPIO chip #2" - help - Enable config options for the PCAL9535A I2C-based GPIO chip #2. - -config GPIO_PCAL9535A_2_DEV_NAME - string "PCAL9535A GPIO chip #2 Device Name" - depends on GPIO_PCAL9535A_2 - default "GPIO_P2" - help - Specify the device name for the PCAL9535A I2C-based GPIO chip #2. - -config GPIO_PCAL9535A_2_I2C_ADDR - hex "PCAL9535A GPIO chip #2 I2C slave address" - depends on GPIO_PCAL9535A_2 - help - Specify the I2C slave address for the PCAL9535A I2C-based GPIO chip #2. - -config GPIO_PCAL9535A_2_I2C_MASTER_DEV_NAME - string "I2C Master where PCAL9535A GPIO chip #2 is connected" - depends on GPIO_PCAL9535A_2 - help - Specify the device name of the I2C master device to which this - PCAL9535A chip #2 is binded. - -config GPIO_PCAL9535A_3 - bool "PCAL9535A GPIO chip #3" - help - Enable config options for the PCAL9535A I2C-based GPIO chip #3. - -config GPIO_PCAL9535A_3_DEV_NAME - string "PCAL9535A GPIO chip #3 Device Name" - depends on GPIO_PCAL9535A_3 - default "GPIO_P3" - help - Specify the device name for the PCAL9535A I2C-based GPIO chip #3. - -config GPIO_PCAL9535A_3_I2C_ADDR - hex "PCAL9535A GPIO chip #3 I2C slave address" - depends on GPIO_PCAL9535A_3 - help - Specify the I2C slave address for the PCAL9535A I2C-based GPIO chip #3. - -config GPIO_PCAL9535A_3_I2C_MASTER_DEV_NAME - string "I2C Master where PCAL9535A GPIO chip #3 is connected" - depends on GPIO_PCAL9535A_3 - help - Specify the device name of the I2C master device to which this - PCAL9535A chip #3 is binded. - -endif # GPIO_PCAL9535A diff --git a/drivers/gpio/gpio_pcal9535a.c b/drivers/gpio/gpio_pca95xx.c similarity index 58% rename from drivers/gpio/gpio_pcal9535a.c rename to drivers/gpio/gpio_pca95xx.c index 29a49611a93..38aec647941 100644 --- a/drivers/gpio/gpio_pcal9535a.c +++ b/drivers/gpio/gpio_pca95xx.c @@ -5,7 +5,7 @@ */ /** - * @file Driver for PCAL9535A I2C-based GPIO driver. + * @file Driver for PCA95XX I2C-based GPIO driver. */ #include @@ -17,11 +17,11 @@ #include #include -#include "gpio_pcal9535a.h" +#include "gpio_pca95xx.h" #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL #include -LOG_MODULE_REGISTER(gpio_pcal9535a); +LOG_MODULE_REGISTER(gpio_pca95xx); /* Register definitions */ #define REG_INPUT_PORT0 0x00 @@ -48,36 +48,39 @@ LOG_MODULE_REGISTER(gpio_pcal9535a); #define REG_INT_STATUS_PORT1 0x4D #define REG_OUTPUT_PORT_CONF 0x4F +/* Driver flags */ +#define PCA_HAS_PUD BIT(0) + /** * @brief Read both port 0 and port 1 registers of certain register function. * * Given the register in reg, read the pair of port 0 and port 1. * - * @param dev Device struct of the PCAL9535A. + * @param dev Device struct of the PCA95XX. * @param reg Register to read (the PORT0 of the pair of registers). * @param buf Buffer to read data into. * * @return 0 if successful, failed otherwise. */ static int read_port_regs(struct device *dev, u8_t reg, - union gpio_pcal9535a_port_data *buf) + union gpio_pca95xx_port_data *buf) { - const struct gpio_pcal9535a_config * const config = + const struct gpio_pca95xx_config * const config = dev->config->config_info; - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; struct device * const i2c_master = drv_data->i2c_master; u16_t i2c_addr = config->i2c_slave_addr; int ret; ret = i2c_burst_read(i2c_master, i2c_addr, reg, buf->byte, 2); if (ret) { - LOG_ERR("PCAL9535A[0x%X]: error reading register 0x%X (%d)", + LOG_ERR("PCA95XX[0x%X]: error reading register 0x%X (%d)", i2c_addr, reg, ret); goto error; } - LOG_DBG("PCAL9535A[0x%X]: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X", + LOG_DBG("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X", i2c_addr, reg, buf->byte[0], (reg + 1), buf->byte[1]); error: @@ -89,35 +92,35 @@ error: * * Given the register in reg, write the pair of port 0 and port 1. * - * @param dev Device struct of the PCAL9535A. + * @param dev Device struct of the PCA95XX. * @param reg Register to write into (the PORT0 of the pair of registers). * @param buf Buffer to write data from. * * @return 0 if successful, failed otherwise. */ static int write_port_regs(struct device *dev, u8_t reg, - union gpio_pcal9535a_port_data *buf) + union gpio_pca95xx_port_data *buf) { - const struct gpio_pcal9535a_config * const config = + const struct gpio_pca95xx_config * const config = dev->config->config_info; - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; struct device * const i2c_master = drv_data->i2c_master; u16_t i2c_addr = config->i2c_slave_addr; int ret; - LOG_DBG("PCAL9535A[0x%X]: Write: REG[0x%X] = 0x%X, REG[0x%X] = " + LOG_DBG("PCA95XX[0x%X]: Write: REG[0x%X] = 0x%X, REG[0x%X] = " "0x%X", i2c_addr, reg, buf->byte[0], (reg + 1), buf->byte[1]); ret = i2c_reg_write_byte(i2c_master, i2c_addr, reg, buf->byte[0]); if (ret) { - LOG_ERR("PCAL9535A[0x%X]: error writing from register 0x%X " + LOG_ERR("PCA95XX[0x%X]: error writing to register 0x%X " "(%d)", i2c_addr, reg, ret); } ret = i2c_reg_write_byte(i2c_master, i2c_addr, reg+1, buf->byte[1]); if (ret) { - LOG_ERR("PCAL9535A[0x%X]: error writing from register 0x%X " + LOG_ERR("PCA95XX[0x%X]: error writing to register 0x%X " "(%d)", i2c_addr, reg, ret); } return ret; @@ -126,7 +129,7 @@ static int write_port_regs(struct device *dev, u8_t reg, /** * @brief Setup the pin direction (input or output) * - * @param dev Device struct of the PCAL9535A + * @param dev Device struct of the PCA95XX * @param access_op Access operation (pin or port) * @param pin The pin number * @param flags Flags of pin or port @@ -136,10 +139,10 @@ static int write_port_regs(struct device *dev, u8_t reg, static int setup_pin_dir(struct device *dev, int access_op, u32_t pin, int flags) { - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; - union gpio_pcal9535a_port_data *reg_dir = &drv_data->reg_cache.dir; - union gpio_pcal9535a_port_data *reg_out = &drv_data->reg_cache.output; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; + union gpio_pca95xx_port_data *reg_dir = &drv_data->reg_cache.dir; + union gpio_pca95xx_port_data *reg_out = &drv_data->reg_cache.output; int ret; /* For each pin, 0 == output, 1 == input */ @@ -189,7 +192,7 @@ done: /** * @brief Setup the pin pull up/pull down status * - * @param dev Device struct of the PCAL9535A + * @param dev Device struct of the PCA95XX * @param access_op Access operation (pin or port) * @param pin The pin number * @param flags Flags of pin or port @@ -199,13 +202,30 @@ done: static int setup_pin_pullupdown(struct device *dev, int access_op, u32_t pin, int flags) { - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; - union gpio_pcal9535a_port_data *reg_pud; + const struct gpio_pca95xx_config * const config = + dev->config->config_info; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; + union gpio_pca95xx_port_data *reg_pud; u16_t bit_mask; u16_t new_value = 0U; int ret; + if ((config->capabilities & PCA_HAS_PUD) == 0) { + /* Chip does not support pull up/pull down */ + if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0U) { + ret = -ENOTSUP; + goto done; + } + + /* If both GPIO_PULL_UP and GPIO_PULL_DOWN are not set, + * we should disable them in hardware. But need to skip + * if the chip does not support pull up/pull down. + */ + ret = 0; + goto done; + } + /* If disabling pull up/down, there is no need to set the selection * register. Just go straight to disabling. */ @@ -282,20 +302,20 @@ done: /** * @brief Configure pin or port * - * @param dev Device struct of the PCAL9535A + * @param dev Device struct of the PCA95XX * @param access_op Access operation (pin or port) * @param pin The pin number * @param flags Flags of pin or port * * @return 0 if successful, failed otherwise */ -static int gpio_pcal9535a_config(struct device *dev, int access_op, +static int gpio_pca95xx_config(struct device *dev, int access_op, u32_t pin, int flags) { int ret; #if (CONFIG_GPIO_LOG_LEVEL >= LOG_LEVEL_DEBUG) - const struct gpio_pcal9535a_config * const config = + const struct gpio_pca95xx_config * const config = dev->config->config_info; u16_t i2c_addr = config->i2c_slave_addr; #endif @@ -314,14 +334,14 @@ static int gpio_pcal9535a_config(struct device *dev, int access_op, ret = setup_pin_dir(dev, access_op, pin, flags); if (ret) { - LOG_ERR("PCAL9535A[0x%X]: error setting pin direction (%d)", + LOG_ERR("PCA95XX[0x%X]: error setting pin direction (%d)", i2c_addr, ret); goto done; } ret = setup_pin_pullupdown(dev, access_op, pin, flags); if (ret) { - LOG_ERR("PCAL9535A[0x%X]: error setting pin pull up/down " + LOG_ERR("PCA95XX[0x%X]: error setting pin pull up/down " "(%d)", i2c_addr, ret); goto done; } @@ -333,19 +353,19 @@ done: /** * @brief Set the pin or port output * - * @param dev Device struct of the PCAL9535A + * @param dev Device struct of the PCA95XX * @param access_op Access operation (pin or port) * @param pin The pin number * @param value Value to set (0 or 1) * * @return 0 if successful, failed otherwise */ -static int gpio_pcal9535a_write(struct device *dev, int access_op, +static int gpio_pca95xx_write(struct device *dev, int access_op, u32_t pin, u32_t value) { - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; - union gpio_pcal9535a_port_data *reg_out = &drv_data->reg_cache.output; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; + union gpio_pca95xx_port_data *reg_out = &drv_data->reg_cache.output; int ret; /* Invert input value for pins configurated as active low. */ @@ -374,17 +394,17 @@ done: /** * @brief Read the pin or port status * - * @param dev Device struct of the PCAL9535A + * @param dev Device struct of the PCA95XX * @param access_op Access operation (pin or port) * @param pin The pin number * @param value Value of input pin(s) * * @return 0 if successful, failed otherwise */ -static int gpio_pcal9535a_read(struct device *dev, int access_op, +static int gpio_pca95xx_read(struct device *dev, int access_op, u32_t pin, u32_t *value) { - union gpio_pcal9535a_port_data buf; + union gpio_pca95xx_port_data buf; int ret; ret = read_port_regs(dev, REG_INPUT_PORT0, &buf); @@ -408,9 +428,9 @@ done: return ret; } -static int gpio_pcal9535a_port_get_raw(struct device *dev, u32_t *value) +static int gpio_pca95xx_port_get_raw(struct device *dev, u32_t *value) { - union gpio_pcal9535a_port_data buf; + union gpio_pca95xx_port_data buf; int ret; ret = read_port_regs(dev, REG_INPUT_PORT0, &buf); @@ -424,40 +444,40 @@ done: return ret; } -static int gpio_pcal9535a_port_set_masked_raw(struct device *dev, +static int gpio_pca95xx_port_set_masked_raw(struct device *dev, u32_t mask, u32_t value) { - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; - union gpio_pcal9535a_port_data *reg_out = &drv_data->reg_cache.output; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; + union gpio_pca95xx_port_data *reg_out = &drv_data->reg_cache.output; reg_out->all = (reg_out->all & ~mask) | (mask & value); return write_port_regs(dev, REG_OUTPUT_PORT0, reg_out); } -static int gpio_pcal9535a_port_set_bits_raw(struct device *dev, u32_t mask) +static int gpio_pca95xx_port_set_bits_raw(struct device *dev, u32_t mask) { - return gpio_pcal9535a_port_set_masked_raw(dev, mask, mask); + return gpio_pca95xx_port_set_masked_raw(dev, mask, mask); } -static int gpio_pcal9535a_port_clear_bits_raw(struct device *dev, u32_t mask) +static int gpio_pca95xx_port_clear_bits_raw(struct device *dev, u32_t mask) { - return gpio_pcal9535a_port_set_masked_raw(dev, mask, 0); + return gpio_pca95xx_port_set_masked_raw(dev, mask, 0); } -static int gpio_pcal9535a_port_toggle_bits(struct device *dev, u32_t mask) +static int gpio_pca95xx_port_toggle_bits(struct device *dev, u32_t mask) { - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; - union gpio_pcal9535a_port_data *reg_out = &drv_data->reg_cache.output; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; + union gpio_pca95xx_port_data *reg_out = &drv_data->reg_cache.output; reg_out->all ^= mask; return write_port_regs(dev, REG_OUTPUT_PORT0, reg_out); } -static int gpio_pcal9535a_pin_interrupt_configure(struct device *dev, +static int gpio_pca95xx_pin_interrupt_configure(struct device *dev, unsigned int pin, enum gpio_int_mode mode, enum gpio_int_trig trig) @@ -465,30 +485,30 @@ static int gpio_pcal9535a_pin_interrupt_configure(struct device *dev, return -ENOTSUP; } -static const struct gpio_driver_api gpio_pcal9535a_drv_api_funcs = { - .config = gpio_pcal9535a_config, - .write = gpio_pcal9535a_write, - .read = gpio_pcal9535a_read, - .port_get_raw = gpio_pcal9535a_port_get_raw, - .port_set_masked_raw = gpio_pcal9535a_port_set_masked_raw, - .port_set_bits_raw = gpio_pcal9535a_port_set_bits_raw, - .port_clear_bits_raw = gpio_pcal9535a_port_clear_bits_raw, - .port_toggle_bits = gpio_pcal9535a_port_toggle_bits, - .pin_interrupt_configure = gpio_pcal9535a_pin_interrupt_configure, +static const struct gpio_driver_api gpio_pca95xx_drv_api_funcs = { + .config = gpio_pca95xx_config, + .write = gpio_pca95xx_write, + .read = gpio_pca95xx_read, + .port_get_raw = gpio_pca95xx_port_get_raw, + .port_set_masked_raw = gpio_pca95xx_port_set_masked_raw, + .port_set_bits_raw = gpio_pca95xx_port_set_bits_raw, + .port_clear_bits_raw = gpio_pca95xx_port_clear_bits_raw, + .port_toggle_bits = gpio_pca95xx_port_toggle_bits, + .pin_interrupt_configure = gpio_pca95xx_pin_interrupt_configure, }; /** - * @brief Initialization function of PCAL9535A + * @brief Initialization function of PCA95XX * * @param dev Device struct * @return 0 if successful, failed otherwise. */ -static int gpio_pcal9535a_init(struct device *dev) +static int gpio_pca95xx_init(struct device *dev) { - const struct gpio_pcal9535a_config * const config = + const struct gpio_pca95xx_config * const config = dev->config->config_info; - struct gpio_pcal9535a_drv_data * const drv_data = - (struct gpio_pcal9535a_drv_data * const)dev->driver_data; + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->driver_data; struct device *i2c_master; /* Find out the device struct of the I2C master */ @@ -501,14 +521,17 @@ static int gpio_pcal9535a_init(struct device *dev) return 0; } -/* Initialization for PCAL9535A_0 */ -#ifdef CONFIG_GPIO_PCAL9535A_0 -static const struct gpio_pcal9535a_config gpio_pcal9535a_0_cfg = { - .i2c_master_dev_name = CONFIG_GPIO_PCAL9535A_0_I2C_MASTER_DEV_NAME, - .i2c_slave_addr = CONFIG_GPIO_PCAL9535A_0_I2C_ADDR, +/* Initialization for PCA95XX_0 */ +#ifdef CONFIG_GPIO_PCA95XX_0 +static const struct gpio_pca95xx_config gpio_pca95xx_0_cfg = { + .i2c_master_dev_name = CONFIG_GPIO_PCA95XX_0_I2C_MASTER_DEV_NAME, + .i2c_slave_addr = CONFIG_GPIO_PCA95XX_0_I2C_ADDR, + .capabilities = + (CONFIG_GPIO_PCA95XX_0_HAS_PUD ? PCA_HAS_PUD : 0) | + 0, }; -static struct gpio_pcal9535a_drv_data gpio_pcal9535a_0_drvdata = { +static struct gpio_pca95xx_drv_data gpio_pca95xx_0_drvdata = { /* Default for registers according to datasheet */ .reg_cache.output = { .all = 0xFFFF }, .reg_cache.dir = { .all = 0xFFFF }, @@ -517,22 +540,25 @@ static struct gpio_pcal9535a_drv_data gpio_pcal9535a_0_drvdata = { }; /* This has to init after I2C master */ -DEVICE_AND_API_INIT(gpio_pcal9535a_0, CONFIG_GPIO_PCAL9535A_0_DEV_NAME, - gpio_pcal9535a_init, - &gpio_pcal9535a_0_drvdata, &gpio_pcal9535a_0_cfg, - POST_KERNEL, CONFIG_GPIO_PCAL9535A_INIT_PRIORITY, - &gpio_pcal9535a_drv_api_funcs); +DEVICE_AND_API_INIT(gpio_pca95xx_0, CONFIG_GPIO_PCA95XX_0_DEV_NAME, + gpio_pca95xx_init, + &gpio_pca95xx_0_drvdata, &gpio_pca95xx_0_cfg, + POST_KERNEL, CONFIG_GPIO_PCA95XX_INIT_PRIORITY, + &gpio_pca95xx_drv_api_funcs); -#endif /* CONFIG_GPIO_PCAL9535A_0 */ +#endif /* CONFIG_GPIO_PCA95XX_0 */ -/* Initialization for PCAL9535A_1 */ -#ifdef CONFIG_GPIO_PCAL9535A_1 -static const struct gpio_pcal9535a_config gpio_pcal9535a_1_cfg = { - .i2c_master_dev_name = CONFIG_GPIO_PCAL9535A_1_I2C_MASTER_DEV_NAME, - .i2c_slave_addr = CONFIG_GPIO_PCAL9535A_1_I2C_ADDR, +/* Initialization for PCA95XX_1 */ +#ifdef CONFIG_GPIO_PCA95XX_1 +static const struct gpio_pca95xx_config gpio_pca95xx_1_cfg = { + .i2c_master_dev_name = CONFIG_GPIO_PCA95XX_1_I2C_MASTER_DEV_NAME, + .i2c_slave_addr = CONFIG_GPIO_PCA95XX_1_I2C_ADDR, + .capabilities = + (CONFIG_GPIO_PCA95XX_1_HAS_PUD ? PCA_HAS_PUD : 0) | + 0, }; -static struct gpio_pcal9535a_drv_data gpio_pcal9535a_1_drvdata = { +static struct gpio_pca95xx_drv_data gpio_pca95xx_1_drvdata = { /* Default for registers according to datasheet */ .reg_cache.output = { .all = 0xFFFF }, .reg_cache.dir = { .all = 0xFFFF }, @@ -541,22 +567,25 @@ static struct gpio_pcal9535a_drv_data gpio_pcal9535a_1_drvdata = { }; /* This has to init after I2C master */ -DEVICE_AND_API_INIT(gpio_pcal9535a_1, CONFIG_GPIO_PCAL9535A_1_DEV_NAME, - gpio_pcal9535a_init, - &gpio_pcal9535a_1_drvdata, &gpio_pcal9535a_1_cfg, - POST_KERNEL, CONFIG_GPIO_PCAL9535A_INIT_PRIORITY, - &gpio_pcal9535a_drv_api_funcs); +DEVICE_AND_API_INIT(gpio_pca95xx_1, CONFIG_GPIO_PCA95XX_1_DEV_NAME, + gpio_pca95xx_init, + &gpio_pca95xx_1_drvdata, &gpio_pca95xx_1_cfg, + POST_KERNEL, CONFIG_GPIO_PCA95XX_INIT_PRIORITY, + &gpio_pca95xx_drv_api_funcs); -#endif /* CONFIG_GPIO_PCAL9535A_1 */ +#endif /* CONFIG_GPIO_PCA95XX_1 */ -/* Initialization for PCAL9535A_2 */ -#ifdef CONFIG_GPIO_PCAL9535A_2 -static const struct gpio_pcal9535a_config gpio_pcal9535a_2_cfg = { - .i2c_master_dev_name = CONFIG_GPIO_PCAL9535A_2_I2C_MASTER_DEV_NAME, - .i2c_slave_addr = CONFIG_GPIO_PCAL9535A_2_I2C_ADDR, +/* Initialization for PCA95XX_2 */ +#ifdef CONFIG_GPIO_PCA95XX_2 +static const struct gpio_pca95xx_config gpio_pca95xx_2_cfg = { + .i2c_master_dev_name = CONFIG_GPIO_PCA95XX_2_I2C_MASTER_DEV_NAME, + .i2c_slave_addr = CONFIG_GPIO_PCA95XX_2_I2C_ADDR, + .capabilities = + (CONFIG_GPIO_PCA95XX_2_HAS_PUD ? PCA_HAS_PUD : 0) | + 0, }; -static struct gpio_pcal9535a_drv_data gpio_pcal9535a_2_drvdata = { +static struct gpio_pca95xx_drv_data gpio_pca95xx_2_drvdata = { /* Default for registers according to datasheet */ .reg_cache.output = { .all = 0xFFFF }, .reg_cache.dir = { .all = 0xFFFF }, @@ -565,22 +594,25 @@ static struct gpio_pcal9535a_drv_data gpio_pcal9535a_2_drvdata = { }; /* This has to init after I2C master */ -DEVICE_AND_API_INIT(gpio_pcal9535a_2, CONFIG_GPIO_PCAL9535A_2_DEV_NAME, - gpio_pcal9535a_init, - &gpio_pcal9535a_2_drvdata, &gpio_pcal9535a_2_cfg, - POST_KERNEL, CONFIG_GPIO_PCAL9535A_INIT_PRIORITY, - &gpio_pcal9535a_drv_api_funcs); +DEVICE_AND_API_INIT(gpio_pca95xx_2, CONFIG_GPIO_PCA95XX_2_DEV_NAME, + gpio_pca95xx_init, + &gpio_pca95xx_2_drvdata, &gpio_pca95xx_2_cfg, + POST_KERNEL, CONFIG_GPIO_PCA95XX_INIT_PRIORITY, + &gpio_pca95xx_drv_api_funcs); -#endif /* CONFIG_GPIO_PCAL9535A_2 */ +#endif /* CONFIG_GPIO_PCA95XX_2 */ -/* Initialization for PCAL9535A_3 */ -#ifdef CONFIG_GPIO_PCAL9535A_3 -static const struct gpio_pcal9535a_config gpio_pcal9535a_3_cfg = { - .i2c_master_dev_name = CONFIG_GPIO_PCAL9535A_3_I2C_MASTER_DEV_NAME, - .i2c_slave_addr = CONFIG_GPIO_PCAL9535A_3_I2C_ADDR, +/* Initialization for PCA95XX_3 */ +#ifdef CONFIG_GPIO_PCA95XX_3 +static const struct gpio_pca95xx_config gpio_pca95xx_3_cfg = { + .i2c_master_dev_name = CONFIG_GPIO_PCA95XX_3_I2C_MASTER_DEV_NAME, + .i2c_slave_addr = CONFIG_GPIO_PCA95XX_3_I2C_ADDR, + .capabilities = + (CONFIG_GPIO_PCA95XX_3_HAS_PUD ? PCA_HAS_PUD : 0) | + 0, }; -static struct gpio_pcal9535a_drv_data gpio_pcal9535a_3_drvdata = { +static struct gpio_pca95xx_drv_data gpio_pca95xx_3_drvdata = { /* Default for registers according to datasheet */ .reg_cache.output = { .all = 0xFFFF }, .reg_cache.dir = { .all = 0xFFFF }, @@ -589,10 +621,10 @@ static struct gpio_pcal9535a_drv_data gpio_pcal9535a_3_drvdata = { }; /* This has to init after I2C master */ -DEVICE_AND_API_INIT(gpio_pcal9535a_3, CONFIG_GPIO_PCAL9535A_3_DEV_NAME, - gpio_pcal9535a_init, - &gpio_pcal9535a_3_drvdata, &gpio_pcal9535a_3_cfg, - POST_KERNEL, CONFIG_GPIO_PCAL9535A_INIT_PRIORITY, - &gpio_pcal9535a_drv_api_funcs); +DEVICE_AND_API_INIT(gpio_pca95xx_3, CONFIG_GPIO_PCA95XX_3_DEV_NAME, + gpio_pca95xx_init, + &gpio_pca95xx_3_drvdata, &gpio_pca95xx_3_cfg, + POST_KERNEL, CONFIG_GPIO_PCA95XX_INIT_PRIORITY, + &gpio_pca95xx_drv_api_funcs); -#endif /* CONFIG_GPIO_PCAL9535A_3 */ +#endif /* CONFIG_GPIO_PCA95XX_3 */ diff --git a/drivers/gpio/gpio_pcal9535a.h b/drivers/gpio/gpio_pca95xx.h similarity index 60% rename from drivers/gpio/gpio_pcal9535a.h rename to drivers/gpio/gpio_pca95xx.h index 92be0ed8723..f6d2ae6aad7 100644 --- a/drivers/gpio/gpio_pcal9535a.h +++ b/drivers/gpio/gpio_pca95xx.h @@ -5,11 +5,11 @@ */ /** - * @file Header file for the PCAL9535A driver. + * @file Header file for the PCA95XX driver. */ -#ifndef ZEPHYR_DRIVERS_GPIO_GPIO_PCAL9535A_H_ -#define ZEPHYR_DRIVERS_GPIO_GPIO_PCAL9535A_H_ +#ifndef ZEPHYR_DRIVERS_GPIO_GPIO_PCA95XX_H_ +#define ZEPHYR_DRIVERS_GPIO_GPIO_PCA95XX_H_ #include @@ -21,23 +21,25 @@ extern "C" { #endif /** Configuration data */ -struct gpio_pcal9535a_config { +struct gpio_pca95xx_config { /** The master I2C device's name */ const char * const i2c_master_dev_name; /** The slave address of the chip */ u16_t i2c_slave_addr; + + u8_t capabilities; }; /** Store the port 0/1 data for each register pair. */ -union gpio_pcal9535a_port_data { +union gpio_pca95xx_port_data { u16_t all; u8_t port[2]; u8_t byte[2]; }; /** Runtime driver data */ -struct gpio_pcal9535a_drv_data { +struct gpio_pca95xx_drv_data { /* gpio_driver_data needs to be first */ struct gpio_driver_data common; @@ -45,10 +47,10 @@ struct gpio_pcal9535a_drv_data { struct device *i2c_master; struct { - union gpio_pcal9535a_port_data output; - union gpio_pcal9535a_port_data dir; - union gpio_pcal9535a_port_data pud_en; - union gpio_pcal9535a_port_data pud_sel; + union gpio_pca95xx_port_data output; + union gpio_pca95xx_port_data dir; + union gpio_pca95xx_port_data pud_en; + union gpio_pca95xx_port_data pud_sel; } reg_cache; }; @@ -56,4 +58,4 @@ struct gpio_pcal9535a_drv_data { } #endif -#endif /* ZEPHYR_DRIVERS_GPIO_GPIO_PCAL9535A_H_ */ +#endif /* ZEPHYR_DRIVERS_GPIO_GPIO_PCA95XX_H_ */