blob: df017b96b4395c1fd20112d736aaccd6d32c9f81 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * Qualcomm's PM8921 ADC Arbiter driver
14 */
15#define pr_fmt(fmt) "%s: " fmt, __func__
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/mutex.h>
20#include <linux/module.h>
21#include <linux/err.h>
22#include <linux/slab.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/completion.h>
26#include <linux/platform_device.h>
27#include <linux/mfd/pm8xxx/core.h>
28#include <linux/mfd/pm8xxx/mpp.h>
29#include <linux/mfd/pm8921-adc.h>
30#include <linux/debugfs.h>
31
32/* User Bank register set */
33#define PM8921_ADC_ARB_USRP_CNTRL1 0x197
34#define PM8921_ADC_ARB_USRP_CNTRL1_EN_ARB BIT(0)
35#define PM8921_ADC_ARB_USRP_CNTRL1_RSV1 BIT(1)
36#define PM8921_ADC_ARB_USRP_CNTRL1_RSV2 BIT(2)
37#define PM8921_ADC_ARB_USRP_CNTRL1_RSV3 BIT(3)
38#define PM8921_ADC_ARB_USRP_CNTRL1_RSV4 BIT(4)
39#define PM8921_ADC_ARB_USRP_CNTRL1_RSV5 BIT(5)
40#define PM8921_ADC_ARB_USRP_CNTRL1_EOC BIT(6)
41#define PM8921_ADC_ARB_USRP_CNTRL1_REQ BIT(7)
42
43#define PM8921_ADC_ARB_USRP_AMUX_CNTRL 0x198
44#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_RSV0 BIT(0)
45#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_RSV1 BIT(1)
46#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_PREMUX0 BIT(2)
47#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_PREMUX1 BIT(3)
48#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_SEL0 BIT(4)
49#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_SEL1 BIT(5)
50#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_SEL2 BIT(6)
51#define PM8921_ADC_ARB_USRP_AMUX_CNTRL_SEL3 BIT(7)
52
53#define PM8921_ADC_ARB_USRP_ANA_PARAM 0x199
54#define PM8921_ADC_ARB_USRP_DIG_PARAM 0x19A
55#define PM8921_ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT0 BIT(0)
56#define PM8921_ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT1 BIT(1)
57#define PM8921_ADC_ARB_USRP_DIG_PARAM_CLK_RATE0 BIT(2)
58#define PM8921_ADC_ARB_USRP_DIG_PARAM_CLK_RATE1 BIT(3)
59#define PM8921_ADC_ARB_USRP_DIG_PARAM_EOC BIT(4)
60#define PM8921_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0 BIT(5)
61#define PM8921_ADC_ARB_USRP_DIG_PARAM_DEC_RATE1 BIT(6)
62#define PM8921_ADC_ARB_USRP_DIG_PARAM_EN BIT(7)
63
64#define PM8921_ADC_ARB_USRP_RSV 0x19B
65#define PM8921_ADC_ARB_USRP_RSV_RST BIT(0)
66#define PM8921_ADC_ARB_USRP_RSV_DTEST0 BIT(1)
67#define PM8921_ADC_ARB_USRP_RSV_DTEST1 BIT(2)
68#define PM8921_ADC_ARB_USRP_RSV_OP BIT(3)
69#define PM8921_ADC_ARB_USRP_RSV_IP_SEL0 BIT(4)
70#define PM8921_ADC_ARB_USRP_RSV_IP_SEL1 BIT(5)
71#define PM8921_ADC_ARB_USRP_RSV_IP_SEL2 BIT(6)
72#define PM8921_ADC_ARB_USRP_RSV_TRM BIT(7)
73
74#define PM8921_ADC_ARB_USRP_DATA0 0x19D
75#define PM8921_ADC_ARB_USRP_DATA1 0x19C
76
77#define PM8921_ADC_ARB_BTM_CNTRL1 0x17e
78#define PM8921_ADC_ARB_BTM_CNTRL1_EN_BTM BIT(0)
79#define PM8921_ADC_ARB_BTM_CNTRL1_SEL_OP_MODE BIT(1)
80#define PM8921_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL1 BIT(2)
81#define PM8921_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL2 BIT(3)
82#define PM8921_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL3 BIT(4)
83#define PM8921_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL4 BIT(5)
84#define PM8921_ADC_ARB_BTM_CNTRL1_EOC BIT(6)
85#define PM8921_ADC_ARB_BTM_CNTRL1_REQ BIT(7)
86
87#define PM8921_ADC_ARB_BTM_CNTRL2 0x18c
88#define PM8921_ADC_ARB_BTM_AMUX_CNTRL 0x17f
89#define PM8921_ADC_ARB_BTM_ANA_PARAM 0x180
90#define PM8921_ADC_ARB_BTM_DIG_PARAM 0x181
91#define PM8921_ADC_ARB_BTM_RSV 0x182
92#define PM8921_ADC_ARB_BTM_DATA1 0x183
93#define PM8921_ADC_ARB_BTM_DATA0 0x184
94#define PM8921_ADC_ARB_BTM_BAT_COOL_THR1 0x185
95#define PM8921_ADC_ARB_BTM_BAT_COOL_THR0 0x186
96#define PM8921_ADC_ARB_BTM_BAT_WARM_THR1 0x187
97#define PM8921_ADC_ARB_BTM_BAT_WARM_THR0 0x188
98
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070099#define PM8921_ADC_ARB_ANA_DIG 0xa0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100#define PM8921_ADC_AMUX_MPP_SEL 2
101#define PM8921_ADC_AMUX_SEL 4
102#define PM8921_ADC_RSV_IP_SEL 4
103#define PM8921_ADC_BTM_CHANNEL_SEL 4
104#define PM8921_MAX_CHANNEL_PROPERTIES 2
105#define PM8921_ADC_IRQ_0 0
106#define PM8921_ADC_IRQ_1 1
107#define PM8921_ADC_IRQ_2 2
108#define PM8921_ADC_BTM_INTERVAL_SEL 5
109#define PM8921_ADC_BTM_DECIMATION_SEL 5
110#define PM8921_ADC_MUL 10
111#define PM8921_ADC_CONV_TIME_MIN 2000
112#define PM8921_ADC_CONV_TIME_MAX 2100
113
114struct pm8921_adc {
115 struct device *dev;
116 struct pm8921_adc_properties *adc_prop;
117 int adc_irq;
118 struct mutex adc_lock;
119 struct mutex btm_lock;
120 uint32_t adc_num_channel;
121 struct completion adc_rslt_completion;
122 struct pm8921_adc_amux *adc_channel;
123 struct pm8921_adc_amux_properties *conv;
124 struct pm8921_adc_arb_btm *batt;
125 int btm_warm_irq;
126 int btm_cold_irq;
127 struct dentry *dent;
128};
129
130struct pm8921_adc_amux_properties {
131 uint32_t amux_channel;
132 uint32_t decimation;
133 uint32_t amux_ip_rsv;
134 uint32_t amux_mpp_channel;
135 struct pm8921_adc_chan_properties *chan_prop;
136};
137
138static const struct pm8921_adc_scaling_ratio pm8921_amux_scaling_ratio[] = {
139 {1, 1},
140 {1, 3},
141 {1, 4},
142 {1, 6}
143};
144
145static struct pm8921_adc *pmic_adc;
146
147static struct pm8921_adc_scale_fn adc_scale_fn[] = {
148 [ADC_SCALE_DEFAULT] = {pm8921_adc_scale_default},
149 [ADC_SCALE_BATT_THERM] = {pm8921_adc_scale_batt_therm},
150 [ADC_SCALE_PMIC_THERM] = {pm8921_adc_scale_pmic_therm},
151 [ADC_SCALE_XTERN_CHGR_CUR] = {pm8921_adc_scale_xtern_chgr_cur},
152};
153
154static bool pm8921_adc_calib_first_adc, pm8921_btm_calib_first_adc;
155static bool pm8921_adc_initialized, pm8921_adc_calib_device_init;
156
157static int32_t pm8921_adc_arb_cntrl(uint32_t arb_cntrl)
158{
159 struct pm8921_adc *adc_pmic = pmic_adc;
160 int i, rc;
161 u8 data_arb_cntrl = 0;
162
163 if (arb_cntrl)
Siddartha Mohanadoss00548e62011-07-18 12:13:09 -0700164 data_arb_cntrl |= PM8921_ADC_ARB_USRP_CNTRL1_EN_ARB;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165
166 /* Write twice to the CNTRL register for the arbiter settings
167 to take into effect */
168 for (i = 0; i < 2; i++) {
169 rc = pm8xxx_writeb(adc_pmic->dev->parent,
170 PM8921_ADC_ARB_USRP_CNTRL1, data_arb_cntrl);
171 if (rc < 0) {
172 pr_err("PM8921 arb cntrl write failed with %d\n", rc);
173 return rc;
174 }
175 }
176
Siddartha Mohanadoss00548e62011-07-18 12:13:09 -0700177 if (arb_cntrl) {
178 data_arb_cntrl |= PM8921_ADC_ARB_USRP_CNTRL1_REQ;
179 rc = pm8xxx_writeb(adc_pmic->dev->parent,
180 PM8921_ADC_ARB_USRP_CNTRL1, data_arb_cntrl);
181 }
182
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183 return 0;
184}
185
186static uint32_t pm8921_adc_read_reg(uint32_t reg, u8 *data)
187{
188 struct pm8921_adc *adc_pmic = pmic_adc;
189 int rc;
190
191 rc = pm8xxx_readb(adc_pmic->dev->parent, reg, data);
192 if (rc < 0) {
193 pr_err("PM8921 adc read reg %d failed with %d\n", reg, rc);
194 return rc;
195 }
196
197 return 0;
198}
199
200static uint32_t pm8921_adc_write_reg(uint32_t reg, u8 data)
201{
202 struct pm8921_adc *adc_pmic = pmic_adc;
203 int rc;
204
205 rc = pm8xxx_writeb(adc_pmic->dev->parent, reg, data);
206 if (rc < 0) {
207 pr_err("PM8921 adc write reg %d failed with %d\n", reg, rc);
208 return rc;
209 }
210
211 return 0;
212}
213
214static int32_t pm8921_adc_configure(
215 struct pm8921_adc_amux_properties *chan_prop)
216{
217 struct pm8921_adc *adc_pmic = pmic_adc;
218 u8 data_amux_chan = 0, data_arb_rsv = 0, data_dig_param = 0;
Siddartha Mohanadoss00548e62011-07-18 12:13:09 -0700219 int rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700220
221 data_amux_chan |= chan_prop->amux_channel << PM8921_ADC_AMUX_SEL;
222
223 if (chan_prop->amux_mpp_channel)
224 data_amux_chan |= chan_prop->amux_mpp_channel <<
225 PM8921_ADC_AMUX_MPP_SEL;
226
227 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_USRP_AMUX_CNTRL,
228 data_amux_chan);
229 if (rc < 0)
230 return rc;
231
232 data_arb_rsv &= (PM8921_ADC_ARB_USRP_RSV_RST |
233 PM8921_ADC_ARB_USRP_RSV_DTEST0 |
234 PM8921_ADC_ARB_USRP_RSV_DTEST1 |
235 PM8921_ADC_ARB_USRP_RSV_OP |
236 PM8921_ADC_ARB_USRP_RSV_TRM);
237 data_arb_rsv |= chan_prop->amux_ip_rsv << PM8921_ADC_RSV_IP_SEL;
238
239 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_USRP_RSV, data_arb_rsv);
240 if (rc < 0)
241 return rc;
242
243 rc = pm8921_adc_read_reg(PM8921_ADC_ARB_USRP_DIG_PARAM,
244 &data_dig_param);
245 if (rc < 0)
246 return rc;
247
248 /* Default 2.4Mhz clock rate */
249 /* Client chooses the decimation */
250 switch (chan_prop->decimation) {
251 case ADC_DECIMATION_TYPE1:
252 data_dig_param |= PM8921_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0;
253 break;
254 case ADC_DECIMATION_TYPE2:
255 data_dig_param |= (PM8921_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0
256 | PM8921_ADC_ARB_USRP_DIG_PARAM_DEC_RATE1);
257 break;
258 default:
259 data_dig_param |= PM8921_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0;
260 break;
261 }
262 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_USRP_DIG_PARAM,
263 PM8921_ADC_ARB_ANA_DIG);
264 if (rc < 0)
265 return rc;
266
267 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_USRP_ANA_PARAM,
268 PM8921_ADC_ARB_ANA_DIG);
269 if (rc < 0)
270 return rc;
271
272 if (!pm8921_adc_calib_first_adc)
273 enable_irq(adc_pmic->adc_irq);
274
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700275 rc = pm8921_adc_arb_cntrl(1);
276 if (rc < 0) {
277 pr_err("Configuring ADC Arbiter"
278 "enable failed with %d\n", rc);
279 return rc;
280 }
281
282 return 0;
283}
284
285static uint32_t pm8921_adc_read_adc_code(int32_t *data)
286{
287 struct pm8921_adc *adc_pmic = pmic_adc;
288 uint8_t rslt_lsb, rslt_msb;
289 int32_t rc, max_ideal_adc_code = 1 << adc_pmic->adc_prop->bitresolution;
290
291 rc = pm8xxx_readb(adc_pmic->dev->parent,
292 PM8921_ADC_ARB_USRP_DATA0, &rslt_lsb);
293 if (rc < 0) {
294 pr_err("PM8921 adc result read failed with %d\n", rc);
295 return rc;
296 }
297
298 rc = pm8xxx_readb(adc_pmic->dev->parent,
299 PM8921_ADC_ARB_USRP_DATA1, &rslt_msb);
300 if (rc < 0) {
301 pr_err("PM8921 adc result read failed with %d\n", rc);
302 return rc;
303 }
304
305 *data = (rslt_msb << 8) | rslt_lsb;
306
307 /* Use the midpoint to determine underflow or overflow */
308 if (*data > max_ideal_adc_code + (max_ideal_adc_code >> 1))
309 *data |= ((1 << (8 * sizeof(*data) -
310 adc_pmic->adc_prop->bitresolution)) - 1) <<
311 adc_pmic->adc_prop->bitresolution;
312
313 /* Default value for switching off the arbiter after reading
314 the ADC value. Bit 0 set to 0. */
315 rc = pm8921_adc_arb_cntrl(0);
316 if (rc < 0) {
317 pr_err("%s: Configuring ADC Arbiter disable"
318 "failed\n", __func__);
319 return rc;
320 }
321
322 return 0;
323}
324
325static irqreturn_t pm8921_adc_isr(int irq, void *dev_id)
326{
327 struct pm8921_adc *adc_8921 = dev_id;
328
329 disable_irq_nosync(adc_8921->adc_irq);
330
331 if (pm8921_adc_calib_first_adc)
332 return IRQ_HANDLED;
333 /* TODO Handle spurius interrupt condition */
334 complete(&adc_8921->adc_rslt_completion);
335
336 return IRQ_HANDLED;
337}
338
339static irqreturn_t pm8921_btm_warm_isr(int irq, void *dev_id)
340{
341 struct pm8921_adc *btm_8921 = dev_id;
342
343 disable_irq_nosync(btm_8921->btm_warm_irq);
344
345 if (pm8921_btm_calib_first_adc)
346 return IRQ_HANDLED;
347
348 if (btm_8921->batt->btm_param->btm_warm_fn != NULL)
349 btm_8921->batt->btm_param->btm_warm_fn();
350
351 return IRQ_HANDLED;
352}
353
354static irqreturn_t pm8921_btm_cold_isr(int irq, void *dev_id)
355{
356 struct pm8921_adc *btm_8921 = dev_id;
357
358 disable_irq_nosync(btm_8921->btm_cold_irq);
359
360 if (pm8921_btm_calib_first_adc)
361 return IRQ_HANDLED;
362
363 if (btm_8921->batt->btm_param->btm_cold_fn != NULL)
364 btm_8921->batt->btm_param->btm_cold_fn();
365
366 return IRQ_HANDLED;
367}
368
369static uint32_t pm8921_adc_calib_device(void)
370{
371 struct pm8921_adc *adc_pmic = pmic_adc;
372 struct pm8921_adc_amux_properties conv;
373 int rc, offset_adc, slope_adc, calib_read_1, calib_read_2;
374 u8 data_arb_usrp_cntrl1 = 0;
375
376 conv.amux_channel = CHANNEL_125V;
377 conv.decimation = ADC_DECIMATION_TYPE2;
378 conv.amux_ip_rsv = AMUX_RSV1;
379 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
380 pm8921_adc_calib_first_adc = true;
381 rc = pm8921_adc_configure(&conv);
382 if (rc) {
383 pr_err("pm8921_adc configure failed with %d\n", rc);
384 goto calib_fail;
385 }
386
387 while (data_arb_usrp_cntrl1 != (PM8921_ADC_ARB_USRP_CNTRL1_EOC |
388 PM8921_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
389 rc = pm8921_adc_read_reg(PM8921_ADC_ARB_USRP_CNTRL1,
390 &data_arb_usrp_cntrl1);
391 if (rc < 0)
392 return rc;
393 usleep_range(PM8921_ADC_CONV_TIME_MIN,
394 PM8921_ADC_CONV_TIME_MAX);
395 }
396 data_arb_usrp_cntrl1 = 0;
397
398 rc = pm8921_adc_read_adc_code(&calib_read_1);
399 if (rc) {
400 pr_err("pm8921_adc read adc failed with %d\n", rc);
401 pm8921_adc_calib_first_adc = false;
402 goto calib_fail;
403 }
404 pm8921_adc_calib_first_adc = false;
405
406 conv.amux_channel = CHANNEL_625MV;
407 conv.decimation = ADC_DECIMATION_TYPE2;
408 conv.amux_ip_rsv = AMUX_RSV1;
409 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
410 pm8921_adc_calib_first_adc = true;
411 rc = pm8921_adc_configure(&conv);
412 if (rc) {
413 pr_err("pm8921_adc configure failed with %d\n", rc);
414 goto calib_fail;
415 }
416
417 while (data_arb_usrp_cntrl1 != (PM8921_ADC_ARB_USRP_CNTRL1_EOC |
418 PM8921_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
419 rc = pm8921_adc_read_reg(PM8921_ADC_ARB_USRP_CNTRL1,
420 &data_arb_usrp_cntrl1);
421 if (rc < 0)
422 return rc;
423 usleep_range(PM8921_ADC_CONV_TIME_MIN,
424 PM8921_ADC_CONV_TIME_MAX);
425 }
426 data_arb_usrp_cntrl1 = 0;
427
428 rc = pm8921_adc_read_adc_code(&calib_read_2);
429 if (rc) {
430 pr_err("pm8921_adc read adc failed with %d\n", rc);
431 pm8921_adc_calib_first_adc = false;
432 goto calib_fail;
433 }
434 pm8921_adc_calib_first_adc = false;
435
436 slope_adc = (((calib_read_1 - calib_read_2) << PM8921_ADC_MUL)/
437 PM8921_CHANNEL_ADC_625_MV);
438 offset_adc = calib_read_2 -
439 ((slope_adc * PM8921_CHANNEL_ADC_625_MV) >>
440 PM8921_ADC_MUL);
441
442 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].offset
443 = offset_adc;
444 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].dy =
445 (calib_read_1 - calib_read_2);
446 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].dx
447 = PM8921_CHANNEL_ADC_625_MV;
448 rc = pm8921_adc_arb_cntrl(0);
449 if (rc < 0) {
450 pr_err("%s: Configuring ADC Arbiter disable"
451 "failed\n", __func__);
452 return rc;
453 }
454 /* Ratiometric Calibration */
455 conv.amux_channel = CHANNEL_MUXOFF;
456 conv.decimation = ADC_DECIMATION_TYPE2;
457 conv.amux_ip_rsv = AMUX_RSV5;
458 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
459 pm8921_adc_calib_first_adc = true;
460 rc = pm8921_adc_configure(&conv);
461 if (rc) {
462 pr_err("pm8921_adc configure failed with %d\n", rc);
463 goto calib_fail;
464 }
465
466 while (data_arb_usrp_cntrl1 != (PM8921_ADC_ARB_USRP_CNTRL1_EOC |
467 PM8921_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
468 rc = pm8921_adc_read_reg(PM8921_ADC_ARB_USRP_CNTRL1,
469 &data_arb_usrp_cntrl1);
470 if (rc < 0)
471 return rc;
472 usleep_range(PM8921_ADC_CONV_TIME_MIN,
473 PM8921_ADC_CONV_TIME_MAX);
474 }
475 data_arb_usrp_cntrl1 = 0;
476
477 rc = pm8921_adc_read_adc_code(&calib_read_1);
478 if (rc) {
479 pr_err("pm8921_adc read adc failed with %d\n", rc);
480 pm8921_adc_calib_first_adc = false;
481 goto calib_fail;
482 }
483 pm8921_adc_calib_first_adc = false;
484
485 conv.amux_channel = CHANNEL_MUXOFF;
486 conv.decimation = ADC_DECIMATION_TYPE2;
487 conv.amux_ip_rsv = AMUX_RSV4;
488 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
489 pm8921_adc_calib_first_adc = true;
490 rc = pm8921_adc_configure(&conv);
491 if (rc) {
492 pr_err("pm8921_adc configure failed with %d\n", rc);
493 goto calib_fail;
494 }
495
496 while (data_arb_usrp_cntrl1 != (PM8921_ADC_ARB_USRP_CNTRL1_EOC |
497 PM8921_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
498 rc = pm8921_adc_read_reg(PM8921_ADC_ARB_USRP_CNTRL1,
499 &data_arb_usrp_cntrl1);
500 if (rc < 0)
501 return rc;
502 usleep_range(PM8921_ADC_CONV_TIME_MIN,
503 PM8921_ADC_CONV_TIME_MAX);
504 }
505 data_arb_usrp_cntrl1 = 0;
506
507 rc = pm8921_adc_read_adc_code(&calib_read_2);
508 if (rc) {
509 pr_err("pm8921_adc read adc failed with %d\n", rc);
510 pm8921_adc_calib_first_adc = false;
511 goto calib_fail;
512 }
513 pm8921_adc_calib_first_adc = false;
514
515 slope_adc = (((calib_read_1 - calib_read_2) << PM8921_ADC_MUL)/
516 adc_pmic->adc_prop->adc_vdd_reference);
517 offset_adc = calib_read_2 -
518 ((slope_adc * adc_pmic->adc_prop->adc_vdd_reference)
519 >> PM8921_ADC_MUL);
520
521 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].offset
522 = offset_adc;
523 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dy =
524 (calib_read_1 - calib_read_2);
525 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dx =
526 adc_pmic->adc_prop->adc_vdd_reference;
527calib_fail:
528 rc = pm8921_adc_arb_cntrl(0);
529 if (rc < 0) {
530 pr_err("%s: Configuring ADC Arbiter disable"
531 "failed\n", __func__);
532 }
533
534 return rc;
535}
536
537uint32_t pm8921_adc_read(enum pm8921_adc_channels channel,
538 struct pm8921_adc_chan_result *result)
539{
540 return pm8921_adc_mpp_read(channel, result, PREMUX_MPP_SCALE_0);
541}
542EXPORT_SYMBOL_GPL(pm8921_adc_read);
543
544uint32_t pm8921_adc_mpp_read(enum pm8921_adc_mpp_channels channel,
545 struct pm8921_adc_chan_result *result,
546 enum pm8921_adc_premux_mpp_scale_type mpp_scale)
547{
548 struct pm8921_adc *adc_pmic = pmic_adc;
549 int i = 0, rc, amux_prescaling, scale_type;
550
551 if (!pm8921_adc_initialized)
552 return -ENODEV;
553
554 if (!pm8921_adc_calib_device_init) {
555 if (pm8921_adc_calib_device() == 0)
556 pm8921_adc_calib_device_init = true;
557 }
558
559 mutex_lock(&adc_pmic->adc_lock);
560
561 for (i = 0; i < adc_pmic->adc_num_channel; i++) {
562 if (channel == adc_pmic->adc_channel[i].channel_name)
563 break;
564 }
565
566 if (i == adc_pmic->adc_num_channel) {
567 mutex_unlock(&adc_pmic->adc_lock);
568 return -EBADF; /* unknown channel */
569 }
570
571 adc_pmic->conv->amux_channel = i;
572 adc_pmic->conv->amux_mpp_channel = mpp_scale;
573
574 adc_pmic->conv->amux_ip_rsv = adc_pmic->adc_channel[i].adc_rsv;
575 adc_pmic->conv->decimation = adc_pmic->adc_channel[i].adc_decimation;
576 amux_prescaling = adc_pmic->adc_channel[i].chan_path_prescaling;
577
578 adc_pmic->conv->chan_prop->offset_gain_numerator =
579 pm8921_amux_scaling_ratio[amux_prescaling].num;
580 adc_pmic->conv->chan_prop->offset_gain_denominator =
581 pm8921_amux_scaling_ratio[amux_prescaling].den;
582
583 rc = pm8921_adc_configure(adc_pmic->conv);
584 if (rc) {
585 mutex_unlock(&adc_pmic->adc_lock);
586 return -EINVAL;
587 }
588
589 wait_for_completion(&adc_pmic->adc_rslt_completion);
590
591 rc = pm8921_adc_read_adc_code(&result->adc_code);
592 if (rc) {
593 mutex_unlock(&adc_pmic->adc_lock);
594 return -EINVAL;
595 }
596
597 scale_type = adc_pmic->adc_channel[i].adc_scale_fn;
598 if (scale_type >= ADC_SCALE_NONE) {
599 mutex_unlock(&adc_pmic->adc_lock);
600 return -EBADF;
601 }
602
603 adc_scale_fn[scale_type].chan(result->adc_code,
604 adc_pmic->adc_prop, adc_pmic->conv->chan_prop, result);
605
606 mutex_unlock(&adc_pmic->adc_lock);
607
608 return 0;
609}
610EXPORT_SYMBOL_GPL(pm8921_adc_mpp_read);
611
612uint32_t pm8921_adc_btm_configure(struct pm8921_adc_arb_btm_param *btm_param)
613{
614 struct pm8921_adc *adc_pmic = pmic_adc;
615 u8 data_btm_cool_thr0, data_btm_cool_thr1;
616 u8 data_btm_warm_thr0, data_btm_warm_thr1;
617 u8 arb_btm_cntrl1;
618 int rc;
619
620 mutex_lock(&adc_pmic->btm_lock);
621
622 data_btm_cool_thr0 = ((btm_param->low_thr_voltage << 24) >> 24);
623 data_btm_cool_thr1 = ((btm_param->low_thr_voltage << 16) >> 24);
624 data_btm_warm_thr0 = ((btm_param->high_thr_voltage << 24) >> 24);
625 data_btm_warm_thr1 = ((btm_param->high_thr_voltage << 16) >> 24);
626
627 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_BAT_COOL_THR0,
628 data_btm_cool_thr0);
629 if (rc < 0)
630 goto write_err;
631
632 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_BAT_COOL_THR1,
633 data_btm_cool_thr0);
634 if (rc < 0)
635 goto write_err;
636
637 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_BAT_WARM_THR0,
638 data_btm_warm_thr0);
639 if (rc < 0)
640 goto write_err;
641
642 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_BAT_WARM_THR1,
643 data_btm_warm_thr1);
644 if (rc < 0)
645 goto write_err;
646
647 arb_btm_cntrl1 = btm_param->interval << PM8921_ADC_BTM_INTERVAL_SEL;
648
649 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_CNTRL1, arb_btm_cntrl1);
650 if (rc < 0)
651 goto write_err;
652
653 adc_pmic->batt->btm_param->btm_warm_fn = btm_param->btm_warm_fn;
654 adc_pmic->batt->btm_param->btm_cold_fn = btm_param->btm_cold_fn;
655
656 mutex_unlock(&adc_pmic->btm_lock);
657
658 return rc;
659
660write_err:
661 mutex_unlock(&adc_pmic->btm_lock);
662 return rc;
663}
664EXPORT_SYMBOL_GPL(pm8921_adc_btm_configure);
665
666static uint32_t pm8921_adc_btm_read(uint32_t channel)
667{
668 struct pm8921_adc *adc_pmic = pmic_adc;
669 int rc, i;
670 u8 arb_btm_dig_param, arb_btm_ana_param, arb_btm_rsv;
671 u8 arb_btm_amux_cntrl, arb_btm_decimation, data_arb_btm_cntrl;
672
673 arb_btm_amux_cntrl = channel << PM8921_ADC_BTM_CHANNEL_SEL;
674 arb_btm_rsv = adc_pmic->adc_channel[channel].adc_rsv;
675 arb_btm_decimation =
676 adc_pmic->adc_channel[channel].adc_decimation;
677 arb_btm_ana_param = PM8921_ADC_ARB_ANA_DIG;
678
679 mutex_lock(&adc_pmic->btm_lock);
680
681 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_AMUX_CNTRL,
682 arb_btm_amux_cntrl);
683 if (rc < 0)
684 goto write_err;
685
686 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_RSV, arb_btm_rsv);
687 if (rc < 0)
688 goto write_err;
689
690 arb_btm_dig_param = arb_btm_decimation <<
691 PM8921_ADC_BTM_DECIMATION_SEL;
692 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_DIG_PARAM,
693 arb_btm_dig_param);
694 if (rc < 0)
695 goto write_err;
696
697 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_ANA_PARAM,
698 arb_btm_ana_param);
699 if (rc < 0)
700 goto write_err;
701
702 data_arb_btm_cntrl = PM8921_ADC_ARB_BTM_CNTRL1_EOC |
703 PM8921_ADC_ARB_BTM_CNTRL1_EN_BTM;
704
705 /* Write twice to the CNTRL register for the arbiter settings
706 to take into effect */
707 for (i = 0; i < 2; i++) {
708 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_CNTRL1,
709 data_arb_btm_cntrl);
710 if (rc < 0)
711 goto write_err;
712 }
713
714 mutex_unlock(&adc_pmic->btm_lock);
715
716 return 0;
717
718write_err:
719 mutex_unlock(&adc_pmic->btm_lock);
720 return rc;
721}
722
723uint32_t pm8921_adc_btm_start(void)
724{
725 int rc;
726
727 rc = pm8921_adc_btm_read(CHANNEL_BATT_THERM);
728 return rc;
729}
730EXPORT_SYMBOL_GPL(pm8921_adc_btm_start);
731
732uint32_t pm8921_adc_btm_end(void)
733{
734 struct pm8921_adc *adc_pmic = pmic_adc;
735 int i, rc;
736 u8 data_arb_btm_cntrl;
737
738 /* Set BTM registers to Disable mode */
739 data_arb_btm_cntrl = PM8921_ADC_ARB_BTM_CNTRL1_EOC;
740
741 mutex_lock(&adc_pmic->btm_lock);
742 /* Write twice to the CNTRL register for the arbiter settings
743 to take into effect */
744 for (i = 0; i < 2; i++) {
745 rc = pm8921_adc_write_reg(PM8921_ADC_ARB_BTM_CNTRL1,
746 data_arb_btm_cntrl);
747 if (rc < 0) {
748 mutex_unlock(&adc_pmic->btm_lock);
749 return rc;
750 }
751 }
752 mutex_unlock(&adc_pmic->btm_lock);
753
754 return rc;
755}
756EXPORT_SYMBOL_GPL(pm8921_adc_btm_end);
757
758static int get_adc(void *data, u64 *val)
759{
760 struct pm8921_adc_chan_result result;
761 int i = (int)data;
762 int rc;
763
764 rc = pm8921_adc_read(i, &result);
765
766 pr_info("ADC value raw:%x physical:%lld\n",
767 result.adc_code, result.physical);
768 *val = result.physical;
769 return 0;
770}
771DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_adc, NULL, "%llu\n");
772
773#ifdef CONFIG_DEBUG_FS
774static void create_debugfs_entries(void)
775{
776 pmic_adc->dent = debugfs_create_dir("pm8921_adc", NULL);
777
778 if (IS_ERR(pmic_adc->dent)) {
779 pr_err("pmic adc debugfs dir not created\n");
780 return;
781 }
782
783 debugfs_create_file("vbat", 0644, pmic_adc->dent,
784 (void *)CHANNEL_VBAT, &reg_fops);
785 debugfs_create_file("625mv", 0644, pmic_adc->dent,
786 (void *)CHANNEL_625MV, &reg_fops);
787 debugfs_create_file("125v", 0644, pmic_adc->dent,
788 (void *)CHANNEL_125V, &reg_fops);
789 debugfs_create_file("die_temp", 0644, pmic_adc->dent,
790 (void *)CHANNEL_DIE_TEMP, &reg_fops);
791 debugfs_create_file("vcoin", 0644, pmic_adc->dent,
792 (void *)CHANNEL_VCOIN, &reg_fops);
793 debugfs_create_file("dc_in", 0644, pmic_adc->dent,
794 (void *)CHANNEL_DCIN, &reg_fops);
795 debugfs_create_file("vph_pwr", 0644, pmic_adc->dent,
796 (void *)CHANNEL_VPH_PWR, &reg_fops);
797 debugfs_create_file("usb_in", 0644, pmic_adc->dent,
798 (void *)CHANNEL_USBIN, &reg_fops);
799 debugfs_create_file("batt_therm", 0644, pmic_adc->dent,
800 (void *)CHANNEL_BATT_THERM, &reg_fops);
801 debugfs_create_file("batt_id", 0644, pmic_adc->dent,
802 (void *)CHANNEL_BATT_ID, &reg_fops);
803 debugfs_create_file("chg_temp", 0644, pmic_adc->dent,
804 (void *)CHANNEL_CHG_TEMP, &reg_fops);
805 debugfs_create_file("charger_current", 0644, pmic_adc->dent,
806 (void *)CHANNEL_ICHG, &reg_fops);
807 debugfs_create_file("ibat", 0644, pmic_adc->dent,
808 (void *)CHANNEL_IBAT, &reg_fops);
809}
810#else
811static inline void create_debugfs_entries(void)
812{
813}
814#endif
815
816static int __devexit pm8921_adc_teardown(struct platform_device *pdev)
817{
818 struct pm8921_adc *adc_pmic = pmic_adc;
819
820 device_init_wakeup(&pdev->dev, 0);
821 free_irq(adc_pmic->adc_irq, adc_pmic);
822 free_irq(adc_pmic->btm_warm_irq, adc_pmic);
823 free_irq(adc_pmic->btm_cold_irq, adc_pmic);
824 platform_set_drvdata(pdev, NULL);
825 pmic_adc = NULL;
826 kfree(adc_pmic->conv->chan_prop);
827 kfree(adc_pmic->adc_channel);
828 kfree(adc_pmic);
829 pm8921_adc_initialized = false;
830
831 return 0;
832}
833
834static int __devinit pm8921_adc_probe(struct platform_device *pdev)
835{
836 const struct pm8921_adc_platform_data *pdata = pdev->dev.platform_data;
837 struct pm8921_adc *adc_pmic;
838 struct pm8921_adc_amux_properties *adc_amux_prop;
839 struct pm8921_adc_chan_properties *adc_pmic_chanprop;
840 struct pm8921_adc_amux *adc_amux;
841 int rc = 0;
842
843 if (!pdata) {
844 dev_err(&pdev->dev, "no platform data?\n");
845 return -EINVAL;
846 }
847
848 adc_pmic = kzalloc(sizeof(struct pm8921_adc),
849 GFP_KERNEL);
850 if (!adc_pmic) {
851 dev_err(&pdev->dev, "Unable to allocate memory\n");
852 return -ENOMEM;
853 }
854
855 adc_amux_prop = kzalloc(sizeof(struct pm8921_adc_amux_properties),
856 GFP_KERNEL);
857 if (!adc_amux_prop) {
858 dev_err(&pdev->dev, "Unable to allocate memory\n");
859 return -ENOMEM;
860 }
861
862 adc_amux = kzalloc(sizeof(struct pm8921_adc_amux),
863 GFP_KERNEL);
864 if (!adc_amux) {
865 dev_err(&pdev->dev, "Unable to allocate memory\n");
866 return -ENOMEM;
867 }
868
869 adc_pmic_chanprop = kzalloc(sizeof(struct pm8921_adc_chan_properties),
870 GFP_KERNEL);
871 if (!adc_pmic_chanprop) {
872 dev_err(&pdev->dev, "Unable to allocate memory\n");
873 return -ENOMEM;
874 }
875
876 adc_pmic->dev = &pdev->dev;
877 adc_pmic->adc_prop = pdata->adc_prop;
878 adc_pmic->conv = adc_amux_prop;
879 adc_pmic->conv->chan_prop = adc_pmic_chanprop;
880
881 init_completion(&adc_pmic->adc_rslt_completion);
882 adc_amux = pdata->adc_channel;
883 adc_pmic->adc_channel = adc_amux;
884 adc_pmic->adc_num_channel = pdata->adc_num_channel;
885
886 mutex_init(&adc_pmic->adc_lock);
887 mutex_init(&adc_pmic->btm_lock);
888
889 adc_pmic->adc_irq = platform_get_irq(pdev, PM8921_ADC_IRQ_0);
890 if (adc_pmic->adc_irq < 0) {
891 rc = -ENXIO;
892 goto err_cleanup;
893 }
894
895 rc = request_irq(adc_pmic->adc_irq,
896 pm8921_adc_isr,
897 IRQF_TRIGGER_RISING, "pm8921_adc_interrupt", adc_pmic);
898 if (rc) {
899 dev_err(&pdev->dev, "failed to request adc irq "
900 "with error %d\n", rc);
901 goto err_cleanup;
902 }
903
904 disable_irq_nosync(adc_pmic->adc_irq);
905
906 adc_pmic->btm_warm_irq = platform_get_irq(pdev, PM8921_ADC_IRQ_1);
907 if (adc_pmic->btm_warm_irq < 0) {
908 rc = -ENXIO;
909 goto err_cleanup;
910 }
911
912 rc = request_irq(adc_pmic->btm_warm_irq,
913 pm8921_btm_warm_isr,
914 IRQF_TRIGGER_RISING, "pm8921_btm_warm_interrupt", adc_pmic);
915 if (rc) {
916 pr_err("btm warm irq failed %d with interrupt number %d\n",
917 rc, adc_pmic->btm_warm_irq);
918 dev_err(&pdev->dev, "failed to request btm irq\n");
919 goto err_cleanup;
920 }
921
922 disable_irq_nosync(adc_pmic->btm_warm_irq);
923
924 adc_pmic->btm_cold_irq = platform_get_irq(pdev, PM8921_ADC_IRQ_2);
925 if (adc_pmic->btm_cold_irq < 0) {
926 rc = -ENXIO;
927 goto err_cleanup;
928 }
929
930 rc = request_irq(adc_pmic->btm_cold_irq,
931 pm8921_btm_cold_isr,
932 IRQF_TRIGGER_RISING, "pm8921_btm_cold_interrupt", adc_pmic);
933 if (rc) {
934 pr_err("btm cold irq failed with return %d and number %d\n",
935 rc, adc_pmic->btm_cold_irq);
936 dev_err(&pdev->dev, "failed to request btm irq\n");
937 goto err_cleanup;
938 }
939
940 disable_irq_nosync(adc_pmic->btm_cold_irq);
941 device_init_wakeup(&pdev->dev, pdata->adc_wakeup);
942 platform_set_drvdata(pdev, adc_pmic);
943 pmic_adc = adc_pmic;
944
945 create_debugfs_entries();
946 pm8921_adc_calib_first_adc = false;
947 pm8921_btm_calib_first_adc = false;
948 pm8921_adc_calib_device_init = false;
949 pm8921_adc_initialized = true;
950 return 0;
951
952err_cleanup:
953 pm8921_adc_teardown(pdev);
954 return rc;
955}
956
957static struct platform_driver pm8921_adc_driver = {
958 .probe = pm8921_adc_probe,
959 .remove = __devexit_p(pm8921_adc_teardown),
960 .driver = {
961 .name = PM8921_ADC_DEV_NAME,
962 .owner = THIS_MODULE,
963 },
964};
965
966static int __init pm8921_adc_init(void)
967{
968 return platform_driver_register(&pm8921_adc_driver);
969}
970module_init(pm8921_adc_init);
971
972static void __exit pm8921_adc_exit(void)
973{
974 platform_driver_unregister(&pm8921_adc_driver);
975}
976module_exit(pm8921_adc_exit);
977
978MODULE_ALIAS("platform:" PM8921_ADC_DEV_NAME);
979MODULE_DESCRIPTION("PMIC8921 ADC driver");
980MODULE_LICENSE("GPL v2");