From c2f74c8f53bd2333d85d5063e9d043382df2a987 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Thu, 31 Mar 2016 23:12:30 +0200 Subject: [PATCH] pmic: Add support for Qualcomm PM8916 PMIC This PMIC is connected on SPMI bus so needs SPMI support enabled. Signed-off-by: Mateusz Kulikowski Reviewed-by: Simon Glass Tested-by: Simon Glass --- doc/device-tree-bindings/pmic/pm8916.txt | 18 +++++ drivers/power/pmic/Kconfig | 16 ++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pm8916.c | 96 ++++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 doc/device-tree-bindings/pmic/pm8916.txt create mode 100644 drivers/power/pmic/pm8916.c diff --git a/doc/device-tree-bindings/pmic/pm8916.txt b/doc/device-tree-bindings/pmic/pm8916.txt new file mode 100644 index 0000000000..15c598b8c4 --- /dev/null +++ b/doc/device-tree-bindings/pmic/pm8916.txt @@ -0,0 +1,18 @@ +Qualcomm pm8916 PMIC + +This PMIC is connected using SPMI bus so should be child of SPMI bus controller. + +Required properties: +- compatible: "qcom,spmi-pmic"; +- reg: SPMI Slave ID, size (ignored) +- #address-cells: 0x1 (peripheral ID) +- #size-cells: 0x1 (size of peripheral register space) + +Example: + +pm8916@0 { + compatible = "qcom,spmi-pmic"; + reg = <0x0 0x1>; + #address-cells = <0x1>; + #size-cells = <0x1>; +}; diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 7f69ae1ca8..69f8d51885 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -54,6 +54,22 @@ config DM_PMIC_MAX77686 This config enables implementation of driver-model pmic uclass features for PMIC MAX77686. The driver implements read/write operations. +config PMIC_PM8916 + bool "Enable Driver Model for Qualcomm PM8916 PMIC" + depends on DM_PMIC + ---help--- + The PM8916 is a PMIC connected to one (or several) processors + with SPMI bus. It has 2 slaves with several peripherals: + - 18x LDO + - 4x GPIO + - Power and Reset buttons + - Watchdog + - RTC + - Vibrator drivers + - Others + + Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt + config PMIC_RK808 bool "Enable support for Rockchip PMIC RK808" depends on DM_PMIC diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index c6e8d0c610..52b4f711fb 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_ACT8846) += act8846.o +obj-$(CONFIG_PMIC_PM8916) += pm8916.o obj-$(CONFIG_PMIC_RK808) += rk808.o obj-$(CONFIG_PMIC_TPS65090) += tps65090.o obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pm8916.c new file mode 100644 index 0000000000..9acf5f55f7 --- /dev/null +++ b/drivers/power/pmic/pm8916.c @@ -0,0 +1,96 @@ +/* + * Qualcomm pm8916 pmic driver + * + * (C) Copyright 2015 Mateusz Kulikowski + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define PID_SHIFT 8 +#define PID_MASK (0xFF << PID_SHIFT) +#define REG_MASK 0xFF + +struct pm8916_priv { + uint16_t usid; /* Slave ID on SPMI bus */ +}; + +static int pm8916_reg_count(struct udevice *dev) +{ + return 0xFFFF; +} + +static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + struct pm8916_priv *priv = dev_get_priv(dev); + + if (len != 1) + return -EINVAL; + + return spmi_reg_write(dev->parent, priv->usid, + (reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK, + *buff); +} + +static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + struct pm8916_priv *priv = dev_get_priv(dev); + int val; + + if (len != 1) + return -EINVAL; + + val = spmi_reg_read(dev->parent, priv->usid, + (reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK); + + if (val < 0) + return val; + *buff = val; + return 0; +} + +static struct dm_pmic_ops pm8916_ops = { + .reg_count = pm8916_reg_count, + .read = pm8916_read, + .write = pm8916_write, +}; + +static const struct udevice_id pm8916_ids[] = { + { .compatible = "qcom,spmi-pmic" }, + { } +}; + +static int pm8916_probe(struct udevice *dev) +{ + struct pm8916_priv *priv = dev_get_priv(dev); + + priv->usid = dev_get_addr(dev); + + if (priv->usid == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + + +static int pm8916_bind(struct udevice *dev) +{ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +U_BOOT_DRIVER(pmic_pm8916) = { + .name = "pmic_pm8916", + .id = UCLASS_PMIC, + .of_match = pm8916_ids, + .bind = pm8916_bind, + .probe = pm8916_probe, + .ops = &pm8916_ops, + .priv_auto_alloc_size = sizeof(struct pm8916_priv), +};