diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2019-10-11 18:27:50 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-10-14 15:18:16 +0200 |
commit | efd517c35f122bb08ebc1fc29e741a5211553acc (patch) | |
tree | c74ed2f4b48b7397b65d6a3edafc87449da5a3b2 /include | |
parent | 6fa1b91f6e7596472c5197f6960e3e14b9c30795 (diff) | |
download | barebox-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.h | 64 |
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 |