blob: 88aab98e8b695c06c37795a97ae8b93d6a874c5d [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
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
Jay Chokshi14df5ce2011-10-27 15:48:33 -0700505 if (!chip)
506 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700507
Jay Chokshi14df5ce2011-10-27 15:48:33 -0700508 status = pm8xxx_batt_alarm_status_read();
509
510 if (status < 0)
511 pr_err("failed to read status, rc=%d\n", status);
512 else
513 srcu_notifier_call_chain(&chip->irq_notifier_list,
514 status, NULL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700515
516 enable_irq(chip->irq);
517}
518
519/**
520 * pm8xxx_batt_alarm_register_notifier - register a notifier to run when a
521 * battery voltage change interrupt fires
522 * @nb: notifier block containing callback function to register
523 *
524 * nb->notifier_call must point to a function of this form -
525 * int (*notifier_call)(struct notifier_block *nb, unsigned long status,
526 * void *unused);
527 * "status" will receive the battery alarm status; "unused" will be NULL.
528 *
529 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
530 */
531int pm8xxx_batt_alarm_register_notifier(struct notifier_block *nb)
532{
533 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
534 int rc;
535
536 if (!chip) {
537 pr_err("no battery alarm device found.\n");
538 return -ENXIO;
539 }
540
541 rc = srcu_notifier_chain_register(&chip->irq_notifier_list, nb);
542 mutex_lock(&chip->lock);
543 if (rc == 0) {
544 if (chip->notifier_count == 0) {
545 enable_irq(chip->irq);
546 rc = irq_set_irq_wake(chip->irq, 1);
547 }
548
549 chip->notifier_count++;
550 }
551
552 mutex_unlock(&chip->lock);
553 return rc;
554}
555EXPORT_SYMBOL(pm8xxx_batt_alarm_register_notifier);
556
557/**
558 * pm8xxx_batt_alarm_unregister_notifier - unregister a notifier that is run
559 * when a battery voltage change interrupt fires
560 * @nb: notifier block containing callback function to unregister
561 *
562 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
563 */
564int pm8xxx_batt_alarm_unregister_notifier(struct notifier_block *nb)
565{
566 struct pm8xxx_batt_alarm_chip *chip = the_battalarm;
567 int rc;
568
569 if (!chip) {
570 pr_err("no battery alarm device found.\n");
571 return -ENXIO;
572 }
573
574 rc = srcu_notifier_chain_unregister(&chip->irq_notifier_list, nb);
575 if (rc == 0) {
576 mutex_lock(&chip->lock);
577
578 chip->notifier_count--;
579
580 if (chip->notifier_count == 0) {
581 rc = irq_set_irq_wake(chip->irq, 0);
582 disable_irq(chip->irq);
583 }
584
585 WARN_ON(chip->notifier_count < 0);
586
587 mutex_unlock(&chip->lock);
588 }
589
590 return rc;
591}
592EXPORT_SYMBOL(pm8xxx_batt_alarm_unregister_notifier);
593
594static int pm8xxx_batt_alarm_reg_init(struct pm8xxx_batt_alarm_chip *chip)
595{
596 int rc = 0;
597
598 /* save the current register states */
599 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_threshold,
600 &chip->reg_threshold);
601 if (rc)
602 goto bail;
603
604 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_ctrl1,
605 &chip->reg_ctrl1);
606 if (rc)
607 goto bail;
608
609 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_ctrl2,
610 &chip->reg_ctrl2);
611 if (rc)
612 goto bail;
613
614 rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_pwm_ctrl,
615 &chip->reg_pwm_ctrl);
616 if (rc)
617 goto bail;
618
619bail:
620 if (rc)
621 pr_err("pm8xxx_readb failed; initial register states "
622 "unknown, rc=%d\n", rc);
623 return rc;
624}
625
626/* TODO: should this default setting function be removed? */
627static int pm8xxx_batt_alarm_config_defaults(void)
628{
629 int rc = 0;
630
631 /* Use default values when no platform data is provided. */
632 rc = pm8xxx_batt_alarm_threshold_set(PM8XXX_BATT_ALARM_LOWER_COMPARATOR,
633 DEFAULT_THRESHOLD_LOWER);
634 if (rc) {
635 pr_err("threshold_set failed, rc=%d\n", rc);
636 goto done;
637 }
638
639 rc = pm8xxx_batt_alarm_threshold_set(PM8XXX_BATT_ALARM_UPPER_COMPARATOR,
640 DEFAULT_THRESHOLD_UPPER);
641 if (rc) {
642 pr_err("threshold_set failed, rc=%d\n", rc);
643 goto done;
644 }
645
646 rc = pm8xxx_batt_alarm_hold_time_set(DEFAULT_HOLD_TIME);
647 if (rc) {
648 pr_err("hold_time_set failed, rc=%d\n", rc);
649 goto done;
650 }
651
652 rc = pm8xxx_batt_alarm_pwm_rate_set(DEFAULT_USE_PWM,
653 DEFAULT_PWM_SCALER, DEFAULT_PWM_DIVIDER);
654 if (rc) {
655 pr_err("pwm_rate_set failed, rc=%d\n", rc);
656 goto done;
657 }
658
659 rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
660 if (rc) {
661 pr_err("disable lower failed, rc=%d\n", rc);
662 goto done;
663 }
664
665 rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
666 if (rc) {
667 pr_err("disable upper failed, rc=%d\n", rc);
668 goto done;
669 }
670
671done:
672 return rc;
673}
674
675static int __devinit pm8xxx_batt_alarm_probe(struct platform_device *pdev)
676{
677 const struct pm8xxx_batt_alarm_core_data *cdata
678 = pdev->dev.platform_data;
679 struct pm8xxx_batt_alarm_chip *chip;
680 struct resource *res;
681 int rc;
682
683 if (the_battalarm) {
684 pr_err("A PMIC battery alarm device has already probed.\n");
685 return -ENODEV;
686 }
687
688 if (!cdata) {
689 pr_err("missing core data\n");
690 return -EINVAL;
691 }
692
693 if (!cdata->irq_name) {
694 pr_err("missing IRQ name\n");
695 return -EINVAL;
696 }
697
698 chip = kzalloc(sizeof(struct pm8xxx_batt_alarm_chip), GFP_KERNEL);
699 if (chip == NULL) {
700 pr_err("kzalloc() failed.\n");
701 return -ENOMEM;
702 }
703
704 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
705 cdata->irq_name);
706 if (res) {
707 chip->irq = res->start;
708 } else {
709 pr_err("Battery alarm IRQ not specified\n");
710 rc = -EINVAL;
711 goto err_free_chip;
712 }
713
714 chip->dev = &pdev->dev;
715 memcpy(&(chip->cdata), cdata,
716 sizeof(struct pm8xxx_batt_alarm_core_data));
717
718 srcu_init_notifier_head(&chip->irq_notifier_list);
719
720 chip->notifier_count = 0;
721 mutex_init(&chip->lock);
722
723 the_battalarm = chip;
724
725 rc = pm8xxx_batt_alarm_reg_init(chip);
726 if (rc)
727 goto err_free_mutex;
728
729 rc = pm8xxx_batt_alarm_config_defaults();
730 if (rc)
731 goto err_free_mutex;
732
733 INIT_WORK(&chip->irq_work, pm8xxx_batt_alarm_isr_work);
734
735/* TODO: Is it best to trigger on both edges? Should this be configurable? */
736 rc = request_irq(chip->irq, pm8xxx_batt_alarm_isr,
737 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, cdata->irq_name,
738 chip);
739 if (rc < 0) {
740 pr_err("request_irq(%d) failed, rc=%d\n", chip->irq, rc);
741 goto err_cancel_work;
742 }
743
744 /* Disable the IRQ until a notifier is registered. */
745 disable_irq(chip->irq);
746
747 platform_set_drvdata(pdev, chip);
748
749 return 0;
750
751err_cancel_work:
752 cancel_work_sync(&chip->irq_work);
753err_free_mutex:
754 mutex_destroy(&chip->lock);
755 srcu_cleanup_notifier_head(&chip->irq_notifier_list);
756err_free_chip:
757 kfree(chip);
758 the_battalarm = NULL;
759
760 return rc;
761}
762
763static int __devexit pm8xxx_batt_alarm_remove(struct platform_device *pdev)
764{
765 struct pm8xxx_batt_alarm_chip *chip = platform_get_drvdata(pdev);
766
767 if (chip) {
768 platform_set_drvdata(pdev, NULL);
769 irq_set_irq_wake(chip->irq, 0);
770 free_irq(chip->irq, chip);
771 cancel_work_sync(&chip->irq_work);
772 srcu_cleanup_notifier_head(&chip->irq_notifier_list);
773 mutex_destroy(&chip->lock);
774 kfree(chip);
775 the_battalarm = NULL;
776 }
777
778 return 0;
779}
780
781static struct platform_driver pm8xxx_batt_alarm_driver = {
782 .probe = pm8xxx_batt_alarm_probe,
783 .remove = __devexit_p(pm8xxx_batt_alarm_remove),
784 .driver = {
785 .name = PM8XXX_BATT_ALARM_DEV_NAME,
786 .owner = THIS_MODULE,
787 },
788};
789
790static int __init pm8xxx_batt_alarm_init(void)
791{
792 return platform_driver_register(&pm8xxx_batt_alarm_driver);
793}
794
795static void __exit pm8xxx_batt_alarm_exit(void)
796{
797 platform_driver_unregister(&pm8xxx_batt_alarm_driver);
798}
799
800module_init(pm8xxx_batt_alarm_init);
801module_exit(pm8xxx_batt_alarm_exit);
802
803MODULE_LICENSE("GPL v2");
804MODULE_DESCRIPTION("PMIC PM8xxx Battery Alarm");
805MODULE_VERSION("1.0");
806MODULE_ALIAS("platform:" PM8XXX_BATT_ALARM_DEV_NAME);