xref: /openbmc/u-boot/drivers/power/pmic/pm8916.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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