summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Zeh <werner.zeh@siemens.com>2018-02-14 07:52:08 +0100
committerWerner Zeh <werner.zeh@siemens.com>2018-02-15 07:33:04 +0000
commita45d94ac0bd388445957e0b116bbae12d010ae1a (patch)
tree2bfcd612460ef183fc44e6c21304f3ef0b77df85
parenta94b112aec5a8df83313816ca2ca8019cffaba5f (diff)
downloadcoreboot-a45d94ac0bd388445957e0b116bbae12d010ae1a.tar.xz
drivers/i2c: Add chip driver for I/O expander PCA9538
The chip PCA9538 is a 8 bit I/O expander connected to the systems I2C bus. Add a chip driver to support this chip. Beside the pure chip driver two interface functions are provided to read the state of the pins and write output values to the pins. As the slave address of this chip is hardware configurable the function pca9538_get_dev() is used to get the right slave address. This function needs to be implemented in mainboard code if one needs to use the interface functions to read and write I/O state. Change-Id: Ic856123b4f4c8b721928ee3a2a4bb37833ea4b20 Signed-off-by: Werner Zeh <werner.zeh@siemens.com> Reviewed-on: https://review.coreboot.org/23748 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/drivers/i2c/pca9538/Kconfig5
-rw-r--r--src/drivers/i2c/pca9538/Makefile.inc5
-rw-r--r--src/drivers/i2c/pca9538/chip.h21
-rw-r--r--src/drivers/i2c/pca9538/pca9538.c70
-rw-r--r--src/drivers/i2c/pca9538/pca9538.h38
5 files changed, 139 insertions, 0 deletions
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 <device/i2c_bus.h>
+#include <device/device.h>
+#include <console/console.h>
+#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 <types.h>
+#include <device/device.h>
+
+/* 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_ */