blob: 13f0accfca4471f0a8225f9df76a249461c3d5d3 [file] [log] [blame]
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -07001/*
Duy Truongf3ac7b32013-02-13 01:07:28 -08002 * * Copyright (c) 2011, The Linux Foundation. All rights reserved.
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -07003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
Duy Truongf3ac7b32013-02-13 01:07:28 -080013 * * Neither the name of The Linux Foundation nor the names of its
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070014 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <debug.h>
31#include <platform/pmic_batt_alarm.h>
32
33static struct pm_batt_alarm_device battdev;
34
35/*
36 * Function to set threshold voltages for battery alarm
37 */
38
39static int pm_batt_alarm_threshold_set(uint32_t lower_threshold_mV,
Ajay Dudanib01e5062011-12-03 23:23:42 -080040 uint32_t upper_threshold_mV)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070041{
42 uint32_t step, fine_step, rc = -1;
43 uint8_t reg_threshold = 0, reg_ctrl2 = 0;
44
45 if (lower_threshold_mV < THRESHOLD_MIN_MV
46 || lower_threshold_mV > THRESHOLD_MAX_MV) {
Ajay Dudanib01e5062011-12-03 23:23:42 -080047 dprintf(CRITICAL,
48 "lower threshold value, %d mV, is outside of allowable "
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070049 "range: [%d, %d] mV\n", lower_threshold_mV,
50 THRESHOLD_MIN_MV, THRESHOLD_MAX_MV);
51 goto bail;
52 }
53
54 if (upper_threshold_mV < THRESHOLD_MIN_MV
55 || upper_threshold_mV > THRESHOLD_MAX_MV) {
Ajay Dudanib01e5062011-12-03 23:23:42 -080056 dprintf(CRITICAL,
57 "upper threshold value, %d mV, is outside of allowable "
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070058 "range: [%d, %d] mV\n", upper_threshold_mV,
59 THRESHOLD_MIN_MV, THRESHOLD_MAX_MV);
60 goto bail;
61 }
62
63 if (upper_threshold_mV < lower_threshold_mV) {
Ajay Dudanib01e5062011-12-03 23:23:42 -080064 dprintf(CRITICAL,
65 "lower threshold value, %d mV, must be <= upper "
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070066 "threshold value, %d mV\n", lower_threshold_mV,
67 upper_threshold_mV);
68 goto bail;
69 }
70
71 /* Determine register settings for lower threshold. */
72 if (lower_threshold_mV < THRESHOLD_BASIC_MIN_MV) {
73 /* Extended low range */
74 reg_ctrl2 |= CTRL2_RANGE_EXT_LOWER_MASK;
75
76 step = (lower_threshold_mV - THRESHOLD_MIN_MV)
Ajay Dudanib01e5062011-12-03 23:23:42 -080077 / THRESHOLD_STEP_MV;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070078
79 fine_step = step & 0x3;
80 /* Extended low range is for steps 0 to 2 */
81 step >>= 2;
82
83 } else if (lower_threshold_mV >= THRESHOLD_EXT_MIN_MV) {
84 /* Extended high range */
85 reg_ctrl2 |= CTRL2_RANGE_EXT_LOWER_MASK;
86
87 step = (lower_threshold_mV - THRESHOLD_EXT_MIN_MV)
Ajay Dudanib01e5062011-12-03 23:23:42 -080088 / THRESHOLD_STEP_MV;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070089
90 fine_step = step & 0x3;
91 /* Extended high range is for steps 3 to 15 */
92 step = (step >> 2) + 3;
93
94 } else {
95 /* Basic range */
96 step = (lower_threshold_mV - THRESHOLD_BASIC_MIN_MV)
Ajay Dudanib01e5062011-12-03 23:23:42 -080097 / THRESHOLD_STEP_MV;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -070098
99 fine_step = step & 0x3;
100 step >>= 2;
101
102 }
103
104 reg_threshold |= (step << THRESHOLD_LOWER_SHIFT);
105 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_LOWER_SHIFT);
106
107 /* Determine register settings for upper threshold. */
108 if (upper_threshold_mV < THRESHOLD_BASIC_MIN_MV) {
109 /* Extended low range */
110 reg_ctrl2 |= CTRL2_RANGE_EXT_UPPER_MASK;
111
112 step = (upper_threshold_mV - THRESHOLD_MIN_MV)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800113 / THRESHOLD_STEP_MV;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700114
115 fine_step = step & 0x3;
116 /* Extended low range is for steps 0 to 2 */
117 step >>= 2;
118
119 } else if (upper_threshold_mV >= THRESHOLD_EXT_MIN_MV) {
120 /* Extended high range */
121 reg_ctrl2 |= CTRL2_RANGE_EXT_UPPER_MASK;
122
123 step = (upper_threshold_mV - THRESHOLD_EXT_MIN_MV)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800124 / THRESHOLD_STEP_MV;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700125
126 fine_step = step & 0x3;
127 /* Extended high range is for steps 3 to 15 */
128 step = (step >> 2) + 3;
129
130 } else {
131 /* Basic range */
132 step = (upper_threshold_mV - THRESHOLD_BASIC_MIN_MV)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800133 / THRESHOLD_STEP_MV;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700134
135 fine_step = step & 0x3;
136 step >>= 2;
137
138 }
139
140 reg_threshold |= (step << THRESHOLD_UPPER_SHIFT);
141 reg_ctrl2 |= (fine_step << CTRL2_FINE_STEP_UPPER_SHIFT);
142
143 rc = pm8058_mwrite(PM8058_REG_THRESHOLD, reg_threshold,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800144 THRESHOLD_LOWER_MASK | THRESHOLD_UPPER_MASK,
145 &battdev.reg_threshold);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700146 if (rc) {
147 dprintf(CRITICAL, "Error in pm8058_mwrite THRESHOLD\n");
148 goto bail;
149 }
150
151 rc = pm8058_mwrite(PM8058_REG_CTRL2, reg_ctrl2,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800152 CTRL2_FINE_STEP_LOWER_MASK |
153 CTRL2_FINE_STEP_UPPER_MASK |
154 CTRL2_RANGE_EXT_LOWER_MASK |
155 CTRL2_RANGE_EXT_UPPER_MASK, &battdev.reg_ctrl2);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700156
157 if (rc)
158 dprintf(CRITICAL, "Error in pm8058_mwrite CTRL2\n");
159
Ajay Dudanib01e5062011-12-03 23:23:42 -0800160 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700161 return rc;
162}
163
164/*
165 * Function to set hold time (hysteresis) for battery alarm
166 */
167
168static int pm_batt_alarm_hold_time_set(pm_batt_alarm_hold_time hold_time)
169{
170 int rc = -1;
171 uint8_t reg_ctrl1 = 0;
172
Ajay Dudanib01e5062011-12-03 23:23:42 -0800173 if (hold_time < CTRL1_HOLD_TIME_MIN || hold_time > CTRL1_HOLD_TIME_MAX) {
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700174
Ajay Dudanib01e5062011-12-03 23:23:42 -0800175 dprintf(CRITICAL,
176 "hold time, %d, is outside of allowable range: "
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700177 "[%d, %d]\n", hold_time, CTRL1_HOLD_TIME_MIN,
178 CTRL1_HOLD_TIME_MAX);
179 goto bail;
180 }
181
182 reg_ctrl1 = hold_time << CTRL1_HOLD_TIME_SHIFT;
183
184 rc = pm8058_mwrite(PM8058_REG_CTRL1, reg_ctrl1,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800185 CTRL1_HOLD_TIME_MASK, &battdev.reg_ctrl1);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700186
Ajay Dudanib01e5062011-12-03 23:23:42 -0800187 if (rc)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700188 dprintf(CRITICAL, "Error in pm8058_mwrite CTRL1\n");
189
Ajay Dudanib01e5062011-12-03 23:23:42 -0800190 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700191 return rc;
192}
193
194/*
195 * Function to set PWM clock rate for battery alarm
196 */
197
198static int pm_batt_alarm_pwm_rate_set(pm_batt_alarm_pwm_ctrl pwm_ctrl_select,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800199 uint32_t clock_scaler,
200 uint32_t clock_divider)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700201{
202 int rc = -1;
203 uint8_t reg_pwm_ctrl = 0, mask = 0;
204
Ajay Dudanib01e5062011-12-03 23:23:42 -0800205 if (pwm_ctrl_select == ALARM_EN_PWM) {
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700206 if (clock_scaler < PWM_CTRL_PRE_INPUT_MIN
Ajay Dudanib01e5062011-12-03 23:23:42 -0800207 || clock_scaler > PWM_CTRL_PRE_INPUT_MAX) {
208 dprintf(CRITICAL,
209 "PWM clock scaler, %d, is outside of allowable range: "
210 "[%d, %d]\n", clock_scaler,
211 PWM_CTRL_PRE_INPUT_MIN, PWM_CTRL_PRE_INPUT_MAX);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700212 goto bail;
213 }
214
215 if (clock_divider < PWM_CTRL_DIV_INPUT_MIN
Ajay Dudanib01e5062011-12-03 23:23:42 -0800216 || clock_divider > PWM_CTRL_DIV_INPUT_MAX) {
217 dprintf(CRITICAL,
218 "PWM clock divider, %d, is outside of allowable range: "
219 "[%d, %d]\n", clock_divider,
220 PWM_CTRL_DIV_INPUT_MIN, PWM_CTRL_DIV_INPUT_MAX);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700221 goto bail;
222 }
223
224 /* Use PWM control. */
225 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_PWM;
226 mask = PWM_CTRL_ALARM_EN_MASK | PWM_CTRL_PRE_MASK
Ajay Dudanib01e5062011-12-03 23:23:42 -0800227 | PWM_CTRL_DIV_MASK;
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700228
229 clock_scaler -= PWM_CTRL_PRE_INPUT_MIN - PWM_CTRL_PRE_MIN;
230 clock_divider -= PWM_CTRL_DIV_INPUT_MIN - PWM_CTRL_DIV_MIN;
231
232 reg_pwm_ctrl |= (clock_scaler << PWM_CTRL_PRE_SHIFT);
233 reg_pwm_ctrl |= (clock_divider << PWM_CTRL_DIV_SHIFT);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800234 } else {
235 if (pwm_ctrl_select == ALARM_EN_ALWAYS) {
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700236 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_ALWAYS;
237 } else if (pwm_ctrl_select == ALARM_EN_NEVER) {
238 reg_pwm_ctrl = PWM_CTRL_ALARM_EN_NEVER;
239 }
240
241 mask = PWM_CTRL_ALARM_EN_MASK;
242 }
243
244 rc = pm8058_mwrite(PM8058_REG_PWM_CTRL, reg_pwm_ctrl,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800245 mask, &battdev.reg_pwm_ctrl);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700246
Ajay Dudanib01e5062011-12-03 23:23:42 -0800247 if (rc)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700248 dprintf(CRITICAL, "Error in pm8058_mwrite PWM_CTRL\n");
249
Ajay Dudanib01e5062011-12-03 23:23:42 -0800250 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700251 return rc;
252}
253
254/*
255 * Function to enable/disable alarm comparators for battery alarm
256 */
257
258static int pm_batt_alarm_state_set(uint8_t enable_lower_comparator,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800259 uint8_t enable_upper_comparator)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700260{
261 int rc = -1;
262 uint8_t reg_ctrl1 = 0, reg_ctrl2 = 0;
263
264 if (!enable_lower_comparator)
265 reg_ctrl2 |= CTRL2_COMP_LOWER_DISABLE_MASK;
266 if (!enable_upper_comparator)
267 reg_ctrl2 |= CTRL2_COMP_UPPER_DISABLE_MASK;
268
269 if (enable_lower_comparator || enable_upper_comparator)
270 reg_ctrl1 = CTRL1_BATT_ALARM_EN_MASK;
271
272 rc = pm8058_mwrite(PM8058_REG_CTRL1, reg_ctrl1,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800273 CTRL1_BATT_ALARM_EN_MASK, &battdev.reg_ctrl1);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700274 if (rc) {
275 dprintf(CRITICAL, "Error in pm8058_mwrite CTRL1\n");
276 goto bail;
277 }
278
279 rc = pm8058_mwrite(PM8058_REG_CTRL2, reg_ctrl2,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800280 CTRL2_COMP_LOWER_DISABLE_MASK |
281 CTRL2_COMP_UPPER_DISABLE_MASK, &battdev.reg_ctrl2);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700282
283 if (rc)
284 dprintf(CRITICAL, "Error in pm8058_mwrite CTRL2\n");
285
Ajay Dudanib01e5062011-12-03 23:23:42 -0800286 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700287 return rc;
288}
289
290/*
291 * Function to read alarm status for battery alarm
292 */
293
Ajay Dudanib01e5062011-12-03 23:23:42 -0800294int pm_batt_alarm_status_read(uint8_t * status)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700295{
296 int rc = -1;
297
298 rc = pm8058_read(PM8058_REG_CTRL1, &battdev.reg_ctrl1, 1);
299 if (rc) {
300 dprintf(CRITICAL, "Error in reading CTRL1\n");
301 goto bail;
302 }
303
304 *status = ((battdev.reg_ctrl1 & CTRL1_STATUS_LOWER_MASK)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800305 ? PM_BATT_ALARM_STATUS_BELOW_LOWER : 0)
306 | ((battdev.reg_ctrl1 & CTRL1_STATUS_UPPER_MASK)
307 ? PM_BATT_ALARM_STATUS_ABOVE_UPPER : 0);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700308
309 /* Disabling Battery alarm below just for power savings. This can be
310 * removed if this does not matter
311 */
312
313 /* After reading, disabling the comparators and BATT_ALARM_EN */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800314 rc = pm_batt_alarm_state_set(LOWER_COMP_DISABLE, UPPER_COMP_DISABLE);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700315 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800316 dprintf(CRITICAL, "state_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700317 goto bail;
318 }
319
320 rc = pm_batt_alarm_pwm_rate_set(ALARM_EN_NEVER, DEFAULT_PWM_SCALER,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800321 DEFAULT_PWM_DIVIDER);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700322 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800323 dprintf(CRITICAL, "state_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700324 goto bail;
325 }
326
Ajay Dudanib01e5062011-12-03 23:23:42 -0800327 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700328 return rc;
329}
330
331/*
332 * Function to read and print battery alarm registers for debugging
333 */
334
335int pm_batt_alarm_read_regs(struct pm_batt_alarm_device *battdev)
336{
337 int rc = -1;
338
Ajay Dudanib01e5062011-12-03 23:23:42 -0800339 if (battdev) {
340 rc = pm8058_read(PM8058_REG_THRESHOLD, &battdev->reg_threshold,
341 1);
342 if (rc)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700343 goto done;
344
345 rc = pm8058_read(PM8058_REG_CTRL1, &battdev->reg_ctrl1, 1);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800346 if (rc)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700347 goto done;
348
349 rc = pm8058_read(PM8058_REG_CTRL2, &battdev->reg_ctrl2, 1);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800350 if (rc)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700351 goto done;
352
Ajay Dudanib01e5062011-12-03 23:23:42 -0800353 rc = pm8058_read(PM8058_REG_PWM_CTRL, &battdev->reg_pwm_ctrl,
354 1);
355 if (rc)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700356 goto done;
357 }
358
Ajay Dudanib01e5062011-12-03 23:23:42 -0800359 done:
360 if (rc)
361 dprintf(CRITICAL, "pm_batt_alarm_read_regs read error\n");
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700362 return rc;
363}
364
365/*
366 * Function for battery alarm initialization
367 */
368
369int pm_batt_alarm_init()
370{
371 int rc = -1;
372
373 rc = pm_batt_alarm_read_regs(&battdev);
374 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800375 dprintf(CRITICAL, "read_regs failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700376 goto bail;
377 }
378
379 rc = pm_batt_alarm_threshold_set(DEFAULT_THRESHOLD_LOWER,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800380 DEFAULT_THRESHOLD_UPPER);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700381 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800382 dprintf(CRITICAL, "threshold_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700383 goto bail;
384 }
385
386 rc = pm_batt_alarm_hold_time_set(DEFAULT_HOLD_TIME);
387 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800388 dprintf(CRITICAL, "hold_time_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700389 goto bail;
390 }
391
392 rc = pm_batt_alarm_pwm_rate_set(ALARM_EN_NEVER, DEFAULT_PWM_SCALER,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800393 DEFAULT_PWM_DIVIDER);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700394 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800395 dprintf(CRITICAL, "pwm_rate_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700396 goto bail;
397 }
398
Ajay Dudanib01e5062011-12-03 23:23:42 -0800399 rc = pm_batt_alarm_state_set(LOWER_COMP_DISABLE, UPPER_COMP_DISABLE);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700400 if (rc)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800401 dprintf(CRITICAL, "state_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700402
Ajay Dudanib01e5062011-12-03 23:23:42 -0800403 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700404 return rc;
405}
406
407/*
408 * Function to configure voltages and change alarm state
409 */
410
Ajay Dudanib01e5062011-12-03 23:23:42 -0800411int pm_batt_alarm_set_voltage(uint32_t lower_threshold,
412 uint32_t upper_threshold)
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700413{
414 int rc = -1;
415
Ajay Dudanib01e5062011-12-03 23:23:42 -0800416 rc = pm_batt_alarm_threshold_set(lower_threshold, upper_threshold);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700417 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800418 dprintf(CRITICAL, "threshold_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700419 goto bail;
420 }
421
422 rc = pm_batt_alarm_pwm_rate_set(ALARM_EN_ALWAYS, DEFAULT_PWM_SCALER,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800423 DEFAULT_PWM_DIVIDER);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700424 if (rc) {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800425 dprintf(CRITICAL, "pwm_rate_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700426 goto bail;
427 }
428
Ajay Dudanib01e5062011-12-03 23:23:42 -0800429 rc = pm_batt_alarm_state_set(LOWER_COMP_ENABLE, UPPER_COMP_ENABLE);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700430 if (rc)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800431 dprintf(CRITICAL, "state_set failed, rc=%d\n", rc);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700432
Ajay Dudanib01e5062011-12-03 23:23:42 -0800433 bail:
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700434 return rc;
435}
436
437/*
438 * Function to test battery alarms
439 */
440
441void pm_ba_test(void)
442{
443 int rc = 0;
444 uint8_t batt_status = 0;
445
446 rc = pm_batt_alarm_init();
Ajay Dudanib01e5062011-12-03 23:23:42 -0800447 if (rc)
448 dprintf(CRITICAL, "pm_batt_alarm_init error\n");
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700449
450 /* wait till hold time */
451 mdelay(16);
452
453 /* 0xe74-> 3700mV, 0x1004-> 4100mv */
454 rc = pm_batt_alarm_set_voltage(0xe74, 0x1004);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800455 if (rc)
456 dprintf(CRITICAL, "pm_batt_alarm_set_voltage error\n");
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700457
458 /* wait till hold time */
459 mdelay(16);
460
461 rc = pm_batt_alarm_status_read(&batt_status);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800462 if (rc)
463 dprintf(CRITICAL, "pm_batt_alarm_status_read error\n");
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700464 else
Ajay Dudanib01e5062011-12-03 23:23:42 -0800465 dprintf(ALWAYS, "batt status: %d\n", batt_status);
Subbaraman Narayanamurthy8c7cd222011-06-16 18:24:28 -0700466}