blob: bff0720d40de3b9b04faa814098a8ba091bf418a [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 8058 Battery Alarm Device 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/pmic8058-batt-alarm.h>
26#include <linux/mfd/pmic8058.h>
27
28/* PMIC 8058 Battery Alarm SSBI registers */
29#define REG_THRESHOLD 0x023
30#define REG_CTRL1 0x024
31#define REG_CTRL2 0x0AA
32#define REG_PWM_CTRL 0x0A3
33
34/* Available voltage threshold values */
35#define THRESHOLD_MIN_MV 2500
36#define THRESHOLD_MAX_MV 5675
37#define THRESHOLD_STEP_MV 25
38
39/* Register bit definitions */
40
41/* Threshold register */
42#define THRESHOLD_UPPER_MASK 0xF0
43#define THRESHOLD_LOWER_MASK 0x0F
44#define THRESHOLD_UPPER_SHIFT 4
45#define THRESHOLD_LOWER_SHIFT 0
46
47/* CTRL 1 register */
48#define CTRL1_BATT_ALARM_EN_MASK 0x80
49#define CTRL1_HOLD_TIME_MASK 0x70
50#define CTRL1_STATUS_UPPER_MASK 0x02
51#define CTRL1_STATUS_LOWER_MASK 0x01
52#define CTRL1_HOLD_TIME_SHIFT 4
53#define CTRL1_HOLD_TIME_MIN 0
54#define CTRL1_HOLD_TIME_MAX 7
55
56/* CTRL 2 register */
57#define CTRL2_COMP_UPPER_DISABLE_MASK 0x80
58#define CTRL2_COMP_LOWER_DISABLE_MASK 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 * pm8058_batt_alarm_state_set.
97 */
98#define DEFAULT_THRESHOLD_LOWER 3200
99#define DEFAULT_THRESHOLD_UPPER 4300
100#define DEFAULT_HOLD_TIME PM8058_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 pm8058_batt_alarm_device {
108 struct srcu_notifier_head irq_notifier_list;
109 struct pm8058_chip *pm_chip;
110 struct mutex batt_mutex;
111 unsigned int irq;
112 int notifier_count;
113 u8 reg_threshold;
114 u8 reg_ctrl1;
115 u8 reg_ctrl2;
116 u8 reg_pwm_ctrl;
117};
118static struct pm8058_batt_alarm_device *the_battalarm;
119
120static int pm8058_reg_write(struct pm8058_chip *chip, u16 addr, u8 val, u8 mask,
121 u8 *reg_save)
122{
123 int rc = 0;
124 u8 reg;
125
126 reg = (*reg_save & ~mask) | (val & mask);
127 if (reg != *reg_save)
128 rc = pm8058_write(chip, addr, &reg, 1);
129 if (rc)
130 pr_err("pm8058_write failed; addr=%03X, rc=%d\n", addr, rc);
131 else
132 *reg_save = reg;
133 return rc;
134}
135
136/**
137 * pm8058_batt_alarm_state_set - enable or disable the threshold comparators
138 * @enable_lower_comparator: 1 = enable comparator, 0 = disable comparator
139 * @enable_upper_comparator: 1 = enable comparator, 0 = disable comparator
140 *
141 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
142 */
143int pm8058_batt_alarm_state_set(int enable_lower_comparator,
144 int enable_upper_comparator)
145{
146 struct pm8058_batt_alarm_device *battdev = the_battalarm;
147 int rc;
148 u8 reg_ctrl1 = 0, reg_ctrl2 = 0;
149
150 if (!battdev) {
151 pr_err("no battery alarm device found.\n");
152 return -ENXIO;
153 }
154
155 if (!enable_lower_comparator)
156 reg_ctrl2 |= CTRL2_COMP_LOWER_DISABLE_MASK;
157 if (!enable_upper_comparator)
158 reg_ctrl2 |= CTRL2_COMP_UPPER_DISABLE_MASK;
159
160 if (enable_lower_comparator || enable_upper_comparator)
161 reg_ctrl1 = CTRL1_BATT_ALARM_EN_MASK;
162
163 mutex_lock(&battdev->batt_mutex);
164 rc = pm8058_reg_write(battdev->pm_chip, REG_CTRL1, reg_ctrl1,
165 CTRL1_BATT_ALARM_EN_MASK, &battdev->reg_ctrl1);
166 if (rc)
167 goto bail;
168
169 rc = pm8058_reg_write(battdev->pm_chip, REG_CTRL2, reg_ctrl2,
170 CTRL2_COMP_LOWER_DISABLE_MASK | CTRL2_COMP_UPPER_DISABLE_MASK,
171 &battdev->reg_ctrl2);
172
173bail:
174 mutex_unlock(&battdev->batt_mutex);
175 return rc;
176}
177EXPORT_SYMBOL_GPL(pm8058_batt_alarm_state_set);
178
179/**
180 * pm8058_batt_alarm_threshold_set - set the lower and upper alarm thresholds
181 * @lower_threshold_mV: battery undervoltage threshold in millivolts
182 * @upper_threshold_mV: battery overvoltage threshold in millivolts
183 *
184 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
185 */
186int pm8058_batt_alarm_threshold_set(int lower_threshold_mV,
187 int upper_threshold_mV)
188{
189 struct pm8058_batt_alarm_device *battdev = the_battalarm;
190 int step, fine_step, rc;
191 u8 reg_threshold = 0, reg_ctrl2 = 0;
192
193 if (!battdev) {
194 pr_err("no battery alarm device found.\n");
195 return -ENXIO;
196 }
197
198 if (lower_threshold_mV < THRESHOLD_MIN_MV
199 || lower_threshold_mV > THRESHOLD_MAX_MV) {
200 pr_err("lower threshold value, %d mV, is outside of allowable "
201 "range: [%d, %d] mV\n", lower_threshold_mV,
202 THRESHOLD_MIN_MV, THRESHOLD_MAX_MV);
203 return -EINVAL;
204 }
205
206 if (upper_threshold_mV < THRESHOLD_MIN_MV
207 || upper_threshold_mV > THRESHOLD_MAX_MV) {
208 pr_err("upper threshold value, %d mV, is outside of allowable "
209 "range: [%d, %d] mV\n", upper_threshold_mV,
210 THRESHOLD_MIN_MV, THRESHOLD_MAX_MV);
211 return -EINVAL;
212 }
213
214 if (upper_threshold_mV < lower_threshold_mV) {
215 pr_err("lower threshold value, %d mV, must be <= upper "
216 "threshold value, %d mV\n", lower_threshold_mV,
217 upper_threshold_mV);
218 return -EINVAL;
219 }
220
221 /* Determine register settings for lower threshold. */
222 if (lower_threshold_mV < THRESHOLD_BASIC_MIN_MV) {
223 /* Extended low range */
224 reg_ctrl2 |= CTRL2_RANGE_EXT_LOWER_MASK;
225
226 step = (lower_threshold_mV - THRESHOLD_MIN_MV)
227 / THRESHOLD_STEP_MV;
228
229 fine_step = step & 0x3;
230 /* Extended low range is for steps 0 to 2 */
231 step >>= 2;
232
233 reg_threshold |= (step << THRESHOLD_LOWER_SHIFT)
234 & THRESHOLD_LOWER_MASK;
235 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_LOWER_SHIFT)
236 & CTRL2_FINE_STEP_LOWER_MASK;
237 } else if (lower_threshold_mV >= THRESHOLD_EXT_MIN_MV) {
238 /* Extended high range */
239 reg_ctrl2 |= CTRL2_RANGE_EXT_LOWER_MASK;
240
241 step = (lower_threshold_mV - THRESHOLD_EXT_MIN_MV)
242 / THRESHOLD_STEP_MV;
243
244 fine_step = step & 0x3;
245 /* Extended high range is for steps 3 to 15 */
246 step = (step >> 2) + 3;
247
248 reg_threshold |= (step << THRESHOLD_LOWER_SHIFT)
249 & THRESHOLD_LOWER_MASK;
250 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_LOWER_SHIFT)
251 & CTRL2_FINE_STEP_LOWER_MASK;
252 } else {
253 /* Basic range */
254 step = (lower_threshold_mV - THRESHOLD_BASIC_MIN_MV)
255 / THRESHOLD_STEP_MV;
256
257 fine_step = step & 0x3;
258 step >>= 2;
259
260 reg_threshold |= (step << THRESHOLD_LOWER_SHIFT)
261 & THRESHOLD_LOWER_MASK;
262 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_LOWER_SHIFT)
263 & CTRL2_FINE_STEP_LOWER_MASK;
264 }
265
266 /* Determine register settings for upper threshold. */
267 if (upper_threshold_mV < THRESHOLD_BASIC_MIN_MV) {
268 /* Extended low range */
269 reg_ctrl2 |= CTRL2_RANGE_EXT_UPPER_MASK;
270
271 step = (upper_threshold_mV - THRESHOLD_MIN_MV)
272 / THRESHOLD_STEP_MV;
273
274 fine_step = step & 0x3;
275 /* Extended low range is for steps 0 to 2 */
276 step >>= 2;
277
278 reg_threshold |= (step << THRESHOLD_UPPER_SHIFT)
279 & THRESHOLD_UPPER_MASK;
280 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_UPPER_SHIFT)
281 & CTRL2_FINE_STEP_UPPER_MASK;
282 } else if (upper_threshold_mV >= THRESHOLD_EXT_MIN_MV) {
283 /* Extended high range */
284 reg_ctrl2 |= CTRL2_RANGE_EXT_UPPER_MASK;
285
286 step = (upper_threshold_mV - THRESHOLD_EXT_MIN_MV)
287 / THRESHOLD_STEP_MV;
288
289 fine_step = step & 0x3;
290 /* Extended high range is for steps 3 to 15 */
291 step = (step >> 2) + 3;
292
293 reg_threshold |= (step << THRESHOLD_UPPER_SHIFT)
294 & THRESHOLD_UPPER_MASK;
295 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_UPPER_SHIFT)
296 & CTRL2_FINE_STEP_UPPER_MASK;
297 } else {
298 /* Basic range */
299 step = (upper_threshold_mV - THRESHOLD_BASIC_MIN_MV)
300 / THRESHOLD_STEP_MV;
301
302 fine_step = step & 0x3;
303 step >>= 2;
304
305 reg_threshold |= (step << THRESHOLD_UPPER_SHIFT)
306 & THRESHOLD_UPPER_MASK;
307 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_UPPER_SHIFT)
308 & CTRL2_FINE_STEP_UPPER_MASK;
309 }
310
311 mutex_lock(&battdev->batt_mutex);
312 rc = pm8058_reg_write(battdev->pm_chip, REG_THRESHOLD, reg_threshold,
313 THRESHOLD_LOWER_MASK | THRESHOLD_UPPER_MASK,
314 &battdev->reg_threshold);
315 if (rc)
316 goto bail;
317
318 rc = pm8058_reg_write(battdev->pm_chip, REG_CTRL2, reg_ctrl2,
319 CTRL2_FINE_STEP_LOWER_MASK | CTRL2_FINE_STEP_UPPER_MASK
320 | CTRL2_RANGE_EXT_LOWER_MASK | CTRL2_RANGE_EXT_UPPER_MASK,
321 &battdev->reg_ctrl2);
322
323bail:
324 mutex_unlock(&battdev->batt_mutex);
325 return rc;
326}
327EXPORT_SYMBOL_GPL(pm8058_batt_alarm_threshold_set);
328
329/**
330 * pm8058_batt_alarm_status_read - get status of both threshold comparators
331 *
332 * RETURNS: < 0 = error
333 * 0 = battery voltage ok
334 * BIT(0) set = battery voltage below lower threshold
335 * BIT(1) set = battery voltage above upper threshold
336 */
337int pm8058_batt_alarm_status_read(void)
338{
339 struct pm8058_batt_alarm_device *battdev = the_battalarm;
340 int status, rc;
341
342 if (!battdev) {
343 pr_err("no battery alarm device found.\n");
344 return -ENXIO;
345 }
346
347 mutex_lock(&battdev->batt_mutex);
348 rc = pm8058_read(battdev->pm_chip, REG_CTRL1, &battdev->reg_ctrl1, 1);
349
350 status = ((battdev->reg_ctrl1 & CTRL1_STATUS_LOWER_MASK)
351 ? PM8058_BATT_ALARM_STATUS_BELOW_LOWER : 0)
352 | ((battdev->reg_ctrl1 & CTRL1_STATUS_UPPER_MASK)
353 ? PM8058_BATT_ALARM_STATUS_ABOVE_UPPER : 0);
354 mutex_unlock(&battdev->batt_mutex);
355
356 if (rc) {
357 pr_err("pm8058_read failed, rc=%d\n", rc);
358 return rc;
359 }
360
361 return status;
362}
363EXPORT_SYMBOL_GPL(pm8058_batt_alarm_status_read);
364
365/**
366 * pm8058_batt_alarm_hold_time_set - set hold time of interrupt output *
367 * @hold_time: amount of time that battery voltage must remain outside of the
368 * threshold range before the battery alarm interrupt triggers
369 *
370 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
371 */
372int pm8058_batt_alarm_hold_time_set(enum pm8058_batt_alarm_hold_time hold_time)
373{
374 struct pm8058_batt_alarm_device *battdev = the_battalarm;
375 int rc;
376 u8 reg_ctrl1 = 0;
377
378 if (!battdev) {
379 pr_err("no battery alarm device found.\n");
380 return -ENXIO;
381 }
382
383 if (hold_time < CTRL1_HOLD_TIME_MIN
384 || hold_time > CTRL1_HOLD_TIME_MAX) {
385
386 pr_err("hold time, %d, is outside of allowable range: "
387 "[%d, %d]\n", hold_time, CTRL1_HOLD_TIME_MIN,
388 CTRL1_HOLD_TIME_MAX);
389 return -EINVAL;
390 }
391
392 reg_ctrl1 = hold_time << CTRL1_HOLD_TIME_SHIFT;
393
394 mutex_lock(&battdev->batt_mutex);
395 rc = pm8058_reg_write(battdev->pm_chip, REG_CTRL1, reg_ctrl1,
396 CTRL1_HOLD_TIME_MASK, &battdev->reg_ctrl1);
397 mutex_unlock(&battdev->batt_mutex);
398
399 return rc;
400}
401EXPORT_SYMBOL_GPL(pm8058_batt_alarm_hold_time_set);
402
403/**
404 * pm8058_batt_alarm_pwm_rate_set - set battery alarm update rate *
405 * @use_pwm: 1 = use PWM update rate, 0 = comparators always active
406 * @clock_scaler: PWM clock scaler = 2 to 9
407 * @clock_divider: PWM clock divider = 2 to 8
408 *
409 * This function sets the rate at which the battery alarm module enables
410 * the threshold comparators. The rate is determined by the following equation:
411 *
412 * f_update = (1024 Hz) / (clock_divider * (2 ^ clock_scaler))
413 *
414 * Thus, the update rate can range from 0.25 Hz to 128 Hz.
415 *
416 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
417 */
418int pm8058_batt_alarm_pwm_rate_set(int use_pwm, int clock_scaler,
419 int clock_divider)
420{
421 struct pm8058_batt_alarm_device *battdev = the_battalarm;
422 int rc;
423 u8 reg_pwm_ctrl = 0, mask = 0;
424
425 if (!battdev) {
426 pr_err("no battery alarm device found.\n");
427 return -ENXIO;
428 }
429
430 if (use_pwm && (clock_scaler < PWM_CTRL_PRE_INPUT_MIN
431 || clock_scaler > PWM_CTRL_PRE_INPUT_MAX)) {
432 pr_err("PWM clock scaler, %d, is outside of allowable range: "
433 "[%d, %d]\n", clock_scaler, PWM_CTRL_PRE_INPUT_MIN,
434 PWM_CTRL_PRE_INPUT_MAX);
435 return -EINVAL;
436 }
437
438 if (use_pwm && (clock_divider < PWM_CTRL_DIV_INPUT_MIN
439 || clock_divider > PWM_CTRL_DIV_INPUT_MAX)) {
440 pr_err("PWM clock divider, %d, is outside of allowable range: "
441 "[%d, %d]\n", clock_divider, PWM_CTRL_DIV_INPUT_MIN,
442 PWM_CTRL_DIV_INPUT_MAX);
443 return -EINVAL;
444 }
445
446 if (!use_pwm) {
447 /* Turn off PWM control and always enable. */
448 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_ALWAYS;
449 mask = PWM_CTRL_ALARM_EN_MASK;
450 } else {
451 /* Use PWM control. */
452 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_PWM;
453 mask = PWM_CTRL_ALARM_EN_MASK | PWM_CTRL_PRE_MASK
454 | PWM_CTRL_DIV_MASK;
455
456 clock_scaler -= PWM_CTRL_PRE_INPUT_MIN - PWM_CTRL_PRE_MIN;
457 clock_divider -= PWM_CTRL_DIV_INPUT_MIN - PWM_CTRL_DIV_MIN;
458
459 reg_pwm_ctrl |= (clock_scaler << PWM_CTRL_PRE_SHIFT)
460 & PWM_CTRL_PRE_MASK;
461 reg_pwm_ctrl |= (clock_divider << PWM_CTRL_DIV_SHIFT)
462 & PWM_CTRL_DIV_MASK;
463 }
464
465 mutex_lock(&battdev->batt_mutex);
466 rc = pm8058_reg_write(battdev->pm_chip, REG_PWM_CTRL, reg_pwm_ctrl,
467 mask, &battdev->reg_pwm_ctrl);
468 mutex_unlock(&battdev->batt_mutex);
469
470 return rc;
471}
472EXPORT_SYMBOL_GPL(pm8058_batt_alarm_pwm_rate_set);
473
474/*
475 * Handle the BATT_ALARM interrupt:
476 * Battery voltage is above or below threshold range.
477 */
478static irqreturn_t pm8058_batt_alarm_isr(int irq, void *data)
479{
480 struct pm8058_batt_alarm_device *battdev = data;
481 int status;
482
483 if (battdev) {
484 status = pm8058_batt_alarm_status_read();
485
486 if (status < 0)
487 pr_err("failed to read status, rc=%d\n", status);
488 else
489 srcu_notifier_call_chain(&battdev->irq_notifier_list,
490 status, NULL);
491 }
492
493 return IRQ_HANDLED;
494}
495
496/**
497 * pm8058_batt_alarm_register_notifier - register a notifier to run when a
498 * battery voltage change interrupt fires
499 * @nb: notifier block containing callback function to register
500 *
501 * nb->notifier_call must point to a function of this form -
502 * int (*notifier_call)(struct notifier_block *nb, unsigned long status,
503 * void *unused);
504 * "status" will receive the battery alarm status; "unused" will be NULL.
505 *
506 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
507 */
508int pm8058_batt_alarm_register_notifier(struct notifier_block *nb)
509{
510 int rc;
511
512 if (!the_battalarm) {
513 pr_err("no battery alarm device found.\n");
514 return -ENXIO;
515 }
516
517 rc = srcu_notifier_chain_register(&the_battalarm->irq_notifier_list,
518 nb);
519 mutex_lock(&the_battalarm->batt_mutex);
520 if (rc == 0) {
521 if (the_battalarm->notifier_count == 0) {
522 /* request the irq */
523 rc = request_threaded_irq(the_battalarm->irq, NULL,
524 pm8058_batt_alarm_isr,
525 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
526 "pm8058-batt_alarm-irq", the_battalarm);
527 if (rc < 0) {
528 pr_err("request_irq(%d) failed, rc=%d\n",
529 the_battalarm->irq, rc);
530 goto done;
531 }
532
533 rc = irq_set_irq_wake(the_battalarm->irq, 1);
534 if (rc < 0) {
535 pr_err("irq_set_irq_wake(%d,1) failed, rc=%d\n",
536 the_battalarm->irq, rc);
537 goto done;
538 }
539 }
540
541 the_battalarm->notifier_count++;
542 }
543done:
544 mutex_unlock(&the_battalarm->batt_mutex);
545 return rc;
546}
547EXPORT_SYMBOL_GPL(pm8058_batt_alarm_register_notifier);
548
549/**
550 * pm8058_batt_alarm_unregister_notifier - unregister a notifier that is run
551 * when a battery voltage change interrupt fires
552 * @nb: notifier block containing callback function to unregister
553 *
554 * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
555 */
556int pm8058_batt_alarm_unregister_notifier(struct notifier_block *nb)
557{
558 int rc;
559
560 if (!the_battalarm) {
561 pr_err("no battery alarm device found.\n");
562 return -ENXIO;
563 }
564
565 rc = srcu_notifier_chain_unregister(&the_battalarm->irq_notifier_list,
566 nb);
567 if (rc == 0) {
568 mutex_lock(&the_battalarm->batt_mutex);
569
570 the_battalarm->notifier_count--;
571
572 if (the_battalarm->notifier_count == 0)
573 free_irq(the_battalarm->irq, the_battalarm);
574
575 WARN_ON(the_battalarm->notifier_count < 0);
576
577 mutex_unlock(&the_battalarm->batt_mutex);
578 }
579
580
581
582 return rc;
583}
584EXPORT_SYMBOL_GPL(pm8058_batt_alarm_unregister_notifier);
585
586static int pm8058_batt_alarm_reg_init(struct pm8058_batt_alarm_device *battdev)
587{
588 int rc = 0;
589
590 /* save the current register states */
591 rc = pm8058_read(battdev->pm_chip, REG_THRESHOLD,
592 &battdev->reg_threshold, 1);
593 if (rc)
594 goto bail;
595
596 rc = pm8058_read(battdev->pm_chip, REG_CTRL1,
597 &battdev->reg_ctrl1, 1);
598 if (rc)
599 goto bail;
600
601 rc = pm8058_read(battdev->pm_chip, REG_CTRL2,
602 &battdev->reg_ctrl2, 1);
603 if (rc)
604 goto bail;
605
606 rc = pm8058_read(battdev->pm_chip, REG_PWM_CTRL,
607 &battdev->reg_pwm_ctrl, 1);
608 if (rc)
609 goto bail;
610
611bail:
612 if (rc)
613 pr_err("pm8058_read failed; initial register states "
614 "unknown, rc=%d\n", rc);
615 return rc;
616}
617
618static int pm8058_batt_alarm_config(void)
619{
620 int rc = 0;
621
622 /* Use default values when no platform data is provided. */
623 rc = pm8058_batt_alarm_threshold_set(DEFAULT_THRESHOLD_LOWER,
624 DEFAULT_THRESHOLD_UPPER);
625 if (rc) {
626 pr_err("threshold_set failed, rc=%d\n", rc);
627 goto done;
628 }
629
630 rc = pm8058_batt_alarm_hold_time_set(DEFAULT_HOLD_TIME);
631 if (rc) {
632 pr_err("hold_time_set failed, rc=%d\n", rc);
633 goto done;
634 }
635
636 rc = pm8058_batt_alarm_pwm_rate_set(DEFAULT_USE_PWM,
637 DEFAULT_PWM_SCALER, DEFAULT_PWM_DIVIDER);
638 if (rc) {
639 pr_err("pwm_rate_set failed, rc=%d\n", rc);
640 goto done;
641 }
642
643 rc = pm8058_batt_alarm_state_set(DEFAULT_LOWER_ENABLE,
644 DEFAULT_UPPER_ENABLE);
645 if (rc) {
646 pr_err("state_set failed, rc=%d\n", rc);
647 goto done;
648 }
649
650done:
651 return rc;
652}
653
654static int __devinit pm8058_batt_alarm_probe(struct platform_device *pdev)
655{
656 struct pm8058_batt_alarm_device *battdev;
657 struct pm8058_chip *pm_chip;
658 unsigned int irq;
659 int rc;
660
661 pm_chip = dev_get_drvdata(pdev->dev.parent);
662 if (pm_chip == NULL) {
663 pr_err("no driver data passed in.\n");
664 rc = -EFAULT;
665 goto exit_input;
666 }
667
668 irq = platform_get_irq(pdev, 0);
669 if (!irq) {
670 pr_err("no IRQ passed in.\n");
671 rc = -EFAULT;
672 goto exit_input;
673 }
674
675 battdev = kzalloc(sizeof *battdev, GFP_KERNEL);
676 if (battdev == NULL) {
677 pr_err("kzalloc() failed.\n");
678 rc = -ENOMEM;
679 goto exit_input;
680 }
681
682 battdev->pm_chip = pm_chip;
683 platform_set_drvdata(pdev, battdev);
684
685 srcu_init_notifier_head(&battdev->irq_notifier_list);
686
687 battdev->irq = irq;
688 battdev->notifier_count = 0;
689 mutex_init(&battdev->batt_mutex);
690
691 rc = pm8058_batt_alarm_reg_init(battdev);
692 if (rc)
693 goto exit_free_dev;
694
695 the_battalarm = battdev;
696
697 rc = pm8058_batt_alarm_config();
698 if (rc)
699 goto exit_free_dev;
700
701 pr_notice("OK\n");
702 return 0;
703
704exit_free_dev:
705 mutex_destroy(&battdev->batt_mutex);
706 srcu_cleanup_notifier_head(&battdev->irq_notifier_list);
707 platform_set_drvdata(pdev, battdev->pm_chip);
708 kfree(battdev);
709exit_input:
710 return rc;
711}
712
713static int __devexit pm8058_batt_alarm_remove(struct platform_device *pdev)
714{
715 struct pm8058_batt_alarm_device *battdev = platform_get_drvdata(pdev);
716
717 mutex_destroy(&battdev->batt_mutex);
718 srcu_cleanup_notifier_head(&battdev->irq_notifier_list);
719 platform_set_drvdata(pdev, battdev->pm_chip);
720 free_irq(battdev->irq, battdev);
721 kfree(battdev);
722
723 the_battalarm = NULL;
724
725 return 0;
726}
727
728static struct platform_driver pm8058_batt_alarm_driver = {
729 .probe = pm8058_batt_alarm_probe,
730 .remove = __devexit_p(pm8058_batt_alarm_remove),
731 .driver = {
732 .name = "pm8058-batt-alarm",
733 .owner = THIS_MODULE,
734 },
735};
736
737static int __init pm8058_batt_alarm_init(void)
738{
739 return platform_driver_register(&pm8058_batt_alarm_driver);
740}
741
742static void __exit pm8058_batt_alarm_exit(void)
743{
744 platform_driver_unregister(&pm8058_batt_alarm_driver);
745}
746
747module_init(pm8058_batt_alarm_init);
748module_exit(pm8058_batt_alarm_exit);
749
750MODULE_LICENSE("GPL v2");
751MODULE_DESCRIPTION("PMIC8058 Battery Alarm Device driver");
752MODULE_VERSION("1.0");
753MODULE_ALIAS("platform:pm8058-batt-alarm");