diff --git a/src/drivers/i2c/pca9538/Kconfig b/src/drivers/i2c/pca9538/Kconfig new file mode 100644 index 0000000000..558332be3d --- /dev/null +++ b/src/drivers/i2c/pca9538/Kconfig @@ -0,0 +1,5 @@ +config DRIVERS_I2C_PCA9538 + bool + default n + help + Enable support for I2C I/O expander PCA9538. diff --git a/src/drivers/i2c/pca9538/Makefile.inc b/src/drivers/i2c/pca9538/Makefile.inc new file mode 100644 index 0000000000..8b7fa2546e --- /dev/null +++ b/src/drivers/i2c/pca9538/Makefile.inc @@ -0,0 +1,5 @@ +ramstage-$(CONFIG_DRIVERS_I2C_PCA9538) += pca9538.c + +ifeq ($(CONFIG_DRIVERS_I2C_PCA9538),y) +CFLAGS_common += -Isrc/drivers/i2c/pca9538 +endif diff --git a/src/drivers/i2c/pca9538/chip.h b/src/drivers/i2c/pca9538/chip.h new file mode 100644 index 0000000000..9c60aab226 --- /dev/null +++ b/src/drivers/i2c/pca9538/chip.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Siemens AG + * + * 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; version 2 of the License. + * + * 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. + */ + + +struct drivers_i2c_pca9538_config { + unsigned char in_out; /* Use bit as input(1) or output (0). */ + unsigned char invert; /* If a bit is 1, the input will be inverted. */ + unsigned char out_val; /* Initial output value to drive. */ +}; diff --git a/src/drivers/i2c/pca9538/pca9538.c b/src/drivers/i2c/pca9538/pca9538.c new file mode 100644 index 0000000000..30e3b47acf --- /dev/null +++ b/src/drivers/i2c/pca9538/pca9538.c @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Siemens AG + * + * 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; version 2 of the License. + * + * 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. + */ + +#include +#include +#include +#include "pca9538.h" +#include "chip.h" + +/* This function can be used from outside the chip driver to read input. */ +uint8_t pca9538_read_input(void) +{ + struct device *dev = pca9538_get_dev(); + + if (!dev) + return 0; + else + return (uint8_t)(i2c_dev_readb_at(dev, INPUT_REG)); +} + +/* This function can be used from outside the chip driver to set output. */ +void pca9538_set_output(uint8_t val) +{ + struct device *dev = pca9538_get_dev(); + + if (dev) + i2c_dev_writeb_at(dev, OUTPUT_REG, val); +} + +static void pca9538_init(struct device *dev) +{ + struct drivers_i2c_pca9538_config *config = dev->chip_info; + + if (!config) + return; + /* Set up registers as requested in devicetree. */ + i2c_dev_writeb_at(dev, INPUT_INVERT_REG, config->invert); + i2c_dev_writeb_at(dev, OUTPUT_REG, config->out_val); + i2c_dev_writeb_at(dev, IO_CONFIG_REG, config->in_out); +} + +static struct device_operations pca9538_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, + .init = pca9538_init, + .final = DEVICE_NOOP +}; + +static void pca9538_enable(struct device *dev) +{ + dev->ops = &pca9538_ops; +} + +struct chip_operations drivers_i2c_pca9538_ops = { + CHIP_NAME("PCA9538") + .enable_dev = pca9538_enable +}; diff --git a/src/drivers/i2c/pca9538/pca9538.h b/src/drivers/i2c/pca9538/pca9538.h new file mode 100644 index 0000000000..6db95be646 --- /dev/null +++ b/src/drivers/i2c/pca9538/pca9538.h @@ -0,0 +1,38 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Siemens AG + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef _I2C_PCA9538_H_ +#define _I2C_PCA9538_H_ + +#include +#include + +/* Register layout */ +#define INPUT_REG 0x00 +#define OUTPUT_REG 0x01 +#define INPUT_INVERT_REG 0x02 +#define IO_CONFIG_REG 0x03 + +/* Provide some functions to read input and write output values. */ +uint8_t pca9538_read_input(void); +void pca9538_set_output(uint8_t val); +/* + * Provide a way to get the right device structure for the I/O expander. + * The user of this driver has to provide this function if read/write of I/O + * values on the I/O expander is needed. + */ +struct device *pca9538_get_dev(void); + +#endif /* _I2C_PCA9538_H_ */