Qualcom processors use proprietary bus to talk with PMIC devices - SPMI (System Power Management Interface). On wiring level it is similar to I2C, but on protocol level, it's multi-master and has simple autodetection capabilities. This commit adds simple uclass that provides bus read/write interface.
Signed-off-by: Mateusz Kulikowski <mateusz.kulikow...@gmail.com> Reviewed-by: Simon Glass <s...@chromium.org> Tested-by: Simon Glass <s...@chromium.org> --- Changes in v3: None Changes in v2: - Use proper entry order in Kconfig - Rename CONFIG_DM_SPMI -> CONFIG_SPMI - Fix header ordering - Add reviewed-by Changes in v1: - Reorder includes - Add read/write arguments documentation drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/spmi/Kconfig | 10 ++++++++++ drivers/spmi/Makefile | 7 +++++++ drivers/spmi/spmi-uclass.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/spmi/spmi.h | 47 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 116 insertions(+) create mode 100644 drivers/spmi/Kconfig create mode 100644 drivers/spmi/Makefile create mode 100644 drivers/spmi/spmi-uclass.c create mode 100644 include/spmi/spmi.h diff --git a/drivers/Kconfig b/drivers/Kconfig index 70993fd..c82a94b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -60,6 +60,8 @@ source "drivers/sound/Kconfig" source "drivers/spi/Kconfig" +source "drivers/spmi/Kconfig" + source "drivers/thermal/Kconfig" source "drivers/timer/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index e7eab66..6900097 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -54,6 +54,7 @@ obj-y += dfu/ obj-$(CONFIG_X86) += pch/ obj-y += rtc/ obj-y += sound/ +obj-y += spmi/ obj-y += timer/ obj-y += tpm/ obj-y += twserial/ diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig new file mode 100644 index 0000000..0b9bd31 --- /dev/null +++ b/drivers/spmi/Kconfig @@ -0,0 +1,10 @@ +menu "SPMI support" + +config SPMI + bool "Enable SPMI bus support" + depends on DM + ---help--- + Select this to enable to support SPMI bus. + SPMI (System Power Management Interface) bus is used + to connect PMIC devices on various SoCs. +endmenu diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile new file mode 100644 index 0000000..99092eb --- /dev/null +++ b/drivers/spmi/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikow...@gmail.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SPMI) += spmi-uclass.o diff --git a/drivers/spmi/spmi-uclass.c b/drivers/spmi/spmi-uclass.c new file mode 100644 index 0000000..4ddd51b --- /dev/null +++ b/drivers/spmi/spmi-uclass.c @@ -0,0 +1,48 @@ +/* + * SPMI bus uclass driver + * + * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikow...@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <dm/root.h> +#include <spmi/spmi.h> +#include <linux/ctype.h> + +DECLARE_GLOBAL_DATA_PTR; + +int spmi_reg_read(struct udevice *dev, int usid, int pid, int reg) +{ + const struct dm_spmi_ops *ops = dev_get_driver_ops(dev); + + if (!ops || !ops->read) + return -ENOSYS; + + return ops->read(dev, usid, pid, reg); +} + +int spmi_reg_write(struct udevice *dev, int usid, int pid, int reg, + uint8_t value) +{ + const struct dm_spmi_ops *ops = dev_get_driver_ops(dev); + + if (!ops || !ops->write) + return -ENOSYS; + + return ops->write(dev, usid, pid, reg, value); +} + +static int spmi_post_bind(struct udevice *dev) +{ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +UCLASS_DRIVER(spmi) = { + .id = UCLASS_SPMI, + .name = "spmi", + .post_bind = spmi_post_bind, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 73cd3ac..956b63f 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -64,6 +64,7 @@ enum uclass_id { UCLASS_RTC, /* Real time clock device */ UCLASS_SERIAL, /* Serial UART */ UCLASS_SPI, /* SPI bus */ + UCLASS_SPMI, /* System Power Management Interface bus */ UCLASS_SPI_FLASH, /* SPI flash */ UCLASS_SPI_GENERIC, /* Generic SPI flash target */ UCLASS_SYSCON, /* System configuration device */ diff --git a/include/spmi/spmi.h b/include/spmi/spmi.h new file mode 100644 index 0000000..65a49bd --- /dev/null +++ b/include/spmi/spmi.h @@ -0,0 +1,47 @@ +#ifndef _SPMI_SPMI_H +#define _SPMI_SPMI_H + +/** + * struct dm_spmi_ops - SPMI device I/O interface + * + * Should be implemented by UCLASS_SPMI device drivers. The standard + * device operations provides the I/O interface for it's childs. + * + * @read: read register 'reg' of slave 'usid' and peripheral 'pid' + * @write: write register 'reg' of slave 'usid' and peripheral 'pid' + * + * Each register is 8-bit, both read and write can return negative values + * on error. + */ +struct dm_spmi_ops { + int (*read)(struct udevice *dev, int usid, int pid, int reg); + int (*write)(struct udevice *dev, int usid, int pid, int reg, + uint8_t value); +}; + +/** + * spmi_reg_read() - read a register from specific slave/peripheral + * + * @dev: SPMI bus to read + * @usid SlaveID + * @pid Peripheral ID + * @reg: Register to read + * @return value read on success or negative value of errno. + */ +int spmi_reg_read(struct udevice *dev, int usid, int pid, int reg); + +/** + * spmi_reg_write() - write a register of specific slave/peripheral + * + * @dev: SPMI bus to write + * @usid SlaveID + * @pid Peripheral ID + * @reg: Register to write + * @value: Value to write + * @return 0 on success or negative value of errno. + */ +int spmi_reg_write(struct udevice *dev, int usid, int pid, int reg, + uint8_t value); + +#endif + -- 2.5.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot