1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2c2f74c8fSMateusz Kulikowski /*
3c2f74c8fSMateusz Kulikowski * Qualcomm pm8916 pmic driver
4c2f74c8fSMateusz Kulikowski *
5c2f74c8fSMateusz Kulikowski * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
6c2f74c8fSMateusz Kulikowski */
7c2f74c8fSMateusz Kulikowski #include <common.h>
8c2f74c8fSMateusz Kulikowski #include <dm.h>
9c2f74c8fSMateusz Kulikowski #include <power/pmic.h>
10c2f74c8fSMateusz Kulikowski #include <spmi/spmi.h>
11c2f74c8fSMateusz Kulikowski
12c2f74c8fSMateusz Kulikowski #define PID_SHIFT 8
13c2f74c8fSMateusz Kulikowski #define PID_MASK (0xFF << PID_SHIFT)
14c2f74c8fSMateusz Kulikowski #define REG_MASK 0xFF
15c2f74c8fSMateusz Kulikowski
16c2f74c8fSMateusz Kulikowski struct pm8916_priv {
173bfc8152STom Rini uint32_t usid; /* Slave ID on SPMI bus */
18c2f74c8fSMateusz Kulikowski };
19c2f74c8fSMateusz Kulikowski
pm8916_reg_count(struct udevice * dev)20c2f74c8fSMateusz Kulikowski static int pm8916_reg_count(struct udevice *dev)
21c2f74c8fSMateusz Kulikowski {
22c2f74c8fSMateusz Kulikowski return 0xFFFF;
23c2f74c8fSMateusz Kulikowski }
24c2f74c8fSMateusz Kulikowski
pm8916_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)25c2f74c8fSMateusz Kulikowski static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
26c2f74c8fSMateusz Kulikowski int len)
27c2f74c8fSMateusz Kulikowski {
28c2f74c8fSMateusz Kulikowski struct pm8916_priv *priv = dev_get_priv(dev);
29c2f74c8fSMateusz Kulikowski
30c2f74c8fSMateusz Kulikowski if (len != 1)
31c2f74c8fSMateusz Kulikowski return -EINVAL;
32c2f74c8fSMateusz Kulikowski
33c2f74c8fSMateusz Kulikowski return spmi_reg_write(dev->parent, priv->usid,
34c2f74c8fSMateusz Kulikowski (reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK,
35c2f74c8fSMateusz Kulikowski *buff);
36c2f74c8fSMateusz Kulikowski }
37c2f74c8fSMateusz Kulikowski
pm8916_read(struct udevice * dev,uint reg,uint8_t * buff,int len)38c2f74c8fSMateusz Kulikowski static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
39c2f74c8fSMateusz Kulikowski {
40c2f74c8fSMateusz Kulikowski struct pm8916_priv *priv = dev_get_priv(dev);
41c2f74c8fSMateusz Kulikowski int val;
42c2f74c8fSMateusz Kulikowski
43c2f74c8fSMateusz Kulikowski if (len != 1)
44c2f74c8fSMateusz Kulikowski return -EINVAL;
45c2f74c8fSMateusz Kulikowski
46c2f74c8fSMateusz Kulikowski val = spmi_reg_read(dev->parent, priv->usid,
47c2f74c8fSMateusz Kulikowski (reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK);
48c2f74c8fSMateusz Kulikowski
49c2f74c8fSMateusz Kulikowski if (val < 0)
50c2f74c8fSMateusz Kulikowski return val;
51c2f74c8fSMateusz Kulikowski *buff = val;
52c2f74c8fSMateusz Kulikowski return 0;
53c2f74c8fSMateusz Kulikowski }
54c2f74c8fSMateusz Kulikowski
55c2f74c8fSMateusz Kulikowski static struct dm_pmic_ops pm8916_ops = {
56c2f74c8fSMateusz Kulikowski .reg_count = pm8916_reg_count,
57c2f74c8fSMateusz Kulikowski .read = pm8916_read,
58c2f74c8fSMateusz Kulikowski .write = pm8916_write,
59c2f74c8fSMateusz Kulikowski };
60c2f74c8fSMateusz Kulikowski
61c2f74c8fSMateusz Kulikowski static const struct udevice_id pm8916_ids[] = {
62c2f74c8fSMateusz Kulikowski { .compatible = "qcom,spmi-pmic" },
63c2f74c8fSMateusz Kulikowski { }
64c2f74c8fSMateusz Kulikowski };
65c2f74c8fSMateusz Kulikowski
pm8916_probe(struct udevice * dev)66c2f74c8fSMateusz Kulikowski static int pm8916_probe(struct udevice *dev)
67c2f74c8fSMateusz Kulikowski {
68c2f74c8fSMateusz Kulikowski struct pm8916_priv *priv = dev_get_priv(dev);
69c2f74c8fSMateusz Kulikowski
7004048d58SSimon Glass priv->usid = dev_read_addr(dev);
71c2f74c8fSMateusz Kulikowski
72c2f74c8fSMateusz Kulikowski if (priv->usid == FDT_ADDR_T_NONE)
73c2f74c8fSMateusz Kulikowski return -EINVAL;
74c2f74c8fSMateusz Kulikowski
75c2f74c8fSMateusz Kulikowski return 0;
76c2f74c8fSMateusz Kulikowski }
77c2f74c8fSMateusz Kulikowski
78c2f74c8fSMateusz Kulikowski U_BOOT_DRIVER(pmic_pm8916) = {
79c2f74c8fSMateusz Kulikowski .name = "pmic_pm8916",
80c2f74c8fSMateusz Kulikowski .id = UCLASS_PMIC,
81c2f74c8fSMateusz Kulikowski .of_match = pm8916_ids,
8291195485SSimon Glass .bind = dm_scan_fdt_dev,
83c2f74c8fSMateusz Kulikowski .probe = pm8916_probe,
84c2f74c8fSMateusz Kulikowski .ops = &pm8916_ops,
85c2f74c8fSMateusz Kulikowski .priv_auto_alloc_size = sizeof(struct pm8916_priv),
86c2f74c8fSMateusz Kulikowski };
87