Initial support for NXP's 4 and 8 bit I2C gpio expanders (eg pca9537, pca9557, etc). The CONFIG_PCA953X define enables support for the devices while the CONFIG_CMD_PCA953X define enables the pca953x command.
Signed-off-by: Peter Tyser <[EMAIL PROTECTED]> --- Makefile | 2 + README | 7 ++ drivers/gpio/Makefile | 47 ++++++++++++ drivers/gpio/pca953x.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++ include/gpio/pca953x.h | 39 ++++++++++ 5 files changed, 281 insertions(+), 0 deletions(-) create mode 100644 drivers/gpio/Makefile create mode 100644 drivers/gpio/pca953x.c create mode 100644 include/gpio/pca953x.h diff --git a/Makefile b/Makefile index fceb8a2..40c08a7 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,7 @@ LIBS += disk/libdisk.a LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/block/libblock.a LIBS += drivers/dma/libdma.a +LIBS += drivers/gpio/libgpio.a LIBS += drivers/hwmon/libhwmon.a LIBS += drivers/i2c/libi2c.a LIBS += drivers/input/libinput.a @@ -396,6 +397,7 @@ TAG_SUBDIRS += disk TAG_SUBDIRS += common TAG_SUBDIRS += drivers/bios_emulator TAG_SUBDIRS += drivers/block +TAG_SUBDIRS += drivers/gpio TAG_SUBDIRS += drivers/hwmon TAG_SUBDIRS += drivers/i2c TAG_SUBDIRS += drivers/input diff --git a/README b/README index ebee20f..73bed41 100644 --- a/README +++ b/README @@ -601,6 +601,7 @@ The following options need to be configured: CONFIG_CMD_MII * MII utility commands CONFIG_CMD_NAND * NAND support CONFIG_CMD_NET bootp, tftpboot, rarpboot + CONFIG_CMD_PCA953X * PCA953x I2C gpio commands CONFIG_CMD_PCI * pciinfo CONFIG_CMD_PCMCIA * PCMCIA support CONFIG_CMD_PING * send ICMP ECHO_REQUEST to network @@ -678,6 +679,12 @@ The following options need to be configured: Note that if the RTC uses I2C, then the I2C interface must also be configured. See I2C Support, below. +- GPIO Support: + CONFIG_PCA953X - use NXP's PCA953X series I2C GPIO + + Note that if the GPIO device uses I2C, then the I2C interface + must also be configured. See I2C Support, below. + - Timestamp Support: When CONFIG_TIMESTAMP is selected, the timestamp diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile new file mode 100644 index 0000000..dd618ed --- /dev/null +++ b/drivers/gpio/Makefile @@ -0,0 +1,47 @@ +# +# Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, [EMAIL PROTECTED] +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libgpio.a + +COBJS-$(CONFIG_PCA953X) += pca953x.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################## diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c new file mode 100644 index 0000000..317241a --- /dev/null +++ b/drivers/gpio/pca953x.c @@ -0,0 +1,186 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Driver for NXP's 4 and 8 bit I2C gpio expanders (eg pca9537, pca9557, etc) + * TODO: support additional devices with more than 8-bits GPIO + */ + +#include <common.h> +#include <i2c.h> +#include <gpio/pca953x.h> + +/* + * Modify masked bits in register + */ +static int pca953x_reg_write(uint8_t chip, uint addr, uint mask, uint data) +{ + uint8_t val; + + if (i2c_read(chip, addr, 1, &val, 1)) + return -1; + + val &= ~mask; + val |= data; + + return i2c_write(chip, addr, 1, &val, 1); +} + +/* + * Set output value of IO pins in 'mask' to corresponding value in 'data' + * 0 = low, 1 = high + */ +int pca953x_set_val(uint8_t chip, uint mask, uint data) +{ + return pca953x_reg_write(chip, PCA953X_OUT, mask, data); +} + +/* + * Set read polarity of IO pins in 'mask' to corresponding value in 'data' + * 0 = read pin value, 1 = read inverted pin value + */ +int pca953x_set_pol(uint8_t chip, uint mask, uint data) +{ + return pca953x_reg_write(chip, PCA953X_POL, mask, data); +} + +/* + * Set direction of IO pins in 'mask' to corresponding value in 'data' + * 0 = output, 1 = input + */ +int pca953x_set_dir(uint8_t chip, uint mask, uint data) +{ + return pca953x_reg_write(chip, PCA953X_CONF, mask, data); +} + +/* + * Read current logic level of all IO pins + */ +int pca953x_get_val(uint8_t chip) +{ + uint8_t val; + + if (i2c_read(chip, 0, 1, &val, 1)) + return -1; + + return (int)val; +} + +#ifdef CONFIG_CMD_PCA953X +/* + * Display pca953x information + */ +static int pca953x_info(uint8_t chip) +{ + int i; + uint8_t data; + + printf("pca953x@ 0x%x:\n\n", chip); + printf("gpio pins: 76543210\n"); + printf("-------------------\n"); + + i2c_read(chip, PCA953X_CONF, 1, &data, 1); + printf("conf: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? 'i' : 'o'); + printf("\n"); + + i2c_read(chip, PCA953X_POL, 1, &data, 1); + printf("invert: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? '1' : '0'); + printf("\n"); + + i2c_read(chip, PCA953X_IN, 1, &data, 1); + printf("input: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? '1' : '0'); + printf("\n"); + + i2c_read(chip, PCA953X_OUT, 1, &data, 1); + printf("output: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? '1' : '0'); + printf("\n"); + + return 0; +} + +int do_pca953x(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int val; + uint8_t chip; + ulong pin; + + chip = (uint8_t)simple_strtoul(argv[1], NULL, 16); + + if (i2c_probe(chip)) { + printf("I2C device 0x%02x not found\n", chip); + return -1; + } + + switch (argc) { + case 3: + if (strcmp(argv[2], "info") == 0) + return pca953x_info(chip); + break; + case 4: + if (strcmp(argv[2], "input") != 0) + break; + + pin = simple_strtoul(argv[3], NULL, 16); + + pca953x_set_dir(chip, (1 << pin), PCA953X_DIR_IN << pin); + val = (pca953x_get_val(chip) & (1 << pin)) != 0; + + printf("chip 0x%02x, pin 0x%lx = %d\n", chip, pin, val); + return val; + case 5: + pin = simple_strtoul(argv[3], NULL, 16); + val = simple_strtoul(argv[4], NULL, 16) & 0x1; + + if (strcmp(argv[2], "output") == 0) { + pca953x_set_dir(chip, (1 << pin), + (PCA953X_DIR_OUT << pin)); + return pca953x_set_val(chip, (1 << pin), (val << pin)); + } else if (strcmp(argv[2], "invert") == 0) { + return pca953x_set_pol(chip, (1 << pin), (val << pin)); + } + break; + default: + break; + } + + printf("Usage:\n%s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD( + pca953x, 6, 2, do_pca953x, + "pca953x - pca953x gpio access\n", + "chip info\n" + " - display info for chip\n" + "pca953x chip output pin 0|1\n" + " - set pin as output and drive low or high\n" + "pca953x chip invert pin 0|1\n" + " - disable/enable polarity inversion for reads\n" + "pca953x chip intput pin\n" + " - set pin as input and read value\n" +); + +#endif /* CONFIG_CMD_PCA953X */ diff --git a/include/gpio/pca953x.h b/include/gpio/pca953x.h new file mode 100644 index 0000000..6c2b58c --- /dev/null +++ b/include/gpio/pca953x.h @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __PCA953X_H_ +#define __PCA953X_H_ + +#define PCA953X_IN 0x00 +#define PCA953X_OUT 0x01 +#define PCA953X_POL 0x02 +#define PCA953X_CONF 0x03 + +#define PCA953X_OUT_LOW 0 +#define PCA953X_OUT_HIGH 1 +#define PCA953X_POL_NORMAL 0 +#define PCA953X_POL_INVERT 1 +#define PCA953X_DIR_OUT 0 +#define PCA953X_DIR_IN 1 + +int pca953x_set_val(u8 chip, uint mask, uint data); +int pca953x_set_pol(u8 chip, uint mask, uint data); +int pca953x_set_dir(u8 chip, uint mask, uint data); +int pca953x_get_val(u8 chip); + +#endif /* __PCA953X_H_ */ -- 1.6.0.2.GIT _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot