diff options
Diffstat (limited to 'drivers/mfd/ricoh583.c')
-rw-r--r-- | drivers/mfd/ricoh583.c | 1213 |
1 files changed, 1213 insertions, 0 deletions
diff --git a/drivers/mfd/ricoh583.c b/drivers/mfd/ricoh583.c new file mode 100644 index 00000000000..a29053ebaf8 --- /dev/null +++ b/drivers/mfd/ricoh583.c | |||
@@ -0,0 +1,1213 @@ | |||
1 | /* | ||
2 | * driver/mfd/ricoh583.c | ||
3 | * | ||
4 | * Core driver implementation to access RICOH583 power management chip. | ||
5 | * | ||
6 | * Copyright (C) 2011 NVIDIA Corporation | ||
7 | * | ||
8 | * Copyright (C) 2011 RICOH COMPANY,LTD | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
23 | * | ||
24 | */ | ||
25 | /*#define DEBUG 1*/ | ||
26 | /*#define VERBOSE_DEBUG 1*/ | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/gpio.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/mfd/core.h> | ||
36 | #include <linux/mfd/ricoh583.h> | ||
37 | |||
38 | #define RICOH_ONOFFSEL_REG 0x10 | ||
39 | #define RICOH_SWCTL_REG 0x5E | ||
40 | |||
41 | /* Interrupt enable register */ | ||
42 | #define RICOH583_INT_EN_SYS1 0x19 | ||
43 | #define RICOH583_INT_EN_SYS2 0x1D | ||
44 | #define RICOH583_INT_EN_DCDC 0x41 | ||
45 | #define RICOH583_INT_EN_RTC 0xED | ||
46 | #define RICOH583_INT_EN_ADC1 0x90 | ||
47 | #define RICOH583_INT_EN_ADC2 0x91 | ||
48 | #define RICOH583_INT_EN_ADC3 0x92 | ||
49 | #define RICOH583_INT_EN_GPIO 0xA8 | ||
50 | |||
51 | /* interrupt status registers (monitor regs in Ricoh)*/ | ||
52 | #define RICOH583_INTC_INTPOL 0xAD | ||
53 | #define RICOH583_INTC_INTEN 0xAE | ||
54 | #define RICOH583_INTC_INTMON 0xAF | ||
55 | |||
56 | #define RICOH583_INT_MON_GRP 0xAF | ||
57 | #define RICOH583_INT_MON_SYS1 0x1B | ||
58 | #define RICOH583_INT_MON_SYS2 0x1F | ||
59 | #define RICOH583_INT_MON_DCDC 0x43 | ||
60 | #define RICOH583_INT_MON_RTC 0xEE | ||
61 | |||
62 | /* interrupt clearing registers */ | ||
63 | #define RICOH583_INT_IR_SYS1 0x1A | ||
64 | #define RICOH583_INT_IR_SYS2 0x1E | ||
65 | #define RICOH583_INT_IR_DCDC 0x42 | ||
66 | #define RICOH583_INT_IR_RTC 0xEE | ||
67 | #define RICOH583_INT_IR_ADCL 0x94 | ||
68 | #define RICOH583_INT_IR_ADCH 0x95 | ||
69 | #define RICOH583_INT_IR_ADCEND 0x96 | ||
70 | #define RICOH583_INT_IR_GPIOR 0xA9 | ||
71 | #define RICOH583_INT_IR_GPIOF 0xAA | ||
72 | |||
73 | /* GPIO register base address */ | ||
74 | #define RICOH583_GPIO_IOSEL 0xA0 | ||
75 | #define RICOH583_GPIO_PDEN 0xA1 | ||
76 | #define RICOH583_GPIO_IOOUT 0xA2 | ||
77 | #define RICOH583_GPIO_PGSEL 0xA3 | ||
78 | #define RICOH583_GPIO_GPINV 0xA4 | ||
79 | #define RICOH583_GPIO_GPDEB 0xA5 | ||
80 | #define RICOH583_GPIO_GPEDGE1 0xA6 | ||
81 | #define RICOH583_GPIO_GPEDGE2 0xA7 | ||
82 | #define RICOH583_GPIO_EN_GPIR 0xA8 | ||
83 | #define RICOH583_GPIO_MON_IOIN 0xAB | ||
84 | #define RICOH583_GPIO_GPOFUNC 0xAC | ||
85 | #define RICOH583_INTC_INTEN 0xAE | ||
86 | |||
87 | enum int_type { | ||
88 | SYS_INT = 0x1, | ||
89 | DCDC_INT = 0x2, | ||
90 | RTC_INT = 0x4, | ||
91 | ADC_INT = 0x8, | ||
92 | GPIO_INT = 0x10, | ||
93 | }; | ||
94 | |||
95 | struct ricoh583_irq_data { | ||
96 | u8 int_type; | ||
97 | u8 master_bit; | ||
98 | u8 int_en_bit; | ||
99 | u8 mask_reg_index; | ||
100 | int grp_index; | ||
101 | }; | ||
102 | |||
103 | struct deepsleep_control_data { | ||
104 | u8 reg_add; | ||
105 | u8 ds_pos_bit; | ||
106 | }; | ||
107 | |||
108 | #define RICOH583_IRQ(_int_type, _master_bit, _grp_index, _int_bit, _mask_ind) \ | ||
109 | { \ | ||
110 | .int_type = _int_type, \ | ||
111 | .master_bit = _master_bit, \ | ||
112 | .grp_index = _grp_index, \ | ||
113 | .int_en_bit = _int_bit, \ | ||
114 | .mask_reg_index = _mask_ind, \ | ||
115 | } | ||
116 | |||
117 | static const struct ricoh583_irq_data ricoh583_irqs[] = { | ||
118 | [RICOH583_IRQ_ONKEY] = RICOH583_IRQ(SYS_INT, 0, 0, 0, 0), | ||
119 | [RICOH583_IRQ_ACOK] = RICOH583_IRQ(SYS_INT, 0, 1, 1, 0), | ||
120 | [RICOH583_IRQ_LIDOPEN] = RICOH583_IRQ(SYS_INT, 0, 2, 2, 0), | ||
121 | [RICOH583_IRQ_PREOT] = RICOH583_IRQ(SYS_INT, 0, 3, 3, 0), | ||
122 | [RICOH583_IRQ_CLKSTP] = RICOH583_IRQ(SYS_INT, 0, 4, 4, 0), | ||
123 | [RICOH583_IRQ_ONKEY_OFF] = RICOH583_IRQ(SYS_INT, 0, 5, 5, 0), | ||
124 | [RICOH583_IRQ_WD] = RICOH583_IRQ(SYS_INT, 0, 7, 7, 0), | ||
125 | [RICOH583_IRQ_EN_PWRREQ1] = RICOH583_IRQ(SYS_INT, 0, 8, 0, 1), | ||
126 | [RICOH583_IRQ_EN_PWRREQ2] = RICOH583_IRQ(SYS_INT, 0, 9, 1, 1), | ||
127 | [RICOH583_IRQ_PRE_VINDET] = RICOH583_IRQ(SYS_INT, 0, 10, 2, 1), | ||
128 | |||
129 | [RICOH583_IRQ_DC0LIM] = RICOH583_IRQ(DCDC_INT, 1, 0, 0, 2), | ||
130 | [RICOH583_IRQ_DC1LIM] = RICOH583_IRQ(DCDC_INT, 1, 1, 1, 2), | ||
131 | [RICOH583_IRQ_DC2LIM] = RICOH583_IRQ(DCDC_INT, 1, 2, 2, 2), | ||
132 | [RICOH583_IRQ_DC3LIM] = RICOH583_IRQ(DCDC_INT, 1, 3, 3, 2), | ||
133 | |||
134 | [RICOH583_IRQ_CTC] = RICOH583_IRQ(RTC_INT, 2, 0, 0, 3), | ||
135 | [RICOH583_IRQ_YALE] = RICOH583_IRQ(RTC_INT, 2, 5, 5, 3), | ||
136 | [RICOH583_IRQ_DALE] = RICOH583_IRQ(RTC_INT, 2, 6, 6, 3), | ||
137 | [RICOH583_IRQ_WALE] = RICOH583_IRQ(RTC_INT, 2, 7, 7, 3), | ||
138 | |||
139 | [RICOH583_IRQ_AIN1L] = RICOH583_IRQ(ADC_INT, 3, 0, 0, 4), | ||
140 | [RICOH583_IRQ_AIN2L] = RICOH583_IRQ(ADC_INT, 3, 1, 1, 4), | ||
141 | [RICOH583_IRQ_AIN3L] = RICOH583_IRQ(ADC_INT, 3, 2, 2, 4), | ||
142 | [RICOH583_IRQ_VBATL] = RICOH583_IRQ(ADC_INT, 3, 3, 3, 4), | ||
143 | [RICOH583_IRQ_VIN3L] = RICOH583_IRQ(ADC_INT, 3, 4, 4, 4), | ||
144 | [RICOH583_IRQ_VIN8L] = RICOH583_IRQ(ADC_INT, 3, 5, 5, 4), | ||
145 | [RICOH583_IRQ_AIN1H] = RICOH583_IRQ(ADC_INT, 3, 6, 0, 5), | ||
146 | [RICOH583_IRQ_AIN2H] = RICOH583_IRQ(ADC_INT, 3, 7, 1, 5), | ||
147 | [RICOH583_IRQ_AIN3H] = RICOH583_IRQ(ADC_INT, 3, 8, 2, 5), | ||
148 | [RICOH583_IRQ_VBATH] = RICOH583_IRQ(ADC_INT, 3, 9, 3, 5), | ||
149 | [RICOH583_IRQ_VIN3H] = RICOH583_IRQ(ADC_INT, 3, 10, 4, 5), | ||
150 | [RICOH583_IRQ_VIN8H] = RICOH583_IRQ(ADC_INT, 3, 11, 5, 5), | ||
151 | [RICOH583_IRQ_ADCEND] = RICOH583_IRQ(ADC_INT, 3, 12, 0, 6), | ||
152 | |||
153 | [RICOH583_IRQ_GPIO0] = RICOH583_IRQ(GPIO_INT, 4, 0, 0, 7), | ||
154 | [RICOH583_IRQ_GPIO1] = RICOH583_IRQ(GPIO_INT, 4, 1, 1, 7), | ||
155 | [RICOH583_IRQ_GPIO2] = RICOH583_IRQ(GPIO_INT, 4, 2, 2, 7), | ||
156 | [RICOH583_IRQ_GPIO3] = RICOH583_IRQ(GPIO_INT, 4, 3, 3, 7), | ||
157 | [RICOH583_IRQ_GPIO4] = RICOH583_IRQ(GPIO_INT, 4, 4, 4, 7), | ||
158 | [RICOH583_IRQ_GPIO5] = RICOH583_IRQ(GPIO_INT, 4, 5, 5, 7), | ||
159 | [RICOH583_IRQ_GPIO6] = RICOH583_IRQ(GPIO_INT, 4, 6, 6, 7), | ||
160 | [RICOH583_IRQ_GPIO7] = RICOH583_IRQ(GPIO_INT, 4, 7, 7, 7), | ||
161 | [RICOH583_NR_IRQS] = RICOH583_IRQ(GPIO_INT, 4, 8, 8, 7), | ||
162 | }; | ||
163 | |||
164 | #define DEEPSLEEP_INIT(_id, _reg, _pos) \ | ||
165 | [RICOH583_DS_##_id] = {.reg_add = _reg, .ds_pos_bit = _pos} | ||
166 | |||
167 | static struct deepsleep_control_data deepsleep_data[] = { | ||
168 | DEEPSLEEP_INIT(DC1, 0x21, 4), | ||
169 | DEEPSLEEP_INIT(DC2, 0x22, 0), | ||
170 | DEEPSLEEP_INIT(DC3, 0x22, 4), | ||
171 | DEEPSLEEP_INIT(LDO0, 0x23, 0), | ||
172 | DEEPSLEEP_INIT(LDO1, 0x23, 4), | ||
173 | DEEPSLEEP_INIT(LDO2, 0x24, 0), | ||
174 | DEEPSLEEP_INIT(LDO3, 0x24, 4), | ||
175 | DEEPSLEEP_INIT(LDO4, 0x25, 0), | ||
176 | DEEPSLEEP_INIT(LDO5, 0x25, 4), | ||
177 | DEEPSLEEP_INIT(LDO6, 0x26, 0), | ||
178 | DEEPSLEEP_INIT(LDO7, 0x26, 4), | ||
179 | DEEPSLEEP_INIT(LDO8, 0x27, 0), | ||
180 | DEEPSLEEP_INIT(LDO9, 0x27, 4), | ||
181 | DEEPSLEEP_INIT(PSO0, 0x28, 0), | ||
182 | DEEPSLEEP_INIT(PSO1, 0x28, 4), | ||
183 | DEEPSLEEP_INIT(PSO2, 0x29, 0), | ||
184 | DEEPSLEEP_INIT(PSO3, 0x29, 4), | ||
185 | DEEPSLEEP_INIT(PSO4, 0x2A, 0), | ||
186 | DEEPSLEEP_INIT(PSO5, 0x2A, 4), | ||
187 | DEEPSLEEP_INIT(PSO6, 0x2B, 0), | ||
188 | DEEPSLEEP_INIT(PSO7, 0x2B, 4), | ||
189 | }; | ||
190 | |||
191 | #define MAX_INTERRUPT_MASKS 8 | ||
192 | #define MAX_MAIN_INTERRUPT 5 | ||
193 | #define EXT_PWR_REQ \ | ||
194 | (RICOH583_EXT_PWRREQ1_CONTROL | RICOH583_EXT_PWRREQ2_CONTROL) | ||
195 | |||
196 | struct ricoh583 { | ||
197 | struct device *dev; | ||
198 | struct i2c_client *client; | ||
199 | struct mutex io_lock; | ||
200 | int gpio_base; | ||
201 | struct gpio_chip gpio; | ||
202 | int irq_base; | ||
203 | struct irq_chip irq_chip; | ||
204 | struct mutex irq_lock; | ||
205 | unsigned long group_irq_en[MAX_MAIN_INTERRUPT]; | ||
206 | |||
207 | /* For main interrupt bits in INTC */ | ||
208 | u8 intc_inten_cache; | ||
209 | u8 intc_inten_reg; | ||
210 | |||
211 | /* For group interrupt bits and address */ | ||
212 | u8 irq_en_cache[MAX_INTERRUPT_MASKS]; | ||
213 | u8 irq_en_reg[MAX_INTERRUPT_MASKS]; | ||
214 | u8 irq_en_add[MAX_INTERRUPT_MASKS]; | ||
215 | |||
216 | /* Interrupt monitor and clear register */ | ||
217 | u8 irq_mon_add[MAX_INTERRUPT_MASKS + 1]; | ||
218 | u8 irq_clr_add[MAX_INTERRUPT_MASKS + 1]; | ||
219 | u8 main_int_type[MAX_INTERRUPT_MASKS + 1]; | ||
220 | |||
221 | /* For gpio edge */ | ||
222 | u8 gpedge_cache[2]; | ||
223 | u8 gpedge_reg[2]; | ||
224 | u8 gpedge_add[2]; | ||
225 | }; | ||
226 | |||
227 | static inline int __ricoh583_read(struct i2c_client *client, | ||
228 | u8 reg, uint8_t *val) | ||
229 | { | ||
230 | int ret; | ||
231 | |||
232 | ret = i2c_smbus_read_byte_data(client, reg); | ||
233 | if (ret < 0) { | ||
234 | dev_err(&client->dev, "failed reading at 0x%02x\n", reg); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | *val = (uint8_t)ret; | ||
239 | dev_dbg(&client->dev, "ricoh583: reg read reg=%x, val=%x\n", | ||
240 | reg, *val); | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static inline int __ricoh583_bulk_reads(struct i2c_client *client, u8 reg, | ||
245 | int len, uint8_t *val) | ||
246 | { | ||
247 | int ret; | ||
248 | int i; | ||
249 | |||
250 | ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); | ||
251 | if (ret < 0) { | ||
252 | dev_err(&client->dev, "failed reading from 0x%02x\n", reg); | ||
253 | return ret; | ||
254 | } | ||
255 | for (i = 0; i < len; ++i) { | ||
256 | dev_dbg(&client->dev, "ricoh583: reg read reg=%x, val=%x\n", | ||
257 | reg + i, *(val + i)); | ||
258 | } | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static inline int __ricoh583_write(struct i2c_client *client, | ||
263 | u8 reg, uint8_t val) | ||
264 | { | ||
265 | int ret; | ||
266 | |||
267 | dev_dbg(&client->dev, "ricoh583: reg write reg=%x, val=%x\n", | ||
268 | reg, val); | ||
269 | ret = i2c_smbus_write_byte_data(client, reg, val); | ||
270 | if (ret < 0) { | ||
271 | dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", | ||
272 | val, reg); | ||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static inline int __ricoh583_bulk_writes(struct i2c_client *client, u8 reg, | ||
280 | int len, uint8_t *val) | ||
281 | { | ||
282 | int ret; | ||
283 | int i; | ||
284 | |||
285 | for (i = 0; i < len; ++i) { | ||
286 | dev_dbg(&client->dev, "ricoh583: reg write reg=%x, val=%x\n", | ||
287 | reg + i, *(val + i)); | ||
288 | } | ||
289 | |||
290 | ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); | ||
291 | if (ret < 0) { | ||
292 | dev_err(&client->dev, "failed writings to 0x%02x\n", reg); | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | int ricoh583_write(struct device *dev, u8 reg, uint8_t val) | ||
300 | { | ||
301 | struct ricoh583 *ricoh583 = dev_get_drvdata(dev); | ||
302 | int ret = 0; | ||
303 | |||
304 | mutex_lock(&ricoh583->io_lock); | ||
305 | ret = __ricoh583_write(to_i2c_client(dev), reg, val); | ||
306 | mutex_unlock(&ricoh583->io_lock); | ||
307 | |||
308 | return ret; | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(ricoh583_write); | ||
311 | |||
312 | int ricoh583_bulk_writes(struct device *dev, u8 reg, u8 len, uint8_t *val) | ||
313 | { | ||
314 | struct ricoh583 *ricoh583 = dev_get_drvdata(dev); | ||
315 | int ret = 0; | ||
316 | |||
317 | mutex_lock(&ricoh583->io_lock); | ||
318 | ret = __ricoh583_bulk_writes(to_i2c_client(dev), reg, len, val); | ||
319 | mutex_unlock(&ricoh583->io_lock); | ||
320 | |||
321 | return ret; | ||
322 | } | ||
323 | EXPORT_SYMBOL_GPL(ricoh583_bulk_writes); | ||
324 | |||
325 | int ricoh583_read(struct device *dev, u8 reg, uint8_t *val) | ||
326 | { | ||
327 | return __ricoh583_read(to_i2c_client(dev), reg, val); | ||
328 | } | ||
329 | EXPORT_SYMBOL_GPL(ricoh583_read); | ||
330 | |||
331 | int ricoh583_bulk_reads(struct device *dev, u8 reg, u8 len, uint8_t *val) | ||
332 | { | ||
333 | return __ricoh583_bulk_reads(to_i2c_client(dev), reg, len, val); | ||
334 | } | ||
335 | EXPORT_SYMBOL_GPL(ricoh583_bulk_reads); | ||
336 | |||
337 | int ricoh583_set_bits(struct device *dev, u8 reg, uint8_t bit_mask) | ||
338 | { | ||
339 | struct ricoh583 *ricoh583 = dev_get_drvdata(dev); | ||
340 | uint8_t reg_val; | ||
341 | int ret = 0; | ||
342 | |||
343 | mutex_lock(&ricoh583->io_lock); | ||
344 | |||
345 | ret = __ricoh583_read(to_i2c_client(dev), reg, ®_val); | ||
346 | if (ret) | ||
347 | goto out; | ||
348 | |||
349 | if ((reg_val & bit_mask) != bit_mask) { | ||
350 | reg_val |= bit_mask; | ||
351 | ret = __ricoh583_write(to_i2c_client(dev), reg, reg_val); | ||
352 | } | ||
353 | out: | ||
354 | mutex_unlock(&ricoh583->io_lock); | ||
355 | return ret; | ||
356 | } | ||
357 | EXPORT_SYMBOL_GPL(ricoh583_set_bits); | ||
358 | |||
359 | int ricoh583_clr_bits(struct device *dev, u8 reg, uint8_t bit_mask) | ||
360 | { | ||
361 | struct ricoh583 *ricoh583 = dev_get_drvdata(dev); | ||
362 | uint8_t reg_val; | ||
363 | int ret = 0; | ||
364 | |||
365 | mutex_lock(&ricoh583->io_lock); | ||
366 | |||
367 | ret = __ricoh583_read(to_i2c_client(dev), reg, ®_val); | ||
368 | if (ret) | ||
369 | goto out; | ||
370 | |||
371 | if (reg_val & bit_mask) { | ||
372 | reg_val &= ~bit_mask; | ||
373 | ret = __ricoh583_write(to_i2c_client(dev), reg, reg_val); | ||
374 | } | ||
375 | out: | ||
376 | mutex_unlock(&ricoh583->io_lock); | ||
377 | return ret; | ||
378 | } | ||
379 | EXPORT_SYMBOL_GPL(ricoh583_clr_bits); | ||
380 | |||
381 | int ricoh583_update(struct device *dev, u8 reg, uint8_t val, uint8_t mask) | ||
382 | { | ||
383 | struct ricoh583 *ricoh583 = dev_get_drvdata(dev); | ||
384 | uint8_t reg_val; | ||
385 | int ret = 0; | ||
386 | |||
387 | mutex_lock(&ricoh583->io_lock); | ||
388 | |||
389 | ret = __ricoh583_read(ricoh583->client, reg, ®_val); | ||
390 | if (ret) | ||
391 | goto out; | ||
392 | |||
393 | if ((reg_val & mask) != val) { | ||
394 | reg_val = (reg_val & ~mask) | (val & mask); | ||
395 | ret = __ricoh583_write(ricoh583->client, reg, reg_val); | ||
396 | } | ||
397 | out: | ||
398 | mutex_unlock(&ricoh583->io_lock); | ||
399 | return ret; | ||
400 | } | ||
401 | EXPORT_SYMBOL_GPL(ricoh583_update); | ||
402 | |||
403 | static int __ricoh583_set_ext_pwrreq1_control(struct device *dev, | ||
404 | enum ricoh583_deepsleep_control_id id, | ||
405 | enum ricoh583_ext_pwrreq_control ext_pwr, int slots) | ||
406 | { | ||
407 | int ret; | ||
408 | uint8_t sleepseq_val; | ||
409 | u8 en_bit; | ||
410 | u8 slot_bit; | ||
411 | |||
412 | if (!(ext_pwr & RICOH583_EXT_PWRREQ1_CONTROL)) | ||
413 | return 0; | ||
414 | |||
415 | if (id == RICOH583_DS_DC0) { | ||
416 | dev_err(dev, "PWRREQ1 is invalid control for rail %d\n", id); | ||
417 | return -EINVAL; | ||
418 | } | ||
419 | |||
420 | en_bit = deepsleep_data[id].ds_pos_bit; | ||
421 | slot_bit = en_bit + 1; | ||
422 | ret = ricoh583_read(dev, deepsleep_data[id].reg_add, &sleepseq_val); | ||
423 | if (ret < 0) { | ||
424 | dev_err(dev, "Error in reading reg 0x%x\n", | ||
425 | deepsleep_data[id].reg_add); | ||
426 | return ret; | ||
427 | } | ||
428 | |||
429 | sleepseq_val &= ~(0xF << en_bit); | ||
430 | sleepseq_val |= (1 << en_bit); | ||
431 | sleepseq_val |= ((slots & 0x7) << slot_bit); | ||
432 | ret = ricoh583_set_bits(dev, RICOH_ONOFFSEL_REG, (1 << 1)); | ||
433 | if (ret < 0) { | ||
434 | dev_err(dev, "Error in updating the 0x%02x register\n", | ||
435 | RICOH_ONOFFSEL_REG); | ||
436 | return ret; | ||
437 | } | ||
438 | |||
439 | ret = ricoh583_write(dev, deepsleep_data[id].reg_add, sleepseq_val); | ||
440 | if (ret < 0) { | ||
441 | dev_err(dev, "Error in writing reg 0x%x\n", | ||
442 | deepsleep_data[id].reg_add); | ||
443 | return ret; | ||
444 | } | ||
445 | |||
446 | if (id == RICOH583_DS_LDO4) { | ||
447 | ret = ricoh583_write(dev, RICOH_SWCTL_REG, 0x1); | ||
448 | if (ret < 0) | ||
449 | dev_err(dev, "Error in writing reg 0x%x\n", | ||
450 | RICOH_SWCTL_REG); | ||
451 | } | ||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | static int __ricoh583_set_ext_pwrreq2_control(struct device *dev, | ||
456 | enum ricoh583_deepsleep_control_id id, | ||
457 | enum ricoh583_ext_pwrreq_control ext_pwr) | ||
458 | { | ||
459 | int ret; | ||
460 | |||
461 | if (!(ext_pwr & RICOH583_EXT_PWRREQ2_CONTROL)) | ||
462 | return 0; | ||
463 | |||
464 | if (id != RICOH583_DS_DC0) { | ||
465 | dev_err(dev, "PWRREQ2 is invalid control for rail %d\n", id); | ||
466 | return -EINVAL; | ||
467 | } | ||
468 | |||
469 | ret = ricoh583_set_bits(dev, RICOH_ONOFFSEL_REG, (1 << 2)); | ||
470 | if (ret < 0) | ||
471 | dev_err(dev, "Error in updating the ONOFFSEL 0x10 register\n"); | ||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | int ricoh583_ext_power_req_config(struct device *dev, | ||
476 | enum ricoh583_deepsleep_control_id id, | ||
477 | enum ricoh583_ext_pwrreq_control ext_pwr_req, | ||
478 | int deepsleep_slot_nr) | ||
479 | { | ||
480 | if ((ext_pwr_req & EXT_PWR_REQ) == EXT_PWR_REQ) | ||
481 | return -EINVAL; | ||
482 | |||
483 | if (ext_pwr_req & RICOH583_EXT_PWRREQ1_CONTROL) | ||
484 | return __ricoh583_set_ext_pwrreq1_control(dev, id, | ||
485 | ext_pwr_req, deepsleep_slot_nr); | ||
486 | |||
487 | if (ext_pwr_req & RICOH583_EXT_PWRREQ2_CONTROL) | ||
488 | return __ricoh583_set_ext_pwrreq2_control(dev, | ||
489 | id, ext_pwr_req); | ||
490 | return 0; | ||
491 | } | ||
492 | EXPORT_SYMBOL_GPL(ricoh583_ext_power_req_config); | ||
493 | |||
494 | static int __devinit ricoh583_ext_power_init(struct ricoh583 *ricoh583, | ||
495 | struct ricoh583_platform_data *pdata) | ||
496 | { | ||
497 | int ret; | ||
498 | int i; | ||
499 | uint8_t on_off_val = 0; | ||
500 | |||
501 | /* Clear ONOFFSEL register */ | ||
502 | mutex_lock(&ricoh583->io_lock); | ||
503 | if (pdata->enable_shutdown_pin) | ||
504 | on_off_val |= 0x1; | ||
505 | |||
506 | ret = __ricoh583_write(ricoh583->client, RICOH_ONOFFSEL_REG, | ||
507 | on_off_val); | ||
508 | if (ret < 0) | ||
509 | dev_err(ricoh583->dev, "Error in writing reg %d error: " | ||
510 | "%d\n", RICOH_ONOFFSEL_REG, ret); | ||
511 | |||
512 | ret = __ricoh583_write(ricoh583->client, RICOH_SWCTL_REG, 0x0); | ||
513 | if (ret < 0) | ||
514 | dev_err(ricoh583->dev, "Error in writing reg %d error: " | ||
515 | "%d\n", RICOH_SWCTL_REG, ret); | ||
516 | |||
517 | /* Clear sleepseq register */ | ||
518 | for (i = 0x21; i < 0x2B; ++i) { | ||
519 | ret = __ricoh583_write(ricoh583->client, i, 0x0); | ||
520 | if (ret < 0) | ||
521 | dev_err(ricoh583->dev, "Error in writing reg 0x%02x " | ||
522 | "error: %d\n", i, ret); | ||
523 | } | ||
524 | mutex_unlock(&ricoh583->io_lock); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static struct i2c_client *ricoh583_i2c_client; | ||
529 | int ricoh583_power_off(void) | ||
530 | { | ||
531 | if (!ricoh583_i2c_client) | ||
532 | return -EINVAL; | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static int ricoh583_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
538 | { | ||
539 | struct ricoh583 *ricoh583 = container_of(gc, struct ricoh583, gpio); | ||
540 | uint8_t val; | ||
541 | int ret; | ||
542 | |||
543 | ret = __ricoh583_read(ricoh583->client, RICOH583_GPIO_MON_IOIN, &val); | ||
544 | if (ret < 0) | ||
545 | return ret; | ||
546 | |||
547 | return ((val & (0x1 << offset)) != 0); | ||
548 | } | ||
549 | |||
550 | static void ricoh583_gpio_set(struct gpio_chip *chip, unsigned offset, | ||
551 | int value) | ||
552 | { | ||
553 | struct ricoh583 *ricoh583 = container_of(chip, struct ricoh583, gpio); | ||
554 | if (value) | ||
555 | ricoh583_set_bits(ricoh583->dev, RICOH583_GPIO_IOOUT, | ||
556 | 1 << offset); | ||
557 | else | ||
558 | ricoh583_clr_bits(ricoh583->dev, RICOH583_GPIO_IOOUT, | ||
559 | 1 << offset); | ||
560 | } | ||
561 | |||
562 | static int ricoh583_gpio_input(struct gpio_chip *chip, unsigned offset) | ||
563 | { | ||
564 | struct ricoh583 *ricoh583 = container_of(chip, struct ricoh583, gpio); | ||
565 | |||
566 | return ricoh583_clr_bits(ricoh583->dev, RICOH583_GPIO_IOSEL, | ||
567 | 1 << offset); | ||
568 | } | ||
569 | |||
570 | static int ricoh583_gpio_output(struct gpio_chip *chip, unsigned offset, | ||
571 | int value) | ||
572 | { | ||
573 | struct ricoh583 *ricoh583 = container_of(chip, struct ricoh583, gpio); | ||
574 | |||
575 | ricoh583_gpio_set(chip, offset, value); | ||
576 | return ricoh583_set_bits(ricoh583->dev, RICOH583_GPIO_IOSEL, | ||
577 | 1 << offset); | ||
578 | } | ||
579 | |||
580 | static int ricoh583_gpio_to_irq(struct gpio_chip *chip, unsigned off) | ||
581 | { | ||
582 | struct ricoh583 *ricoh583 = container_of(chip, struct ricoh583, gpio); | ||
583 | |||
584 | if ((off >= 0) && (off < 8)) | ||
585 | return ricoh583->irq_base + RICOH583_IRQ_GPIO0 + off; | ||
586 | |||
587 | return -EIO; | ||
588 | } | ||
589 | |||
590 | static int ricoh583_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
591 | { | ||
592 | struct ricoh583 *ricoh583 = container_of(chip, struct ricoh583, gpio); | ||
593 | int ret; | ||
594 | |||
595 | ret = ricoh583_clr_bits(ricoh583->dev, RICOH583_GPIO_PGSEL, | ||
596 | 1 << offset); | ||
597 | if (ret < 0) | ||
598 | dev_err(ricoh583->dev, "%s(): The error in writing register " | ||
599 | "0x%02x\n", __func__, RICOH583_GPIO_PGSEL); | ||
600 | return ret; | ||
601 | } | ||
602 | |||
603 | static void ricoh583_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
604 | { | ||
605 | struct ricoh583 *ricoh583 = container_of(chip, struct ricoh583, gpio); | ||
606 | int ret; | ||
607 | |||
608 | ret = ricoh583_set_bits(ricoh583->dev, RICOH583_GPIO_PGSEL, | ||
609 | 1 << offset); | ||
610 | if (ret < 0) | ||
611 | dev_err(ricoh583->dev, "%s(): The error in writing register " | ||
612 | "0x%02x\n", __func__, RICOH583_GPIO_PGSEL); | ||
613 | } | ||
614 | |||
615 | static void __devinit ricoh583_gpio_init(struct ricoh583 *ricoh583, | ||
616 | struct ricoh583_platform_data *pdata) | ||
617 | { | ||
618 | int ret; | ||
619 | int i; | ||
620 | struct ricoh583_gpio_init_data *ginit; | ||
621 | |||
622 | if (pdata->gpio_base <= 0) | ||
623 | return; | ||
624 | |||
625 | ret = ricoh583_write(ricoh583->dev, RICOH583_GPIO_PGSEL, 0xEF); | ||
626 | if (ret < 0) { | ||
627 | dev_err(ricoh583->dev, "%s(): The error in writing register " | ||
628 | "0x%02x\n", __func__, RICOH583_GPIO_PGSEL); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | for (i = 0; i < pdata->num_gpioinit_data; ++i) { | ||
633 | ginit = &pdata->gpio_init_data[i]; | ||
634 | if (!ginit->init_apply) | ||
635 | continue; | ||
636 | if (ginit->pulldn_en) | ||
637 | ret = ricoh583_set_bits(ricoh583->dev, | ||
638 | RICOH583_GPIO_PDEN, 1 << i); | ||
639 | else | ||
640 | ret = ricoh583_clr_bits(ricoh583->dev, | ||
641 | RICOH583_GPIO_PDEN, 1 << i); | ||
642 | if (ret < 0) | ||
643 | dev_err(ricoh583->dev, "Gpio %d init " | ||
644 | "pden configuration failed: %d\n", i, ret); | ||
645 | |||
646 | if (ginit->output_mode_en) { | ||
647 | if (ginit->output_val) | ||
648 | ret = ricoh583_set_bits(ricoh583->dev, | ||
649 | RICOH583_GPIO_IOOUT, 1 << i); | ||
650 | else | ||
651 | ret = ricoh583_clr_bits(ricoh583->dev, | ||
652 | RICOH583_GPIO_IOOUT, 1 << i); | ||
653 | if (!ret) | ||
654 | ret = ricoh583_set_bits(ricoh583->dev, | ||
655 | RICOH583_GPIO_IOSEL, 1 << i); | ||
656 | } else | ||
657 | ret = ricoh583_clr_bits(ricoh583->dev, | ||
658 | RICOH583_GPIO_IOSEL, 1 << i); | ||
659 | |||
660 | if (ret < 0) | ||
661 | dev_err(ricoh583->dev, "Gpio %d init " | ||
662 | "dir configuration failed: %d\n", i, ret); | ||
663 | |||
664 | ret = ricoh583_clr_bits(ricoh583->dev, RICOH583_GPIO_PGSEL, | ||
665 | 1 << i); | ||
666 | if (ret < 0) | ||
667 | dev_err(ricoh583->dev, "%s(): The error in writing " | ||
668 | "register 0x%02x\n", __func__, | ||
669 | RICOH583_GPIO_PGSEL); | ||
670 | } | ||
671 | |||
672 | ricoh583->gpio.owner = THIS_MODULE; | ||
673 | ricoh583->gpio.label = ricoh583->client->name; | ||
674 | ricoh583->gpio.dev = ricoh583->dev; | ||
675 | ricoh583->gpio.base = pdata->gpio_base; | ||
676 | ricoh583->gpio.ngpio = RICOH583_NR_GPIO; | ||
677 | ricoh583->gpio.can_sleep = 1; | ||
678 | |||
679 | ricoh583->gpio.request = ricoh583_gpio_request; | ||
680 | ricoh583->gpio.free = ricoh583_gpio_free; | ||
681 | ricoh583->gpio.direction_input = ricoh583_gpio_input; | ||
682 | ricoh583->gpio.direction_output = ricoh583_gpio_output; | ||
683 | ricoh583->gpio.set = ricoh583_gpio_set; | ||
684 | ricoh583->gpio.get = ricoh583_gpio_get; | ||
685 | ricoh583->gpio.to_irq = ricoh583_gpio_to_irq; | ||
686 | |||
687 | ret = gpiochip_add(&ricoh583->gpio); | ||
688 | if (ret) | ||
689 | dev_warn(ricoh583->dev, "GPIO registration failed: %d\n", ret); | ||
690 | } | ||
691 | |||
692 | static void ricoh583_irq_lock(struct irq_data *irq_data) | ||
693 | { | ||
694 | struct ricoh583 *ricoh583 = irq_data_get_irq_chip_data(irq_data); | ||
695 | |||
696 | mutex_lock(&ricoh583->irq_lock); | ||
697 | } | ||
698 | |||
699 | static void ricoh583_irq_unmask(struct irq_data *irq_data) | ||
700 | { | ||
701 | struct ricoh583 *ricoh583 = irq_data_get_irq_chip_data(irq_data); | ||
702 | unsigned int __irq = irq_data->irq - ricoh583->irq_base; | ||
703 | const struct ricoh583_irq_data *data = &ricoh583_irqs[__irq]; | ||
704 | |||
705 | ricoh583->group_irq_en[data->grp_index] |= (1 << data->grp_index); | ||
706 | if (ricoh583->group_irq_en[data->grp_index]) | ||
707 | ricoh583->intc_inten_reg |= 1 << data->master_bit; | ||
708 | |||
709 | ricoh583->irq_en_reg[data->mask_reg_index] |= 1 << data->int_en_bit; | ||
710 | } | ||
711 | |||
712 | static void ricoh583_irq_mask(struct irq_data *irq_data) | ||
713 | { | ||
714 | struct ricoh583 *ricoh583 = irq_data_get_irq_chip_data(irq_data); | ||
715 | unsigned int __irq = irq_data->irq - ricoh583->irq_base; | ||
716 | const struct ricoh583_irq_data *data = &ricoh583_irqs[__irq]; | ||
717 | |||
718 | ricoh583->group_irq_en[data->grp_index] &= ~(1 << data->grp_index); | ||
719 | if (!ricoh583->group_irq_en[data->grp_index]) | ||
720 | ricoh583->intc_inten_reg &= ~(1 << data->master_bit); | ||
721 | |||
722 | ricoh583->irq_en_reg[data->mask_reg_index] &= ~(1 << data->int_en_bit); | ||
723 | } | ||
724 | |||
725 | static void ricoh583_irq_sync_unlock(struct irq_data *irq_data) | ||
726 | { | ||
727 | struct ricoh583 *ricoh583 = irq_data_get_irq_chip_data(irq_data); | ||
728 | int i; | ||
729 | |||
730 | for (i = 0; i < ARRAY_SIZE(ricoh583->gpedge_reg); i++) { | ||
731 | if (ricoh583->gpedge_reg[i] != ricoh583->gpedge_cache[i]) { | ||
732 | if (!WARN_ON(__ricoh583_write(ricoh583->client, | ||
733 | ricoh583->gpedge_add[i], | ||
734 | ricoh583->gpedge_reg[i]))) | ||
735 | ricoh583->gpedge_cache[i] = | ||
736 | ricoh583->gpedge_reg[i]; | ||
737 | } | ||
738 | } | ||
739 | |||
740 | for (i = 0; i < ARRAY_SIZE(ricoh583->irq_en_reg); i++) { | ||
741 | if (ricoh583->irq_en_reg[i] != ricoh583->irq_en_cache[i]) { | ||
742 | if (!WARN_ON(__ricoh583_write(ricoh583->client, | ||
743 | ricoh583->irq_en_add[i], | ||
744 | ricoh583->irq_en_reg[i]))) | ||
745 | ricoh583->irq_en_cache[i] = | ||
746 | ricoh583->irq_en_reg[i]; | ||
747 | } | ||
748 | } | ||
749 | |||
750 | if (ricoh583->intc_inten_reg != ricoh583->intc_inten_cache) { | ||
751 | if (!WARN_ON(__ricoh583_write(ricoh583->client, | ||
752 | RICOH583_INTC_INTEN, ricoh583->intc_inten_reg))) | ||
753 | ricoh583->intc_inten_cache = ricoh583->intc_inten_reg; | ||
754 | } | ||
755 | |||
756 | mutex_unlock(&ricoh583->irq_lock); | ||
757 | } | ||
758 | |||
759 | static int ricoh583_irq_set_type(struct irq_data *irq_data, unsigned int type) | ||
760 | { | ||
761 | struct ricoh583 *ricoh583 = irq_data_get_irq_chip_data(irq_data); | ||
762 | unsigned int __irq = irq_data->irq - ricoh583->irq_base; | ||
763 | const struct ricoh583_irq_data *data = &ricoh583_irqs[__irq]; | ||
764 | int val = 0; | ||
765 | int gpedge_index; | ||
766 | int gpedge_bit_pos; | ||
767 | |||
768 | if (data->int_type & GPIO_INT) { | ||
769 | gpedge_index = data->int_en_bit / 4; | ||
770 | gpedge_bit_pos = data->int_en_bit % 4; | ||
771 | |||
772 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
773 | val |= 0x2; | ||
774 | |||
775 | if (type & IRQ_TYPE_EDGE_RISING) | ||
776 | val |= 0x1; | ||
777 | |||
778 | ricoh583->gpedge_reg[gpedge_index] &= ~(3 << gpedge_bit_pos); | ||
779 | ricoh583->gpedge_reg[gpedge_index] |= (val << gpedge_bit_pos); | ||
780 | ricoh583_irq_unmask(irq_data); | ||
781 | } | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static irqreturn_t ricoh583_irq(int irq, void *data) | ||
786 | { | ||
787 | struct ricoh583 *ricoh583 = data; | ||
788 | u8 int_sts[9]; | ||
789 | u8 master_int; | ||
790 | int i; | ||
791 | int ret; | ||
792 | u8 rtc_int_sts = 0; | ||
793 | |||
794 | /* Clear the status */ | ||
795 | for (i = 0; i < 9; i++) | ||
796 | int_sts[i] = 0; | ||
797 | |||
798 | ret = __ricoh583_read(ricoh583->client, RICOH583_INTC_INTMON, | ||
799 | &master_int); | ||
800 | if (ret < 0) { | ||
801 | dev_err(ricoh583->dev, "Error in reading reg 0x%02x " | ||
802 | "error: %d\n", RICOH583_INTC_INTMON, ret); | ||
803 | return IRQ_HANDLED; | ||
804 | } | ||
805 | |||
806 | for (i = 0; i < 9; ++i) { | ||
807 | if (!(master_int & ricoh583->main_int_type[i])) | ||
808 | continue; | ||
809 | ret = __ricoh583_read(ricoh583->client, | ||
810 | ricoh583->irq_mon_add[i], &int_sts[i]); | ||
811 | if (ret < 0) { | ||
812 | dev_err(ricoh583->dev, "Error in reading reg 0x%02x " | ||
813 | "error: %d\n", ricoh583->irq_mon_add[i], ret); | ||
814 | int_sts[i] = 0; | ||
815 | continue; | ||
816 | } | ||
817 | |||
818 | if (ricoh583->main_int_type[i] & RTC_INT) { | ||
819 | rtc_int_sts = 0; | ||
820 | if (int_sts[i] & 0x1) | ||
821 | rtc_int_sts |= BIT(6); | ||
822 | if (int_sts[i] & 0x2) | ||
823 | rtc_int_sts |= BIT(7); | ||
824 | if (int_sts[i] & 0x4) | ||
825 | rtc_int_sts |= BIT(0); | ||
826 | if (int_sts[i] & 0x8) | ||
827 | rtc_int_sts |= BIT(5); | ||
828 | } | ||
829 | |||
830 | ret = __ricoh583_write(ricoh583->client, | ||
831 | ricoh583->irq_clr_add[i], ~int_sts[i]); | ||
832 | if (ret < 0) { | ||
833 | dev_err(ricoh583->dev, "Error in reading reg 0x%02x " | ||
834 | "error: %d\n", ricoh583->irq_clr_add[i], ret); | ||
835 | } | ||
836 | if (ricoh583->main_int_type[i] & RTC_INT) | ||
837 | int_sts[i] = rtc_int_sts; | ||
838 | } | ||
839 | |||
840 | /* Merge gpio interrupts for rising and falling case*/ | ||
841 | int_sts[7] |= int_sts[8]; | ||
842 | |||
843 | /* Call interrupt handler if enabled */ | ||
844 | for (i = 0; i < RICOH583_NR_IRQS; ++i) { | ||
845 | const struct ricoh583_irq_data *data = &ricoh583_irqs[i]; | ||
846 | if ((int_sts[data->mask_reg_index] & (1 << data->int_en_bit)) && | ||
847 | (ricoh583->group_irq_en[data->master_bit] & | ||
848 | (1 << data->grp_index))) | ||
849 | handle_nested_irq(ricoh583->irq_base + i); | ||
850 | } | ||
851 | return IRQ_HANDLED; | ||
852 | } | ||
853 | |||
854 | static int __devinit ricoh583_irq_init(struct ricoh583 *ricoh583, int irq, | ||
855 | int irq_base) | ||
856 | { | ||
857 | int i, ret; | ||
858 | |||
859 | if (!irq_base) { | ||
860 | dev_warn(ricoh583->dev, "No interrupt support on IRQ base\n"); | ||
861 | return -EINVAL; | ||
862 | } | ||
863 | |||
864 | mutex_init(&ricoh583->irq_lock); | ||
865 | |||
866 | /* Initialize all locals to 0 */ | ||
867 | for (i = 0; i < MAX_INTERRUPT_MASKS; i++) { | ||
868 | ricoh583->irq_en_cache[i] = 0; | ||
869 | ricoh583->irq_en_reg[i] = 0; | ||
870 | } | ||
871 | ricoh583->intc_inten_cache = 0; | ||
872 | ricoh583->intc_inten_reg = 0; | ||
873 | for (i = 0; i < 2; i++) { | ||
874 | ricoh583->gpedge_cache[i] = 0; | ||
875 | ricoh583->gpedge_reg[i] = 0; | ||
876 | } | ||
877 | |||
878 | /* Interrupt enable register */ | ||
879 | ricoh583->gpedge_add[0] = RICOH583_GPIO_GPEDGE2; | ||
880 | ricoh583->gpedge_add[1] = RICOH583_GPIO_GPEDGE1; | ||
881 | ricoh583->irq_en_add[0] = RICOH583_INT_EN_SYS1; | ||
882 | ricoh583->irq_en_add[1] = RICOH583_INT_EN_SYS2; | ||
883 | ricoh583->irq_en_add[2] = RICOH583_INT_EN_DCDC; | ||
884 | ricoh583->irq_en_add[3] = RICOH583_INT_EN_RTC; | ||
885 | ricoh583->irq_en_add[4] = RICOH583_INT_EN_ADC1; | ||
886 | ricoh583->irq_en_add[5] = RICOH583_INT_EN_ADC2; | ||
887 | ricoh583->irq_en_add[6] = RICOH583_INT_EN_ADC3; | ||
888 | ricoh583->irq_en_add[7] = RICOH583_INT_EN_GPIO; | ||
889 | |||
890 | /* Interrupt status monitor register */ | ||
891 | ricoh583->irq_mon_add[0] = RICOH583_INT_MON_SYS1; | ||
892 | ricoh583->irq_mon_add[1] = RICOH583_INT_MON_SYS2; | ||
893 | ricoh583->irq_mon_add[2] = RICOH583_INT_MON_DCDC; | ||
894 | ricoh583->irq_mon_add[3] = RICOH583_INT_MON_RTC; | ||
895 | ricoh583->irq_mon_add[4] = RICOH583_INT_IR_ADCL; | ||
896 | ricoh583->irq_mon_add[5] = RICOH583_INT_IR_ADCH; | ||
897 | ricoh583->irq_mon_add[6] = RICOH583_INT_IR_ADCEND; | ||
898 | ricoh583->irq_mon_add[7] = RICOH583_INT_IR_GPIOF; | ||
899 | ricoh583->irq_mon_add[8] = RICOH583_INT_IR_GPIOR; | ||
900 | |||
901 | /* Interrupt status clear register */ | ||
902 | ricoh583->irq_clr_add[0] = RICOH583_INT_IR_SYS1; | ||
903 | ricoh583->irq_clr_add[1] = RICOH583_INT_IR_SYS2; | ||
904 | ricoh583->irq_clr_add[2] = RICOH583_INT_IR_DCDC; | ||
905 | ricoh583->irq_clr_add[3] = RICOH583_INT_IR_RTC; | ||
906 | ricoh583->irq_clr_add[4] = RICOH583_INT_IR_ADCL; | ||
907 | ricoh583->irq_clr_add[5] = RICOH583_INT_IR_ADCH; | ||
908 | ricoh583->irq_clr_add[6] = RICOH583_INT_IR_ADCEND; | ||
909 | ricoh583->irq_clr_add[7] = RICOH583_INT_IR_GPIOF; | ||
910 | ricoh583->irq_clr_add[8] = RICOH583_INT_IR_GPIOR; | ||
911 | |||
912 | ricoh583->main_int_type[0] = SYS_INT; | ||
913 | ricoh583->main_int_type[1] = SYS_INT; | ||
914 | ricoh583->main_int_type[2] = DCDC_INT; | ||
915 | ricoh583->main_int_type[3] = RTC_INT; | ||
916 | ricoh583->main_int_type[4] = ADC_INT; | ||
917 | ricoh583->main_int_type[5] = ADC_INT; | ||
918 | ricoh583->main_int_type[6] = ADC_INT; | ||
919 | ricoh583->main_int_type[7] = GPIO_INT; | ||
920 | ricoh583->main_int_type[8] = GPIO_INT; | ||
921 | |||
922 | /* Initailize all int register to 0 */ | ||
923 | for (i = 0; i < MAX_INTERRUPT_MASKS; i++) { | ||
924 | ret = __ricoh583_write(ricoh583->client, | ||
925 | ricoh583->irq_en_add[i], | ||
926 | ricoh583->irq_en_reg[i]); | ||
927 | if (ret < 0) | ||
928 | dev_err(ricoh583->dev, "Error in writing reg 0x%02x " | ||
929 | "error: %d\n", ricoh583->irq_en_add[i], ret); | ||
930 | } | ||
931 | |||
932 | for (i = 0; i < 2; i++) { | ||
933 | ret = __ricoh583_write(ricoh583->client, | ||
934 | ricoh583->gpedge_add[i], | ||
935 | ricoh583->gpedge_reg[i]); | ||
936 | if (ret < 0) | ||
937 | dev_err(ricoh583->dev, "Error in writing reg 0x%02x " | ||
938 | "error: %d\n", ricoh583->gpedge_add[i], ret); | ||
939 | } | ||
940 | |||
941 | ret = __ricoh583_write(ricoh583->client, RICOH583_INTC_INTEN, 0x0); | ||
942 | if (ret < 0) | ||
943 | dev_err(ricoh583->dev, "Error in writing reg 0x%02x " | ||
944 | "error: %d\n", RICOH583_INTC_INTEN, ret); | ||
945 | |||
946 | /* Clear all interrupts in case they woke up active. */ | ||
947 | for (i = 0; i < 9; i++) { | ||
948 | ret = __ricoh583_write(ricoh583->client, | ||
949 | ricoh583->irq_clr_add[i], 0); | ||
950 | if (ret < 0) | ||
951 | dev_err(ricoh583->dev, "Error in writing reg 0x%02x " | ||
952 | "error: %d\n", ricoh583->irq_clr_add[i], ret); | ||
953 | } | ||
954 | |||
955 | ricoh583->irq_base = irq_base; | ||
956 | ricoh583->irq_chip.name = "ricoh583"; | ||
957 | ricoh583->irq_chip.irq_mask = ricoh583_irq_mask; | ||
958 | ricoh583->irq_chip.irq_unmask = ricoh583_irq_unmask; | ||
959 | ricoh583->irq_chip.irq_bus_lock = ricoh583_irq_lock; | ||
960 | ricoh583->irq_chip.irq_bus_sync_unlock = ricoh583_irq_sync_unlock; | ||
961 | ricoh583->irq_chip.irq_set_type = ricoh583_irq_set_type; | ||
962 | |||
963 | for (i = 0; i < RICOH583_NR_IRQS; i++) { | ||
964 | int __irq = i + ricoh583->irq_base; | ||
965 | irq_set_chip_data(__irq, ricoh583); | ||
966 | irq_set_chip_and_handler(__irq, &ricoh583->irq_chip, | ||
967 | handle_simple_irq); | ||
968 | irq_set_nested_thread(__irq, 1); | ||
969 | #ifdef CONFIG_ARM | ||
970 | set_irq_flags(__irq, IRQF_VALID); | ||
971 | #endif | ||
972 | } | ||
973 | |||
974 | ret = request_threaded_irq(irq, NULL, ricoh583_irq, IRQF_ONESHOT, | ||
975 | "ricoh583", ricoh583); | ||
976 | if (ret < 0) | ||
977 | dev_err(ricoh583->dev, "Error in registering interrupt " | ||
978 | "error: %d\n", ret); | ||
979 | if (!ret) { | ||
980 | device_init_wakeup(ricoh583->dev, 1); | ||
981 | enable_irq_wake(irq); | ||
982 | } | ||
983 | return ret; | ||
984 | } | ||
985 | |||
986 | static int ricoh583_remove_subdev(struct device *dev, void *unused) | ||
987 | { | ||
988 | platform_device_unregister(to_platform_device(dev)); | ||
989 | return 0; | ||
990 | } | ||
991 | |||
992 | static int ricoh583_remove_subdevs(struct ricoh583 *ricoh583) | ||
993 | { | ||
994 | return device_for_each_child(ricoh583->dev, NULL, | ||
995 | ricoh583_remove_subdev); | ||
996 | } | ||
997 | |||
998 | static int __devinit ricoh583_add_subdevs(struct ricoh583 *ricoh583, | ||
999 | struct ricoh583_platform_data *pdata) | ||
1000 | { | ||
1001 | struct ricoh583_subdev_info *subdev; | ||
1002 | struct platform_device *pdev; | ||
1003 | int i, ret = 0; | ||
1004 | |||
1005 | for (i = 0; i < pdata->num_subdevs; i++) { | ||
1006 | subdev = &pdata->subdevs[i]; | ||
1007 | |||
1008 | pdev = platform_device_alloc(subdev->name, subdev->id); | ||
1009 | |||
1010 | pdev->dev.parent = ricoh583->dev; | ||
1011 | pdev->dev.platform_data = subdev->platform_data; | ||
1012 | |||
1013 | ret = platform_device_add(pdev); | ||
1014 | if (ret) | ||
1015 | goto failed; | ||
1016 | } | ||
1017 | return 0; | ||
1018 | |||
1019 | failed: | ||
1020 | ricoh583_remove_subdevs(ricoh583); | ||
1021 | return ret; | ||
1022 | } | ||
1023 | |||
1024 | #ifdef CONFIG_DEBUG_FS | ||
1025 | #include <linux/debugfs.h> | ||
1026 | #include <linux/seq_file.h> | ||
1027 | static void print_regs(const char *header, struct seq_file *s, | ||
1028 | struct i2c_client *client, int start_offset, | ||
1029 | int end_offset) | ||
1030 | { | ||
1031 | uint8_t reg_val; | ||
1032 | int i; | ||
1033 | int ret; | ||
1034 | |||
1035 | seq_printf(s, "%s\n", header); | ||
1036 | for (i = start_offset; i <= end_offset; ++i) { | ||
1037 | ret = __ricoh583_read(client, i, ®_val); | ||
1038 | if (ret >= 0) | ||
1039 | seq_printf(s, "Reg 0x%02x Value 0x%02x\n", i, reg_val); | ||
1040 | } | ||
1041 | seq_printf(s, "------------------\n"); | ||
1042 | } | ||
1043 | |||
1044 | static int dbg_tps_show(struct seq_file *s, void *unused) | ||
1045 | { | ||
1046 | struct ricoh583 *tps = s->private; | ||
1047 | struct i2c_client *client = tps->client; | ||
1048 | |||
1049 | seq_printf(s, "RICOH583 Registers\n"); | ||
1050 | seq_printf(s, "------------------\n"); | ||
1051 | |||
1052 | print_regs("System Regs", s, client, 0x0, 0xF); | ||
1053 | print_regs("Power Control Regs", s, client, 0x10, 0x2B); | ||
1054 | print_regs("DCDC1 Regs", s, client, 0x30, 0x43); | ||
1055 | print_regs("DCDC1 Regs", s, client, 0x60, 0x63); | ||
1056 | print_regs("LDO Regs", s, client, 0x50, 0x5F); | ||
1057 | print_regs("LDO Regs", s, client, 0x64, 0x6D); | ||
1058 | print_regs("ADC Regs", s, client, 0x70, 0x72); | ||
1059 | print_regs("ADC Regs", s, client, 0x74, 0x8B); | ||
1060 | print_regs("ADC Regs", s, client, 0x90, 0x96); | ||
1061 | print_regs("GPIO Regs", s, client, 0xA0, 0xAC); | ||
1062 | print_regs("INTC Regs", s, client, 0xAD, 0xAF); | ||
1063 | print_regs("RTC Regs", s, client, 0xE0, 0xEE); | ||
1064 | print_regs("RTC Regs", s, client, 0xF0, 0xF4); | ||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | static int dbg_tps_open(struct inode *inode, struct file *file) | ||
1069 | { | ||
1070 | return single_open(file, dbg_tps_show, inode->i_private); | ||
1071 | } | ||
1072 | |||
1073 | static const struct file_operations debug_fops = { | ||
1074 | .open = dbg_tps_open, | ||
1075 | .read = seq_read, | ||
1076 | .llseek = seq_lseek, | ||
1077 | .release = single_release, | ||
1078 | }; | ||
1079 | static void __init ricoh583_debuginit(struct ricoh583 *tps) | ||
1080 | { | ||
1081 | (void)debugfs_create_file("ricoh583", S_IRUGO, NULL, | ||
1082 | tps, &debug_fops); | ||
1083 | } | ||
1084 | #else | ||
1085 | static void __init ricoh583_debuginit(struct ricoh583 *tpsi) | ||
1086 | { | ||
1087 | return; | ||
1088 | } | ||
1089 | #endif | ||
1090 | |||
1091 | static int ricoh583_i2c_probe(struct i2c_client *i2c, | ||
1092 | const struct i2c_device_id *id) | ||
1093 | { | ||
1094 | struct ricoh583 *ricoh583; | ||
1095 | struct ricoh583_platform_data *pdata = i2c->dev.platform_data; | ||
1096 | int ret; | ||
1097 | |||
1098 | ricoh583 = kzalloc(sizeof(struct ricoh583), GFP_KERNEL); | ||
1099 | if (ricoh583 == NULL) | ||
1100 | return -ENOMEM; | ||
1101 | |||
1102 | ricoh583->client = i2c; | ||
1103 | ricoh583->dev = &i2c->dev; | ||
1104 | i2c_set_clientdata(i2c, ricoh583); | ||
1105 | |||
1106 | mutex_init(&ricoh583->io_lock); | ||
1107 | |||
1108 | ret = ricoh583_ext_power_init(ricoh583, pdata); | ||
1109 | if (ret < 0) | ||
1110 | goto err_irq_init; | ||
1111 | |||
1112 | if (i2c->irq) { | ||
1113 | ret = ricoh583_irq_init(ricoh583, i2c->irq, pdata->irq_base); | ||
1114 | if (ret) { | ||
1115 | dev_err(&i2c->dev, "IRQ init failed: %d\n", ret); | ||
1116 | goto err_irq_init; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | ret = ricoh583_add_subdevs(ricoh583, pdata); | ||
1121 | if (ret) { | ||
1122 | dev_err(&i2c->dev, "add devices failed: %d\n", ret); | ||
1123 | goto err_add_devs; | ||
1124 | } | ||
1125 | |||
1126 | ricoh583_gpio_init(ricoh583, pdata); | ||
1127 | |||
1128 | ricoh583_debuginit(ricoh583); | ||
1129 | |||
1130 | ricoh583_i2c_client = i2c; | ||
1131 | return 0; | ||
1132 | |||
1133 | err_add_devs: | ||
1134 | if (i2c->irq) | ||
1135 | free_irq(i2c->irq, ricoh583); | ||
1136 | err_irq_init: | ||
1137 | kfree(ricoh583); | ||
1138 | return ret; | ||
1139 | } | ||
1140 | |||
1141 | static int __devexit ricoh583_i2c_remove(struct i2c_client *i2c) | ||
1142 | { | ||
1143 | struct ricoh583 *ricoh583 = i2c_get_clientdata(i2c); | ||
1144 | |||
1145 | if (i2c->irq) | ||
1146 | free_irq(i2c->irq, ricoh583); | ||
1147 | |||
1148 | ricoh583_remove_subdevs(ricoh583); | ||
1149 | kfree(ricoh583); | ||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | #ifdef CONFIG_PM | ||
1154 | static int ricoh583_i2c_suspend(struct i2c_client *i2c, pm_message_t state) | ||
1155 | { | ||
1156 | if (i2c->irq) | ||
1157 | disable_irq(i2c->irq); | ||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | |||
1162 | static int ricoh583_i2c_resume(struct i2c_client *i2c) | ||
1163 | { | ||
1164 | if (i2c->irq) | ||
1165 | enable_irq(i2c->irq); | ||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | #endif | ||
1170 | |||
1171 | static const struct i2c_device_id ricoh583_i2c_id[] = { | ||
1172 | {"ricoh583", 0}, | ||
1173 | {} | ||
1174 | }; | ||
1175 | |||
1176 | MODULE_DEVICE_TABLE(i2c, ricoh583_i2c_id); | ||
1177 | |||
1178 | static struct i2c_driver ricoh583_i2c_driver = { | ||
1179 | .driver = { | ||
1180 | .name = "ricoh583", | ||
1181 | .owner = THIS_MODULE, | ||
1182 | }, | ||
1183 | .probe = ricoh583_i2c_probe, | ||
1184 | .remove = __devexit_p(ricoh583_i2c_remove), | ||
1185 | #ifdef CONFIG_PM | ||
1186 | .suspend = ricoh583_i2c_suspend, | ||
1187 | .resume = ricoh583_i2c_resume, | ||
1188 | #endif | ||
1189 | .id_table = ricoh583_i2c_id, | ||
1190 | }; | ||
1191 | |||
1192 | |||
1193 | static int __init ricoh583_i2c_init(void) | ||
1194 | { | ||
1195 | int ret = -ENODEV; | ||
1196 | ret = i2c_add_driver(&ricoh583_i2c_driver); | ||
1197 | if (ret != 0) | ||
1198 | pr_err("Failed to register I2C driver: %d\n", ret); | ||
1199 | |||
1200 | return ret; | ||
1201 | } | ||
1202 | |||
1203 | subsys_initcall(ricoh583_i2c_init); | ||
1204 | |||
1205 | static void __exit ricoh583_i2c_exit(void) | ||
1206 | { | ||
1207 | i2c_del_driver(&ricoh583_i2c_driver); | ||
1208 | } | ||
1209 | |||
1210 | module_exit(ricoh583_i2c_exit); | ||
1211 | |||
1212 | MODULE_DESCRIPTION("RICOH583 multi-function core driver"); | ||
1213 | MODULE_LICENSE("GPL"); | ||