summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2019-10-11 18:27:50 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-10-14 15:18:16 +0200
commitefd517c35f122bb08ebc1fc29e741a5211553acc (patch)
treec74ed2f4b48b7397b65d6a3edafc87449da5a3b2 /include
parent6fa1b91f6e7596472c5197f6960e3e14b9c30795 (diff)
downloadbarebox-efd517c35f122bb08ebc1fc29e741a5211553acc.tar.gz
barebox-efd517c35f122bb08ebc1fc29e741a5211553acc.tar.xz
mfd: add basic Super I/O chip helpers
Super I/O chips are ICs common to x86 that are used for interfacing to low-bandwidth peripherals. They often contain serial ports, watchdog timers and hardware monitoring units. They are usually addressable via one of two I/O port pairs, either 0x2e-0x2f or 0x4e-0x4f, but they don't typically respond to reads from their range unless a device-specific 'password' has been poked in. After this is done, they are read and written in the same manner however. On Linux, these devices aren't subject to any device/driver model. Each driver for some function (e.g. watchdog or GPIO) duplicates the device probe in the module_init and board-specific configuration is handled via module parameters. Lets do it a bit fancier in barebox and add a helper to register chips and a regmap for the control and configuration registers as well as a helper to register child devices for each function contained within the Super I/O chip. Board-specific configuration, e.g. which pin to use as a watchdog reset, can then be realized using barebox device-specific parameters. The regmap will be more of a debugging aid, however. For ease of porting from Linux, it's expected that access to the I/O ports won't happen via the regmap. For this reason, the new <superio.h> header offers functions to read/write these chips' registers as well. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/superio.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/include/superio.h b/include/superio.h
new file mode 100644
index 0000000000..12bff58b6b
--- /dev/null
+++ b/include/superio.h
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef _SUPERIO_H_
+#define _SUPERIO_H_
+
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <driver.h>
+#include <linux/types.h>
+
+#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
+#define SIO_REG_DEVREV 0x22 /* Device revision */
+#define SIO_REG_MANID 0x23 /* Vendor ID (2 bytes) */
+
+static inline u8 superio_inb(u16 base, u8 reg)
+{
+ outb(reg, base);
+ return inb(base + 1);
+}
+
+static inline u16 superio_inw(u16 base, u8 reg)
+{
+ u16 val;
+ val = superio_inb(base, reg) << 8;
+ val |= superio_inb(base, reg + 1);
+ return val;
+}
+
+static inline void superio_outb(u16 base, u8 reg, u8 val)
+{
+ outb(reg, base);
+ outb(val, base + 1);
+}
+
+static inline void superio_set_bit(u16 base, u8 reg, unsigned bit)
+{
+ unsigned long val = superio_inb(base, reg);
+ __set_bit(bit, &val);
+ superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(u16 base, u8 reg, unsigned bit)
+{
+ unsigned long val = superio_inb(base, reg);
+ __clear_bit(bit, &val);
+ superio_outb(base, reg, val);
+}
+
+struct superio_chip {
+ struct device_d *dev;
+ u16 vid;
+ u16 devid;
+ u16 sioaddr;
+ void (*enter)(u16 sioaddr);
+ void (*exit)(u16 sioaddr);
+};
+
+void superio_chip_add(struct superio_chip *chip);
+struct device_d *superio_func_add(struct superio_chip *chip, const char *name);
+
+#endif