aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorAndrew F. Davis <afd@ti.com>2016-01-25 10:50:11 -0500
committerLee Jones <lee.jones@linaro.org>2016-03-16 04:50:15 -0400
commitb45b719ee03162eb54772c30a6474d57b41b6b54 (patch)
tree07f87dcc3b8d1395d0d79e881d3d8078ed0a4545 /drivers/mfd
parenta85b9e0b3ccf4a90cd42f41fdfff1fc91513720c (diff)
mfd: tps65086: Add driver for the TPS65086 PMIC
Add support for the TPS65912 device. It provides communication through I2C and contains the following components: - Regulators - Load switches - GPO controller Signed-off-by: Andrew F. Davis <afd@ti.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig13
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/tps65086.c149
3 files changed, 163 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f47965834a6b..97d94068cb4d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1130,6 +1130,19 @@ config TPS6507X
1130 This driver can also be built as a module. If so, the module 1130 This driver can also be built as a module. If so, the module
1131 will be called tps6507x. 1131 will be called tps6507x.
1132 1132
1133config MFD_TPS65086
1134 tristate "TI TPS65086 Power Management Integrated Chips (PMICs)"
1135 select REGMAP
1136 select REGMAP_IRQ
1137 select REGMAP_I2C
1138 depends on I2C
1139 help
1140 If you say yes here you get support for the TPS65086 series of
1141 Power Management chips.
1142 This driver provides common support for accessing the device,
1143 additional drivers must be enabled in order to use the
1144 functionality of the device.
1145
1133config TPS65911_COMPARATOR 1146config TPS65911_COMPARATOR
1134 tristate 1147 tristate
1135 1148
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b7a3cd9adaee..d2ddcf45ccd1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_MFD_WM8994) += wm8994.o
70obj-$(CONFIG_TPS6105X) += tps6105x.o 70obj-$(CONFIG_TPS6105X) += tps6105x.o
71obj-$(CONFIG_TPS65010) += tps65010.o 71obj-$(CONFIG_TPS65010) += tps65010.o
72obj-$(CONFIG_TPS6507X) += tps6507x.o 72obj-$(CONFIG_TPS6507X) += tps6507x.o
73obj-$(CONFIG_MFD_TPS65086) += tps65086.o
73obj-$(CONFIG_MFD_TPS65217) += tps65217.o 74obj-$(CONFIG_MFD_TPS65217) += tps65217.o
74obj-$(CONFIG_MFD_TPS65218) += tps65218.o 75obj-$(CONFIG_MFD_TPS65218) += tps65218.o
75obj-$(CONFIG_MFD_TPS65910) += tps65910.o 76obj-$(CONFIG_MFD_TPS65910) += tps65910.o
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
new file mode 100644
index 000000000000..43119a6867fe
--- /dev/null
+++ b/drivers/mfd/tps65086.c
@@ -0,0 +1,149 @@
1/*
2 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
3 * Andrew F. Davis <afd@ti.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
10 * kind, whether expressed or implied; without even the implied warranty
11 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License version 2 for more details.
13 *
14 * Based on the TPS65912 driver
15 */
16
17#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/mfd/core.h>
20#include <linux/module.h>
21
22#include <linux/mfd/tps65086.h>
23
24static const struct mfd_cell tps65086_cells[] = {
25 { .name = "tps65086-regulator", },
26 { .name = "tps65086-gpio", },
27};
28
29static const struct regmap_range tps65086_yes_ranges[] = {
30 regmap_reg_range(TPS65086_IRQ, TPS65086_IRQ),
31 regmap_reg_range(TPS65086_PMICSTAT, TPS65086_SHUTDNSRC),
32 regmap_reg_range(TPS65086_GPOCTRL, TPS65086_GPOCTRL),
33 regmap_reg_range(TPS65086_PG_STATUS1, TPS65086_OC_STATUS),
34};
35
36static const struct regmap_access_table tps65086_volatile_table = {
37 .yes_ranges = tps65086_yes_ranges,
38 .n_yes_ranges = ARRAY_SIZE(tps65086_yes_ranges),
39};
40
41static const struct regmap_config tps65086_regmap_config = {
42 .reg_bits = 8,
43 .val_bits = 8,
44 .cache_type = REGCACHE_RBTREE,
45 .volatile_table = &tps65086_volatile_table,
46};
47
48static const struct regmap_irq tps65086_irqs[] = {
49 REGMAP_IRQ_REG(TPS65086_IRQ_DIETEMP, 0, TPS65086_IRQ_DIETEMP_MASK),
50 REGMAP_IRQ_REG(TPS65086_IRQ_SHUTDN, 0, TPS65086_IRQ_SHUTDN_MASK),
51 REGMAP_IRQ_REG(TPS65086_IRQ_FAULT, 0, TPS65086_IRQ_FAULT_MASK),
52};
53
54static struct regmap_irq_chip tps65086_irq_chip = {
55 .name = "tps65086",
56 .status_base = TPS65086_IRQ,
57 .mask_base = TPS65086_IRQ_MASK,
58 .ack_base = TPS65086_IRQ,
59 .init_ack_masked = true,
60 .num_regs = 1,
61 .irqs = tps65086_irqs,
62 .num_irqs = ARRAY_SIZE(tps65086_irqs),
63};
64
65static const struct of_device_id tps65086_of_match_table[] = {
66 { .compatible = "ti,tps65086", },
67 { /* sentinel */ }
68};
69MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
70
71static int tps65086_probe(struct i2c_client *client,
72 const struct i2c_device_id *ids)
73{
74 struct tps65086 *tps;
75 unsigned int version;
76 int ret;
77
78 tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
79 if (!tps)
80 return -ENOMEM;
81
82 i2c_set_clientdata(client, tps);
83 tps->dev = &client->dev;
84 tps->irq = client->irq;
85
86 tps->regmap = devm_regmap_init_i2c(client, &tps65086_regmap_config);
87 if (IS_ERR(tps->regmap)) {
88 dev_err(tps->dev, "Failed to initialize register map\n");
89 return PTR_ERR(tps->regmap);
90 }
91
92 ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
93 if (ret) {
94 dev_err(tps->dev, "Failed to read revision register\n");
95 return ret;
96 }
97
98 dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
99 (version & TPS65086_DEVICEID_PART_MASK),
100 (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
101 (version & TPS65086_DEVICEID_REV_MASK) >> 6);
102
103 ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
104 &tps65086_irq_chip, &tps->irq_data);
105 if (ret) {
106 dev_err(tps->dev, "Failed to register IRQ chip\n");
107 return ret;
108 }
109
110 ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65086_cells,
111 ARRAY_SIZE(tps65086_cells), NULL, 0,
112 regmap_irq_get_domain(tps->irq_data));
113 if (ret) {
114 regmap_del_irq_chip(tps->irq, tps->irq_data);
115 return ret;
116 }
117
118 return 0;
119}
120
121static int tps65086_remove(struct i2c_client *client)
122{
123 struct tps65086 *tps = i2c_get_clientdata(client);
124
125 regmap_del_irq_chip(tps->irq, tps->irq_data);
126
127 return 0;
128}
129
130static const struct i2c_device_id tps65086_id_table[] = {
131 { "tps65086", 0 },
132 { /* sentinel */ }
133};
134MODULE_DEVICE_TABLE(i2c, tps65086_id_table);
135
136static struct i2c_driver tps65086_driver = {
137 .driver = {
138 .name = "tps65086",
139 .of_match_table = tps65086_of_match_table,
140 },
141 .probe = tps65086_probe,
142 .remove = tps65086_remove,
143 .id_table = tps65086_id_table,
144};
145module_i2c_driver(tps65086_driver);
146
147MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
148MODULE_DESCRIPTION("TPS65086 PMIC Driver");
149MODULE_LICENSE("GPL v2");