aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2016-03-09 05:40:37 -0500
committerLinus Walleij <linus.walleij@linaro.org>2016-03-09 05:40:37 -0500
commit0bae2f17323a4630c487a9b77c37bebf407424af (patch)
treefc1f71a0209ec61841a5acb65d59d147af3cc4fa /drivers/mfd
parentadf32eaa05323449b74b36f25b918583e2bdb6f1 (diff)
parentca801a22f465eae39fadc770e15b5b7e82595f81 (diff)
Merge branch 'ib-mfd-regulator-gpio-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into devel
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig20
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/tps65912-core.c240
-rw-r--r--drivers/mfd/tps65912-i2c.c162
-rw-r--r--drivers/mfd/tps65912-irq.c217
-rw-r--r--drivers/mfd/tps65912-spi.c160
6 files changed, 198 insertions, 604 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 9ca66de0c1c1..1bc97c2761e4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1181,27 +1181,25 @@ config MFD_TPS65910
1181 Power Management chips. 1181 Power Management chips.
1182 1182
1183config MFD_TPS65912 1183config MFD_TPS65912
1184 bool "TI TPS65912 Power Management chip" 1184 tristate
1185 depends on GPIOLIB
1186 select MFD_CORE 1185 select MFD_CORE
1187 help 1186 select REGMAP
1188 If you say yes here you get support for the TPS65912 series of 1187 select REGMAP_IRQ
1189 PM chips.
1190 1188
1191config MFD_TPS65912_I2C 1189config MFD_TPS65912_I2C
1192 bool "TI TPS65912 Power Management chip with I2C" 1190 tristate "TI TPS65912 Power Management chip with I2C"
1193 select MFD_CORE
1194 select MFD_TPS65912 1191 select MFD_TPS65912
1195 depends on I2C=y && GPIOLIB 1192 select REGMAP_I2C
1193 depends on I2C
1196 help 1194 help
1197 If you say yes here you get support for the TPS65912 series of 1195 If you say yes here you get support for the TPS65912 series of
1198 PM chips with I2C interface. 1196 PM chips with I2C interface.
1199 1197
1200config MFD_TPS65912_SPI 1198config MFD_TPS65912_SPI
1201 bool "TI TPS65912 Power Management chip with SPI" 1199 tristate "TI TPS65912 Power Management chip with SPI"
1202 select MFD_CORE
1203 select MFD_TPS65912 1200 select MFD_TPS65912
1204 depends on SPI_MASTER && GPIOLIB 1201 select REGMAP_SPI
1202 depends on SPI_MASTER
1205 help 1203 help
1206 If you say yes here you get support for the TPS65912 series of 1204 If you say yes here you get support for the TPS65912 series of
1207 PM chips with SPI interface. 1205 PM chips with SPI interface.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 0f230a6103f8..1811202cee19 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -73,8 +73,7 @@ obj-$(CONFIG_TPS6507X) += tps6507x.o
73obj-$(CONFIG_MFD_TPS65217) += tps65217.o 73obj-$(CONFIG_MFD_TPS65217) += tps65217.o
74obj-$(CONFIG_MFD_TPS65218) += tps65218.o 74obj-$(CONFIG_MFD_TPS65218) += tps65218.o
75obj-$(CONFIG_MFD_TPS65910) += tps65910.o 75obj-$(CONFIG_MFD_TPS65910) += tps65910.o
76tps65912-objs := tps65912-core.o tps65912-irq.o 76obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o
77obj-$(CONFIG_MFD_TPS65912) += tps65912.o
78obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o 77obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
79obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o 78obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
80obj-$(CONFIG_MFD_TPS80031) += tps80031.o 79obj-$(CONFIG_MFD_TPS80031) += tps80031.o
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
index 1f82d60b1d0f..a88cfa80dbc4 100644
--- a/drivers/mfd/tps65912-core.c
+++ b/drivers/mfd/tps65912-core.c
@@ -1,175 +1,111 @@
1/* 1/*
2 * tps65912-core.c -- TI TPS65912x 2 * Core functions for TI TPS65912x PMICs
3 * 3 *
4 * Copyright 2011 Texas Instruments Inc. 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com>
5 * 6 *
6 * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
7 * 10 *
8 * This program is free software; you can redistribute it and/or modify it 11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * under the terms of the GNU General Public License as published by the 12 * kind, whether expressed or implied; without even the implied warranty
10 * Free Software Foundation; either version 2 of the License, or (at your 13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * option) any later version. 14 * GNU General Public License version 2 for more details.
12 * 15 *
13 * This driver is based on wm8350 implementation. 16 * Based on the TPS65218 driver and the previous TPS65912 driver by
17 * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
14 */ 18 */
15 19
16#include <linux/module.h> 20#include <linux/interrupt.h>
17#include <linux/moduleparam.h>
18#include <linux/slab.h>
19#include <linux/gpio.h>
20#include <linux/mfd/core.h> 21#include <linux/mfd/core.h>
22#include <linux/module.h>
23
21#include <linux/mfd/tps65912.h> 24#include <linux/mfd/tps65912.h>
22 25
23static const struct mfd_cell tps65912s[] = { 26static const struct mfd_cell tps65912_cells[] = {
24 { 27 { .name = "tps65912-regulator", },
25 .name = "tps65912-pmic", 28 { .name = "tps65912-gpio", },
26 },
27}; 29};
28 30
29int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask) 31static const struct regmap_irq tps65912_irqs[] = {
30{ 32 /* INT_STS IRQs */
31 u8 data; 33 REGMAP_IRQ_REG(TPS65912_IRQ_PWRHOLD_F, 0, TPS65912_INT_STS_PWRHOLD_F),
32 int err; 34 REGMAP_IRQ_REG(TPS65912_IRQ_VMON, 0, TPS65912_INT_STS_VMON),
33 35 REGMAP_IRQ_REG(TPS65912_IRQ_PWRON, 0, TPS65912_INT_STS_PWRON),
34 mutex_lock(&tps65912->io_mutex); 36 REGMAP_IRQ_REG(TPS65912_IRQ_PWRON_LP, 0, TPS65912_INT_STS_PWRON_LP),
35 37 REGMAP_IRQ_REG(TPS65912_IRQ_PWRHOLD_R, 0, TPS65912_INT_STS_PWRHOLD_R),
36 err = tps65912->read(tps65912, reg, 1, &data); 38 REGMAP_IRQ_REG(TPS65912_IRQ_HOTDIE, 0, TPS65912_INT_STS_HOTDIE),
37 if (err) { 39 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO1_R, 0, TPS65912_INT_STS_GPIO1_R),
38 dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); 40 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO1_F, 0, TPS65912_INT_STS_GPIO1_F),
39 goto out; 41 /* INT_STS2 IRQs */
40 } 42 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO2_R, 1, TPS65912_INT_STS2_GPIO2_R),
41 43 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO2_F, 1, TPS65912_INT_STS2_GPIO2_F),
42 data |= mask; 44 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO3_R, 1, TPS65912_INT_STS2_GPIO3_R),
43 err = tps65912->write(tps65912, reg, 1, &data); 45 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO3_F, 1, TPS65912_INT_STS2_GPIO3_F),
44 if (err) 46 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO4_R, 1, TPS65912_INT_STS2_GPIO4_R),
45 dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); 47 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO4_F, 1, TPS65912_INT_STS2_GPIO4_F),
48 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO5_R, 1, TPS65912_INT_STS2_GPIO5_R),
49 REGMAP_IRQ_REG(TPS65912_IRQ_GPIO5_F, 1, TPS65912_INT_STS2_GPIO5_F),
50 /* INT_STS3 IRQs */
51 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC1, 2, TPS65912_INT_STS3_PGOOD_DCDC1),
52 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC2, 2, TPS65912_INT_STS3_PGOOD_DCDC2),
53 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC3, 2, TPS65912_INT_STS3_PGOOD_DCDC3),
54 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_DCDC4, 2, TPS65912_INT_STS3_PGOOD_DCDC4),
55 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO1, 2, TPS65912_INT_STS3_PGOOD_LDO1),
56 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO2, 2, TPS65912_INT_STS3_PGOOD_LDO2),
57 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO3, 2, TPS65912_INT_STS3_PGOOD_LDO3),
58 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO4, 2, TPS65912_INT_STS3_PGOOD_LDO4),
59 /* INT_STS4 IRQs */
60 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO5, 3, TPS65912_INT_STS4_PGOOD_LDO5),
61 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO6, 3, TPS65912_INT_STS4_PGOOD_LDO6),
62 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO7, 3, TPS65912_INT_STS4_PGOOD_LDO7),
63 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO8, 3, TPS65912_INT_STS4_PGOOD_LDO8),
64 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO9, 3, TPS65912_INT_STS4_PGOOD_LDO9),
65 REGMAP_IRQ_REG(TPS65912_IRQ_PGOOD_LDO10, 3, TPS65912_INT_STS4_PGOOD_LDO10),
66};
46 67
47out: 68static struct regmap_irq_chip tps65912_irq_chip = {
48 mutex_unlock(&tps65912->io_mutex); 69 .name = "tps65912",
49 return err; 70 .irqs = tps65912_irqs,
50} 71 .num_irqs = ARRAY_SIZE(tps65912_irqs),
51EXPORT_SYMBOL_GPL(tps65912_set_bits); 72 .num_regs = 4,
73 .irq_reg_stride = 2,
74 .mask_base = TPS65912_INT_MSK,
75 .status_base = TPS65912_INT_STS,
76 .ack_base = TPS65912_INT_STS,
77 .init_ack_masked = true,
78};
52 79
53int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask) 80int tps65912_device_init(struct tps65912 *tps)
54{ 81{
55 u8 data; 82 int ret;
56 int err; 83
57 84 ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
58 mutex_lock(&tps65912->io_mutex); 85 &tps65912_irq_chip, &tps->irq_data);
59 err = tps65912->read(tps65912, reg, 1, &data); 86 if (ret)
60 if (err) { 87 return ret;
61 dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); 88
62 goto out; 89 ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65912_cells,
90 ARRAY_SIZE(tps65912_cells), NULL, 0,
91 regmap_irq_get_domain(tps->irq_data));
92 if (ret) {
93 regmap_del_irq_chip(tps->irq, tps->irq_data);
94 return ret;
63 } 95 }
64 96
65 data &= ~mask; 97 return 0;
66 err = tps65912->write(tps65912, reg, 1, &data);
67 if (err)
68 dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
69
70out:
71 mutex_unlock(&tps65912->io_mutex);
72 return err;
73} 98}
74EXPORT_SYMBOL_GPL(tps65912_clear_bits); 99EXPORT_SYMBOL_GPL(tps65912_device_init);
75 100
76static inline int tps65912_read(struct tps65912 *tps65912, u8 reg) 101int tps65912_device_exit(struct tps65912 *tps)
77{ 102{
78 u8 val; 103 regmap_del_irq_chip(tps->irq, tps->irq_data);
79 int err;
80
81 err = tps65912->read(tps65912, reg, 1, &val);
82 if (err < 0)
83 return err;
84
85 return val;
86}
87
88static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val)
89{
90 return tps65912->write(tps65912, reg, 1, &val);
91}
92
93int tps65912_reg_read(struct tps65912 *tps65912, u8 reg)
94{
95 int data;
96
97 mutex_lock(&tps65912->io_mutex);
98 104
99 data = tps65912_read(tps65912, reg); 105 return 0;
100 if (data < 0)
101 dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
102
103 mutex_unlock(&tps65912->io_mutex);
104 return data;
105}
106EXPORT_SYMBOL_GPL(tps65912_reg_read);
107
108int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val)
109{
110 int err;
111
112 mutex_lock(&tps65912->io_mutex);
113
114 err = tps65912_write(tps65912, reg, val);
115 if (err < 0)
116 dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg);
117
118 mutex_unlock(&tps65912->io_mutex);
119 return err;
120}
121EXPORT_SYMBOL_GPL(tps65912_reg_write);
122
123int tps65912_device_init(struct tps65912 *tps65912)
124{
125 struct tps65912_board *pmic_plat_data = dev_get_platdata(tps65912->dev);
126 struct tps65912_platform_data *init_data;
127 int ret, dcdc_avs, value;
128
129 init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL);
130 if (init_data == NULL)
131 return -ENOMEM;
132
133 mutex_init(&tps65912->io_mutex);
134 dev_set_drvdata(tps65912->dev, tps65912);
135
136 dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 |
137 pmic_plat_data->is_dcdc2_avs << 1 |
138 pmic_plat_data->is_dcdc3_avs << 2 |
139 pmic_plat_data->is_dcdc4_avs << 3);
140 if (dcdc_avs) {
141 tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value);
142 dcdc_avs |= value;
143 tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs);
144 }
145
146 ret = mfd_add_devices(tps65912->dev, -1,
147 tps65912s, ARRAY_SIZE(tps65912s),
148 NULL, 0, NULL);
149 if (ret < 0)
150 goto err;
151
152 init_data->irq = pmic_plat_data->irq;
153 init_data->irq_base = pmic_plat_data->irq_base;
154 ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
155 if (ret < 0)
156 goto err;
157
158 kfree(init_data);
159 return ret;
160
161err:
162 kfree(init_data);
163 mfd_remove_devices(tps65912->dev);
164 return ret;
165}
166
167void tps65912_device_exit(struct tps65912 *tps65912)
168{
169 mfd_remove_devices(tps65912->dev);
170 tps65912_irq_exit(tps65912);
171} 106}
107EXPORT_SYMBOL_GPL(tps65912_device_exit);
172 108
173MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); 109MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
174MODULE_DESCRIPTION("TPS65912x chip family multi-function driver"); 110MODULE_DESCRIPTION("TPS65912x MFD Driver");
175MODULE_LICENSE("GPL"); 111MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65912-i2c.c b/drivers/mfd/tps65912-i2c.c
index 7e55640b3ed5..45871403f995 100644
--- a/drivers/mfd/tps65912-i2c.c
+++ b/drivers/mfd/tps65912-i2c.c
@@ -1,139 +1,79 @@
1/* 1/*
2 * tps65912-i2c.c -- I2C access for TI TPS65912x PMIC 2 * I2C access driver for TI TPS65912x PMICs
3 * 3 *
4 * Copyright 2011 Texas Instruments Inc. 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com>
5 * 6 *
6 * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
7 * 10 *
8 * This program is free software; you can redistribute it and/or modify it 11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * under the terms of the GNU General Public License as published by the 12 * kind, whether expressed or implied; without even the implied warranty
10 * Free Software Foundation; either version 2 of the License, or (at your 13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * option) any later version. 14 * GNU General Public License version 2 for more details.
12 * 15 *
13 * This driver is based on wm8350 implementation. 16 * Based on the TPS65218 driver and the previous TPS65912 driver by
17 * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
14 */ 18 */
15 19
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h> 20#include <linux/i2c.h>
22#include <linux/mfd/core.h> 21#include <linux/module.h>
23#include <linux/mfd/tps65912.h> 22#include <linux/regmap.h>
24
25static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg,
26 int bytes, void *dest)
27{
28 struct i2c_client *i2c = tps65912->control_data;
29 struct i2c_msg xfer[2];
30 int ret;
31
32 /* Write register */
33 xfer[0].addr = i2c->addr;
34 xfer[0].flags = 0;
35 xfer[0].len = 1;
36 xfer[0].buf = &reg;
37
38 /* Read data */
39 xfer[1].addr = i2c->addr;
40 xfer[1].flags = I2C_M_RD;
41 xfer[1].len = bytes;
42 xfer[1].buf = dest;
43
44 ret = i2c_transfer(i2c->adapter, xfer, 2);
45 if (ret == 2)
46 ret = 0;
47 else if (ret >= 0)
48 ret = -EIO;
49 return ret;
50}
51
52static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg,
53 int bytes, void *src)
54{
55 struct i2c_client *i2c = tps65912->control_data;
56 /* we add 1 byte for device register */
57 u8 msg[TPS6591X_MAX_REGISTER + 1];
58 int ret;
59
60 if (bytes > TPS6591X_MAX_REGISTER)
61 return -EINVAL;
62
63 msg[0] = reg;
64 memcpy(&msg[1], src, bytes);
65 23
66 ret = i2c_master_send(i2c, msg, bytes + 1); 24#include <linux/mfd/tps65912.h>
67 if (ret < 0)
68 return ret;
69 if (ret != bytes + 1)
70 return -EIO;
71 25
72 return 0; 26static const struct of_device_id tps65912_i2c_of_match_table[] = {
73} 27 { .compatible = "ti,tps65912", },
28 { /* sentinel */ }
29};
74 30
75static int tps65912_i2c_probe(struct i2c_client *i2c, 31static int tps65912_i2c_probe(struct i2c_client *client,
76 const struct i2c_device_id *id) 32 const struct i2c_device_id *ids)
77{ 33{
78 struct tps65912 *tps65912; 34 struct tps65912 *tps;
79 35
80 tps65912 = devm_kzalloc(&i2c->dev, 36 tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
81 sizeof(struct tps65912), GFP_KERNEL); 37 if (!tps)
82 if (tps65912 == NULL)
83 return -ENOMEM; 38 return -ENOMEM;
84 39
85 i2c_set_clientdata(i2c, tps65912); 40 i2c_set_clientdata(client, tps);
86 tps65912->dev = &i2c->dev; 41 tps->dev = &client->dev;
87 tps65912->control_data = i2c; 42 tps->irq = client->irq;
88 tps65912->read = tps65912_i2c_read; 43
89 tps65912->write = tps65912_i2c_write; 44 tps->regmap = devm_regmap_init_i2c(client, &tps65912_regmap_config);
45 if (IS_ERR(tps->regmap)) {
46 dev_err(tps->dev, "Failed to initialize register map\n");
47 return PTR_ERR(tps->regmap);
48 }
90 49
91 return tps65912_device_init(tps65912); 50 return tps65912_device_init(tps);
92} 51}
93 52
94static int tps65912_i2c_remove(struct i2c_client *i2c) 53static int tps65912_i2c_remove(struct i2c_client *client)
95{ 54{
96 struct tps65912 *tps65912 = i2c_get_clientdata(i2c); 55 struct tps65912 *tps = i2c_get_clientdata(client);
97 56
98 tps65912_device_exit(tps65912); 57 return tps65912_device_exit(tps);
99
100 return 0;
101} 58}
102 59
103static const struct i2c_device_id tps65912_i2c_id[] = { 60static const struct i2c_device_id tps65912_i2c_id_table[] = {
104 {"tps65912", 0 }, 61 { "tps65912", 0 },
105 { } 62 { /* sentinel */ }
106}; 63};
107MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id); 64MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id_table);
108 65
109static struct i2c_driver tps65912_i2c_driver = { 66static struct i2c_driver tps65912_i2c_driver = {
110 .driver = { 67 .driver = {
111 .name = "tps65912", 68 .name = "tps65912",
69 .of_match_table = tps65912_i2c_of_match_table,
112 }, 70 },
113 .probe = tps65912_i2c_probe, 71 .probe = tps65912_i2c_probe,
114 .remove = tps65912_i2c_remove, 72 .remove = tps65912_i2c_remove,
115 .id_table = tps65912_i2c_id, 73 .id_table = tps65912_i2c_id_table,
116}; 74};
75module_i2c_driver(tps65912_i2c_driver);
117 76
118static int __init tps65912_i2c_init(void) 77MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
119{ 78MODULE_DESCRIPTION("TPS65912x I2C Interface Driver");
120 int ret; 79MODULE_LICENSE("GPL v2");
121
122 ret = i2c_add_driver(&tps65912_i2c_driver);
123 if (ret != 0)
124 pr_err("Failed to register TPS65912 I2C driver: %d\n", ret);
125
126 return ret;
127}
128/* init early so consumer devices can complete system boot */
129subsys_initcall(tps65912_i2c_init);
130
131static void __exit tps65912_i2c_exit(void)
132{
133 i2c_del_driver(&tps65912_i2c_driver);
134}
135module_exit(tps65912_i2c_exit);
136
137MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>");
138MODULE_DESCRIPTION("TPS6591x chip family multi-function driver");
139MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/tps65912-irq.c b/drivers/mfd/tps65912-irq.c
deleted file mode 100644
index db2c29cb709b..000000000000
--- a/drivers/mfd/tps65912-irq.c
+++ /dev/null
@@ -1,217 +0,0 @@
1/*
2 * tps65912-irq.c -- TI TPS6591x
3 *
4 * Copyright 2011 Texas Instruments Inc.
5 *
6 * Author: Margarita Olaya <magi@slimlogic.co.uk>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This driver is based on wm8350 implementation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/bug.h>
19#include <linux/device.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/gpio.h>
23#include <linux/mfd/tps65912.h>
24
25static inline int irq_to_tps65912_irq(struct tps65912 *tps65912,
26 int irq)
27{
28 return irq - tps65912->irq_base;
29}
30
31/*
32 * This is a threaded IRQ handler so can access I2C/SPI. Since the
33 * IRQ handler explicitly clears the IRQ it handles the IRQ line
34 * will be reasserted and the physical IRQ will be handled again if
35 * another interrupt is asserted while we run - in the normal course
36 * of events this is a rare occurrence so we save I2C/SPI reads. We're
37 * also assuming that it's rare to get lots of interrupts firing
38 * simultaneously so try to minimise I/O.
39 */
40static irqreturn_t tps65912_irq(int irq, void *irq_data)
41{
42 struct tps65912 *tps65912 = irq_data;
43 u32 irq_sts;
44 u32 irq_mask;
45 u8 reg;
46 int i;
47
48
49 tps65912->read(tps65912, TPS65912_INT_STS, 1, &reg);
50 irq_sts = reg;
51 tps65912->read(tps65912, TPS65912_INT_STS2, 1, &reg);
52 irq_sts |= reg << 8;
53 tps65912->read(tps65912, TPS65912_INT_STS3, 1, &reg);
54 irq_sts |= reg << 16;
55 tps65912->read(tps65912, TPS65912_INT_STS4, 1, &reg);
56 irq_sts |= reg << 24;
57
58 tps65912->read(tps65912, TPS65912_INT_MSK, 1, &reg);
59 irq_mask = reg;
60 tps65912->read(tps65912, TPS65912_INT_MSK2, 1, &reg);
61 irq_mask |= reg << 8;
62 tps65912->read(tps65912, TPS65912_INT_MSK3, 1, &reg);
63 irq_mask |= reg << 16;
64 tps65912->read(tps65912, TPS65912_INT_MSK4, 1, &reg);
65 irq_mask |= reg << 24;
66
67 irq_sts &= ~irq_mask;
68 if (!irq_sts)
69 return IRQ_NONE;
70
71 for (i = 0; i < tps65912->irq_num; i++) {
72 if (!(irq_sts & (1 << i)))
73 continue;
74
75 handle_nested_irq(tps65912->irq_base + i);
76 }
77
78 /* Write the STS register back to clear IRQs we handled */
79 reg = irq_sts & 0xFF;
80 irq_sts >>= 8;
81 if (reg)
82 tps65912->write(tps65912, TPS65912_INT_STS, 1, &reg);
83 reg = irq_sts & 0xFF;
84 irq_sts >>= 8;
85 if (reg)
86 tps65912->write(tps65912, TPS65912_INT_STS2, 1, &reg);
87 reg = irq_sts & 0xFF;
88 irq_sts >>= 8;
89 if (reg)
90 tps65912->write(tps65912, TPS65912_INT_STS3, 1, &reg);
91 reg = irq_sts & 0xFF;
92 if (reg)
93 tps65912->write(tps65912, TPS65912_INT_STS4, 1, &reg);
94
95 return IRQ_HANDLED;
96}
97
98static void tps65912_irq_lock(struct irq_data *data)
99{
100 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
101
102 mutex_lock(&tps65912->irq_lock);
103}
104
105static void tps65912_irq_sync_unlock(struct irq_data *data)
106{
107 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
108 u32 reg_mask;
109 u8 reg;
110
111 tps65912->read(tps65912, TPS65912_INT_MSK, 1, &reg);
112 reg_mask = reg;
113 tps65912->read(tps65912, TPS65912_INT_MSK2, 1, &reg);
114 reg_mask |= reg << 8;
115 tps65912->read(tps65912, TPS65912_INT_MSK3, 1, &reg);
116 reg_mask |= reg << 16;
117 tps65912->read(tps65912, TPS65912_INT_MSK4, 1, &reg);
118 reg_mask |= reg << 24;
119
120 if (tps65912->irq_mask != reg_mask) {
121 reg = tps65912->irq_mask & 0xFF;
122 tps65912->write(tps65912, TPS65912_INT_MSK, 1, &reg);
123 reg = tps65912->irq_mask >> 8 & 0xFF;
124 tps65912->write(tps65912, TPS65912_INT_MSK2, 1, &reg);
125 reg = tps65912->irq_mask >> 16 & 0xFF;
126 tps65912->write(tps65912, TPS65912_INT_MSK3, 1, &reg);
127 reg = tps65912->irq_mask >> 24 & 0xFF;
128 tps65912->write(tps65912, TPS65912_INT_MSK4, 1, &reg);
129 }
130
131 mutex_unlock(&tps65912->irq_lock);
132}
133
134static void tps65912_irq_enable(struct irq_data *data)
135{
136 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
137
138 tps65912->irq_mask &= ~(1 << irq_to_tps65912_irq(tps65912, data->irq));
139}
140
141static void tps65912_irq_disable(struct irq_data *data)
142{
143 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data);
144
145 tps65912->irq_mask |= (1 << irq_to_tps65912_irq(tps65912, data->irq));
146}
147
148static struct irq_chip tps65912_irq_chip = {
149 .name = "tps65912",
150 .irq_bus_lock = tps65912_irq_lock,
151 .irq_bus_sync_unlock = tps65912_irq_sync_unlock,
152 .irq_disable = tps65912_irq_disable,
153 .irq_enable = tps65912_irq_enable,
154};
155
156int tps65912_irq_init(struct tps65912 *tps65912, int irq,
157 struct tps65912_platform_data *pdata)
158{
159 int ret, cur_irq;
160 int flags = IRQF_ONESHOT;
161 u8 reg;
162
163 if (!irq) {
164 dev_warn(tps65912->dev, "No interrupt support, no core IRQ\n");
165 return 0;
166 }
167
168 if (!pdata || !pdata->irq_base) {
169 dev_warn(tps65912->dev, "No interrupt support, no IRQ base\n");
170 return 0;
171 }
172
173 /* Clear unattended interrupts */
174 tps65912->read(tps65912, TPS65912_INT_STS, 1, &reg);
175 tps65912->write(tps65912, TPS65912_INT_STS, 1, &reg);
176 tps65912->read(tps65912, TPS65912_INT_STS2, 1, &reg);
177 tps65912->write(tps65912, TPS65912_INT_STS2, 1, &reg);
178 tps65912->read(tps65912, TPS65912_INT_STS3, 1, &reg);
179 tps65912->write(tps65912, TPS65912_INT_STS3, 1, &reg);
180 tps65912->read(tps65912, TPS65912_INT_STS4, 1, &reg);
181 tps65912->write(tps65912, TPS65912_INT_STS4, 1, &reg);
182
183 /* Mask top level interrupts */
184 tps65912->irq_mask = 0xFFFFFFFF;
185
186 mutex_init(&tps65912->irq_lock);
187 tps65912->chip_irq = irq;
188 tps65912->irq_base = pdata->irq_base;
189
190 tps65912->irq_num = TPS65912_NUM_IRQ;
191
192 /* Register with genirq */
193 for (cur_irq = tps65912->irq_base;
194 cur_irq < tps65912->irq_num + tps65912->irq_base;
195 cur_irq++) {
196 irq_set_chip_data(cur_irq, tps65912);
197 irq_set_chip_and_handler(cur_irq, &tps65912_irq_chip,
198 handle_edge_irq);
199 irq_set_nested_thread(cur_irq, 1);
200 irq_clear_status_flags(cur_irq, IRQ_NOREQUEST | IRQ_NOPROBE);
201 }
202
203 ret = request_threaded_irq(irq, NULL, tps65912_irq, flags,
204 "tps65912", tps65912);
205
206 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
207 if (ret != 0)
208 dev_err(tps65912->dev, "Failed to request IRQ: %d\n", ret);
209
210 return ret;
211}
212
213int tps65912_irq_exit(struct tps65912 *tps65912)
214{
215 free_irq(tps65912->chip_irq, tps65912);
216 return 0;
217}
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index d59aa55b1495..4aeba9b6942a 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -1,140 +1,78 @@
1/* 1/*
2 * tps65912-spi.c -- SPI access for TI TPS65912x PMIC 2 * SPI access driver for TI TPS65912x PMICs
3 * 3 *
4 * Copyright 2011 Texas Instruments Inc. 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com>
5 * 6 *
6 * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
7 * 10 *
8 * This program is free software; you can redistribute it and/or modify it 11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * under the terms of the GNU General Public License as published by the 12 * kind, whether expressed or implied; without even the implied warranty
10 * Free Software Foundation; either version 2 of the License, or (at your 13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * option) any later version. 14 * GNU General Public License version 2 for more details.
12 * 15 *
13 * This driver is based on wm8350 implementation. 16 * Based on the TPS65218 driver and the previous TPS65912 driver by
17 * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
14 */ 18 */
15 19
16#include <linux/module.h> 20#include <linux/module.h>
17#include <linux/moduleparam.h> 21#include <linux/regmap.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/gpio.h>
21#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
22#include <linux/mfd/core.h>
23#include <linux/mfd/tps65912.h>
24
25static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr,
26 int bytes, void *src)
27{
28 struct spi_device *spi = tps65912->control_data;
29 u8 *data = (u8 *) src;
30 int ret;
31 /* bit 23 is the read/write bit */
32 unsigned long spi_data = 1 << 23 | addr << 15 | *data;
33 struct spi_transfer xfer;
34 struct spi_message msg;
35 u32 tx_buf;
36
37 tx_buf = spi_data;
38
39 xfer.tx_buf = &tx_buf;
40 xfer.rx_buf = NULL;
41 xfer.len = sizeof(unsigned long);
42 xfer.bits_per_word = 24;
43
44 spi_message_init(&msg);
45 spi_message_add_tail(&xfer, &msg);
46
47 ret = spi_sync(spi, &msg);
48 return ret;
49}
50
51static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr,
52 int bytes, void *dest)
53{
54 struct spi_device *spi = tps65912->control_data;
55 /* bit 23 is the read/write bit */
56 unsigned long spi_data = 0 << 23 | addr << 15;
57 struct spi_transfer xfer;
58 struct spi_message msg;
59 int ret;
60 u8 *data = (u8 *) dest;
61 u32 tx_buf, rx_buf;
62
63 tx_buf = spi_data;
64 rx_buf = 0;
65 23
66 xfer.tx_buf = &tx_buf; 24#include <linux/mfd/tps65912.h>
67 xfer.rx_buf = &rx_buf;
68 xfer.len = sizeof(unsigned long);
69 xfer.bits_per_word = 24;
70
71 spi_message_init(&msg);
72 spi_message_add_tail(&xfer, &msg);
73
74 if (spi == NULL)
75 return 0;
76 25
77 ret = spi_sync(spi, &msg); 26static const struct of_device_id tps65912_spi_of_match_table[] = {
78 if (ret == 0) 27 { .compatible = "ti,tps65912", },
79 *data = (u8) (rx_buf & 0xFF); 28 { /* sentinel */ }
80 return ret; 29};
81}
82 30
83static int tps65912_spi_probe(struct spi_device *spi) 31static int tps65912_spi_probe(struct spi_device *spi)
84{ 32{
85 struct tps65912 *tps65912; 33 struct tps65912 *tps;
86 34
87 tps65912 = devm_kzalloc(&spi->dev, 35 tps = devm_kzalloc(&spi->dev, sizeof(*tps), GFP_KERNEL);
88 sizeof(struct tps65912), GFP_KERNEL); 36 if (!tps)
89 if (tps65912 == NULL)
90 return -ENOMEM; 37 return -ENOMEM;
91 38
92 tps65912->dev = &spi->dev; 39 spi_set_drvdata(spi, tps);
93 tps65912->control_data = spi; 40 tps->dev = &spi->dev;
94 tps65912->read = tps65912_spi_read; 41 tps->irq = spi->irq;
95 tps65912->write = tps65912_spi_write;
96 42
97 spi_set_drvdata(spi, tps65912); 43 tps->regmap = devm_regmap_init_spi(spi, &tps65912_regmap_config);
44 if (IS_ERR(tps->regmap)) {
45 dev_err(tps->dev, "Failed to initialize register map\n");
46 return PTR_ERR(tps->regmap);
47 }
98 48
99 return tps65912_device_init(tps65912); 49 return tps65912_device_init(tps);
100} 50}
101 51
102static int tps65912_spi_remove(struct spi_device *spi) 52static int tps65912_spi_remove(struct spi_device *client)
103{ 53{
104 struct tps65912 *tps65912 = spi_get_drvdata(spi); 54 struct tps65912 *tps = spi_get_drvdata(client);
105 55
106 tps65912_device_exit(tps65912); 56 return tps65912_device_exit(tps);
107
108 return 0;
109} 57}
110 58
59static const struct spi_device_id tps65912_spi_id_table[] = {
60 { "tps65912", 0 },
61 { /* sentinel */ }
62};
63MODULE_DEVICE_TABLE(spi, tps65912_spi_id_table);
64
111static struct spi_driver tps65912_spi_driver = { 65static struct spi_driver tps65912_spi_driver = {
112 .driver = { 66 .driver = {
113 .name = "tps65912", 67 .name = "tps65912",
68 .of_match_table = tps65912_spi_of_match_table,
114 }, 69 },
115 .probe = tps65912_spi_probe, 70 .probe = tps65912_spi_probe,
116 .remove = tps65912_spi_remove, 71 .remove = tps65912_spi_remove,
72 .id_table = tps65912_spi_id_table,
117}; 73};
74module_spi_driver(tps65912_spi_driver);
118 75
119static int __init tps65912_spi_init(void) 76MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
120{ 77MODULE_DESCRIPTION("TPS65912x SPI Interface Driver");
121 int ret; 78MODULE_LICENSE("GPL v2");
122
123 ret = spi_register_driver(&tps65912_spi_driver);
124 if (ret != 0)
125 pr_err("Failed to register TPS65912 SPI driver: %d\n", ret);
126
127 return 0;
128}
129/* init early so consumer devices can complete system boot */
130subsys_initcall(tps65912_spi_init);
131
132static void __exit tps65912_spi_exit(void)
133{
134 spi_unregister_driver(&tps65912_spi_driver);
135}
136module_exit(tps65912_spi_exit);
137
138MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>");
139MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd");
140MODULE_LICENSE("GPL");