blob: 92ade1c2ec23bf75ddd188f006074720e8d10fa8 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 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 * Qualcomm PMIC PM8xxx Battery Alarm driver
14 *
15 */
16
17#define pr_fmt(fmt) "%s: " fmt, __func__
18
19#include <linux/err.h>
20#include <linux/interrupt.h>
21#include <linux/module.h>
22#include <linux/notifier.h>
23#include <linux/platform_device.h>
24#include <linux/slab.h>
25#include <linux/mfd/pm8xxx/core.h>
26#include <linux/mfd/pm8xxx/batt-alarm.h>
27
28/* Available voltage threshold values */
29#define THRESHOLD_MIN_MV 2500
30#define THRESHOLD_MAX_MV 5675
31#define THRESHOLD_STEP_MV 25
32
33/* Register bit definitions */
34
35/* Threshold register */
36#define THRESHOLD_UPPER_MASK 0xF0
37#define THRESHOLD_LOWER_MASK 0x0F
38#define THRESHOLD_UPPER_SHIFT 4
39#define THRESHOLD_LOWER_SHIFT 0
40
41/* CTRL 1 register */
42#define CTRL1_BATT_ALARM_ENABLE_MASK 0x80
43#define CTRL1_BATT_ALARM_ENABLE 0x80
44#define CTRL1_BATT_ALARM_DISABLE 0x00
45#define CTRL1_HOLD_TIME_MASK 0x70
46#define CTRL1_STATUS_UPPER_MASK 0x02
47#define CTRL1_STATUS_LOWER_MASK 0x01
48#define CTRL1_HOLD_TIME_SHIFT 4
49#define CTRL1_HOLD_TIME_MIN 0
50#define CTRL1_HOLD_TIME_MAX 7
51
52/* CTRL 2 register */
53#define CTRL2_COMP_UPPER_DISABLE_MASK 0x80
54#define CTRL2_COMP_UPPER_ENABLE 0x00
55#define CTRL2_COMP_UPPER_DISABLE 0x80
56#define CTRL2_COMP_LOWER_DISABLE_MASK 0x40
57#define CTRL2_COMP_LOWER_ENABLE 0x00
58#define CTRL2_COMP_LOWER_DISABLE 0x40
59#define CTRL2_FINE_STEP_UPPER_MASK 0x30
60#define CTRL2_RANGE_EXT_UPPER_MASK 0x08
61#define CTRL2_FINE_STEP_LOWER_MASK 0x06
62#define CTRL2_RANGE_EXT_LOWER_MASK 0x01
63#define CTRL2_FINE_STEP_UPPER_SHIFT 4
64#define CTRL2_FINE_STEP_LOWER_SHIFT 1
65
66/* PWM control register */
67#define PWM_CTRL_ALARM_EN_MASK 0xC0
68#define PWM_CTRL_ALARM_EN_NEVER 0x00
69#define PWM_CTRL_ALARM_EN_TCXO 0x40
70#define PWM_CTRL_ALARM_EN_PWM 0x80
71#define PWM_CTRL_ALARM_EN_ALWAYS 0xC0
72#define PWM_CTRL_PRE_MASK 0x38
73#define PWM_CTRL_DIV_MASK 0x07
74#define PWM_CTRL_PRE_SHIFT 3
75#define PWM_CTRL_DIV_SHIFT 0
76#define PWM_CTRL_PRE_MIN 0
77#define PWM_CTRL_PRE_MAX 7
78#define PWM_CTRL_DIV_MIN 1
79#define PWM_CTRL_DIV_MAX 7
80
81/* PWM control input range */
82#define PWM_CTRL_PRE_INPUT_MIN 2
83#define PWM_CTRL_PRE_INPUT_MAX 9
84#define PWM_CTRL_DIV_INPUT_MIN 2
85#define PWM_CTRL_DIV_INPUT_MAX 8
86
87/* Available voltage threshold values */
88#define THRESHOLD_BASIC_MIN_MV 2800
89#define THRESHOLD_EXT_MIN_MV 4400
90
91/*
92 * Default values used during initialization:
93 * Slowest PWM rate to ensure minimal status jittering when crossing thresholds.
94 * Largest hold time also helps reduce status value jittering. Comparators
95 * are disabled by default and must be turned on by calling
96 * pm8xxx_batt_alarm_state_set.
97 */
98#define DEFAULT_THRESHOLD_LOWER 3200
99#define DEFAULT_THRESHOLD_UPPER 4300
100#define DEFAULT_HOLD_TIME PM8XXX_BATT_ALARM_HOLD_TIME_16_MS
101#define DEFAULT_USE_PWM 1
102#define DEFAULT_PWM_SCALER 9
103#define DEFAULT_PWM_DIVIDER 8
104#define DEFAULT_LOWER_ENABLE 0
105#define DEFAULT_UPPER_ENABLE 0
106
107struct pm8xxx_batt_alarm_chip {
108 struct pm8xxx_batt_alarm_core_data cdata;
109 struct srcu_notifier_head irq_notifier_list;
110 struct work_struct irq_work;
111 struct device *dev;
112 struct mutex lock;
113 unsigned int irq;
114 int notifier_count;
115 u8 reg_threshold;
116 u8 reg_ctrl1;
117 u8 reg_ctrl2;
118 u8 reg_pwm_ctrl;
119};
120static struct pm8xxx_batt_alarm_chip *the_battalarm;
121
122static int pm8xxx_reg_write(struct pm8xxx_batt_alarm_chip *chip, u16 addr,
123 u8 val, u8 mask, u8 *reg_save)
124{
125 int rc = 0;
126 u8 reg;
127
128 reg = (*reg_save & ~mask) | (val & mask);
129 if (reg != *reg_save)
130 rc = pm8xxx_writeb(chip->dev->parent, addr, reg);
131 if (rc)
132 pr_err("pm8xxx_writeb failed; addr=%03X, rc=%d\n", addr, rc);
133 else
134 *reg_save = reg;
135 return rc;
136}
137
138/**
139 * pm8xxx_batt_alarm_enable - enable one of the battery voltage threshold
140 * comparators
141 * @comparator: selects which comparator to enable
142 *
143 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
144 */
145int pm8xxx_batt_alarm_enable(enum pm8xxx_batt_alarm_comparator comparator)
146{
147 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
148 int rc;
149 u8 val_ctrl2 = 0, mask_ctrl2 = 0;
150
151 if (!chip) {
152 pr_err("no battery alarm device found.\n");
153 return -ENODEV;
154 }
155
156 if (comparator < 0 || comparator > PM8XXX_BATT_ALARM_UPPER_COMPARATOR) {
157 pr_err("invalid comparator ID number: %d\n", comparator);
158 return -EINVAL;
159 }
160
161 if (comparator == PM8XXX_BATT_ALARM_LOWER_COMPARATOR) {
162 val_ctrl2 = CTRL2_COMP_LOWER_ENABLE;
163 mask_ctrl2 = CTRL2_COMP_LOWER_DISABLE_MASK;
164 } else {
165 val_ctrl2 = CTRL2_COMP_UPPER_ENABLE;
166 mask_ctrl2 = CTRL2_COMP_UPPER_DISABLE_MASK;
167 }
168
169 mutex_lock(&chip->lock);
170
171 /* Enable the battery alarm block. */
172 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_ctrl1,
173 CTRL1_BATT_ALARM_ENABLE,
174 CTRL1_BATT_ALARM_ENABLE_MASK, &chip->reg_ctrl1);
175 if (rc)
176 goto bail;
177
178 /* Enable the individual comparators. */
179 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_ctrl2, val_ctrl2,
180 mask_ctrl2, &chip->reg_ctrl2);
181
182bail:
183 mutex_unlock(&chip->lock);
184 return rc;
185}
186EXPORT_SYMBOL(pm8xxx_batt_alarm_enable);
187
188/**
189 * pm8xxx_batt_alarm_disable - disable one of the battery voltage threshold
190 * comparators
191 * @comparator: selects which comparator to disable
192 *
193 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
194 */
195int pm8xxx_batt_alarm_disable(enum pm8xxx_batt_alarm_comparator comparator)
196{
197 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
198 int rc;
199 u8 val_ctrl1 = 0, val_ctrl2 = 0, mask_ctrl2 = 0;
200
201 if (!chip) {
202 pr_err("no battery alarm device found.\n");
203 return -ENODEV;
204 }
205
206 if (comparator < 0 || comparator > PM8XXX_BATT_ALARM_UPPER_COMPARATOR) {
207 pr_err("invalid comparator ID number: %d\n", comparator);
208 return -EINVAL;
209 }
210
211 if (comparator == PM8XXX_BATT_ALARM_LOWER_COMPARATOR) {
212 val_ctrl2 = CTRL2_COMP_LOWER_DISABLE;
213 mask_ctrl2 = CTRL2_COMP_LOWER_DISABLE_MASK;
214 } else {
215 val_ctrl2 = CTRL2_COMP_UPPER_DISABLE;
216 mask_ctrl2 = CTRL2_COMP_UPPER_DISABLE_MASK;
217 }
218
219 mutex_lock(&chip->lock);
220
221 /* Disable the specified comparator. */
222 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_ctrl2, val_ctrl2,
223 mask_ctrl2, &chip->reg_ctrl2);
224 if (rc)
225 goto bail;
226
227 /* Disable the battery alarm block if both comparators are disabled. */
228 val_ctrl2 = chip->reg_ctrl2
229 & (CTRL2_COMP_LOWER_DISABLE_MASK | CTRL2_COMP_UPPER_DISABLE_MASK);
230 if (val_ctrl2 == (CTRL2_COMP_LOWER_DISABLE | CTRL2_COMP_UPPER_DISABLE))
231 val_ctrl1 = CTRL1_BATT_ALARM_DISABLE;
232 else
233 val_ctrl1 = CTRL1_BATT_ALARM_ENABLE;
234
235 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_ctrl1, val_ctrl1,
236 CTRL1_BATT_ALARM_ENABLE_MASK, &chip->reg_ctrl1);
237
238bail:
239 mutex_unlock(&chip->lock);
240 return rc;
241}
242EXPORT_SYMBOL(pm8xxx_batt_alarm_disable);
243
244/**
245 * pm8xxx_batt_alarm_threshold_set - set the lower and upper alarm thresholds
246 * @comparator: selects which comparator to set the threshold of
247 * @threshold_mV: battery voltage threshold in millivolts
248 * set points = 2500-5675 mV in 25 mV steps
249 *
250 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
251 */
252int pm8xxx_batt_alarm_threshold_set(
253 enum pm8xxx_batt_alarm_comparator comparator, int threshold_mV)
254{
255 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
256 int step, fine_step, rc;
257 u8 val_threshold = 0, val_ctrl2 = 0;
258 int threshold_mask, threshold_shift, range_ext_mask, fine_step_mask;
259 int fine_step_shift;
260
261 if (!chip) {
262 pr_err("no battery alarm device found.\n");
263 return -ENXIO;
264 }
265
266 if (comparator < 0 || comparator > PM8XXX_BATT_ALARM_UPPER_COMPARATOR) {
267 pr_err("invalid comparator ID number: %d\n", comparator);
268 return -EINVAL;
269 }
270
271 if (threshold_mV < THRESHOLD_MIN_MV
272 || threshold_mV > THRESHOLD_MAX_MV) {
273 pr_err("threshold value, %d mV, is outside of allowable "
274 "range: [%d, %d] mV\n", threshold_mV,
275 THRESHOLD_MIN_MV, THRESHOLD_MAX_MV);
276 return -EINVAL;
277 }
278
279 if (comparator == PM8XXX_BATT_ALARM_LOWER_COMPARATOR) {
280 threshold_mask = THRESHOLD_LOWER_MASK;
281 threshold_shift = THRESHOLD_LOWER_SHIFT;
282 range_ext_mask = CTRL2_RANGE_EXT_LOWER_MASK;
283 fine_step_mask = CTRL2_FINE_STEP_LOWER_MASK;
284 fine_step_shift = CTRL2_FINE_STEP_LOWER_SHIFT;
285 } else {
286 threshold_mask = THRESHOLD_UPPER_MASK;
287 threshold_shift = THRESHOLD_UPPER_SHIFT;
288 range_ext_mask = CTRL2_RANGE_EXT_UPPER_MASK;
289 fine_step_mask = CTRL2_FINE_STEP_UPPER_MASK;
290 fine_step_shift = CTRL2_FINE_STEP_UPPER_SHIFT;
291 }
292
293 /* Determine register settings to achieve the threshold. */
294 if (threshold_mV < THRESHOLD_BASIC_MIN_MV) {
295 /* Extended low range */
296 val_ctrl2 |= range_ext_mask;
297
298 step = (threshold_mV - THRESHOLD_MIN_MV) / THRESHOLD_STEP_MV;
299
300 fine_step = step & 0x3;
301 /* Extended low range is for steps 0 to 2 */
302 step >>= 2;
303 } else if (threshold_mV >= THRESHOLD_EXT_MIN_MV) {
304 /* Extended high range */
305 val_ctrl2 |= range_ext_mask;
306
307 step = (threshold_mV - THRESHOLD_EXT_MIN_MV)
308 / THRESHOLD_STEP_MV;
309
310 fine_step = step & 0x3;
311 /* Extended high range is for steps 3 to 15 */
312 step = (step >> 2) + 3;
313 } else {
314 /* Basic range */
315 step = (threshold_mV - THRESHOLD_BASIC_MIN_MV)
316 / THRESHOLD_STEP_MV;
317
318 fine_step = step & 0x3;
319 step >>= 2;
320 }
321 val_threshold |= step << threshold_shift;
322 val_ctrl2 |= (fine_step << fine_step_shift) & fine_step_mask;
323
324 mutex_lock(&chip->lock);
325 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_threshold,
326 val_threshold, threshold_mask, &chip->reg_threshold);
327 if (rc)
328 goto bail;
329
330 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_ctrl2, val_ctrl2,
331 range_ext_mask | fine_step_mask, &chip->reg_ctrl2);
332
333bail:
334 mutex_unlock(&chip->lock);
335 return rc;
336}
337EXPORT_SYMBOL(pm8xxx_batt_alarm_threshold_set);
338
339/**
340 * pm8xxx_batt_alarm_status_read - get status of both threshold comparators
341 *
342 * RETURNS: < 0 = error
343 * 0 = battery voltage ok
344 * BIT(0) set = battery voltage below lower threshold
345 * BIT(1) set = battery voltage above upper threshold
346 */
347int pm8xxx_batt_alarm_status_read(void)
348{
349 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
350 int status, rc;
351
352 if (!chip) {
353 pr_err("no battery alarm device found.\n");
354 return -ENXIO;
355 }
356
357 mutex_lock(&chip->lock);
358 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_ctrl1,
359 &chip->reg_ctrl1);
360
361 status = ((chip->reg_ctrl1 & CTRL1_STATUS_LOWER_MASK)
362 ? PM8XXX_BATT_ALARM_STATUS_BELOW_LOWER : 0)
363 | ((chip->reg_ctrl1 & CTRL1_STATUS_UPPER_MASK)
364 ? PM8XXX_BATT_ALARM_STATUS_ABOVE_UPPER : 0);
365 mutex_unlock(&chip->lock);
366
367 if (rc) {
368 pr_err("pm8xxx_readb failed, rc=%d\n", rc);
369 return rc;
370 }
371
372 return status;
373}
374EXPORT_SYMBOL(pm8xxx_batt_alarm_status_read);
375
376/**
377 * pm8xxx_batt_alarm_hold_time_set - set hold time of interrupt output *
378 * @hold_time: amount of time that battery voltage must remain outside of the
379 * threshold range before the battery alarm interrupt triggers
380 *
381 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
382 */
383int pm8xxx_batt_alarm_hold_time_set(enum pm8xxx_batt_alarm_hold_time hold_time)
384{
385 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
386 int rc;
387 u8 reg_ctrl1 = 0;
388
389 if (!chip) {
390 pr_err("no battery alarm device found.\n");
391 return -ENXIO;
392 }
393
394 if (hold_time < CTRL1_HOLD_TIME_MIN
395 || hold_time > CTRL1_HOLD_TIME_MAX) {
396
397 pr_err("hold time, %d, is outside of allowable range: "
398 "[%d, %d]\n", hold_time, CTRL1_HOLD_TIME_MIN,
399 CTRL1_HOLD_TIME_MAX);
400 return -EINVAL;
401 }
402
403 reg_ctrl1 = hold_time << CTRL1_HOLD_TIME_SHIFT;
404
405 mutex_lock(&chip->lock);
406 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_ctrl1, reg_ctrl1,
407 CTRL1_HOLD_TIME_MASK, &chip->reg_ctrl1);
408 mutex_unlock(&chip->lock);
409
410 return rc;
411}
412EXPORT_SYMBOL(pm8xxx_batt_alarm_hold_time_set);
413
414/**
415 * pm8xxx_batt_alarm_pwm_rate_set - set battery alarm update rate *
416 * @use_pwm: 1 = use PWM update rate, 0 = comparators always active
417 * @clock_scaler: PWM clock scaler = 2 to 9
418 * @clock_divider: PWM clock divider = 2 to 8
419 *
420 * This function sets the rate at which the battery alarm module enables
421 * the threshold comparators. The rate is determined by the following equation:
422 *
423 * f_update = (1024 Hz) / (clock_divider * (2 ^ clock_scaler))
424 *
425 * Thus, the update rate can range from 0.25 Hz to 128 Hz.
426 *
427 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
428 */
429int pm8xxx_batt_alarm_pwm_rate_set(int use_pwm, int clock_scaler,
430 int clock_divider)
431{
432 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
433 int rc;
434 u8 reg_pwm_ctrl = 0, mask = 0;
435
436 if (!chip) {
437 pr_err("no battery alarm device found.\n");
438 return -ENXIO;
439 }
440
441 if (use_pwm && (clock_scaler < PWM_CTRL_PRE_INPUT_MIN
442 || clock_scaler > PWM_CTRL_PRE_INPUT_MAX)) {
443 pr_err("PWM clock scaler, %d, is outside of allowable range: "
444 "[%d, %d]\n", clock_scaler, PWM_CTRL_PRE_INPUT_MIN,
445 PWM_CTRL_PRE_INPUT_MAX);
446 return -EINVAL;
447 }
448
449 if (use_pwm && (clock_divider < PWM_CTRL_DIV_INPUT_MIN
450 || clock_divider > PWM_CTRL_DIV_INPUT_MAX)) {
451 pr_err("PWM clock divider, %d, is outside of allowable range: "
452 "[%d, %d]\n", clock_divider, PWM_CTRL_DIV_INPUT_MIN,
453 PWM_CTRL_DIV_INPUT_MAX);
454 return -EINVAL;
455 }
456
457 if (!use_pwm) {
458 /* Turn off PWM control and always enable. */
459 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_ALWAYS;
460 mask = PWM_CTRL_ALARM_EN_MASK;
461 } else {
462 /* Use PWM control. */
463 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_PWM;
464 mask = PWM_CTRL_ALARM_EN_MASK | PWM_CTRL_PRE_MASK
465 | PWM_CTRL_DIV_MASK;
466
467 clock_scaler -= PWM_CTRL_PRE_INPUT_MIN - PWM_CTRL_PRE_MIN;
468 clock_divider -= PWM_CTRL_DIV_INPUT_MIN - PWM_CTRL_DIV_MIN;
469
470 reg_pwm_ctrl |= (clock_scaler << PWM_CTRL_PRE_SHIFT)
471 & PWM_CTRL_PRE_MASK;
472 reg_pwm_ctrl |= (clock_divider << PWM_CTRL_DIV_SHIFT)
473 & PWM_CTRL_DIV_MASK;
474 }
475
476 mutex_lock(&chip->lock);
477 rc = pm8xxx_reg_write(chip, chip->cdata.reg_addr_pwm_ctrl, reg_pwm_ctrl,
478 mask, &chip->reg_pwm_ctrl);
479 mutex_unlock(&chip->lock);
480
481 return rc;
482}
483EXPORT_SYMBOL(pm8xxx_batt_alarm_pwm_rate_set);
484
485/*
486 * Handle the BATT_ALARM interrupt:
487 * Battery voltage is above or below threshold range.
488 */
489static irqreturn_t pm8xxx_batt_alarm_isr(int irq, void *data)
490{
491 struct pm8xxx_batt_alarm_chip *chip = data;
492
493 disable_irq_nosync(chip->irq);
494 schedule_work(&chip->irq_work);
495
496 return IRQ_HANDLED;
497}
498
499static void pm8xxx_batt_alarm_isr_work(struct work_struct *work)
500{
501 struct pm8xxx_batt_alarm_chip *chip
502 = container_of(work, struct pm8xxx_batt_alarm_chip, irq_work);
503 int status;
504
505 if (chip) {
506 status = pm8xxx_batt_alarm_status_read();
507
508 if (status < 0)
509 pr_err("failed to read status, rc=%d\n", status);
510 else
511 srcu_notifier_call_chain(&chip->irq_notifier_list,
512 status, NULL);
513 }
514
515 enable_irq(chip->irq);
516}
517
518/**
519 * pm8xxx_batt_alarm_register_notifier - register a notifier to run when a
520 * battery voltage change interrupt fires
521 * @nb: notifier block containing callback function to register
522 *
523 * nb->notifier_call must point to a function of this form -
524 * int (*notifier_call)(struct notifier_block *nb, unsigned long status,
525 * void *unused);
526 * "status" will receive the battery alarm status; "unused" will be NULL.
527 *
528 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
529 */
530int pm8xxx_batt_alarm_register_notifier(struct notifier_block *nb)
531{
532 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
533 int rc;
534
535 if (!chip) {
536 pr_err("no battery alarm device found.\n");
537 return -ENXIO;
538 }
539
540 rc = srcu_notifier_chain_register(&chip->irq_notifier_list, nb);
541 mutex_lock(&chip->lock);
542 if (rc == 0) {
543 if (chip->notifier_count == 0) {
544 enable_irq(chip->irq);
545 rc = irq_set_irq_wake(chip->irq, 1);
546 }
547
548 chip->notifier_count++;
549 }
550
551 mutex_unlock(&chip->lock);
552 return rc;
553}
554EXPORT_SYMBOL(pm8xxx_batt_alarm_register_notifier);
555
556/**
557 * pm8xxx_batt_alarm_unregister_notifier - unregister a notifier that is run
558 * when a battery voltage change interrupt fires
559 * @nb: notifier block containing callback function to unregister
560 *
561 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
562 */
563int pm8xxx_batt_alarm_unregister_notifier(struct notifier_block *nb)
564{
565 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
566 int rc;
567
568 if (!chip) {
569 pr_err("no battery alarm device found.\n");
570 return -ENXIO;
571 }
572
573 rc = srcu_notifier_chain_unregister(&chip->irq_notifier_list, nb);
574 if (rc == 0) {
575 mutex_lock(&chip->lock);
576
577 chip->notifier_count--;
578
579 if (chip->notifier_count == 0) {
580 rc = irq_set_irq_wake(chip->irq, 0);
581 disable_irq(chip->irq);
582 }
583
584 WARN_ON(chip->notifier_count < 0);
585
586 mutex_unlock(&chip->lock);
587 }
588
589 return rc;
590}
591EXPORT_SYMBOL(pm8xxx_batt_alarm_unregister_notifier);
592
593static int pm8xxx_batt_alarm_reg_init(struct pm8xxx_batt_alarm_chip *chip)
594{
595 int rc = 0;
596
597 /* save the current register states */
598 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_threshold,
599 &chip->reg_threshold);
600 if (rc)
601 goto bail;
602
603 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_ctrl1,
604 &chip->reg_ctrl1);
605 if (rc)
606 goto bail;
607
608 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_ctrl2,
609 &chip->reg_ctrl2);
610 if (rc)
611 goto bail;
612
613 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_pwm_ctrl,
614 &chip->reg_pwm_ctrl);
615 if (rc)
616 goto bail;
617
618bail:
619 if (rc)
620 pr_err("pm8xxx_readb failed; initial register states "
621 "unknown, rc=%d\n", rc);
622 return rc;
623}
624
625/* TODO: should this default setting function be removed? */
626static int pm8xxx_batt_alarm_config_defaults(void)
627{
628 int rc = 0;
629
630 /* Use default values when no platform data is provided. */
631 rc = pm8xxx_batt_alarm_threshold_set(PM8XXX_BATT_ALARM_LOWER_COMPARATOR,
632 DEFAULT_THRESHOLD_LOWER);
633 if (rc) {
634 pr_err("threshold_set failed, rc=%d\n", rc);
635 goto done;
636 }
637
638 rc = pm8xxx_batt_alarm_threshold_set(PM8XXX_BATT_ALARM_UPPER_COMPARATOR,
639 DEFAULT_THRESHOLD_UPPER);
640 if (rc) {
641 pr_err("threshold_set failed, rc=%d\n", rc);
642 goto done;
643 }
644
645 rc = pm8xxx_batt_alarm_hold_time_set(DEFAULT_HOLD_TIME);
646 if (rc) {
647 pr_err("hold_time_set failed, rc=%d\n", rc);
648 goto done;
649 }
650
651 rc = pm8xxx_batt_alarm_pwm_rate_set(DEFAULT_USE_PWM,
652 DEFAULT_PWM_SCALER, DEFAULT_PWM_DIVIDER);
653 if (rc) {
654 pr_err("pwm_rate_set failed, rc=%d\n", rc);
655 goto done;
656 }
657
658 rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
659 if (rc) {
660 pr_err("disable lower failed, rc=%d\n", rc);
661 goto done;
662 }
663
664 rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
665 if (rc) {
666 pr_err("disable upper failed, rc=%d\n", rc);
667 goto done;
668 }
669
670done:
671 return rc;
672}
673
674static int __devinit pm8xxx_batt_alarm_probe(struct platform_device *pdev)
675{
676 const struct pm8xxx_batt_alarm_core_data *cdata
677 = pdev->dev.platform_data;
678 struct pm8xxx_batt_alarm_chip *chip;
679 struct resource *res;
680 int rc;
681
682 if (the_battalarm) {
683 pr_err("A PMIC battery alarm device has already probed.\n");
684 return -ENODEV;
685 }
686
687 if (!cdata) {
688 pr_err("missing core data\n");
689 return -EINVAL;
690 }
691
692 if (!cdata->irq_name) {
693 pr_err("missing IRQ name\n");
694 return -EINVAL;
695 }
696
697 chip = kzalloc(sizeof(struct pm8xxx_batt_alarm_chip), GFP_KERNEL);
698 if (chip == NULL) {
699 pr_err("kzalloc() failed.\n");
700 return -ENOMEM;
701 }
702
703 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
704 cdata->irq_name);
705 if (res) {
706 chip->irq = res->start;
707 } else {
708 pr_err("Battery alarm IRQ not specified\n");
709 rc = -EINVAL;
710 goto err_free_chip;
711 }
712
713 chip->dev = &pdev->dev;
714 memcpy(&(chip->cdata), cdata,
715 sizeof(struct pm8xxx_batt_alarm_core_data));
716
717 srcu_init_notifier_head(&chip->irq_notifier_list);
718
719 chip->notifier_count = 0;
720 mutex_init(&chip->lock);
721
722 the_battalarm = chip;
723
724 rc = pm8xxx_batt_alarm_reg_init(chip);
725 if (rc)
726 goto err_free_mutex;
727
728 rc = pm8xxx_batt_alarm_config_defaults();
729 if (rc)
730 goto err_free_mutex;
731
732 INIT_WORK(&chip->irq_work, pm8xxx_batt_alarm_isr_work);
733
734/* TODO: Is it best to trigger on both edges? Should this be configurable? */
735 rc = request_irq(chip->irq, pm8xxx_batt_alarm_isr,
736 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, cdata->irq_name,
737 chip);
738 if (rc < 0) {
739 pr_err("request_irq(%d) failed, rc=%d\n", chip->irq, rc);
740 goto err_cancel_work;
741 }
742
743 /* Disable the IRQ until a notifier is registered. */
744 disable_irq(chip->irq);
745
746 platform_set_drvdata(pdev, chip);
747
748 return 0;
749
750err_cancel_work:
751 cancel_work_sync(&chip->irq_work);
752err_free_mutex:
753 mutex_destroy(&chip->lock);
754 srcu_cleanup_notifier_head(&chip->irq_notifier_list);
755err_free_chip:
756 kfree(chip);
757 the_battalarm = NULL;
758
759 return rc;
760}
761
762static int __devexit pm8xxx_batt_alarm_remove(struct platform_device *pdev)
763{
764 struct pm8xxx_batt_alarm_chip *chip = platform_get_drvdata(pdev);
765
766 if (chip) {
767 platform_set_drvdata(pdev, NULL);
768 irq_set_irq_wake(chip->irq, 0);
769 free_irq(chip->irq, chip);
770 cancel_work_sync(&chip->irq_work);
771 srcu_cleanup_notifier_head(&chip->irq_notifier_list);
772 mutex_destroy(&chip->lock);
773 kfree(chip);
774 the_battalarm = NULL;
775 }
776
777 return 0;
778}
779
780static struct platform_driver pm8xxx_batt_alarm_driver = {
781 .probe = pm8xxx_batt_alarm_probe,
782 .remove = __devexit_p(pm8xxx_batt_alarm_remove),
783 .driver = {
784 .name = PM8XXX_BATT_ALARM_DEV_NAME,
785 .owner = THIS_MODULE,
786 },
787};
788
789static int __init pm8xxx_batt_alarm_init(void)
790{
791 return platform_driver_register(&pm8xxx_batt_alarm_driver);
792}
793
794static void __exit pm8xxx_batt_alarm_exit(void)
795{
796 platform_driver_unregister(&pm8xxx_batt_alarm_driver);
797}
798
799module_init(pm8xxx_batt_alarm_init);
800module_exit(pm8xxx_batt_alarm_exit);
801
802MODULE_LICENSE("GPL v2");
803MODULE_DESCRIPTION("PMIC PM8xxx Battery Alarm");
804MODULE_VERSION("1.0");
805MODULE_ALIAS("platform:" PM8XXX_BATT_ALARM_DEV_NAME);