blob: 85c8a9db5944f76904858210ce139a5b791bef69 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13/*
14 * Qualcomm PMIC8058 driver
15 *
16 */
17#include <linux/interrupt.h>
18#include <linux/i2c.h>
David Collins0a911602011-06-15 15:03:13 -070019#include <linux/bitops.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020#include <linux/slab.h>
21#include <linux/ratelimit.h>
22#include <linux/kthread.h>
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +053023#include <linux/msm_ssbi.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070024#include <linux/mfd/core.h>
25#include <linux/mfd/pmic8058.h>
26#include <linux/platform_device.h>
27#include <linux/ratelimit.h>
28#include <linux/slab.h>
29#include <linux/debugfs.h>
30#include <linux/irq.h>
Abhijeet Dharmapurikara3c0d942011-07-25 17:53:45 -070031#include <linux/syscore_ops.h>
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +053032#include <linux/gpio.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070033
34/* PMIC8058 Revision */
35#define SSBI_REG_REV 0x002 /* PMIC4 revision */
36
37/* PMIC8058 IRQ */
38#define SSBI_REG_ADDR_IRQ_BASE 0x1BB
39
40#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0)
41#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
42#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
43#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
44#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
45#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5)
46#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
47#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
48#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
49
50#define PM8058_IRQF_LVL_SEL 0x01 /* level select */
51#define PM8058_IRQF_MASK_FE 0x02 /* mask falling edge */
52#define PM8058_IRQF_MASK_RE 0x04 /* mask rising edge */
53#define PM8058_IRQF_CLR 0x08 /* clear interrupt */
54#define PM8058_IRQF_BITS_MASK 0x70
55#define PM8058_IRQF_BITS_SHIFT 4
56#define PM8058_IRQF_WRITE 0x80
57
58#define PM8058_IRQF_MASK_ALL (PM8058_IRQF_MASK_FE | \
59 PM8058_IRQF_MASK_RE)
60#define PM8058_IRQF_W_C_M (PM8058_IRQF_WRITE | \
61 PM8058_IRQF_CLR | \
62 PM8058_IRQF_MASK_ALL)
63
64/* MISC register */
65#define SSBI_REG_ADDR_MISC 0x1CC
66
67/* PON CNTL 1 register */
68#define SSBI_REG_ADDR_PON_CNTL_1 0x01C
69
70#define PM8058_PON_PUP_MASK 0xF0
71
72#define PM8058_PON_WD_EN_MASK 0x08
73#define PM8058_PON_WD_EN_RESET 0x08
74#define PM8058_PON_WD_EN_PWR_OFF 0x00
75
76/* PON CNTL 4 register */
77#define SSBI_REG_ADDR_PON_CNTL_4 0x98
78#define PM8058_PON_RESET_EN_MASK 0x01
79
80/* PON CNTL 5 register */
81#define SSBI_REG_ADDR_PON_CNTL_5 0x7B
82#define PM8058_HARD_RESET_EN_MASK 0x08
83
David Collins0a911602011-06-15 15:03:13 -070084/* Regulator master enable addresses */
85#define SSBI_REG_ADDR_VREG_EN_MSM 0x018
86#define SSBI_REG_ADDR_VREG_EN_GRP_5_4 0x1C8
87
88/* Regulator control registers for shutdown/reset */
89#define SSBI_REG_ADDR_S0_CTRL 0x004
90#define SSBI_REG_ADDR_S1_CTRL 0x005
91#define SSBI_REG_ADDR_S3_CTRL 0x111
92#define SSBI_REG_ADDR_L21_CTRL 0x120
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093#define SSBI_REG_ADDR_L22_CTRL 0x121
94
David Collins0a911602011-06-15 15:03:13 -070095#define REGULATOR_ENABLE_MASK 0x80
96#define REGULATOR_ENABLE 0x80
97#define REGULATOR_DISABLE 0x00
98#define REGULATOR_PULL_DOWN_MASK 0x40
99#define REGULATOR_PULL_DOWN_EN 0x40
100#define REGULATOR_PULL_DOWN_DIS 0x00
101
102/* Buck CTRL register */
103#define SMPS_LEGACY_VREF_SEL 0x20
104#define SMPS_LEGACY_VPROG_MASK 0x1F
105#define SMPS_ADVANCED_BAND_MASK 0xC0
106#define SMPS_ADVANCED_BAND_SHIFT 6
107#define SMPS_ADVANCED_VPROG_MASK 0x3F
108
109/* Buck TEST2 registers for shutdown/reset */
110#define SSBI_REG_ADDR_S0_TEST2 0x084
111#define SSBI_REG_ADDR_S1_TEST2 0x085
112#define SSBI_REG_ADDR_S3_TEST2 0x11A
113
114#define REGULATOR_BANK_WRITE 0x80
115#define REGULATOR_BANK_MASK 0x70
116#define REGULATOR_BANK_SHIFT 4
117#define REGULATOR_BANK_SEL(n) ((n) << REGULATOR_BANK_SHIFT)
118
119/* Buck TEST2 register bank 1 */
120#define SMPS_LEGACY_VLOW_SEL 0x01
121
122/* Buck TEST2 register bank 7 */
123#define SMPS_ADVANCED_MODE_MASK 0x02
124#define SMPS_ADVANCED_MODE 0x02
125#define SMPS_LEGACY_MODE 0x00
126
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700127/* SLEEP CNTL register */
128#define SSBI_REG_ADDR_SLEEP_CNTL 0x02B
129
130#define PM8058_SLEEP_SMPL_EN_MASK 0x04
131#define PM8058_SLEEP_SMPL_EN_RESET 0x04
132#define PM8058_SLEEP_SMPL_EN_PWR_OFF 0x00
133
134#define PM8058_SLEEP_SMPL_SEL_MASK 0x03
135#define PM8058_SLEEP_SMPL_SEL_MIN 0
136#define PM8058_SLEEP_SMPL_SEL_MAX 3
137
Willie Ruan6a3c9142011-07-14 16:52:41 -0700138/* GP_TEST1 register */
139#define SSBI_REG_ADDR_GP_TEST_1 0x07A
140
141/* IRQ */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700142#define MAX_PM_IRQ 256
143#define MAX_PM_BLOCKS (MAX_PM_IRQ / 8 + 1)
144#define MAX_PM_MASTERS (MAX_PM_BLOCKS / 8 + 1)
145
146struct pm8058_chip {
147 struct pm8058_platform_data pdata;
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +0530148 struct device *dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700149
150 u8 irqs_allowed[MAX_PM_BLOCKS];
151 u8 blocks_allowed[MAX_PM_MASTERS];
152 u8 masters_allowed;
153 int pm_max_irq;
154 int pm_max_blocks;
155 int pm_max_masters;
156
157 u8 config[MAX_PM_IRQ];
158 u8 bus_unlock_config[MAX_PM_IRQ];
159 u8 wake_enable[MAX_PM_IRQ];
160 u16 count_wakeable;
161
162 u8 revision;
163
164 struct mutex pm_lock;
165};
166
167#if defined(CONFIG_DEBUG_FS)
168struct pm8058_dbg_device {
169 struct mutex dbg_mutex;
170 struct pm8058_chip *pm_chip;
171 struct dentry *dent;
172 int addr;
173};
174
175static struct pm8058_dbg_device *pmic_dbg_device;
176#endif
177
178static struct pm8058_chip *pmic_chip;
179
180/* Helper Functions */
181DEFINE_RATELIMIT_STATE(pm8058_msg_ratelimit, 60 * HZ, 10);
182
183static inline int pm8058_can_print(void)
184{
185 return __ratelimit(&pm8058_msg_ratelimit);
186}
187
188static inline int
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +0530189ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190{
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +0530191 return msm_ssbi_read(dev->parent, addr, buf, len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700192}
193
194static inline int
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +0530195ssbi_write(struct device *dev, u16 addr, u8 *buf, size_t len)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700196{
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +0530197 return msm_ssbi_write(dev->parent, addr, buf, len);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700198}
199
200static int pm8058_masked_write(u16 addr, u8 val, u8 mask)
201{
202 int rc;
203 u8 reg;
204
205 if (pmic_chip == NULL)
206 return -ENODEV;
207
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208 rc = ssbi_read(pmic_chip->dev, addr, &reg, 1);
209 if (rc) {
210 pr_err("%s: ssbi_read(0x%03X) failed: rc=%d\n", __func__, addr,
211 rc);
212 goto done;
213 }
214
215 reg &= ~mask;
216 reg |= val & mask;
217
218 rc = ssbi_write(pmic_chip->dev, addr, &reg, 1);
219 if (rc)
220 pr_err("%s: ssbi_write(0x%03X)=0x%02X failed: rc=%d\n",
221 __func__, addr, reg, rc);
222done:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700223 return rc;
224}
225
226/* External APIs */
227int pm8058_rev(struct pm8058_chip *chip)
228{
229 if (chip == NULL)
230 return -EINVAL;
231
232 return chip->revision;
233}
234EXPORT_SYMBOL(pm8058_rev);
235
236int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq)
237{
238 int rc;
239 u8 block, bits, bit;
240
241 if (chip == NULL || irq < chip->pdata.irq_base ||
242 irq >= chip->pdata.irq_base + MAX_PM_IRQ)
243 return -EINVAL;
244
245 irq -= chip->pdata.irq_base;
246
247 block = irq / 8;
248 bit = irq % 8;
249
250 mutex_lock(&chip->pm_lock);
251
252 rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1);
253 if (rc) {
254 pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
255 __func__, rc);
256 goto bail_out;
257 }
258
259 rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1);
260 if (rc) {
261 pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n",
262 __func__, rc);
263 goto bail_out;
264 }
265
266 rc = (bits & (1 << bit)) ? 1 : 0;
267
268bail_out:
269 mutex_unlock(&chip->pm_lock);
270
271 return rc;
272}
273EXPORT_SYMBOL(pm8058_irq_get_rt_status);
274
275int pm8058_read(struct pm8058_chip *chip, u16 addr, u8 *values,
276 unsigned int len)
277{
278 if (chip == NULL)
279 return -EINVAL;
280
281 return ssbi_read(chip->dev, addr, values, len);
282}
283EXPORT_SYMBOL(pm8058_read);
284
285int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values,
286 unsigned int len)
287{
288 if (chip == NULL)
289 return -EINVAL;
290
291 return ssbi_write(chip->dev, addr, values, len);
292}
293EXPORT_SYMBOL(pm8058_write);
294
295int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag)
296{
297 int rc;
298 u8 misc;
299
300 if (chip == NULL)
301 chip = pmic_chip; /* for calls from non child */
302 if (chip == NULL)
303 return -ENODEV;
304
305 mutex_lock(&chip->pm_lock);
306
307 rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
308 if (rc) {
309 pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
310 __func__, SSBI_REG_ADDR_MISC, rc);
311 goto get_out;
312 }
313
314 misc &= ~mask;
315 misc |= flag;
316
317 rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
318 if (rc) {
319 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
320 __func__, SSBI_REG_ADDR_MISC, misc, rc);
321 goto get_out;
322 }
323
324get_out:
325 mutex_unlock(&chip->pm_lock);
326
327 return rc;
328}
329EXPORT_SYMBOL(pm8058_misc_control);
330
331/**
332 * pm8058_smpl_control - enables/disables SMPL detection
333 * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
334 *
335 * This function enables or disables the Sudden Momentary Power Loss detection
336 * module. If SMPL detection is enabled, then when a sufficiently long power
337 * loss event occurs, the PMIC will automatically reset itself. If SMPL
338 * detection is disabled, then the PMIC will shutdown when power loss occurs.
339 *
340 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
341 */
342int pm8058_smpl_control(int enable)
343{
344 return pm8058_masked_write(SSBI_REG_ADDR_SLEEP_CNTL,
345 (enable ? PM8058_SLEEP_SMPL_EN_RESET
346 : PM8058_SLEEP_SMPL_EN_PWR_OFF),
347 PM8058_SLEEP_SMPL_EN_MASK);
348}
349EXPORT_SYMBOL(pm8058_smpl_control);
350
351/**
352 * pm8058_smpl_set_delay - sets the SMPL detection time delay
353 * @delay: enum value corresponding to delay time
354 *
355 * This function sets the time delay of the SMPL detection module. If power
356 * is reapplied within this interval, then the PMIC reset automatically. The
357 * SMPL detection module must be enabled for this delay time to take effect.
358 *
359 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
360 */
361int pm8058_smpl_set_delay(enum pm8058_smpl_delay delay)
362{
363 if (delay < PM8058_SLEEP_SMPL_SEL_MIN
364 || delay > PM8058_SLEEP_SMPL_SEL_MAX) {
365 pr_err("%s: invalid delay specified: %d\n", __func__, delay);
366 return -EINVAL;
367 }
368
369 return pm8058_masked_write(SSBI_REG_ADDR_SLEEP_CNTL, delay,
370 PM8058_SLEEP_SMPL_SEL_MASK);
371}
372EXPORT_SYMBOL(pm8058_smpl_set_delay);
373
374/**
375 * pm8058_watchdog_reset_control - enables/disables watchdog reset detection
376 * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
377 *
378 * This function enables or disables the PMIC watchdog reset detection feature.
379 * If watchdog reset detection is enabled, then the PMIC will reset itself
380 * when PS_HOLD goes low. If it is not enabled, then the PMIC will shutdown
381 * when PS_HOLD goes low.
382 *
383 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
384 */
385int pm8058_watchdog_reset_control(int enable)
386{
387 return pm8058_masked_write(SSBI_REG_ADDR_PON_CNTL_1,
388 (enable ? PM8058_PON_WD_EN_RESET
389 : PM8058_PON_WD_EN_PWR_OFF),
390 PM8058_PON_WD_EN_MASK);
391}
392EXPORT_SYMBOL(pm8058_watchdog_reset_control);
393
David Collins0a911602011-06-15 15:03:13 -0700394/*
395 * Set an SMPS regulator to be disabled in its CTRL register, but enabled
396 * in the master enable register. Also set it's pull down enable bit.
397 * Take care to make sure that the output voltage doesn't change if switching
398 * from advanced mode to legacy mode.
399 */
400static int disable_smps_locally_set_pull_down(u16 ctrl_addr, u16 test2_addr,
401 u16 master_enable_addr, u8 master_enable_bit)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700402{
David Collins0a911602011-06-15 15:03:13 -0700403 int rc = 0;
404 u8 vref_sel, vlow_sel, band, vprog, bank, reg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700405
406 if (pmic_chip == NULL)
407 return -ENODEV;
408
David Collins0a911602011-06-15 15:03:13 -0700409 bank = REGULATOR_BANK_SEL(7);
410 rc = ssbi_write(pmic_chip->dev, test2_addr, &bank, 1);
411 if (rc) {
412 pr_err("%s: FAIL ssbi_write(0x%03X): rc=%d\n", __func__,
413 test2_addr, rc);
414 goto done;
415 }
416
417 rc = ssbi_read(pmic_chip->dev, test2_addr, &reg, 1);
418 if (rc) {
419 pr_err("%s: FAIL pm8058_read(0x%03X): rc=%d\n",
420 __func__, test2_addr, rc);
421 goto done;
422 }
423
424 /* Check if in advanced mode. */
425 if ((reg & SMPS_ADVANCED_MODE_MASK) == SMPS_ADVANCED_MODE) {
426 /* Determine current output voltage. */
427 rc = ssbi_read(pmic_chip->dev, ctrl_addr, &reg, 1);
428 if (rc) {
429 pr_err("%s: FAIL pm8058_read(0x%03X): rc=%d\n",
430 __func__, ctrl_addr, rc);
431 goto done;
432 }
433
434 band = (reg & SMPS_ADVANCED_BAND_MASK)
435 >> SMPS_ADVANCED_BAND_SHIFT;
436 switch (band) {
437 case 3:
438 vref_sel = 0;
439 vlow_sel = 0;
440 break;
441 case 2:
442 vref_sel = SMPS_LEGACY_VREF_SEL;
443 vlow_sel = 0;
444 break;
445 case 1:
446 vref_sel = SMPS_LEGACY_VREF_SEL;
447 vlow_sel = SMPS_LEGACY_VLOW_SEL;
448 break;
449 default:
450 pr_err("%s: regulator already disabled\n", __func__);
451 return -EPERM;
452 }
453 vprog = (reg & SMPS_ADVANCED_VPROG_MASK);
454 /* Round up if fine step is in use. */
455 vprog = (vprog + 1) >> 1;
456 if (vprog > SMPS_LEGACY_VPROG_MASK)
457 vprog = SMPS_LEGACY_VPROG_MASK;
458
459 /* Set VLOW_SEL bit. */
460 bank = REGULATOR_BANK_SEL(1);
461 rc = ssbi_write(pmic_chip->dev, test2_addr, &bank, 1);
462 if (rc) {
463 pr_err("%s: FAIL ssbi_write(0x%03X): rc=%d\n",
464 __func__, test2_addr, rc);
465 goto done;
466 }
467 rc = pm8058_masked_write(test2_addr,
468 REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(1)
469 | vlow_sel,
470 REGULATOR_BANK_WRITE | REGULATOR_BANK_MASK
471 | SMPS_LEGACY_VLOW_SEL);
472 if (rc)
473 goto done;
474
475 /* Switch to legacy mode */
476 bank = REGULATOR_BANK_SEL(7);
477 rc = ssbi_write(pmic_chip->dev, test2_addr, &bank, 1);
478 if (rc) {
479 pr_err("%s: FAIL ssbi_write(0x%03X): rc=%d\n", __func__,
480 test2_addr, rc);
481 goto done;
482 }
483 rc = pm8058_masked_write(test2_addr,
484 REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7)
485 | SMPS_LEGACY_MODE,
486 REGULATOR_BANK_WRITE | REGULATOR_BANK_MASK
487 | SMPS_ADVANCED_MODE_MASK);
488 if (rc)
489 goto done;
490
491 /* Enable locally, enable pull down, keep voltage the same. */
492 rc = pm8058_masked_write(ctrl_addr,
493 REGULATOR_ENABLE | REGULATOR_PULL_DOWN_EN
494 | vref_sel | vprog,
495 REGULATOR_ENABLE_MASK | REGULATOR_PULL_DOWN_MASK
496 | SMPS_LEGACY_VREF_SEL | SMPS_LEGACY_VPROG_MASK);
497 if (rc)
498 goto done;
499 }
500
501 /* Enable in master control register. */
502 rc = pm8058_masked_write(master_enable_addr, master_enable_bit,
503 master_enable_bit);
504 if (rc)
505 goto done;
506
507 /* Disable locally and enable pull down. */
508 rc = pm8058_masked_write(ctrl_addr,
509 REGULATOR_DISABLE | REGULATOR_PULL_DOWN_EN,
510 REGULATOR_ENABLE_MASK | REGULATOR_PULL_DOWN_MASK);
511
512done:
513 return rc;
514}
515
516static int disable_ldo_locally_set_pull_down(u16 ctrl_addr,
517 u16 master_enable_addr, u8 master_enable_bit)
518{
519 int rc;
520
521 /* Enable LDO in master control register. */
522 rc = pm8058_masked_write(master_enable_addr, master_enable_bit,
523 master_enable_bit);
524 if (rc)
525 goto done;
526
527 /* Disable LDO in CTRL register and set pull down */
528 rc = pm8058_masked_write(ctrl_addr,
529 REGULATOR_DISABLE | REGULATOR_PULL_DOWN_EN,
530 REGULATOR_ENABLE_MASK | REGULATOR_PULL_DOWN_MASK);
531
532done:
533 return rc;
534}
535
536int pm8058_reset_pwr_off(int reset)
537{
538 int rc;
539 u8 pon, ctrl, smpl;
540
541 if (pmic_chip == NULL)
542 return -ENODEV;
543
544 /* When shutting down, enable active pulldowns on important rails. */
545 if (!reset) {
546 /* Disable SMPS's 0,1,3 locally and set pulldown enable bits. */
547 disable_smps_locally_set_pull_down(SSBI_REG_ADDR_S0_CTRL,
548 SSBI_REG_ADDR_S0_TEST2, SSBI_REG_ADDR_VREG_EN_MSM, BIT(7));
549 disable_smps_locally_set_pull_down(SSBI_REG_ADDR_S1_CTRL,
550 SSBI_REG_ADDR_S1_TEST2, SSBI_REG_ADDR_VREG_EN_MSM, BIT(6));
551 disable_smps_locally_set_pull_down(SSBI_REG_ADDR_S3_CTRL,
552 SSBI_REG_ADDR_S3_TEST2, SSBI_REG_ADDR_VREG_EN_GRP_5_4,
553 BIT(7) | BIT(4));
554 /* Disable LDO 21 locally and set pulldown enable bit. */
555 disable_ldo_locally_set_pull_down(SSBI_REG_ADDR_L21_CTRL,
556 SSBI_REG_ADDR_VREG_EN_GRP_5_4, BIT(1));
557 }
558
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559 /* Set regulator L22 to 1.225V in high power mode. */
560 rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_L22_CTRL, &ctrl, 1);
561 if (rc) {
562 pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__,
563 SSBI_REG_ADDR_L22_CTRL, rc);
564 goto get_out3;
565 }
566 /* Leave pull-down state intact. */
567 ctrl &= 0x40;
568 ctrl |= 0x93;
569 rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_L22_CTRL, &ctrl, 1);
570 if (rc)
571 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__,
572 SSBI_REG_ADDR_L22_CTRL, ctrl, rc);
573
574get_out3:
575 if (!reset) {
576 /* Only modify the SLEEP_CNTL reg if shutdown is desired. */
577 rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_SLEEP_CNTL,
578 &smpl, 1);
579 if (rc) {
580 pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
581 __func__, SSBI_REG_ADDR_SLEEP_CNTL, rc);
582 goto get_out2;
583 }
584
585 smpl &= ~PM8058_SLEEP_SMPL_EN_MASK;
586 smpl |= PM8058_SLEEP_SMPL_EN_PWR_OFF;
587
588 rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_SLEEP_CNTL,
589 &smpl, 1);
590 if (rc)
591 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
592 __func__, SSBI_REG_ADDR_SLEEP_CNTL, smpl, rc);
593 }
594
595get_out2:
596 rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_1, &pon, 1);
597 if (rc) {
598 pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
599 __func__, SSBI_REG_ADDR_PON_CNTL_1, rc);
600 goto get_out;
601 }
602
603 pon &= ~PM8058_PON_WD_EN_MASK;
604 pon |= reset ? PM8058_PON_WD_EN_RESET : PM8058_PON_WD_EN_PWR_OFF;
605
606 /* Enable all pullups */
607 pon |= PM8058_PON_PUP_MASK;
608
609 rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_1, &pon, 1);
610 if (rc) {
611 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
612 __func__, SSBI_REG_ADDR_PON_CNTL_1, pon, rc);
613 goto get_out;
614 }
615
616get_out:
617 return rc;
618}
619EXPORT_SYMBOL(pm8058_reset_pwr_off);
620
Willie Ruan6a3c9142011-07-14 16:52:41 -0700621/**
622 * pm8058_stay_on - enables stay_on feature
623 *
624 * PMIC stay-on feature allows PMIC to ignore MSM PS_HOLD=low
625 * signal so that some special functions like debugging could be
626 * performed.
627 *
628 * This feature should not be used in any product release.
629 *
630 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
631 */
632int pm8058_stay_on(void)
633{
634 u8 ctrl = 0x92;
635 int rc;
636
637 rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_GP_TEST_1, &ctrl, 1);
638 pr_info("%s: set stay-on: rc = %d\n", __func__, rc);
639 return rc;
640}
641EXPORT_SYMBOL(pm8058_stay_on);
642
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700643/*
644 power on hard reset configuration
645 config = DISABLE_HARD_RESET to disable hard reset
646 = SHUTDOWN_ON_HARD_RESET to turn off the system on hard reset
647 = RESTART_ON_HARD_RESET to restart the system on hard reset
648 */
649int pm8058_hard_reset_config(enum pon_config config)
650{
651 int rc, ret;
652 u8 pon, pon_5;
653
654 if (config >= MAX_PON_CONFIG)
655 return -EINVAL;
656
657 if (pmic_chip == NULL)
658 return -ENODEV;
659
660 mutex_lock(&pmic_chip->pm_lock);
661
662 rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_5, &pon, 1);
663 if (rc) {
664 pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
665 __func__, SSBI_REG_ADDR_PON_CNTL_5, rc);
666 mutex_unlock(&pmic_chip->pm_lock);
667 return rc;
668 }
669
670 pon_5 = pon;
671 (config != DISABLE_HARD_RESET) ? (pon |= PM8058_HARD_RESET_EN_MASK) :
672 (pon &= ~PM8058_HARD_RESET_EN_MASK);
673
674 rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_5, &pon, 1);
675 if (rc) {
676 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
677 __func__, SSBI_REG_ADDR_PON_CNTL_5, pon, rc);
678 mutex_unlock(&pmic_chip->pm_lock);
679 return rc;
680 }
681
682 if (config == DISABLE_HARD_RESET) {
683 mutex_unlock(&pmic_chip->pm_lock);
684 return 0;
685 }
686
687 rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_4, &pon, 1);
688 if (rc) {
689 pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
690 __func__, SSBI_REG_ADDR_PON_CNTL_4, rc);
691 goto err_restore_pon_5;
692 }
693
694 (config == RESTART_ON_HARD_RESET) ? (pon |= PM8058_PON_RESET_EN_MASK) :
695 (pon &= ~PM8058_PON_RESET_EN_MASK);
696
697 rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_4, &pon, 1);
698 if (rc) {
699 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
700 __func__, SSBI_REG_ADDR_PON_CNTL_4, pon, rc);
701 goto err_restore_pon_5;
702 }
703 mutex_unlock(&pmic_chip->pm_lock);
704 return 0;
705
706err_restore_pon_5:
707 ret = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_5, &pon_5, 1);
708 if (ret)
709 pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
710 __func__, SSBI_REG_ADDR_PON_CNTL_5, pon, ret);
711 mutex_unlock(&pmic_chip->pm_lock);
712 return rc;
713}
714EXPORT_SYMBOL(pm8058_hard_reset_config);
715
716/* Internal functions */
717static inline int
718pm8058_config_irq(struct pm8058_chip *chip, u8 *bp, u8 *cp)
719{
720 int rc;
721
722 rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
723 if (rc) {
724 pr_err("%s: ssbi_write: rc=%d (Select block)\n",
725 __func__, rc);
726 goto bail_out;
727 }
728
729 rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp, 1);
730 if (rc)
731 pr_err("%s: ssbi_write: rc=%d (Configure IRQ)\n",
732 __func__, rc);
733
734bail_out:
735 return rc;
736}
737
738static void pm8058_irq_mask(struct irq_data *data)
739{
740 int master, irq_bit;
741 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
742 u8 block, config;
743 unsigned int irq = data->irq;
744
745 irq -= chip->pdata.irq_base;
746 block = irq / 8;
747 master = block / 8;
748 irq_bit = irq % 8;
749
750 chip->irqs_allowed[block] &= ~(1 << irq_bit);
751 if (!chip->irqs_allowed[block]) {
752 chip->blocks_allowed[master] &= ~(1 << (block % 8));
753
754 if (!chip->blocks_allowed[master])
755 chip->masters_allowed &= ~(1 << master);
756 }
757
758 config = PM8058_IRQF_WRITE | chip->config[irq] |
759 PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
760 chip->bus_unlock_config[irq] = config;
761}
762
763static void pm8058_irq_unmask(struct irq_data *data)
764{
765 int master, irq_bit;
766 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
767 u8 block, config, old_irqs_allowed, old_blocks_allowed;
768 unsigned int irq = data->irq;
769
770 irq -= chip->pdata.irq_base;
771 block = irq / 8;
772 master = block / 8;
773 irq_bit = irq % 8;
774
775 old_irqs_allowed = chip->irqs_allowed[block];
Abhijeet Dharmapurikara346e2c2011-08-30 18:17:51 -0700776 if (old_irqs_allowed & (1 << irq_bit)) {
777 pr_debug("%s: no need to enable an already enabled irq=%d\n",
778 __func__, irq + chip->pdata.irq_base);
779 return;
780 }
781
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700782 chip->irqs_allowed[block] |= 1 << irq_bit;
783 if (!old_irqs_allowed) {
784 master = block / 8;
785
786 old_blocks_allowed = chip->blocks_allowed[master];
787 chip->blocks_allowed[master] |= 1 << (block % 8);
788
789 if (!old_blocks_allowed)
790 chip->masters_allowed |= 1 << master;
791 }
792
793 config = PM8058_IRQF_WRITE | chip->config[irq];
794 chip->bus_unlock_config[irq] = config;
795}
796
797static void pm8058_irq_ack(struct irq_data *data)
798{
799 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
800 u8 block, config;
801 unsigned int irq = data->irq;
802
803 irq -= chip->pdata.irq_base;
804 block = irq / 8;
805
806 config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
807 /* Keep the mask */
808 if (!(chip->irqs_allowed[block] & (1 << (irq % 8))))
809 config |= PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
810 chip->bus_unlock_config[irq] = config;
811}
812
813static int pm8058_irq_set_type(struct irq_data *data, unsigned int flow_type)
814{
815 int master, irq_bit;
816 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
817 u8 block, config;
818 unsigned int irq = data->irq;
819
820 irq -= chip->pdata.irq_base;
821 if (irq > chip->pm_max_irq) {
822 chip->pm_max_irq = irq;
823 chip->pm_max_blocks =
824 chip->pm_max_irq / 8 + 1;
825 chip->pm_max_masters =
826 chip->pm_max_blocks / 8 + 1;
827 }
828 block = irq / 8;
829 master = block / 8;
830 irq_bit = irq % 8;
831
832 chip->config[irq] = (irq_bit << PM8058_IRQF_BITS_SHIFT) |
833 PM8058_IRQF_MASK_RE | PM8058_IRQF_MASK_FE;
834 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
835 if (flow_type & IRQF_TRIGGER_RISING)
836 chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
837 if (flow_type & IRQF_TRIGGER_FALLING)
838 chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
839 } else {
840 chip->config[irq] |= PM8058_IRQF_LVL_SEL;
841
842 if (flow_type & IRQF_TRIGGER_HIGH)
843 chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
844 else
845 chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
846 }
847
848 config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
849 chip->bus_unlock_config[irq] = config;
850 return 0;
851}
852
853static int pm8058_irq_set_wake(struct irq_data *data, unsigned int on)
854{
855 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
856 unsigned int irq = data->irq;
857
858 irq -= chip->pdata.irq_base;
859 if (on) {
860 if (!chip->wake_enable[irq]) {
861 chip->wake_enable[irq] = 1;
862 chip->count_wakeable++;
863 }
864 } else {
865 if (chip->wake_enable[irq]) {
866 chip->wake_enable[irq] = 0;
867 chip->count_wakeable--;
868 }
869 }
870
871 return 0;
872}
873
874static void pm8058_irq_bus_lock(struct irq_data *data)
875{
876 u8 block;
877 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
878 unsigned int irq = data->irq;
879
880 irq -= chip->pdata.irq_base;
881 block = irq / 8;
882 chip->bus_unlock_config[irq] = 0;
883
884 mutex_lock(&chip->pm_lock);
885}
886
887static void pm8058_irq_bus_sync_unlock(struct irq_data *data)
888{
889 u8 block, config;
890 struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
891 unsigned int irq = data->irq;
892
893 irq -= chip->pdata.irq_base;
894 block = irq / 8;
895 config = chip->bus_unlock_config[irq];
896 /* dont waste cpu cycles if we dont have data to write */
897 if (config)
898 pm8058_config_irq(chip, &block, &config);
899 mutex_unlock(&chip->pm_lock);
900}
901
902static inline int
903pm8058_read_root(struct pm8058_chip *chip, u8 *rp)
904{
905 int rc;
906
907 rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp, 1);
908 if (rc) {
909 pr_err("%s: FAIL ssbi_read(): rc=%d (Read Root)\n",
910 __func__, rc);
911 *rp = 0;
912 }
913
914 return rc;
915}
916
917static inline int
918pm8058_read_master(struct pm8058_chip *chip, u8 m, u8 *bp)
919{
920 int rc;
921
922 rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp, 1);
923 if (rc) {
924 pr_err("%s: FAIL ssbi_read(): rc=%d (Read Master)\n",
925 __func__, rc);
926 *bp = 0;
927 }
928
929 return rc;
930}
931
932static inline int
933pm8058_read_block(struct pm8058_chip *chip, u8 *bp, u8 *ip)
934{
935 int rc;
936
937 rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
938 if (rc) {
939 pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
940 __func__, rc);
941 *bp = 0;
942 goto bail_out;
943 }
944
945 rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip, 1);
946 if (rc)
947 pr_err("%s: FAIL ssbi_read(): rc=%d (Read Status)\n",
948 __func__, rc);
949
950bail_out:
951 return rc;
952}
953
954static irqreturn_t pm8058_isr_thread(int irq_requested, void *data)
955{
956 struct pm8058_chip *chip = data;
957 int i, j, k;
958 u8 root, block, config, bits;
959 u8 blocks[MAX_PM_MASTERS];
960 int masters = 0, irq, handled = 0, spurious = 0;
961 u16 irqs_to_handle[MAX_PM_IRQ];
962
963 mutex_lock(&chip->pm_lock);
964
965 /* Read root for masters */
966 if (pm8058_read_root(chip, &root))
967 goto bail_out;
968
969 masters = root >> 1;
970
971 if (!(masters & chip->masters_allowed) ||
972 (masters & ~chip->masters_allowed)) {
973 spurious = 1000000;
974 }
975
976 /* Read allowed masters for blocks. */
977 for (i = 0; i < chip->pm_max_masters; i++) {
978 if (masters & (1 << i)) {
979 if (pm8058_read_master(chip, i, &blocks[i]))
980 goto bail_out;
981
982 if (!blocks[i]) {
983 if (pm8058_can_print())
984 pr_err("%s: Spurious master: %d "
985 "(blocks=0)", __func__, i);
986 spurious += 10000;
987 }
988 } else
989 blocks[i] = 0;
990 }
991
992 /* Select block, read status and call isr */
993 for (i = 0; i < chip->pm_max_masters; i++) {
994 if (!blocks[i])
995 continue;
996
997 for (j = 0; j < 8; j++) {
998 if (!(blocks[i] & (1 << j)))
999 continue;
1000
1001 block = i * 8 + j; /* block # */
1002 if (pm8058_read_block(chip, &block, &bits))
1003 goto bail_out;
1004
1005 if (!bits) {
1006 if (pm8058_can_print())
1007 pr_err("%s: Spurious block: "
1008 "[master, block]=[%d, %d] "
1009 "(bits=0)\n", __func__, i, j);
1010 spurious += 100;
1011 continue;
1012 }
1013
1014 /* Check IRQ bits */
1015 for (k = 0; k < 8; k++) {
1016 if (!(bits & (1 << k)))
1017 continue;
1018
1019 /* Check spurious interrupts */
1020 if (((1 << i) & chip->masters_allowed) &&
1021 (blocks[i] & chip->blocks_allowed[i]) &&
1022 (bits & chip->irqs_allowed[block])) {
1023
1024 /* Found one */
1025 irq = block * 8 + k;
1026 irqs_to_handle[handled] = irq +
1027 chip->pdata.irq_base;
1028 handled++;
1029 } else {
1030 /* Clear and mask wrong one */
1031 config = PM8058_IRQF_W_C_M |
1032 (k << PM8058_IRQF_BITS_SHIFT);
1033
1034 pm8058_config_irq(chip,
1035 &block, &config);
1036
1037 if (pm8058_can_print())
1038 pr_err("%s: Spurious IRQ: "
1039 "[master, block, bit]="
1040 "[%d, %d (%d), %d]\n",
1041 __func__,
1042 i, j, block, k);
1043 spurious++;
1044 }
1045 }
1046 }
1047
1048 }
1049
1050bail_out:
1051
1052 mutex_unlock(&chip->pm_lock);
1053
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001054 for (i = 0; i < handled; i++) {
Abhijeet Dharmapurikarbb23a052011-09-19 10:44:53 -07001055 int pmic_irq = irqs_to_handle[i] - chip->pdata.irq_base;
1056
1057 /* ack the interrupt first */
1058 block = pmic_irq / 8 ;
1059 config = PM8058_IRQF_WRITE | chip->config[pmic_irq]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001060 | PM8058_IRQF_CLR;
1061 pm8058_config_irq(chip, &block, &config);
Abhijeet Dharmapurikarbb23a052011-09-19 10:44:53 -07001062
1063 /* calle the action handler */
1064 handle_nested_irq(irqs_to_handle[i]);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001065 }
1066
1067 if (spurious) {
1068 if (!pm8058_can_print())
1069 return IRQ_HANDLED;
1070
1071 pr_err("%s: spurious = %d (handled = %d)\n",
1072 __func__, spurious, handled);
1073 pr_err(" root = 0x%x (masters_allowed<<1 = 0x%x)\n",
1074 root, chip->masters_allowed << 1);
1075 for (i = 0; i < chip->pm_max_masters; i++) {
1076 if (masters & (1 << i))
1077 pr_err(" blocks[%d]=0x%x, "
1078 "allowed[%d]=0x%x\n",
1079 i, blocks[i],
1080 i, chip->blocks_allowed[i]);
1081 }
1082 }
1083
1084 return IRQ_HANDLED;
1085}
1086
1087#if defined(CONFIG_DEBUG_FS)
1088
1089static int check_addr(int addr, const char *func_name)
1090{
1091 if (addr < 0 || addr > 0x3FF) {
1092 pr_err("%s: PMIC 8058 register address is invalid: %d\n",
1093 func_name, addr);
1094 return -EINVAL;
1095 }
1096 return 0;
1097}
1098
1099static int data_set(void *data, u64 val)
1100{
1101 struct pm8058_dbg_device *dbgdev = data;
1102 u8 reg = val;
1103 int rc;
1104
1105 mutex_lock(&dbgdev->dbg_mutex);
1106
1107 rc = check_addr(dbgdev->addr, __func__);
1108 if (rc)
1109 goto done;
1110
1111 rc = pm8058_write(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
1112
1113 if (rc)
1114 pr_err("%s: FAIL pm8058_write(0x%03X)=0x%02X: rc=%d\n",
1115 __func__, dbgdev->addr, reg, rc);
1116done:
1117 mutex_unlock(&dbgdev->dbg_mutex);
1118 return rc;
1119}
1120
1121static int data_get(void *data, u64 *val)
1122{
1123 struct pm8058_dbg_device *dbgdev = data;
1124 int rc;
1125 u8 reg;
1126
1127 mutex_lock(&dbgdev->dbg_mutex);
1128
1129 rc = check_addr(dbgdev->addr, __func__);
1130 if (rc)
1131 goto done;
1132
1133 rc = pm8058_read(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
1134
1135 if (rc) {
1136 pr_err("%s: FAIL pm8058_read(0x%03X)=0x%02X: rc=%d\n",
1137 __func__, dbgdev->addr, reg, rc);
1138 goto done;
1139 }
1140
1141 *val = reg;
1142done:
1143 mutex_unlock(&dbgdev->dbg_mutex);
1144 return rc;
1145}
1146
1147DEFINE_SIMPLE_ATTRIBUTE(dbg_data_fops, data_get, data_set, "0x%02llX\n");
1148
1149static int addr_set(void *data, u64 val)
1150{
1151 struct pm8058_dbg_device *dbgdev = data;
1152 int rc;
1153
1154 rc = check_addr(val, __func__);
1155 if (rc)
1156 return rc;
1157
1158 mutex_lock(&dbgdev->dbg_mutex);
1159 dbgdev->addr = val;
1160 mutex_unlock(&dbgdev->dbg_mutex);
1161
1162 return 0;
1163}
1164
1165static int addr_get(void *data, u64 *val)
1166{
1167 struct pm8058_dbg_device *dbgdev = data;
1168 int rc;
1169
1170 mutex_lock(&dbgdev->dbg_mutex);
1171
1172 rc = check_addr(dbgdev->addr, __func__);
1173 if (rc) {
1174 mutex_unlock(&dbgdev->dbg_mutex);
1175 return rc;
1176 }
1177 *val = dbgdev->addr;
1178
1179 mutex_unlock(&dbgdev->dbg_mutex);
1180
1181 return 0;
1182}
1183
1184DEFINE_SIMPLE_ATTRIBUTE(dbg_addr_fops, addr_get, addr_set, "0x%03llX\n");
1185
1186static int __devinit pmic8058_dbg_probe(struct pm8058_chip *chip)
1187{
1188 struct pm8058_dbg_device *dbgdev;
1189 struct dentry *dent;
1190 struct dentry *temp;
Jay Chokshi898340f2011-09-29 17:19:31 -07001191 int rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001192
1193 if (chip == NULL) {
1194 pr_err("%s: no parent data passed in.\n", __func__);
1195 return -EINVAL;
1196 }
1197
1198 dbgdev = kzalloc(sizeof *dbgdev, GFP_KERNEL);
1199 if (dbgdev == NULL) {
1200 pr_err("%s: kzalloc() failed.\n", __func__);
1201 return -ENOMEM;
1202 }
1203
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001204 dbgdev->pm_chip = chip;
1205 dbgdev->addr = -1;
1206
1207 dent = debugfs_create_dir("pm8058-dbg", NULL);
1208 if (dent == NULL || IS_ERR(dent)) {
1209 pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
1210 __func__, (unsigned)dent);
Jay Chokshi898340f2011-09-29 17:19:31 -07001211 rc = PTR_ERR(dent);
1212 goto dir_error;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001213 }
1214
1215 temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
1216 dbgdev, &dbg_addr_fops);
1217 if (temp == NULL || IS_ERR(temp)) {
1218 pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
1219 __func__, (unsigned)temp);
Jay Chokshi898340f2011-09-29 17:19:31 -07001220 rc = PTR_ERR(temp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001221 goto debug_error;
1222 }
1223
1224 temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, dent,
1225 dbgdev, &dbg_data_fops);
1226 if (temp == NULL || IS_ERR(temp)) {
1227 pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
1228 __func__, (unsigned)temp);
Jay Chokshi898340f2011-09-29 17:19:31 -07001229 rc = PTR_ERR(temp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001230 goto debug_error;
1231 }
1232
Jay Chokshi898340f2011-09-29 17:19:31 -07001233 mutex_init(&dbgdev->dbg_mutex);
1234
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001235 dbgdev->dent = dent;
1236
1237 pmic_dbg_device = dbgdev;
1238
1239 return 0;
1240
1241debug_error:
1242 debugfs_remove_recursive(dent);
Jay Chokshi898340f2011-09-29 17:19:31 -07001243dir_error:
1244 kfree(dbgdev);
1245
1246 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001247}
1248
1249static int __devexit pmic8058_dbg_remove(void)
1250{
1251 if (pmic_dbg_device) {
1252 debugfs_remove_recursive(pmic_dbg_device->dent);
Jay Chokshi898340f2011-09-29 17:19:31 -07001253 mutex_destroy(&pmic_dbg_device->dbg_mutex);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001254 kfree(pmic_dbg_device);
1255 }
1256 return 0;
1257}
1258
1259#else
1260
1261static int __devinit pmic8058_dbg_probe(struct pm8058_chip *chip)
1262{
1263 return 0;
1264}
1265
1266static int __devexit pmic8058_dbg_remove(void)
1267{
1268 return 0;
1269}
1270
1271#endif
1272
1273static struct irq_chip pm8058_irq_chip = {
1274 .name = "pm8058",
1275 .irq_ack = pm8058_irq_ack,
1276 .irq_mask = pm8058_irq_mask,
1277 .irq_unmask = pm8058_irq_unmask,
1278 .irq_set_type = pm8058_irq_set_type,
1279 .irq_set_wake = pm8058_irq_set_wake,
1280 .irq_bus_lock = pm8058_irq_bus_lock,
1281 .irq_bus_sync_unlock = pm8058_irq_bus_sync_unlock,
1282};
1283
Abhijeet Dharmapurikara3c0d942011-07-25 17:53:45 -07001284static int pm8058_suspend(void)
1285{
1286 struct pm8058_chip *chip = pmic_chip;
1287 struct irq_data *data;
1288 int i;
1289
1290 for (i = 0; i < MAX_PM_IRQ; i++) {
1291 if (chip->config[i] && !chip->wake_enable[i]) {
1292 if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
1293 == PM8058_IRQF_MASK_ALL)) {
1294 data = irq_get_irq_data(i +
1295 chip->pdata.irq_base);
1296 pm8058_irq_bus_lock(data);
1297 pm8058_irq_mask(data);
1298 pm8058_irq_bus_sync_unlock(data);
1299 }
1300 }
1301 }
1302
1303 if (!chip->count_wakeable)
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301304 disable_irq(chip->pdata.irq);
Abhijeet Dharmapurikara3c0d942011-07-25 17:53:45 -07001305
1306 return 0;
1307}
1308
1309extern int msm_show_resume_irq_mask;
1310
1311static void pm8058_show_resume_irq(void)
1312{
1313 u8 block, bits;
1314 int i;
1315 struct pm8058_chip *chip = pmic_chip;
1316
1317 if (!msm_show_resume_irq_mask)
1318 return;
1319
1320 for (i = 0; i < MAX_PM_IRQ; i++) {
1321 if (chip->wake_enable[i]) {
1322 block = i / 8;
1323 if (!pm8058_read_block(chip, &block, &bits)) {
1324 if (bits & (1 << (i & 0x7)))
1325 pr_warning("%s:%d triggered\n",
1326 __func__, i + chip->pdata.irq_base);
1327 }
1328 }
1329 }
1330}
1331
1332static void pm8058_resume(void)
1333{
1334 struct pm8058_chip *chip = pmic_chip;
1335 struct irq_data *data;
1336 int i;
1337
1338 pm8058_show_resume_irq();
1339
1340 for (i = 0; i < MAX_PM_IRQ; i++) {
1341 if (chip->config[i] && !chip->wake_enable[i]) {
1342 if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
1343 == PM8058_IRQF_MASK_ALL)) {
1344 data = irq_get_irq_data(i +
1345 chip->pdata.irq_base);
1346 pm8058_irq_bus_lock(data);
1347 pm8058_irq_unmask(data);
1348 pm8058_irq_bus_sync_unlock(data);
1349 }
1350 }
1351 }
1352
1353 if (!chip->count_wakeable)
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301354 enable_irq(chip->pdata.irq);
Abhijeet Dharmapurikara3c0d942011-07-25 17:53:45 -07001355}
1356
1357static struct syscore_ops pm8058_pm = {
1358 .suspend = pm8058_suspend,
1359 .resume = pm8058_resume,
1360};
1361
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301362static int __devinit pm8058_probe(struct platform_device *pdev)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001363{
1364 int i, rc;
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301365 struct pm8058_platform_data *pdata = pdev->dev.platform_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001366 struct pm8058_chip *chip;
1367
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301368 if (pdata == NULL || !gpio_is_valid(pdata->irq)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001369 pr_err("%s: No platform_data or IRQ.\n", __func__);
1370 return -ENODEV;
1371 }
1372
1373 if (pdata->num_subdevs == 0) {
1374 pr_err("%s: No sub devices to support.\n", __func__);
1375 return -ENODEV;
1376 }
1377
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001378 chip = kzalloc(sizeof *chip, GFP_KERNEL);
1379 if (chip == NULL) {
1380 pr_err("%s: kzalloc() failed.\n", __func__);
1381 return -ENOMEM;
1382 }
1383
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301384 chip->dev = &pdev->dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001385
1386 /* Read PMIC chip revision */
1387 rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
1388 if (rc)
1389 pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
1390 __func__, rc);
1391 pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);
1392
1393 (void) memcpy((void *)&chip->pdata, (const void *)pdata,
1394 sizeof(chip->pdata));
1395
1396 mutex_init(&chip->pm_lock);
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301397 irq_set_handler_data(pdata->irq, (void *)chip);
1398 irq_set_irq_wake(pdata->irq, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001399
1400 chip->pm_max_irq = 0;
1401 chip->pm_max_blocks = 0;
1402 chip->pm_max_masters = 0;
1403
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301404 platform_set_drvdata(pdev, chip);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001405
1406 pmic_chip = chip;
1407
1408 /* Register for all reserved IRQs */
1409 for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
1410 irq_set_chip(i, &pm8058_irq_chip);
1411 irq_set_chip_data(i, (void *)chip);
1412 irq_set_handler(i, handle_edge_irq);
1413 set_irq_flags(i, IRQF_VALID);
1414 irq_set_nested_thread(i, 1);
1415 }
1416
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301417 rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001418 pdata->num_subdevs, NULL, 0);
1419
1420 /* Add charger sub device with the chip parameter as driver data */
1421 if (pdata->charger_sub_device) {
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301422 rc = mfd_add_devices(chip->dev, 0,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001423 pdata->charger_sub_device,
1424 1, NULL, 0);
1425 }
1426
1427 if (pdata->init) {
1428 rc = pdata->init(chip);
1429 if (rc != 0) {
1430 pr_err("%s: board init failed\n", __func__);
1431 chip->dev = NULL;
1432 kfree(chip);
1433 return -ENODEV;
1434 }
1435 }
1436
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301437 rc = request_threaded_irq(pdata->irq, NULL, pm8058_isr_thread,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001438 IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
1439 "pm8058-irq", chip);
1440 if (rc < 0)
1441 pr_err("%s: could not request irq %d: %d\n", __func__,
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301442 pdata->irq, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001443
1444 rc = pmic8058_dbg_probe(chip);
1445 if (rc < 0)
1446 pr_err("%s: could not set up debugfs: %d\n", __func__, rc);
1447
Abhijeet Dharmapurikara4a3eaf2011-09-22 15:27:28 -07001448 rc = pm8058_hard_reset_config(SHUTDOWN_ON_HARD_RESET);
1449 if (rc < 0)
1450 pr_err("%s: failed to config shutdown on hard reset: %d\n",
1451 __func__, rc);
1452
Abhijeet Dharmapurikara3c0d942011-07-25 17:53:45 -07001453 register_syscore_ops(&pm8058_pm);
1454
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001455 return 0;
1456}
1457
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301458static int __devexit pm8058_remove(struct platform_device *pdev)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001459{
1460 struct pm8058_chip *chip;
1461
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301462 chip = platform_get_drvdata(pdev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001463 if (chip) {
1464 if (chip->pm_max_irq) {
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301465 irq_set_irq_wake(chip->pdata.irq, 0);
1466 free_irq(chip->pdata.irq, chip);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001467 }
1468 mutex_destroy(&chip->pm_lock);
1469 chip->dev = NULL;
1470
1471 kfree(chip);
1472 }
1473
1474 pmic8058_dbg_remove();
1475
1476 return 0;
1477}
1478
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301479static struct platform_driver pm8058_driver = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001480 .probe = pm8058_probe,
1481 .remove = __devexit_p(pm8058_remove),
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301482 .driver = {
1483 .name = "pm8058-core",
1484 .owner = THIS_MODULE,
1485 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001486};
1487
1488static int __init pm8058_init(void)
1489{
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301490 return platform_driver_register(&pm8058_driver);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001491}
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301492arch_initcall(pm8058_init);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001493
1494static void __exit pm8058_exit(void)
1495{
Anirudh Ghayalf1f1e142011-10-10 17:47:45 +05301496 platform_driver_unregister(&pm8058_driver);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001497}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001498module_exit(pm8058_exit);
1499
1500MODULE_LICENSE("GPL v2");
1501MODULE_DESCRIPTION("PMIC8058 core driver");
1502MODULE_VERSION("1.0");
1503MODULE_ALIAS("platform:pmic8058-core");