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