aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/Kconfig14
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/rc5t583-irq.c408
-rw-r--r--drivers/mfd/rc5t583.c386
-rw-r--r--include/linux/mfd/rc5t583.h295
5 files changed, 1104 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 82da44877cdc..0f593966a310 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -846,6 +846,20 @@ config MFD_INTEL_MSIC
846 Passage) chip. This chip embeds audio, battery, GPIO, etc. 846 Passage) chip. This chip embeds audio, battery, GPIO, etc.
847 devices used in Intel Medfield platforms. 847 devices used in Intel Medfield platforms.
848 848
849config MFD_RC5T583
850 bool "Ricoh RC5T583 Power Management system device"
851 depends on I2C && GENERIC_HARDIRQS
852 select MFD_CORE
853 select REGMAP_I2C
854 help
855 Select this option to get support for the RICOH583 Power
856 Management system device.
857 This driver provides common support for accessing the device
858 through i2c interface. The device supports multiple sub-devices
859 like GPIO, interrupts, RTC, LDO and DCDC regulators, onkey.
860 Additional drivers must be enabled in order to use the
861 different functionality of the device.
862
849endmenu 863endmenu
850endif 864endif
851 865
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 27430d3e839c..ea0bb809739e 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -112,4 +112,5 @@ obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
112obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o 112obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
113obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o 113obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
114obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o 114obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
115obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
115obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o 116obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c
new file mode 100644
index 000000000000..fa6f80fad5f1
--- /dev/null
+++ b/drivers/mfd/rc5t583-irq.c
@@ -0,0 +1,408 @@
1/*
2 * Interrupt driver for RICOH583 power management chip.
3 *
4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
5 * Author: Laxman dewangan <ldewangan@nvidia.com>
6 *
7 * based on code
8 * Copyright (C) 2011 RICOH COMPANY,LTD
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/init.h>
26#include <linux/i2c.h>
27#include <linux/mfd/rc5t583.h>
28
29enum int_type {
30 SYS_INT = 0x1,
31 DCDC_INT = 0x2,
32 RTC_INT = 0x4,
33 ADC_INT = 0x8,
34 GPIO_INT = 0x10,
35};
36
37static int gpedge_add[] = {
38 RC5T583_GPIO_GPEDGE2,
39 RC5T583_GPIO_GPEDGE2
40};
41
42static int irq_en_add[] = {
43 RC5T583_INT_EN_SYS1,
44 RC5T583_INT_EN_SYS2,
45 RC5T583_INT_EN_DCDC,
46 RC5T583_INT_EN_RTC,
47 RC5T583_INT_EN_ADC1,
48 RC5T583_INT_EN_ADC2,
49 RC5T583_INT_EN_ADC3,
50 RC5T583_GPIO_EN_INT
51};
52
53static int irq_mon_add[] = {
54 RC5T583_INT_MON_SYS1,
55 RC5T583_INT_MON_SYS2,
56 RC5T583_INT_MON_DCDC,
57 RC5T583_INT_MON_RTC,
58 RC5T583_INT_IR_ADCL,
59 RC5T583_INT_IR_ADCH,
60 RC5T583_INT_IR_ADCEND,
61 RC5T583_INT_IR_GPIOF,
62 RC5T583_INT_IR_GPIOR
63};
64
65static int irq_clr_add[] = {
66 RC5T583_INT_IR_SYS1,
67 RC5T583_INT_IR_SYS2,
68 RC5T583_INT_IR_DCDC,
69 RC5T583_INT_IR_RTC,
70 RC5T583_INT_IR_ADCL,
71 RC5T583_INT_IR_ADCH,
72 RC5T583_INT_IR_ADCEND,
73 RC5T583_INT_IR_GPIOF,
74 RC5T583_INT_IR_GPIOR
75};
76
77static int main_int_type[] = {
78 SYS_INT,
79 SYS_INT,
80 DCDC_INT,
81 RTC_INT,
82 ADC_INT,
83 ADC_INT,
84 ADC_INT,
85 GPIO_INT,
86 GPIO_INT,
87};
88
89struct rc5t583_irq_data {
90 u8 int_type;
91 u8 master_bit;
92 u8 int_en_bit;
93 u8 mask_reg_index;
94 int grp_index;
95};
96
97#define RC5T583_IRQ(_int_type, _master_bit, _grp_index, \
98 _int_bit, _mask_ind) \
99 { \
100 .int_type = _int_type, \
101 .master_bit = _master_bit, \
102 .grp_index = _grp_index, \
103 .int_en_bit = _int_bit, \
104 .mask_reg_index = _mask_ind, \
105 }
106
107static const struct rc5t583_irq_data rc5t583_irqs[RC5T583_MAX_IRQS] = {
108 [RC5T583_IRQ_ONKEY] = RC5T583_IRQ(SYS_INT, 0, 0, 0, 0),
109 [RC5T583_IRQ_ACOK] = RC5T583_IRQ(SYS_INT, 0, 1, 1, 0),
110 [RC5T583_IRQ_LIDOPEN] = RC5T583_IRQ(SYS_INT, 0, 2, 2, 0),
111 [RC5T583_IRQ_PREOT] = RC5T583_IRQ(SYS_INT, 0, 3, 3, 0),
112 [RC5T583_IRQ_CLKSTP] = RC5T583_IRQ(SYS_INT, 0, 4, 4, 0),
113 [RC5T583_IRQ_ONKEY_OFF] = RC5T583_IRQ(SYS_INT, 0, 5, 5, 0),
114 [RC5T583_IRQ_WD] = RC5T583_IRQ(SYS_INT, 0, 7, 7, 0),
115 [RC5T583_IRQ_EN_PWRREQ1] = RC5T583_IRQ(SYS_INT, 0, 8, 0, 1),
116 [RC5T583_IRQ_EN_PWRREQ2] = RC5T583_IRQ(SYS_INT, 0, 9, 1, 1),
117 [RC5T583_IRQ_PRE_VINDET] = RC5T583_IRQ(SYS_INT, 0, 10, 2, 1),
118
119 [RC5T583_IRQ_DC0LIM] = RC5T583_IRQ(DCDC_INT, 1, 0, 0, 2),
120 [RC5T583_IRQ_DC1LIM] = RC5T583_IRQ(DCDC_INT, 1, 1, 1, 2),
121 [RC5T583_IRQ_DC2LIM] = RC5T583_IRQ(DCDC_INT, 1, 2, 2, 2),
122 [RC5T583_IRQ_DC3LIM] = RC5T583_IRQ(DCDC_INT, 1, 3, 3, 2),
123
124 [RC5T583_IRQ_CTC] = RC5T583_IRQ(RTC_INT, 2, 0, 0, 3),
125 [RC5T583_IRQ_YALE] = RC5T583_IRQ(RTC_INT, 2, 5, 5, 3),
126 [RC5T583_IRQ_DALE] = RC5T583_IRQ(RTC_INT, 2, 6, 6, 3),
127 [RC5T583_IRQ_WALE] = RC5T583_IRQ(RTC_INT, 2, 7, 7, 3),
128
129 [RC5T583_IRQ_AIN1L] = RC5T583_IRQ(ADC_INT, 3, 0, 0, 4),
130 [RC5T583_IRQ_AIN2L] = RC5T583_IRQ(ADC_INT, 3, 1, 1, 4),
131 [RC5T583_IRQ_AIN3L] = RC5T583_IRQ(ADC_INT, 3, 2, 2, 4),
132 [RC5T583_IRQ_VBATL] = RC5T583_IRQ(ADC_INT, 3, 3, 3, 4),
133 [RC5T583_IRQ_VIN3L] = RC5T583_IRQ(ADC_INT, 3, 4, 4, 4),
134 [RC5T583_IRQ_VIN8L] = RC5T583_IRQ(ADC_INT, 3, 5, 5, 4),
135 [RC5T583_IRQ_AIN1H] = RC5T583_IRQ(ADC_INT, 3, 6, 0, 5),
136 [RC5T583_IRQ_AIN2H] = RC5T583_IRQ(ADC_INT, 3, 7, 1, 5),
137 [RC5T583_IRQ_AIN3H] = RC5T583_IRQ(ADC_INT, 3, 8, 2, 5),
138 [RC5T583_IRQ_VBATH] = RC5T583_IRQ(ADC_INT, 3, 9, 3, 5),
139 [RC5T583_IRQ_VIN3H] = RC5T583_IRQ(ADC_INT, 3, 10, 4, 5),
140 [RC5T583_IRQ_VIN8H] = RC5T583_IRQ(ADC_INT, 3, 11, 5, 5),
141 [RC5T583_IRQ_ADCEND] = RC5T583_IRQ(ADC_INT, 3, 12, 0, 6),
142
143 [RC5T583_IRQ_GPIO0] = RC5T583_IRQ(GPIO_INT, 4, 0, 0, 7),
144 [RC5T583_IRQ_GPIO1] = RC5T583_IRQ(GPIO_INT, 4, 1, 1, 7),
145 [RC5T583_IRQ_GPIO2] = RC5T583_IRQ(GPIO_INT, 4, 2, 2, 7),
146 [RC5T583_IRQ_GPIO3] = RC5T583_IRQ(GPIO_INT, 4, 3, 3, 7),
147 [RC5T583_IRQ_GPIO4] = RC5T583_IRQ(GPIO_INT, 4, 4, 4, 7),
148 [RC5T583_IRQ_GPIO5] = RC5T583_IRQ(GPIO_INT, 4, 5, 5, 7),
149 [RC5T583_IRQ_GPIO6] = RC5T583_IRQ(GPIO_INT, 4, 6, 6, 7),
150 [RC5T583_IRQ_GPIO7] = RC5T583_IRQ(GPIO_INT, 4, 7, 7, 7),
151};
152
153static void rc5t583_irq_lock(struct irq_data *irq_data)
154{
155 struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
156 mutex_lock(&rc5t583->irq_lock);
157}
158
159static void rc5t583_irq_unmask(struct irq_data *irq_data)
160{
161 struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
162 unsigned int __irq = irq_data->irq - rc5t583->irq_base;
163 const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq];
164
165 rc5t583->group_irq_en[data->grp_index] |= 1 << data->grp_index;
166 rc5t583->intc_inten_reg |= 1 << data->master_bit;
167 rc5t583->irq_en_reg[data->mask_reg_index] |= 1 << data->int_en_bit;
168}
169
170static void rc5t583_irq_mask(struct irq_data *irq_data)
171{
172 struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
173 unsigned int __irq = irq_data->irq - rc5t583->irq_base;
174 const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq];
175
176 rc5t583->group_irq_en[data->grp_index] &= ~(1 << data->grp_index);
177 if (!rc5t583->group_irq_en[data->grp_index])
178 rc5t583->intc_inten_reg &= ~(1 << data->master_bit);
179
180 rc5t583->irq_en_reg[data->mask_reg_index] &= ~(1 << data->int_en_bit);
181}
182
183static int rc5t583_irq_set_type(struct irq_data *irq_data, unsigned int type)
184{
185 struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
186 unsigned int __irq = irq_data->irq - rc5t583->irq_base;
187 const struct rc5t583_irq_data *data = &rc5t583_irqs[__irq];
188 int val = 0;
189 int gpedge_index;
190 int gpedge_bit_pos;
191
192 /* Supporting only trigger level inetrrupt */
193 if ((data->int_type & GPIO_INT) && (type & IRQ_TYPE_EDGE_BOTH)) {
194 gpedge_index = data->int_en_bit / 4;
195 gpedge_bit_pos = data->int_en_bit % 4;
196
197 if (type & IRQ_TYPE_EDGE_FALLING)
198 val |= 0x2;
199
200 if (type & IRQ_TYPE_EDGE_RISING)
201 val |= 0x1;
202
203 rc5t583->gpedge_reg[gpedge_index] &= ~(3 << gpedge_bit_pos);
204 rc5t583->gpedge_reg[gpedge_index] |= (val << gpedge_bit_pos);
205 rc5t583_irq_unmask(irq_data);
206 return 0;
207 }
208 return -EINVAL;
209}
210
211static void rc5t583_irq_sync_unlock(struct irq_data *irq_data)
212{
213 struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
214 int i;
215 int ret;
216
217 for (i = 0; i < ARRAY_SIZE(rc5t583->gpedge_reg); i++) {
218 ret = rc5t583_write(rc5t583->dev, gpedge_add[i],
219 rc5t583->gpedge_reg[i]);
220 if (ret < 0)
221 dev_warn(rc5t583->dev,
222 "Error in writing reg 0x%02x error: %d\n",
223 gpedge_add[i], ret);
224 }
225
226 for (i = 0; i < ARRAY_SIZE(rc5t583->irq_en_reg); i++) {
227 ret = rc5t583_write(rc5t583->dev, irq_en_add[i],
228 rc5t583->irq_en_reg[i]);
229 if (ret < 0)
230 dev_warn(rc5t583->dev,
231 "Error in writing reg 0x%02x error: %d\n",
232 irq_en_add[i], ret);
233 }
234
235 ret = rc5t583_write(rc5t583->dev, RC5T583_INTC_INTEN,
236 rc5t583->intc_inten_reg);
237 if (ret < 0)
238 dev_warn(rc5t583->dev,
239 "Error in writing reg 0x%02x error: %d\n",
240 RC5T583_INTC_INTEN, ret);
241
242 mutex_unlock(&rc5t583->irq_lock);
243}
244#ifdef CONFIG_PM_SLEEP
245static int rc5t583_irq_set_wake(struct irq_data *irq_data, unsigned int on)
246{
247 struct rc5t583 *rc5t583 = irq_data_get_irq_chip_data(irq_data);
248 return irq_set_irq_wake(rc5t583->chip_irq, on);
249}
250#else
251#define rc5t583_irq_set_wake NULL
252#endif
253
254static irqreturn_t rc5t583_irq(int irq, void *data)
255{
256 struct rc5t583 *rc5t583 = data;
257 uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS];
258 uint8_t master_int;
259 int i;
260 int ret;
261 unsigned int rtc_int_sts = 0;
262
263 /* Clear the status */
264 for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++)
265 int_sts[i] = 0;
266
267 ret = rc5t583_read(rc5t583->dev, RC5T583_INTC_INTMON, &master_int);
268 if (ret < 0) {
269 dev_err(rc5t583->dev,
270 "Error in reading reg 0x%02x error: %d\n",
271 RC5T583_INTC_INTMON, ret);
272 return IRQ_HANDLED;
273 }
274
275 for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; ++i) {
276 if (!(master_int & main_int_type[i]))
277 continue;
278
279 ret = rc5t583_read(rc5t583->dev, irq_mon_add[i], &int_sts[i]);
280 if (ret < 0) {
281 dev_warn(rc5t583->dev,
282 "Error in reading reg 0x%02x error: %d\n",
283 irq_mon_add[i], ret);
284 int_sts[i] = 0;
285 continue;
286 }
287
288 if (main_int_type[i] & RTC_INT) {
289 rtc_int_sts = 0;
290 if (int_sts[i] & 0x1)
291 rtc_int_sts |= BIT(6);
292 if (int_sts[i] & 0x2)
293 rtc_int_sts |= BIT(7);
294 if (int_sts[i] & 0x4)
295 rtc_int_sts |= BIT(0);
296 if (int_sts[i] & 0x8)
297 rtc_int_sts |= BIT(5);
298 }
299
300 ret = rc5t583_write(rc5t583->dev, irq_clr_add[i],
301 ~int_sts[i]);
302 if (ret < 0)
303 dev_warn(rc5t583->dev,
304 "Error in reading reg 0x%02x error: %d\n",
305 irq_clr_add[i], ret);
306
307 if (main_int_type[i] & RTC_INT)
308 int_sts[i] = rtc_int_sts;
309 }
310
311 /* Merge gpio interrupts for rising and falling case*/
312 int_sts[7] |= int_sts[8];
313
314 /* Call interrupt handler if enabled */
315 for (i = 0; i < RC5T583_MAX_IRQS; ++i) {
316 const struct rc5t583_irq_data *data = &rc5t583_irqs[i];
317 if ((int_sts[data->mask_reg_index] & (1 << data->int_en_bit)) &&
318 (rc5t583->group_irq_en[data->master_bit] &
319 (1 << data->grp_index)))
320 handle_nested_irq(rc5t583->irq_base + i);
321 }
322
323 return IRQ_HANDLED;
324}
325
326static struct irq_chip rc5t583_irq_chip = {
327 .name = "rc5t583-irq",
328 .irq_mask = rc5t583_irq_mask,
329 .irq_unmask = rc5t583_irq_unmask,
330 .irq_bus_lock = rc5t583_irq_lock,
331 .irq_bus_sync_unlock = rc5t583_irq_sync_unlock,
332 .irq_set_type = rc5t583_irq_set_type,
333 .irq_set_wake = rc5t583_irq_set_wake,
334};
335
336int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base)
337{
338 int i, ret;
339
340 if (!irq_base) {
341 dev_warn(rc5t583->dev, "No interrupt support on IRQ base\n");
342 return -EINVAL;
343 }
344
345 mutex_init(&rc5t583->irq_lock);
346
347 /* Initailize all int register to 0 */
348 for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++) {
349 ret = rc5t583_write(rc5t583->dev, irq_en_add[i],
350 rc5t583->irq_en_reg[i]);
351 if (ret < 0)
352 dev_warn(rc5t583->dev,
353 "Error in writing reg 0x%02x error: %d\n",
354 irq_en_add[i], ret);
355 }
356
357 for (i = 0; i < RC5T583_MAX_GPEDGE_REG; i++) {
358 ret = rc5t583_write(rc5t583->dev, gpedge_add[i],
359 rc5t583->gpedge_reg[i]);
360 if (ret < 0)
361 dev_warn(rc5t583->dev,
362 "Error in writing reg 0x%02x error: %d\n",
363 gpedge_add[i], ret);
364 }
365
366 ret = rc5t583_write(rc5t583->dev, RC5T583_INTC_INTEN, 0x0);
367 if (ret < 0)
368 dev_warn(rc5t583->dev,
369 "Error in writing reg 0x%02x error: %d\n",
370 RC5T583_INTC_INTEN, ret);
371
372 /* Clear all interrupts in case they woke up active. */
373 for (i = 0; i < RC5T583_MAX_INTERRUPT_MASK_REGS; i++) {
374 ret = rc5t583_write(rc5t583->dev, irq_clr_add[i], 0);
375 if (ret < 0)
376 dev_warn(rc5t583->dev,
377 "Error in writing reg 0x%02x error: %d\n",
378 irq_clr_add[i], ret);
379 }
380
381 rc5t583->irq_base = irq_base;
382 rc5t583->chip_irq = irq;
383
384 for (i = 0; i < RC5T583_MAX_IRQS; i++) {
385 int __irq = i + rc5t583->irq_base;
386 irq_set_chip_data(__irq, rc5t583);
387 irq_set_chip_and_handler(__irq, &rc5t583_irq_chip,
388 handle_simple_irq);
389 irq_set_nested_thread(__irq, 1);
390#ifdef CONFIG_ARM
391 set_irq_flags(__irq, IRQF_VALID);
392#endif
393 }
394
395 ret = request_threaded_irq(irq, NULL, rc5t583_irq, IRQF_ONESHOT,
396 "rc5t583", rc5t583);
397 if (ret < 0)
398 dev_err(rc5t583->dev,
399 "Error in registering interrupt error: %d\n", ret);
400 return ret;
401}
402
403int rc5t583_irq_exit(struct rc5t583 *rc5t583)
404{
405 if (rc5t583->chip_irq)
406 free_irq(rc5t583->chip_irq, rc5t583);
407 return 0;
408}
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
new file mode 100644
index 000000000000..99ef944c621d
--- /dev/null
+++ b/drivers/mfd/rc5t583.c
@@ -0,0 +1,386 @@
1/*
2 * Core driver access RC5T583 power management chip.
3 *
4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
5 * Author: Laxman dewangan <ldewangan@nvidia.com>
6 *
7 * Based on code
8 * Copyright (C) 2011 RICOH COMPANY,LTD
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/err.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31#include <linux/mfd/core.h>
32#include <linux/mfd/rc5t583.h>
33#include <linux/regmap.h>
34
35#define RICOH_ONOFFSEL_REG 0x10
36#define RICOH_SWCTL_REG 0x5E
37
38struct deepsleep_control_data {
39 u8 reg_add;
40 u8 ds_pos_bit;
41};
42
43#define DEEPSLEEP_INIT(_id, _reg, _pos) \
44 { \
45 .reg_add = RC5T583_##_reg, \
46 .ds_pos_bit = _pos, \
47 }
48
49static struct deepsleep_control_data deepsleep_data[] = {
50 DEEPSLEEP_INIT(DC0, SLPSEQ1, 0),
51 DEEPSLEEP_INIT(DC1, SLPSEQ1, 4),
52 DEEPSLEEP_INIT(DC2, SLPSEQ2, 0),
53 DEEPSLEEP_INIT(DC3, SLPSEQ2, 4),
54 DEEPSLEEP_INIT(LDO0, SLPSEQ3, 0),
55 DEEPSLEEP_INIT(LDO1, SLPSEQ3, 4),
56 DEEPSLEEP_INIT(LDO2, SLPSEQ4, 0),
57 DEEPSLEEP_INIT(LDO3, SLPSEQ4, 4),
58 DEEPSLEEP_INIT(LDO4, SLPSEQ5, 0),
59 DEEPSLEEP_INIT(LDO5, SLPSEQ5, 4),
60 DEEPSLEEP_INIT(LDO6, SLPSEQ6, 0),
61 DEEPSLEEP_INIT(LDO7, SLPSEQ6, 4),
62 DEEPSLEEP_INIT(LDO8, SLPSEQ7, 0),
63 DEEPSLEEP_INIT(LDO9, SLPSEQ7, 4),
64 DEEPSLEEP_INIT(PSO0, SLPSEQ8, 0),
65 DEEPSLEEP_INIT(PSO1, SLPSEQ8, 4),
66 DEEPSLEEP_INIT(PSO2, SLPSEQ9, 0),
67 DEEPSLEEP_INIT(PSO3, SLPSEQ9, 4),
68 DEEPSLEEP_INIT(PSO4, SLPSEQ10, 0),
69 DEEPSLEEP_INIT(PSO5, SLPSEQ10, 4),
70 DEEPSLEEP_INIT(PSO6, SLPSEQ11, 0),
71 DEEPSLEEP_INIT(PSO7, SLPSEQ11, 4),
72};
73
74#define EXT_PWR_REQ \
75 (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL)
76
77static struct mfd_cell rc5t583_subdevs[] = {
78 {.name = "rc5t583-regulator",},
79 {.name = "rc5t583-rtc", },
80 {.name = "rc5t583-key", }
81};
82
83int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
84{
85 struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
86 return regmap_write(rc5t583->regmap, reg, val);
87}
88
89int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
90{
91 struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
92 unsigned int ival;
93 int ret;
94 ret = regmap_read(rc5t583->regmap, reg, &ival);
95 if (!ret)
96 *val = (uint8_t)ival;
97 return ret;
98}
99
100int rc5t583_set_bits(struct device *dev, unsigned int reg,
101 unsigned int bit_mask)
102{
103 struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
104 return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
105}
106
107int rc5t583_clear_bits(struct device *dev, unsigned int reg,
108 unsigned int bit_mask)
109{
110 struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
111 return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
112}
113
114int rc5t583_update(struct device *dev, unsigned int reg,
115 unsigned int val, unsigned int mask)
116{
117 struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
118 return regmap_update_bits(rc5t583->regmap, reg, mask, val);
119}
120
121static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
122 int id, int ext_pwr, int slots)
123{
124 int ret;
125 uint8_t sleepseq_val;
126 unsigned int en_bit;
127 unsigned int slot_bit;
128
129 if (id == RC5T583_DS_DC0) {
130 dev_err(dev, "PWRREQ1 is invalid control for rail %d\n", id);
131 return -EINVAL;
132 }
133
134 en_bit = deepsleep_data[id].ds_pos_bit;
135 slot_bit = en_bit + 1;
136 ret = rc5t583_read(dev, deepsleep_data[id].reg_add, &sleepseq_val);
137 if (ret < 0) {
138 dev_err(dev, "Error in reading reg 0x%x\n",
139 deepsleep_data[id].reg_add);
140 return ret;
141 }
142
143 sleepseq_val &= ~(0xF << en_bit);
144 sleepseq_val |= BIT(en_bit);
145 sleepseq_val |= ((slots & 0x7) << slot_bit);
146 ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(1));
147 if (ret < 0) {
148 dev_err(dev, "Error in updating the 0x%02x register\n",
149 RICOH_ONOFFSEL_REG);
150 return ret;
151 }
152
153 ret = rc5t583_write(dev, deepsleep_data[id].reg_add, sleepseq_val);
154 if (ret < 0) {
155 dev_err(dev, "Error in writing reg 0x%x\n",
156 deepsleep_data[id].reg_add);
157 return ret;
158 }
159
160 if (id == RC5T583_DS_LDO4) {
161 ret = rc5t583_write(dev, RICOH_SWCTL_REG, 0x1);
162 if (ret < 0)
163 dev_err(dev, "Error in writing reg 0x%x\n",
164 RICOH_SWCTL_REG);
165 }
166 return ret;
167}
168
169static int __rc5t583_set_ext_pwrreq2_control(struct device *dev,
170 int id, int ext_pwr)
171{
172 int ret;
173
174 if (id != RC5T583_DS_DC0) {
175 dev_err(dev, "PWRREQ2 is invalid control for rail %d\n", id);
176 return -EINVAL;
177 }
178
179 ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(2));
180 if (ret < 0)
181 dev_err(dev, "Error in updating the ONOFFSEL 0x10 register\n");
182 return ret;
183}
184
185int rc5t583_ext_power_req_config(struct device *dev, int ds_id,
186 int ext_pwr_req, int deepsleep_slot_nr)
187{
188 if ((ext_pwr_req & EXT_PWR_REQ) == EXT_PWR_REQ)
189 return -EINVAL;
190
191 if (ext_pwr_req & RC5T583_EXT_PWRREQ1_CONTROL)
192 return __rc5t583_set_ext_pwrreq1_control(dev, ds_id,
193 ext_pwr_req, deepsleep_slot_nr);
194
195 if (ext_pwr_req & RC5T583_EXT_PWRREQ2_CONTROL)
196 return __rc5t583_set_ext_pwrreq2_control(dev,
197 ds_id, ext_pwr_req);
198 return 0;
199}
200
201static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
202 struct rc5t583_platform_data *pdata)
203{
204 int ret;
205 int i;
206 uint8_t on_off_val = 0;
207
208 /* Clear ONOFFSEL register */
209 if (pdata->enable_shutdown)
210 on_off_val = 0x1;
211
212 ret = rc5t583_write(rc5t583->dev, RICOH_ONOFFSEL_REG, on_off_val);
213 if (ret < 0)
214 dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n",
215 RICOH_ONOFFSEL_REG, ret);
216
217 ret = rc5t583_write(rc5t583->dev, RICOH_SWCTL_REG, 0x0);
218 if (ret < 0)
219 dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n",
220 RICOH_SWCTL_REG, ret);
221
222 /* Clear sleep sequence register */
223 for (i = RC5T583_SLPSEQ1; i <= RC5T583_SLPSEQ11; ++i) {
224 ret = rc5t583_write(rc5t583->dev, i, 0x0);
225 if (ret < 0)
226 dev_warn(rc5t583->dev,
227 "Error in writing reg 0x%02x error: %d\n",
228 i, ret);
229 }
230 return 0;
231}
232
233static bool volatile_reg(struct device *dev, unsigned int reg)
234{
235 /* Enable caching in interrupt registers */
236 switch (reg) {
237 case RC5T583_INT_EN_SYS1:
238 case RC5T583_INT_EN_SYS2:
239 case RC5T583_INT_EN_DCDC:
240 case RC5T583_INT_EN_RTC:
241 case RC5T583_INT_EN_ADC1:
242 case RC5T583_INT_EN_ADC2:
243 case RC5T583_INT_EN_ADC3:
244 case RC5T583_GPIO_GPEDGE1:
245 case RC5T583_GPIO_GPEDGE2:
246 case RC5T583_GPIO_EN_INT:
247 return false;
248
249 case RC5T583_GPIO_MON_IOIN:
250 /* This is gpio input register */
251 return true;
252
253 default:
254 /* Enable caching in gpio registers */
255 if ((reg >= RC5T583_GPIO_IOSEL) &&
256 (reg <= RC5T583_GPIO_GPOFUNC))
257 return false;
258
259 /* Enable caching in sleep seq registers */
260 if ((reg >= RC5T583_SLPSEQ1) && (reg <= RC5T583_SLPSEQ11))
261 return false;
262
263 /* Enable caching of regulator registers */
264 if ((reg >= RC5T583_REG_DC0CTL) && (reg <= RC5T583_REG_SR3CTL))
265 return false;
266 if ((reg >= RC5T583_REG_LDOEN1) &&
267 (reg <= RC5T583_REG_LDO9DAC_DS))
268 return false;
269
270 break;
271 }
272
273 return true;
274}
275
276static const struct regmap_config rc5t583_regmap_config = {
277 .reg_bits = 8,
278 .val_bits = 8,
279 .volatile_reg = volatile_reg,
280 .max_register = RC5T583_MAX_REGS,
281 .num_reg_defaults_raw = RC5T583_MAX_REGS,
282 .cache_type = REGCACHE_RBTREE,
283};
284
285static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,
286 const struct i2c_device_id *id)
287{
288 struct rc5t583 *rc5t583;
289 struct rc5t583_platform_data *pdata = i2c->dev.platform_data;
290 int ret;
291 bool irq_init_success = false;
292
293 if (!pdata) {
294 dev_err(&i2c->dev, "Err: Platform data not found\n");
295 return -EINVAL;
296 }
297
298 rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL);
299 if (!rc5t583) {
300 dev_err(&i2c->dev, "Memory allocation failed\n");
301 return -ENOMEM;
302 }
303
304 rc5t583->dev = &i2c->dev;
305 i2c_set_clientdata(i2c, rc5t583);
306
307 rc5t583->regmap = regmap_init_i2c(i2c, &rc5t583_regmap_config);
308 if (IS_ERR(rc5t583->regmap)) {
309 ret = PTR_ERR(rc5t583->regmap);
310 dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
311 return ret;
312 }
313
314 ret = rc5t583_clear_ext_power_req(rc5t583, pdata);
315 if (ret < 0)
316 goto err_irq_init;
317
318 if (i2c->irq) {
319 ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base);
320 /* Still continue with waring if irq init fails */
321 if (ret)
322 dev_warn(&i2c->dev, "IRQ init failed: %d\n", ret);
323 else
324 irq_init_success = true;
325 }
326
327 ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs,
328 ARRAY_SIZE(rc5t583_subdevs), NULL, 0);
329 if (ret) {
330 dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret);
331 goto err_add_devs;
332 }
333
334 return 0;
335
336err_add_devs:
337 if (irq_init_success)
338 rc5t583_irq_exit(rc5t583);
339err_irq_init:
340 regmap_exit(rc5t583->regmap);
341 return ret;
342}
343
344static int __devexit rc5t583_i2c_remove(struct i2c_client *i2c)
345{
346 struct rc5t583 *rc5t583 = i2c_get_clientdata(i2c);
347
348 mfd_remove_devices(rc5t583->dev);
349 rc5t583_irq_exit(rc5t583);
350 regmap_exit(rc5t583->regmap);
351 return 0;
352}
353
354static const struct i2c_device_id rc5t583_i2c_id[] = {
355 {.name = "rc5t583", .driver_data = 0},
356 {}
357};
358
359MODULE_DEVICE_TABLE(i2c, rc5t583_i2c_id);
360
361static struct i2c_driver rc5t583_i2c_driver = {
362 .driver = {
363 .name = "rc5t583",
364 .owner = THIS_MODULE,
365 },
366 .probe = rc5t583_i2c_probe,
367 .remove = __devexit_p(rc5t583_i2c_remove),
368 .id_table = rc5t583_i2c_id,
369};
370
371static int __init rc5t583_i2c_init(void)
372{
373 return i2c_add_driver(&rc5t583_i2c_driver);
374}
375subsys_initcall(rc5t583_i2c_init);
376
377static void __exit rc5t583_i2c_exit(void)
378{
379 i2c_del_driver(&rc5t583_i2c_driver);
380}
381
382module_exit(rc5t583_i2c_exit);
383
384MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
385MODULE_DESCRIPTION("RICOH RC5T583 power management system device driver");
386MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h
new file mode 100644
index 000000000000..a2c61609d21d
--- /dev/null
+++ b/include/linux/mfd/rc5t583.h
@@ -0,0 +1,295 @@
1/*
2 * Core driver interface to access RICOH_RC5T583 power management chip.
3 *
4 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
5 * Author: Laxman dewangan <ldewangan@nvidia.com>
6 *
7 * Based on code
8 * Copyright (C) 2011 RICOH COMPANY,LTD
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#ifndef __LINUX_MFD_RC5T583_H
25#define __LINUX_MFD_RC5T583_H
26
27#include <linux/mutex.h>
28#include <linux/types.h>
29
30#define RC5T583_MAX_REGS 0xF8
31
32/* Maximum number of main interrupts */
33#define MAX_MAIN_INTERRUPT 5
34#define RC5T583_MAX_GPEDGE_REG 2
35#define RC5T583_MAX_INTERRUPT_MASK_REGS 9
36
37/* Interrupt enable register */
38#define RC5T583_INT_EN_SYS1 0x19
39#define RC5T583_INT_EN_SYS2 0x1D
40#define RC5T583_INT_EN_DCDC 0x41
41#define RC5T583_INT_EN_RTC 0xED
42#define RC5T583_INT_EN_ADC1 0x90
43#define RC5T583_INT_EN_ADC2 0x91
44#define RC5T583_INT_EN_ADC3 0x92
45
46/* Interrupt status registers (monitor regs in Ricoh)*/
47#define RC5T583_INTC_INTPOL 0xAD
48#define RC5T583_INTC_INTEN 0xAE
49#define RC5T583_INTC_INTMON 0xAF
50
51#define RC5T583_INT_MON_GRP 0xAF
52#define RC5T583_INT_MON_SYS1 0x1B
53#define RC5T583_INT_MON_SYS2 0x1F
54#define RC5T583_INT_MON_DCDC 0x43
55#define RC5T583_INT_MON_RTC 0xEE
56
57/* Interrupt clearing registers */
58#define RC5T583_INT_IR_SYS1 0x1A
59#define RC5T583_INT_IR_SYS2 0x1E
60#define RC5T583_INT_IR_DCDC 0x42
61#define RC5T583_INT_IR_RTC 0xEE
62#define RC5T583_INT_IR_ADCL 0x94
63#define RC5T583_INT_IR_ADCH 0x95
64#define RC5T583_INT_IR_ADCEND 0x96
65#define RC5T583_INT_IR_GPIOR 0xA9
66#define RC5T583_INT_IR_GPIOF 0xAA
67
68/* Sleep sequence registers */
69#define RC5T583_SLPSEQ1 0x21
70#define RC5T583_SLPSEQ2 0x22
71#define RC5T583_SLPSEQ3 0x23
72#define RC5T583_SLPSEQ4 0x24
73#define RC5T583_SLPSEQ5 0x25
74#define RC5T583_SLPSEQ6 0x26
75#define RC5T583_SLPSEQ7 0x27
76#define RC5T583_SLPSEQ8 0x28
77#define RC5T583_SLPSEQ9 0x29
78#define RC5T583_SLPSEQ10 0x2A
79#define RC5T583_SLPSEQ11 0x2B
80
81/* Regulator registers */
82#define RC5T583_REG_DC0CTL 0x30
83#define RC5T583_REG_DC0DAC 0x31
84#define RC5T583_REG_DC0LATCTL 0x32
85#define RC5T583_REG_SR0CTL 0x33
86
87#define RC5T583_REG_DC1CTL 0x34
88#define RC5T583_REG_DC1DAC 0x35
89#define RC5T583_REG_DC1LATCTL 0x36
90#define RC5T583_REG_SR1CTL 0x37
91
92#define RC5T583_REG_DC2CTL 0x38
93#define RC5T583_REG_DC2DAC 0x39
94#define RC5T583_REG_DC2LATCTL 0x3A
95#define RC5T583_REG_SR2CTL 0x3B
96
97#define RC5T583_REG_DC3CTL 0x3C
98#define RC5T583_REG_DC3DAC 0x3D
99#define RC5T583_REG_DC3LATCTL 0x3E
100#define RC5T583_REG_SR3CTL 0x3F
101
102
103#define RC5T583_REG_LDOEN1 0x50
104#define RC5T583_REG_LDOEN2 0x51
105#define RC5T583_REG_LDODIS1 0x52
106#define RC5T583_REG_LDODIS2 0x53
107
108#define RC5T583_REG_LDO0DAC 0x54
109#define RC5T583_REG_LDO1DAC 0x55
110#define RC5T583_REG_LDO2DAC 0x56
111#define RC5T583_REG_LDO3DAC 0x57
112#define RC5T583_REG_LDO4DAC 0x58
113#define RC5T583_REG_LDO5DAC 0x59
114#define RC5T583_REG_LDO6DAC 0x5A
115#define RC5T583_REG_LDO7DAC 0x5B
116#define RC5T583_REG_LDO8DAC 0x5C
117#define RC5T583_REG_LDO9DAC 0x5D
118
119#define RC5T583_REG_DC0DAC_DS 0x60
120#define RC5T583_REG_DC1DAC_DS 0x61
121#define RC5T583_REG_DC2DAC_DS 0x62
122#define RC5T583_REG_DC3DAC_DS 0x63
123
124#define RC5T583_REG_LDO0DAC_DS 0x64
125#define RC5T583_REG_LDO1DAC_DS 0x65
126#define RC5T583_REG_LDO2DAC_DS 0x66
127#define RC5T583_REG_LDO3DAC_DS 0x67
128#define RC5T583_REG_LDO4DAC_DS 0x68
129#define RC5T583_REG_LDO5DAC_DS 0x69
130#define RC5T583_REG_LDO6DAC_DS 0x6A
131#define RC5T583_REG_LDO7DAC_DS 0x6B
132#define RC5T583_REG_LDO8DAC_DS 0x6C
133#define RC5T583_REG_LDO9DAC_DS 0x6D
134
135/* GPIO register base address */
136#define RC5T583_GPIO_IOSEL 0xA0
137#define RC5T583_GPIO_PDEN 0xA1
138#define RC5T583_GPIO_IOOUT 0xA2
139#define RC5T583_GPIO_PGSEL 0xA3
140#define RC5T583_GPIO_GPINV 0xA4
141#define RC5T583_GPIO_GPDEB 0xA5
142#define RC5T583_GPIO_GPEDGE1 0xA6
143#define RC5T583_GPIO_GPEDGE2 0xA7
144#define RC5T583_GPIO_EN_INT 0xA8
145#define RC5T583_GPIO_MON_IOIN 0xAB
146#define RC5T583_GPIO_GPOFUNC 0xAC
147
148/* RICOH_RC5T583 IRQ definitions */
149enum {
150 RC5T583_IRQ_ONKEY,
151 RC5T583_IRQ_ACOK,
152 RC5T583_IRQ_LIDOPEN,
153 RC5T583_IRQ_PREOT,
154 RC5T583_IRQ_CLKSTP,
155 RC5T583_IRQ_ONKEY_OFF,
156 RC5T583_IRQ_WD,
157 RC5T583_IRQ_EN_PWRREQ1,
158 RC5T583_IRQ_EN_PWRREQ2,
159 RC5T583_IRQ_PRE_VINDET,
160
161 RC5T583_IRQ_DC0LIM,
162 RC5T583_IRQ_DC1LIM,
163 RC5T583_IRQ_DC2LIM,
164 RC5T583_IRQ_DC3LIM,
165
166 RC5T583_IRQ_CTC,
167 RC5T583_IRQ_YALE,
168 RC5T583_IRQ_DALE,
169 RC5T583_IRQ_WALE,
170
171 RC5T583_IRQ_AIN1L,
172 RC5T583_IRQ_AIN2L,
173 RC5T583_IRQ_AIN3L,
174 RC5T583_IRQ_VBATL,
175 RC5T583_IRQ_VIN3L,
176 RC5T583_IRQ_VIN8L,
177 RC5T583_IRQ_AIN1H,
178 RC5T583_IRQ_AIN2H,
179 RC5T583_IRQ_AIN3H,
180 RC5T583_IRQ_VBATH,
181 RC5T583_IRQ_VIN3H,
182 RC5T583_IRQ_VIN8H,
183 RC5T583_IRQ_ADCEND,
184
185 RC5T583_IRQ_GPIO0,
186 RC5T583_IRQ_GPIO1,
187 RC5T583_IRQ_GPIO2,
188 RC5T583_IRQ_GPIO3,
189 RC5T583_IRQ_GPIO4,
190 RC5T583_IRQ_GPIO5,
191 RC5T583_IRQ_GPIO6,
192 RC5T583_IRQ_GPIO7,
193
194 /* Should be last entry */
195 RC5T583_MAX_IRQS,
196};
197
198/* Ricoh583 gpio definitions */
199enum {
200 RC5T583_GPIO0,
201 RC5T583_GPIO1,
202 RC5T583_GPIO2,
203 RC5T583_GPIO3,
204 RC5T583_GPIO4,
205 RC5T583_GPIO5,
206 RC5T583_GPIO6,
207 RC5T583_GPIO7,
208
209 /* Should be last entry */
210 RC5T583_MAX_GPIO,
211};
212
213enum {
214 RC5T583_DS_NONE,
215 RC5T583_DS_DC0,
216 RC5T583_DS_DC1,
217 RC5T583_DS_DC2,
218 RC5T583_DS_DC3,
219 RC5T583_DS_LDO0,
220 RC5T583_DS_LDO1,
221 RC5T583_DS_LDO2,
222 RC5T583_DS_LDO3,
223 RC5T583_DS_LDO4,
224 RC5T583_DS_LDO5,
225 RC5T583_DS_LDO6,
226 RC5T583_DS_LDO7,
227 RC5T583_DS_LDO8,
228 RC5T583_DS_LDO9,
229 RC5T583_DS_PSO0,
230 RC5T583_DS_PSO1,
231 RC5T583_DS_PSO2,
232 RC5T583_DS_PSO3,
233 RC5T583_DS_PSO4,
234 RC5T583_DS_PSO5,
235 RC5T583_DS_PSO6,
236 RC5T583_DS_PSO7,
237
238 /* Should be last entry */
239 RC5T583_DS_MAX,
240};
241
242/*
243 * Ricoh pmic RC5T583 supports sleep through two external controls.
244 * The output of gpios and regulator can be enable/disable through
245 * this external signals.
246 */
247enum {
248 RC5T583_EXT_PWRREQ1_CONTROL = 0x1,
249 RC5T583_EXT_PWRREQ2_CONTROL = 0x2,
250};
251
252struct rc5t583 {
253 struct device *dev;
254 struct regmap *regmap;
255 int chip_irq;
256 int irq_base;
257 struct mutex irq_lock;
258 unsigned long group_irq_en[MAX_MAIN_INTERRUPT];
259
260 /* For main interrupt bits in INTC */
261 uint8_t intc_inten_reg;
262
263 /* For group interrupt bits and address */
264 uint8_t irq_en_reg[RC5T583_MAX_INTERRUPT_MASK_REGS];
265
266 /* For gpio edge */
267 uint8_t gpedge_reg[RC5T583_MAX_GPEDGE_REG];
268};
269
270/*
271 * rc5t583_platform_data: Platform data for ricoh rc5t583 pmu.
272 * The board specific data is provided through this structure.
273 * @irq_base: Irq base number on which this device registers their interrupts.
274 * @enable_shutdown: Enable shutdown through the input pin "shutdown".
275 */
276
277struct rc5t583_platform_data {
278 int irq_base;
279 bool enable_shutdown;
280};
281
282int rc5t583_write(struct device *dev, u8 reg, uint8_t val);
283int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val);
284int rc5t583_set_bits(struct device *dev, unsigned int reg,
285 unsigned int bit_mask);
286int rc5t583_clear_bits(struct device *dev, unsigned int reg,
287 unsigned int bit_mask);
288int rc5t583_update(struct device *dev, unsigned int reg,
289 unsigned int val, unsigned int mask);
290int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,
291 int ext_pwr_req, int deepsleep_slot_nr);
292int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base);
293int rc5t583_irq_exit(struct rc5t583 *rc5t583);
294
295#endif