diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/Makefile | 74 | ||||
| -rw-r--r-- | drivers/gpio/adi_gpio2.c | 17 | ||||
| -rw-r--r-- | drivers/gpio/sx151x.c | 242 |
3 files changed, 268 insertions, 65 deletions
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 71ddb00bb..b903c45c5 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -5,51 +5,29 @@ # SPDX-License-Identifier: GPL-2.0+ # -include $(TOPDIR)/config.mk - -LIB := $(obj)libgpio.o - -COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o -COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o -COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o -COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o -COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o -COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o -COBJS-$(CONFIG_MXS_GPIO) += mxs_gpio.o -COBJS-$(CONFIG_PCA953X) += pca953x.o -COBJS-$(CONFIG_PCA9698) += pca9698.o -COBJS-$(CONFIG_S5P) += s5p_gpio.o -COBJS-$(CONFIG_SANDBOX_GPIO) += sandbox.o -COBJS-$(CONFIG_SPEAR_GPIO) += spear_gpio.o -COBJS-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o -COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o -COBJS-$(CONFIG_DM644X_GPIO) += da8xx_gpio.o -COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o -COBJS-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o -COBJS-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o -COBJS-$(CONFIG_OMAP_GPIO) += omap_gpio.o -COBJS-$(CONFIG_DB8500_GPIO) += db8500_gpio.o -COBJS-$(CONFIG_BCM2835_GPIO) += bcm2835_gpio.o -COBJS-$(CONFIG_S3C2440_GPIO) += s3c2440_gpio.o -COBJS-$(CONFIG_XILINX_GPIO) += xilinx_gpio.o -COBJS-$(CONFIG_ADI_GPIO2) += adi_gpio2.o -COBJS-$(CONFIG_TCA642X) += tca642x.o - -COBJS := $(COBJS-y) -SRCS := $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) - -all: $(LIB) - -$(LIB): $(obj).depend $(OBJS) - $(call cmd_link_o_target, $(OBJS)) - - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################## +obj-$(CONFIG_AT91_GPIO) += at91_gpio.o +obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o +obj-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o +obj-$(CONFIG_MARVELL_GPIO) += mvgpio.o +obj-$(CONFIG_MARVELL_MFP) += mvmfp.o +obj-$(CONFIG_MXC_GPIO) += mxc_gpio.o +obj-$(CONFIG_MXS_GPIO) += mxs_gpio.o +obj-$(CONFIG_PCA953X) += pca953x.o +obj-$(CONFIG_PCA9698) += pca9698.o +obj-$(CONFIG_S5P) += s5p_gpio.o +obj-$(CONFIG_SANDBOX_GPIO) += sandbox.o +obj-$(CONFIG_SPEAR_GPIO) += spear_gpio.o +obj-$(CONFIG_TEGRA_GPIO) += tegra_gpio.o +obj-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o +obj-$(CONFIG_DM644X_GPIO) += da8xx_gpio.o +obj-$(CONFIG_ALTERA_PIO) += altera_pio.o +obj-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o +obj-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o +obj-$(CONFIG_OMAP_GPIO) += omap_gpio.o +obj-$(CONFIG_DB8500_GPIO) += db8500_gpio.o +obj-$(CONFIG_BCM2835_GPIO) += bcm2835_gpio.o +obj-$(CONFIG_S3C2440_GPIO) += s3c2440_gpio.o +obj-$(CONFIG_XILINX_GPIO) += xilinx_gpio.o +obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o +obj-$(CONFIG_TCA642X) += tca642x.o +oby-$(CONFIG_SX151X) += sx151x.o diff --git a/drivers/gpio/adi_gpio2.c b/drivers/gpio/adi_gpio2.c index 051073cee..88cd65b87 100644 --- a/drivers/gpio/adi_gpio2.c +++ b/drivers/gpio/adi_gpio2.c @@ -10,22 +10,6 @@ #include <common.h> #include <asm/errno.h> #include <asm/gpio.h> -#include <asm/portmux.h> - -static struct gpio_port_t * const gpio_array[] = { - (struct gpio_port_t *)PORTA_FER, - (struct gpio_port_t *)PORTB_FER, - (struct gpio_port_t *)PORTC_FER, - (struct gpio_port_t *)PORTD_FER, - (struct gpio_port_t *)PORTE_FER, - (struct gpio_port_t *)PORTF_FER, - (struct gpio_port_t *)PORTG_FER, -#if defined(CONFIG_BF54x) - (struct gpio_port_t *)PORTH_FER, - (struct gpio_port_t *)PORTI_FER, - (struct gpio_port_t *)PORTJ_FER, -#endif -}; #define RESOURCE_LABEL_SIZE 16 @@ -98,7 +82,6 @@ static void port_setup(unsigned gpio, unsigned short usage) else gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio); #endif - SSYNC(); } inline void portmux_setup(unsigned short per) diff --git a/drivers/gpio/sx151x.c b/drivers/gpio/sx151x.c new file mode 100644 index 000000000..167cf40c7 --- /dev/null +++ b/drivers/gpio/sx151x.c @@ -0,0 +1,242 @@ +/* + * (C) Copyright 2013 + * Viktar Palstsiuk, Promwad, viktar.palstsiuk@promwad.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Driver for Semtech SX151x SPI GPIO Expanders + */ + +#include <common.h> +#include <spi.h> +#include <sx151x.h> + +#ifndef CONFIG_SX151X_SPI_BUS +#define CONFIG_SX151X_SPI_BUS 0 +#endif + +/* + * The SX151x registers + */ + +#ifdef CONFIG_SX151X_GPIO_COUNT_8 +/* 8bit: SX1511 */ +#define SX151X_REG_DIR 0x07 +#define SX151X_REG_DATA 0x08 +#else +/* 16bit: SX1512 */ +#define SX151X_REG_DIR 0x0F +#define SX151X_REG_DATA 0x11 +#endif +#define SX151X_REG_RESET 0x7D + +static int sx151x_spi_write(int chip, unsigned char reg, unsigned char val) +{ + struct spi_slave *slave; + unsigned char buf[2]; + int ret; + + slave = spi_setup_slave(CONFIG_SX151X_SPI_BUS, chip, 1000000, + SPI_MODE_0); + if (!slave) + return 0; + + spi_claim_bus(slave); + + buf[0] = reg; + buf[1] = val; + + ret = spi_xfer(slave, 16, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END); + if (ret < 0) + printf("spi%d.%d write fail: can't write %02x to %02x: %d\n", + CONFIG_SX151X_SPI_BUS, chip, val, reg, ret); + else + printf("spi%d.%d write 0x%02x to register 0x%02x\n", + CONFIG_SX151X_SPI_BUS, chip, val, reg); + spi_release_bus(slave); + spi_free_slave(slave); + + return ret; +} + +static int sx151x_spi_read(int chip, unsigned char reg) +{ + struct spi_slave *slave; + int ret; + + slave = spi_setup_slave(CONFIG_SX151X_SPI_BUS, chip, 1000000, + SPI_MODE_0); + if (!slave) + return 0; + + spi_claim_bus(slave); + + ret = spi_w8r8(slave, reg | 0x80); + if (ret < 0) + printf("spi%d.%d read fail: can't read %02x: %d\n", + CONFIG_SX151X_SPI_BUS, chip, reg, ret); + else + printf("spi%d.%d read register 0x%02x: 0x%02x\n", + CONFIG_SX151X_SPI_BUS, chip, reg, ret); + + spi_release_bus(slave); + spi_free_slave(slave); + + return ret; +} + +static inline void sx151x_find_cfg(int gpio, unsigned char *reg, unsigned char *mask) +{ + *reg -= gpio / 8; + *mask = 1 << (gpio % 8); +} + +static int sx151x_write_cfg(int chip, unsigned char gpio, unsigned char reg, int val) +{ + unsigned char mask; + unsigned char data; + int ret; + + sx151x_find_cfg(gpio, ®, &mask); + ret = sx151x_spi_read(chip, reg); + if (ret < 0) + return ret; + else + data = ret; + data &= ~mask; + data |= (val << (gpio % 8)) & mask; + return sx151x_spi_write(chip, reg, data); +} + +int sx151x_get_value(int chip, int gpio) +{ + unsigned char reg = SX151X_REG_DATA; + unsigned char mask; + int ret; + + sx151x_find_cfg(gpio, ®, &mask); + ret = sx151x_spi_read(chip, reg); + if (ret >= 0) + ret = (ret & mask) != 0 ? 1 : 0; + + return ret; +} + +int sx151x_set_value(int chip, int gpio, int val) +{ + return sx151x_write_cfg(chip, gpio, SX151X_REG_DATA, (val ? 1 : 0)); +} + +int sx151x_direction_input(int chip, int gpio) +{ + return sx151x_write_cfg(chip, gpio, SX151X_REG_DIR, 1); +} + +int sx151x_direction_output(int chip, int gpio) +{ + return sx151x_write_cfg(chip, gpio, SX151X_REG_DIR, 0); +} + +int sx151x_reset(int chip) +{ + int err; + + err = sx151x_spi_write(chip, SX151X_REG_RESET, 0x12); + if (err < 0) + return err; + + err = sx151x_spi_write(chip, SX151X_REG_RESET, 0x34); + return err; +} + +#ifdef CONFIG_CMD_SX151X + +int do_sx151x(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret = CMD_RET_USAGE, chip = 0, gpio = 0, val = 0; + + if (argc < 3) + return CMD_RET_USAGE; + + /* arg2 used as chip number */ + chip = simple_strtoul(argv[2], NULL, 10); + + if (strcmp(argv[1], "reset") == 0) { + ret = sx151x_reset(chip); + if (!ret) { + printf("Device at spi%d.%d was reset\n", + CONFIG_SX151X_SPI_BUS, chip); + } + return ret; + } + + if (argc < 4) + return CMD_RET_USAGE; + + /* arg3 used as gpio number */ + gpio = simple_strtoul(argv[3], NULL, 10); + + if (strcmp(argv[1], "get") == 0) { + ret = sx151x_get_value(chip, gpio); + if (ret < 0) + printf("Failed to get value at spi%d.%d gpio %d\n", + CONFIG_SX151X_SPI_BUS, chip, gpio); + else { + printf("Value at spi%d.%d gpio %d is %d\n", + CONFIG_SX151X_SPI_BUS, chip, gpio, ret); + ret = 0; + } + return ret; + } + + if (argc < 5) + return CMD_RET_USAGE; + + /* arg4 used as value or direction */ + val = simple_strtoul(argv[4], NULL, 10); + + if (strcmp(argv[1], "set") == 0) { + ret = sx151x_set_value(chip, gpio, val); + if (ret < 0) + printf("Failed to set value at spi%d.%d gpio %d\n", + CONFIG_SX151X_SPI_BUS, chip, gpio); + else + printf("New value at spi%d.%d gpio %d is %d\n", + CONFIG_SX151X_SPI_BUS, chip, gpio, val); + return ret; + } else if (strcmp(argv[1], "dir") == 0) { + if (val == 0) + ret = sx151x_direction_output(chip, gpio); + else + ret = sx151x_direction_input(chip, gpio); + + if (ret < 0) + printf("Failed to set direction of spi%d.%d gpio %d\n", + CONFIG_SX151X_SPI_BUS, chip, gpio); + else + printf("New direction of spi%d.%d gpio %d is %d\n", + CONFIG_SX151X_SPI_BUS, chip, gpio, val); + return ret; + } + + printf("Please see usage\n"); + + return ret; +} + +U_BOOT_CMD( + sx151x, 5, 1, do_sx151x, + "sx151x gpio access", + "dir chip gpio 0|1\n" + " - set gpio direction (0 for output, 1 for input)\n" + "sx151x get chip gpio\n" + " - get gpio value\n" + "sx151x set chip gpio 0|1\n" + " - set gpio value\n" + "sx151x reset chip\n" + " - reset chip" +); + +#endif /* CONFIG_CMD_SX151X */ |