Commit 151b223b9c4e309d65166558afdfa0ce3c3b3213
1 parent
7fb57396e6
Exists in
v2017.01-smarct4x
and in
30 other branches
dm: power: Add a new driver for the TPS65090 PMIC
The existing TPS65090 driver does not support driver model. Add a new one that does. This can be used as a base for a regulator driver also. It uses the standard device tree binding. Signed-off-by: Simon Glass <sjg@chromium.org> Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
Showing 4 changed files with 160 additions and 0 deletions Side-by-side Diff
drivers/power/pmic/Kconfig
... | ... | @@ -41,4 +41,13 @@ |
41 | 41 | - set by i2c emul driver's probe() (defaults in header) |
42 | 42 | |
43 | 43 | Driver binding info: doc/device-tree-bindings/pmic/sandbox.txt |
44 | + | |
45 | +config PMIC_TPS65090 | |
46 | + bool "Enable driver for Texas Instruments TPS65090 PMIC" | |
47 | + depends on DM_PMIC | |
48 | + ---help--- | |
49 | + The TPS65090 is a PMIC containing several LDOs, DC to DC convertors, | |
50 | + FETs and a battery charger. This driver provides register access | |
51 | + only, and you can enable the regulator/charger drivers separately if | |
52 | + required. |
drivers/power/pmic/Makefile
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | obj-$(CONFIG_DM_PMIC) += pmic-uclass.o |
9 | 9 | obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o |
10 | 10 | obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o |
11 | +obj-$(CONFIG_PMIC_TPS65090) += tps65090.o | |
11 | 12 | obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o |
12 | 13 | obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o |
13 | 14 | obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o |
drivers/power/pmic/tps65090.c
1 | +/* | |
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> | |
11 | +#include <fdtdec.h> | |
12 | +#include <i2c.h> | |
13 | +#include <power/pmic.h> | |
14 | +#include <power/tps65090.h> | |
15 | + | |
16 | +DECLARE_GLOBAL_DATA_PTR; | |
17 | + | |
18 | +static const struct pmic_child_info pmic_children_info[] = { | |
19 | + { .prefix = "fet", .driver = TPS65090_FET_DRIVER }, | |
20 | + { }, | |
21 | +}; | |
22 | + | |
23 | +static int tps65090_reg_count(struct udevice *dev) | |
24 | +{ | |
25 | + return TPS65090_NUM_REGS; | |
26 | +} | |
27 | + | |
28 | +static int tps65090_write(struct udevice *dev, uint reg, const uint8_t *buff, | |
29 | + int len) | |
30 | +{ | |
31 | + if (dm_i2c_write(dev, reg, buff, len)) { | |
32 | + error("write error to device: %p register: %#x!", dev, reg); | |
33 | + return -EIO; | |
34 | + } | |
35 | + | |
36 | + return 0; | |
37 | +} | |
38 | + | |
39 | +static int tps65090_read(struct udevice *dev, uint reg, uint8_t *buff, int len) | |
40 | +{ | |
41 | + int ret; | |
42 | + | |
43 | + ret = dm_i2c_read(dev, reg, buff, len); | |
44 | + if (ret) { | |
45 | + error("read error %d from device: %p register: %#x!", ret, dev, | |
46 | + reg); | |
47 | + return -EIO; | |
48 | + } | |
49 | + | |
50 | + return 0; | |
51 | +} | |
52 | + | |
53 | +static int tps65090_bind(struct udevice *dev) | |
54 | +{ | |
55 | + int regulators_node; | |
56 | + const void *blob = gd->fdt_blob; | |
57 | + int children; | |
58 | + | |
59 | + regulators_node = fdt_subnode_offset(blob, dev->of_offset, | |
60 | + "regulators"); | |
61 | + if (regulators_node <= 0) { | |
62 | + debug("%s: %s regulators subnode not found!", __func__, | |
63 | + dev->name); | |
64 | + return -ENXIO; | |
65 | + } | |
66 | + | |
67 | + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); | |
68 | + | |
69 | + children = pmic_bind_children(dev, regulators_node, pmic_children_info); | |
70 | + if (!children) | |
71 | + debug("%s: %s - no child found\n", __func__, dev->name); | |
72 | + | |
73 | + /* Always return success for this device */ | |
74 | + return 0; | |
75 | +} | |
76 | + | |
77 | +static struct dm_pmic_ops tps65090_ops = { | |
78 | + .reg_count = tps65090_reg_count, | |
79 | + .read = tps65090_read, | |
80 | + .write = tps65090_write, | |
81 | +}; | |
82 | + | |
83 | +static const struct udevice_id tps65090_ids[] = { | |
84 | + { .compatible = "ti,tps65090" }, | |
85 | + { } | |
86 | +}; | |
87 | + | |
88 | +U_BOOT_DRIVER(pmic_tps65090) = { | |
89 | + .name = "tps65090 pmic", | |
90 | + .id = UCLASS_PMIC, | |
91 | + .of_match = tps65090_ids, | |
92 | + .bind = tps65090_bind, | |
93 | + .ops = &tps65090_ops, | |
94 | +}; |
include/power/tps65090.h
1 | +/* | |
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 | +#ifndef __TPS65090_PMIC_H_ | |
9 | +#define __TPS65090_PMIC_H_ | |
10 | + | |
11 | +/* I2C device address for TPS65090 PMU */ | |
12 | +#define TPS65090_I2C_ADDR 0x48 | |
13 | + | |
14 | +/* TPS65090 register addresses */ | |
15 | +enum { | |
16 | + REG_IRQ1 = 0, | |
17 | + REG_CG_CTRL0 = 4, | |
18 | + REG_CG_STATUS1 = 0xa, | |
19 | + REG_FET_BASE = 0xe, /* Not a real register, FETs count from here */ | |
20 | + REG_FET1_CTRL, | |
21 | + REG_FET2_CTRL, | |
22 | + REG_FET3_CTRL, | |
23 | + REG_FET4_CTRL, | |
24 | + REG_FET5_CTRL, | |
25 | + REG_FET6_CTRL, | |
26 | + REG_FET7_CTRL, | |
27 | + TPS65090_NUM_REGS, | |
28 | +}; | |
29 | + | |
30 | +enum { | |
31 | + IRQ1_VBATG = 1 << 3, | |
32 | + CG_CTRL0_ENC_MASK = 0x01, | |
33 | + | |
34 | + MAX_FET_NUM = 7, | |
35 | + MAX_CTRL_READ_TRIES = 5, | |
36 | + | |
37 | + /* TPS65090 FET_CTRL register values */ | |
38 | + FET_CTRL_TOFET = 1 << 7, /* Timeout, startup, overload */ | |
39 | + FET_CTRL_PGFET = 1 << 4, /* Power good for FET status */ | |
40 | + FET_CTRL_WAIT = 3 << 2, /* Overcurrent timeout max */ | |
41 | + FET_CTRL_ADENFET = 1 << 1, /* Enable output auto discharge */ | |
42 | + FET_CTRL_ENFET = 1 << 0, /* Enable FET */ | |
43 | +}; | |
44 | + | |
45 | +enum { | |
46 | + /* Status register fields */ | |
47 | + TPS65090_ST1_OTC = 1 << 0, | |
48 | + TPS65090_ST1_OCC = 1 << 1, | |
49 | + TPS65090_ST1_STATE_SHIFT = 4, | |
50 | + TPS65090_ST1_STATE_MASK = 0xf << TPS65090_ST1_STATE_SHIFT, | |
51 | +}; | |
52 | + | |
53 | +/* Drivers name */ | |
54 | +#define TPS65090_FET_DRIVER "tps65090_fet" | |
55 | + | |
56 | +#endif /* __TPS65090_PMIC_H_ */ |