--- /dev/null
+ Qualcomm SPMI PMICs multi-function device bindings
+
+The Qualcomm SPMI series presently includes PM8941, PM8841 and PMA8084
+PMICs. These PMICs use a QPNP scheme through SPMI interface.
+QPNP is effectively a partitioning scheme for dividing the SPMI extended
+register space up into logical pieces, and set of fixed register
+locations/definitions within these regions, with some of these regions
+specifically used for interrupt handling.
+
+The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are
+interfaced to the chip via the SPMI (System Power Management Interface) bus.
+Support for multiple independent functions are implemented by splitting the
+16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes
+each. A function can consume one or more of these fixed-size register regions.
+
+Required properties:
+- compatible: Should contain one of:
+ "qcom,pm660",
+ "qcom,pm660l",
+ "qcom,pm7325",
+ "qcom,pm8004",
+ "qcom,pm8005",
+ "qcom,pm8019",
+ "qcom,pm8028",
+ "qcom,pm8110",
+ "qcom,pm8150",
+ "qcom,pm8150b",
+ "qcom,pm8150c",
+ "qcom,pm8150l",
+ "qcom,pm8226",
+ "qcom,pm8350c",
+ "qcom,pm8841",
+ "qcom,pm8901",
+ "qcom,pm8909",
+ "qcom,pm8916",
+ "qcom,pm8941",
+ "qcom,pm8950",
+ "qcom,pm8953",
+ "qcom,pm8994",
+ "qcom,pm8998",
+ "qcom,pma8084",
+ "qcom,pmd9635",
+ "qcom,pmi8950",
+ "qcom,pmi8962",
+ "qcom,pmi8994",
+ "qcom,pmi8998",
+ "qcom,pmk8002",
+ "qcom,pmk8350",
+ "qcom,pmr735a",
+ "qcom,smb2351",
+ or generalized "qcom,spmi-pmic".
+- reg: Specifies the SPMI USID slave address for this device.
+ For more information see:
+ Documentation/devicetree/bindings/spmi/spmi.yaml
+
+Required properties for peripheral child nodes:
+- compatible: Should contain "qcom,xxx", where "xxx" is a peripheral name.
+
+Optional properties for peripheral child nodes:
+- interrupts: Interrupts are specified as a 4-tuple. For more information
+ see:
+ Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
+- interrupt-names: Corresponding interrupt name to the interrupts property
+
+Each child node of SPMI slave id represents a function of the PMIC. In the
+example below the rtc device node represents a peripheral of pm8941
+SID = 0. The regulator device node represents a peripheral of pm8941 SID = 1.
+
+Example:
+
+ spmi {
+ compatible = "qcom,spmi-pmic-arb";
+
+ pm8941@0 {
+ compatible = "qcom,pm8941", "qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+
+ rtc {
+ compatible = "qcom,rtc";
+ interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "alarm";
+ };
+ };
+
+ pm8941@1 {
+ compatible = "qcom,pm8941", "qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+
+ regulator {
+ compatible = "qcom,regulator";
+ regulator-name = "8941_boost";
+ };
+ };
+ };
// SPDX-License-Identifier: GPL-2.0+
/*
- * Qualcomm pm8916 pmic gpio driver - part of Qualcomm PM8916 PMIC
+ * Qualcomm generic pmic gpio driver
*
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
*/
/* Register maps */
-/* Type and subtype are shared for all pm8916 peripherals */
+/* Type and subtype are shared for all PMIC peripherals */
#define REG_TYPE 0x4
#define REG_SUBTYPE 0x5
#define REG_EN_CTL 0x46
#define REG_EN_CTL_ENABLE (1 << 7)
-struct pm8916_gpio_bank {
+struct qcom_gpio_bank {
uint32_t pid; /* Peripheral ID on SPMI bus */
};
-static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset,
- bool input, int value)
+static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset,
+ bool input, int value)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int ret;
REG_EN_CTL_ENABLE);
}
-static int pm8916_gpio_direction_input(struct udevice *dev, unsigned offset)
+static int qcom_gpio_direction_input(struct udevice *dev, unsigned offset)
{
- return pm8916_gpio_set_direction(dev, offset, true, 0);
+ return qcom_gpio_set_direction(dev, offset, true, 0);
}
-static int pm8916_gpio_direction_output(struct udevice *dev, unsigned offset,
- int value)
+static int qcom_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
{
- return pm8916_gpio_set_direction(dev, offset, false, value);
+ return qcom_gpio_set_direction(dev, offset, false, value);
}
-static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset)
+static int qcom_gpio_get_function(struct udevice *dev, unsigned offset)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int reg;
}
}
-static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset)
+static int qcom_gpio_get_value(struct udevice *dev, unsigned offset)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int reg;
return !!(reg & REG_STATUS_VAL_MASK);
}
-static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset,
- int value)
+static int qcom_gpio_set_value(struct udevice *dev, unsigned offset,
+ int value)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
/* Set the output value of the gpio */
REG_CTL_OUTPUT_MASK, !!value);
}
-static const struct dm_gpio_ops pm8916_gpio_ops = {
- .direction_input = pm8916_gpio_direction_input,
- .direction_output = pm8916_gpio_direction_output,
- .get_value = pm8916_gpio_get_value,
- .set_value = pm8916_gpio_set_value,
- .get_function = pm8916_gpio_get_function,
+static const struct dm_gpio_ops qcom_gpio_ops = {
+ .direction_input = qcom_gpio_direction_input,
+ .direction_output = qcom_gpio_direction_output,
+ .get_value = qcom_gpio_get_value,
+ .set_value = qcom_gpio_set_value,
+ .get_function = qcom_gpio_get_function,
};
-static int pm8916_gpio_probe(struct udevice *dev)
+static int qcom_gpio_probe(struct udevice *dev)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
int reg;
priv->pid = dev_read_addr(dev);
return 0;
}
-static int pm8916_gpio_of_to_plat(struct udevice *dev)
+static int qcom_gpio_of_to_plat(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
if (uc_priv->bank_name == NULL)
- uc_priv->bank_name = "pm8916";
+ uc_priv->bank_name = "qcom_pmic";
return 0;
}
-static const struct udevice_id pm8916_gpio_ids[] = {
+static const struct udevice_id qcom_gpio_ids[] = {
{ .compatible = "qcom,pm8916-gpio" },
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
{ .compatible = "qcom,pm8998-gpio" },
{ }
};
-U_BOOT_DRIVER(gpio_pm8916) = {
- .name = "gpio_pm8916",
+U_BOOT_DRIVER(qcom_pmic_gpio) = {
+ .name = "qcom_pmic_gpio",
.id = UCLASS_GPIO,
- .of_match = pm8916_gpio_ids,
- .of_to_plat = pm8916_gpio_of_to_plat,
- .probe = pm8916_gpio_probe,
- .ops = &pm8916_gpio_ops,
- .priv_auto = sizeof(struct pm8916_gpio_bank),
+ .of_match = qcom_gpio_ids,
+ .of_to_plat = qcom_gpio_of_to_plat,
+ .probe = qcom_gpio_probe,
+ .ops = &qcom_gpio_ops,
+ .priv_auto = sizeof(struct qcom_gpio_bank),
};
#define KPDPWR_ON_INT_BIT 0
#define RESIN_ON_INT_BIT 1
-static int pm8941_pwrkey_get_function(struct udevice *dev, unsigned offset)
+static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset)
{
return GPIOF_INPUT;
}
-static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset)
+static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS);
}
}
-static const struct dm_gpio_ops pm8941_pwrkey_ops = {
- .get_value = pm8941_pwrkey_get_value,
- .get_function = pm8941_pwrkey_get_function,
+static const struct dm_gpio_ops qcom_pwrkey_ops = {
+ .get_value = qcom_pwrkey_get_value,
+ .get_function = qcom_pwrkey_get_function,
};
-static int pm8941_pwrkey_probe(struct udevice *dev)
+static int qcom_pwrkey_probe(struct udevice *dev)
{
- struct pm8916_gpio_bank *priv = dev_get_priv(dev);
+ struct qcom_gpio_bank *priv = dev_get_priv(dev);
int reg;
priv->pid = dev_read_addr(dev);
return 0;
}
-static int pm8941_pwrkey_of_to_plat(struct udevice *dev)
+static int qcom_pwrkey_of_to_plat(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->gpio_count = 2;
uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
if (uc_priv->bank_name == NULL)
- uc_priv->bank_name = "pm8916_key";
+ uc_priv->bank_name = "pwkey_qcom";
return 0;
}
-static const struct udevice_id pm8941_pwrkey_ids[] = {
+static const struct udevice_id qcom_pwrkey_ids[] = {
{ .compatible = "qcom,pm8916-pwrkey" },
{ .compatible = "qcom,pm8994-pwrkey" },
{ .compatible = "qcom,pm8998-pwrkey" },
{ }
};
-U_BOOT_DRIVER(pwrkey_pm89xx) = {
- .name = "pwrkey_pm89xx",
+U_BOOT_DRIVER(pwrkey_qcom) = {
+ .name = "pwrkey_qcom",
.id = UCLASS_GPIO,
- .of_match = pm8941_pwrkey_ids,
- .of_to_plat = pm8941_pwrkey_of_to_plat,
- .probe = pm8941_pwrkey_probe,
- .ops = &pm8941_pwrkey_ops,
- .priv_auto = sizeof(struct pm8916_gpio_bank),
+ .of_match = qcom_pwrkey_ids,
+ .of_to_plat = qcom_pwrkey_of_to_plat,
+ .probe = qcom_pwrkey_probe,
+ .ops = &qcom_pwrkey_ops,
+ .priv_auto = sizeof(struct qcom_gpio_bank),
};
// SPDX-License-Identifier: GPL-2.0+
/*
- * Qualcomm pm8916 pmic driver
+ * Qualcomm generic pmic driver
*
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
*/
#define PID_MASK (0xFF << PID_SHIFT)
#define REG_MASK 0xFF
-struct pm8916_priv {
+struct pmic_qcom_priv {
uint32_t usid; /* Slave ID on SPMI bus */
};
-static int pm8916_reg_count(struct udevice *dev)
+static int pmic_qcom_reg_count(struct udevice *dev)
{
return 0xFFFF;
}
-static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
- int len)
+static int pmic_qcom_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
{
- struct pm8916_priv *priv = dev_get_priv(dev);
+ struct pmic_qcom_priv *priv = dev_get_priv(dev);
if (len != 1)
return -EINVAL;
*buff);
}
-static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+static int pmic_qcom_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
- struct pm8916_priv *priv = dev_get_priv(dev);
+ struct pmic_qcom_priv *priv = dev_get_priv(dev);
int val;
if (len != 1)
return 0;
}
-static struct dm_pmic_ops pm8916_ops = {
- .reg_count = pm8916_reg_count,
- .read = pm8916_read,
- .write = pm8916_write,
+static struct dm_pmic_ops pmic_qcom_ops = {
+ .reg_count = pmic_qcom_reg_count,
+ .read = pmic_qcom_read,
+ .write = pmic_qcom_write,
};
-static const struct udevice_id pm8916_ids[] = {
+static const struct udevice_id pmic_qcom_ids[] = {
{ .compatible = "qcom,spmi-pmic" },
{ }
};
-static int pm8916_probe(struct udevice *dev)
+static int pmic_qcom_probe(struct udevice *dev)
{
- struct pm8916_priv *priv = dev_get_priv(dev);
+ struct pmic_qcom_priv *priv = dev_get_priv(dev);
priv->usid = dev_read_addr(dev);
return 0;
}
-U_BOOT_DRIVER(pmic_pm8916) = {
- .name = "pmic_pm8916",
+U_BOOT_DRIVER(pmic_qcom) = {
+ .name = "pmic_qcom",
.id = UCLASS_PMIC,
- .of_match = pm8916_ids,
+ .of_match = pmic_qcom_ids,
.bind = dm_scan_fdt_dev,
- .probe = pm8916_probe,
- .ops = &pm8916_ops,
- .priv_auto = sizeof(struct pm8916_priv),
+ .probe = pmic_qcom_probe,
+ .ops = &pmic_qcom_ops,
+ .priv_auto = sizeof(struct pmic_qcom_priv),
};