xref: /rk3399_rockchip-uboot/drivers/power/pmic/pm8916.c (revision 04048d58a8fdc607010cb611d0656c4f6cae6296)
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