blob: 735046dc43d869d20f451eca19cb6ff9937605aa [file] [log] [blame]
Simon Glassa8bd2ac2016-01-21 19:43:29 -07001/*
2 * Copyright (C) 2015 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <errno.h>
Jacob Chen614704b2017-05-02 14:54:52 +080011#include <power/rk8xx_pmic.h>
Simon Glassa8bd2ac2016-01-21 19:43:29 -070012#include <power/pmic.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
16static const struct pmic_child_info pmic_children_info[] = {
Jacob Chen614704b2017-05-02 14:54:52 +080017 { .prefix = "DCDC_REG", .driver = "rk8xx_buck"},
18 { .prefix = "LDO_REG", .driver = "rk8xx_ldo"},
19 { .prefix = "SWITCH_REG", .driver = "rk8xx_switch"},
Simon Glassa8bd2ac2016-01-21 19:43:29 -070020 { },
21};
22
Jacob Chen614704b2017-05-02 14:54:52 +080023static int rk8xx_reg_count(struct udevice *dev)
Simon Glassa8bd2ac2016-01-21 19:43:29 -070024{
25 return RK808_NUM_OF_REGS;
26}
27
Jacob Chen614704b2017-05-02 14:54:52 +080028static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff,
Simon Glassa8bd2ac2016-01-21 19:43:29 -070029 int len)
30{
Simon Glass46ad8cb2016-01-21 19:43:58 -070031 int ret;
32
33 ret = dm_i2c_write(dev, reg, buff, len);
34 if (ret) {
Simon Glassa8bd2ac2016-01-21 19:43:29 -070035 debug("write error to device: %p register: %#x!", dev, reg);
Simon Glass46ad8cb2016-01-21 19:43:58 -070036 return ret;
Simon Glassa8bd2ac2016-01-21 19:43:29 -070037 }
38
39 return 0;
40}
41
Jacob Chen614704b2017-05-02 14:54:52 +080042static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
Simon Glassa8bd2ac2016-01-21 19:43:29 -070043{
Simon Glass46ad8cb2016-01-21 19:43:58 -070044 int ret;
45
46 ret = dm_i2c_read(dev, reg, buff, len);
47 if (ret) {
Simon Glassa8bd2ac2016-01-21 19:43:29 -070048 debug("read error from device: %p register: %#x!", dev, reg);
Simon Glass46ad8cb2016-01-21 19:43:58 -070049 return ret;
Simon Glassa8bd2ac2016-01-21 19:43:29 -070050 }
51
52 return 0;
53}
54
55#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
Jacob Chen614704b2017-05-02 14:54:52 +080056static int rk8xx_bind(struct udevice *dev)
Simon Glassa8bd2ac2016-01-21 19:43:29 -070057{
Simon Glass2c2d2c22017-05-18 20:09:32 -060058 ofnode regulators_node;
Simon Glassa8bd2ac2016-01-21 19:43:29 -070059 int children;
60
Simon Glass2c2d2c22017-05-18 20:09:32 -060061 regulators_node = dev_read_subnode(dev, "regulators");
62 if (!ofnode_valid(regulators_node)) {
Simon Glassa8bd2ac2016-01-21 19:43:29 -070063 debug("%s: %s regulators subnode not found!", __func__,
64 dev->name);
65 return -ENXIO;
66 }
67
68 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
69
70 children = pmic_bind_children(dev, regulators_node, pmic_children_info);
71 if (!children)
72 debug("%s: %s - no child found\n", __func__, dev->name);
73
74 /* Always return success for this device */
75 return 0;
76}
77#endif
78
Jacob Chen614704b2017-05-02 14:54:52 +080079static int rk8xx_probe(struct udevice *dev)
Jacob Chen0234adb2017-05-02 14:54:49 +080080{
Jacob Chen614704b2017-05-02 14:54:52 +080081 struct rk8xx_priv *priv = dev_get_priv(dev);
Jacob Chen0234adb2017-05-02 14:54:49 +080082 uint8_t msb, lsb;
83
84 /* read Chip variant */
Jacob Chen614704b2017-05-02 14:54:52 +080085 rk8xx_read(dev, ID_MSB, &msb, 1);
86 rk8xx_read(dev, ID_LSB, &lsb, 1);
Jacob Chen0234adb2017-05-02 14:54:49 +080087
88 priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
89
90 return 0;
91}
92
Jacob Chen614704b2017-05-02 14:54:52 +080093static struct dm_pmic_ops rk8xx_ops = {
94 .reg_count = rk8xx_reg_count,
95 .read = rk8xx_read,
96 .write = rk8xx_write,
Simon Glassa8bd2ac2016-01-21 19:43:29 -070097};
98
Jacob Chen614704b2017-05-02 14:54:52 +080099static const struct udevice_id rk8xx_ids[] = {
Simon Glassa8bd2ac2016-01-21 19:43:29 -0700100 { .compatible = "rockchip,rk808" },
Jacob Chen0234adb2017-05-02 14:54:49 +0800101 { .compatible = "rockchip,rk818" },
Simon Glassa8bd2ac2016-01-21 19:43:29 -0700102 { }
103};
104
Jacob Chen614704b2017-05-02 14:54:52 +0800105U_BOOT_DRIVER(pmic_rk8xx) = {
106 .name = "rk8xx pmic",
Simon Glassa8bd2ac2016-01-21 19:43:29 -0700107 .id = UCLASS_PMIC,
Jacob Chen614704b2017-05-02 14:54:52 +0800108 .of_match = rk8xx_ids,
Simon Glassa8bd2ac2016-01-21 19:43:29 -0700109#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
Jacob Chen614704b2017-05-02 14:54:52 +0800110 .bind = rk8xx_bind,
Simon Glassa8bd2ac2016-01-21 19:43:29 -0700111#endif
Kever Yang00ab7fb2017-05-05 14:50:56 +0800112 .priv_auto_alloc_size = sizeof(struct rk8xx_priv),
Jacob Chen614704b2017-05-02 14:54:52 +0800113 .probe = rk8xx_probe,
114 .ops = &rk8xx_ops,
Simon Glassa8bd2ac2016-01-21 19:43:29 -0700115};