blob: 5f8faee2300820a9af7d939f99f3fd8d1f96dadf [file] [log] [blame]
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -07001/*
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -08002 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -07003 *
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/PM8018 ADC Arbiter driver
14 */
15#define pr_fmt(fmt) "%s: " fmt, __func__
16
17#include <linux/kernel.h>
18#include <linux/err.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22#include <linux/mutex.h>
23#include <linux/hwmon.h>
24#include <linux/module.h>
25#include <linux/debugfs.h>
26#include <linux/wakelock.h>
27#include <linux/interrupt.h>
28#include <linux/completion.h>
29#include <linux/hwmon-sysfs.h>
30#include <linux/mfd/pm8xxx/mpp.h>
31#include <linux/platform_device.h>
32#include <linux/mfd/pm8xxx/core.h>
33#include <linux/regulator/consumer.h>
34#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
35
36/* User Bank register set */
37#define PM8XXX_ADC_ARB_USRP_CNTRL1 0x197
38#define PM8XXX_ADC_ARB_USRP_CNTRL1_EN_ARB BIT(0)
39#define PM8XXX_ADC_ARB_USRP_CNTRL1_RSV1 BIT(1)
40#define PM8XXX_ADC_ARB_USRP_CNTRL1_RSV2 BIT(2)
41#define PM8XXX_ADC_ARB_USRP_CNTRL1_RSV3 BIT(3)
42#define PM8XXX_ADC_ARB_USRP_CNTRL1_RSV4 BIT(4)
43#define PM8XXX_ADC_ARB_USRP_CNTRL1_RSV5 BIT(5)
44#define PM8XXX_ADC_ARB_USRP_CNTRL1_EOC BIT(6)
45#define PM8XXX_ADC_ARB_USRP_CNTRL1_REQ BIT(7)
46
47#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL 0x198
48#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_RSV0 BIT(0)
49#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_RSV1 BIT(1)
50#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_PREMUX0 BIT(2)
51#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_PREMUX1 BIT(3)
52#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_SEL0 BIT(4)
53#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_SEL1 BIT(5)
54#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_SEL2 BIT(6)
55#define PM8XXX_ADC_ARB_USRP_AMUX_CNTRL_SEL3 BIT(7)
56
57#define PM8XXX_ADC_ARB_USRP_ANA_PARAM 0x199
58#define PM8XXX_ADC_ARB_USRP_DIG_PARAM 0x19A
59#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT0 BIT(0)
60#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT1 BIT(1)
61#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_CLK_RATE0 BIT(2)
62#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_CLK_RATE1 BIT(3)
63#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_EOC BIT(4)
64#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0 BIT(5)
65#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_DEC_RATE1 BIT(6)
66#define PM8XXX_ADC_ARB_USRP_DIG_PARAM_EN BIT(7)
67
68#define PM8XXX_ADC_ARB_USRP_RSV 0x19B
69#define PM8XXX_ADC_ARB_USRP_RSV_RST BIT(0)
70#define PM8XXX_ADC_ARB_USRP_RSV_DTEST0 BIT(1)
71#define PM8XXX_ADC_ARB_USRP_RSV_DTEST1 BIT(2)
72#define PM8XXX_ADC_ARB_USRP_RSV_OP BIT(3)
73#define PM8XXX_ADC_ARB_USRP_RSV_IP_SEL0 BIT(4)
74#define PM8XXX_ADC_ARB_USRP_RSV_IP_SEL1 BIT(5)
75#define PM8XXX_ADC_ARB_USRP_RSV_IP_SEL2 BIT(6)
76#define PM8XXX_ADC_ARB_USRP_RSV_TRM BIT(7)
77
78#define PM8XXX_ADC_ARB_USRP_DATA0 0x19D
79#define PM8XXX_ADC_ARB_USRP_DATA1 0x19C
80
81#define PM8XXX_ADC_ARB_BTM_CNTRL1 0x17e
82#define PM8XXX_ADC_ARB_BTM_CNTRL1_EN_BTM BIT(0)
83#define PM8XXX_ADC_ARB_BTM_CNTRL1_SEL_OP_MODE BIT(1)
84#define PM8XXX_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL1 BIT(2)
85#define PM8XXX_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL2 BIT(3)
86#define PM8XXX_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL3 BIT(4)
87#define PM8XXX_ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL4 BIT(5)
88#define PM8XXX_ADC_ARB_BTM_CNTRL1_EOC BIT(6)
89#define PM8XXX_ADC_ARB_BTM_CNTRL1_REQ BIT(7)
90
91#define PM8XXX_ADC_ARB_BTM_CNTRL2 0x18c
92#define PM8XXX_ADC_ARB_BTM_AMUX_CNTRL 0x17f
93#define PM8XXX_ADC_ARB_BTM_ANA_PARAM 0x180
94#define PM8XXX_ADC_ARB_BTM_DIG_PARAM 0x181
95#define PM8XXX_ADC_ARB_BTM_RSV 0x182
96#define PM8XXX_ADC_ARB_BTM_DATA1 0x183
97#define PM8XXX_ADC_ARB_BTM_DATA0 0x184
98#define PM8XXX_ADC_ARB_BTM_BAT_COOL_THR1 0x185
99#define PM8XXX_ADC_ARB_BTM_BAT_COOL_THR0 0x186
100#define PM8XXX_ADC_ARB_BTM_BAT_WARM_THR1 0x187
101#define PM8XXX_ADC_ARB_BTM_BAT_WARM_THR0 0x188
102
103#define PM8XXX_ADC_ARB_ANA_DIG 0xa0
104#define PM8XXX_ADC_BTM_RSV 0x10
105#define PM8XXX_ADC_AMUX_MPP_SEL 2
106#define PM8XXX_ADC_AMUX_SEL 4
107#define PM8XXX_ADC_RSV_IP_SEL 4
108#define PM8XXX_ADC_BTM_CHANNEL_SEL 4
109#define PM8XXX_MAX_CHANNEL_PROPERTIES 2
110#define PM8XXX_ADC_IRQ_0 0
111#define PM8XXX_ADC_IRQ_1 1
112#define PM8XXX_ADC_IRQ_2 2
113#define PM8XXX_ADC_BTM_INTERVAL_SEL_MASK 0xF
114#define PM8XXX_ADC_BTM_INTERVAL_SEL_SHIFT 2
115#define PM8XXX_ADC_BTM_DECIMATION_SEL 5
116#define PM8XXX_ADC_MUL 10
117#define PM8XXX_ADC_CONV_TIME_MIN 2000
118#define PM8XXX_ADC_CONV_TIME_MAX 2100
119#define PM8XXX_ADC_MPP_SETTLE_TIME_MIN 200
120#define PM8XXX_ADC_MPP_SETTLE_TIME_MAX 200
121#define PM8XXX_ADC_PA_THERM_VREG_UV_MIN 1800000
122#define PM8XXX_ADC_PA_THERM_VREG_UV_MAX 1800000
123#define PM8XXX_ADC_PA_THERM_VREG_UA_LOAD 100000
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800124#define PM8XXX_ADC_HWMON_NAME_LENGTH 32
Siddartha Mohanadoss68ceac12011-12-09 16:04:41 -0800125#define PM8XXX_ADC_BTM_INTERVAL_MAX 0x14
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700126
127struct pm8xxx_adc {
128 struct device *dev;
129 struct pm8xxx_adc_properties *adc_prop;
130 int adc_irq;
131 struct mutex adc_lock;
132 struct mutex mpp_adc_lock;
133 spinlock_t btm_lock;
134 uint32_t adc_num_channel;
135 uint32_t adc_num_board_channel;
136 struct completion adc_rslt_completion;
137 struct pm8xxx_adc_amux *adc_channel;
138 int btm_warm_irq;
139 int btm_cool_irq;
140 struct dentry *dent;
141 struct work_struct warm_work;
142 struct work_struct cool_work;
143 uint32_t mpp_base;
144 struct device *hwmon;
145 struct wake_lock adc_wakelock;
146 int msm_suspend_check;
147 struct pm8xxx_adc_amux_properties *conv;
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800148 struct pm8xxx_adc_arb_btm_param batt;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700149 struct sensor_device_attribute sens_attr[0];
150};
151
152struct pm8xxx_adc_amux_properties {
153 uint32_t amux_channel;
154 uint32_t decimation;
155 uint32_t amux_ip_rsv;
156 uint32_t amux_mpp_channel;
157 struct pm8xxx_adc_chan_properties chan_prop[0];
158};
159
160static const struct pm8xxx_adc_scaling_ratio pm8xxx_amux_scaling_ratio[] = {
161 {1, 1},
162 {1, 3},
163 {1, 4},
164 {1, 6}
165};
166
167static struct pm8xxx_adc *pmic_adc;
168
169static struct pm8xxx_adc_scale_fn adc_scale_fn[] = {
170 [ADC_SCALE_DEFAULT] = {pm8xxx_adc_scale_default},
171 [ADC_SCALE_BATT_THERM] = {pm8xxx_adc_scale_batt_therm},
172 [ADC_SCALE_PA_THERM] = {pm8xxx_adc_scale_pa_therm},
173 [ADC_SCALE_PMIC_THERM] = {pm8xxx_adc_scale_pmic_therm},
174 [ADC_SCALE_XOTHERM] = {pm8xxx_adc_tdkntcg_therm},
175};
176
177/* On PM8921 ADC the MPP needs to first be configured
178as an analog input to the AMUX pre-mux channel before
179issuing a read request. PM8921 MPP 8 is mapped to AMUX8
180and is common between remote processor's.
181On PM8018 ADC the MPP is directly connected to the AMUX
182pre-mux. Therefore clients of the PM8018 MPP do not need
183to configure the MPP as an analog input to the pre-mux.
184Clients can directly issue request on the pre-mux AMUX
185channel to read the ADC on the MPP */
186static struct pm8xxx_mpp_config_data pm8xxx_adc_mpp_config = {
187 .type = PM8XXX_MPP_TYPE_A_INPUT,
188 /* AMUX6 is dedicated to be used for apps processor */
189 .level = PM8XXX_MPP_AIN_AMUX_CH6,
190 .control = PM8XXX_MPP_AOUT_CTRL_DISABLE,
191};
192
193/* MPP Configuration for default settings */
194static struct pm8xxx_mpp_config_data pm8xxx_adc_mpp_unconfig = {
195 .type = PM8XXX_MPP_TYPE_SINK,
196 .level = PM8XXX_MPP_AIN_AMUX_CH5,
197 .control = PM8XXX_MPP_AOUT_CTRL_DISABLE,
198};
199
200static bool pm8xxx_adc_calib_first_adc;
201static bool pm8xxx_adc_initialized, pm8xxx_adc_calib_device_init;
202
203static int32_t pm8xxx_adc_arb_cntrl(uint32_t arb_cntrl,
204 uint32_t channel)
205{
206 struct pm8xxx_adc *adc_pmic = pmic_adc;
207 int i, rc;
208 u8 data_arb_cntrl = 0;
209
210 if (arb_cntrl) {
211 if (adc_pmic->msm_suspend_check)
212 pr_err("PM8xxx ADC request made after suspend_noirq "
213 "with channel: %d\n", channel);
214 data_arb_cntrl |= PM8XXX_ADC_ARB_USRP_CNTRL1_EN_ARB;
215 wake_lock(&adc_pmic->adc_wakelock);
216 }
217
218 /* Write twice to the CNTRL register for the arbiter settings
219 to take into effect */
220 for (i = 0; i < 2; i++) {
221 rc = pm8xxx_writeb(adc_pmic->dev->parent,
222 PM8XXX_ADC_ARB_USRP_CNTRL1, data_arb_cntrl);
223 if (rc < 0) {
224 pr_err("PM8xxx arb cntrl write failed with %d\n", rc);
225 return rc;
226 }
227 }
228
229 if (arb_cntrl) {
230 data_arb_cntrl |= PM8XXX_ADC_ARB_USRP_CNTRL1_REQ;
231 rc = pm8xxx_writeb(adc_pmic->dev->parent,
232 PM8XXX_ADC_ARB_USRP_CNTRL1, data_arb_cntrl);
233 } else
234 wake_unlock(&adc_pmic->adc_wakelock);
235
236 return 0;
237}
238
239static int32_t pm8xxx_adc_patherm_power(bool on)
240{
241 static struct regulator *pa_therm;
242 struct pm8xxx_adc *adc_pmic = pmic_adc;
243 int rc = 0;
244 if (on) {
245 pa_therm = regulator_get(adc_pmic->dev,
246 "pa_therm");
247 if (IS_ERR(pa_therm)) {
248 rc = PTR_ERR(pa_therm);
249 pr_err("failed to request pa_therm vreg "
250 "with error %d\n", rc);
251 return rc;
252 }
253
254 rc = regulator_set_voltage(pa_therm,
255 PM8XXX_ADC_PA_THERM_VREG_UV_MIN,
256 PM8XXX_ADC_PA_THERM_VREG_UV_MAX);
257 if (rc < 0) {
258 pr_err("failed to set the voltage for "
259 "pa_therm with error %d\n", rc);
260 goto fail;
261 }
262
263 rc = regulator_set_optimum_mode(pa_therm,
264 PM8XXX_ADC_PA_THERM_VREG_UA_LOAD);
265 if (rc < 0) {
266 pr_err("failed to set optimum mode for "
267 "pa_therm with error %d\n", rc);
268 goto fail;
269 }
270
271 if (regulator_enable(pa_therm)) {
272 pr_err("failed to enable pa_therm vreg with "
273 "error %d\n", rc);
274 goto fail;
275 }
276 } else {
277 if (pa_therm != NULL) {
278 regulator_disable(pa_therm);
279 regulator_put(pa_therm);
280 }
281 }
282
283 return rc;
284fail:
285 regulator_put(pa_therm);
286 return rc;
287}
288
289static int32_t pm8xxx_adc_channel_power_enable(uint32_t channel,
290 bool power_cntrl)
291{
292 int rc = 0;
293
294 switch (channel)
295 case ADC_MPP_1_AMUX8:
296 pm8xxx_adc_patherm_power(power_cntrl);
297
298 return rc;
299}
300
301
302static uint32_t pm8xxx_adc_read_reg(uint32_t reg, u8 *data)
303{
304 struct pm8xxx_adc *adc_pmic = pmic_adc;
305 int rc;
306
307 rc = pm8xxx_readb(adc_pmic->dev->parent, reg, data);
308 if (rc < 0) {
309 pr_err("PM8xxx adc read reg %d failed with %d\n", reg, rc);
310 return rc;
311 }
312
313 return 0;
314}
315
316static uint32_t pm8xxx_adc_write_reg(uint32_t reg, u8 data)
317{
318 struct pm8xxx_adc *adc_pmic = pmic_adc;
319 int rc;
320
321 rc = pm8xxx_writeb(adc_pmic->dev->parent, reg, data);
322 if (rc < 0) {
323 pr_err("PM8xxx adc write reg %d failed with %d\n", reg, rc);
324 return rc;
325 }
326
327 return 0;
328}
329
330static int32_t pm8xxx_adc_configure(
331 struct pm8xxx_adc_amux_properties *chan_prop)
332{
333 struct pm8xxx_adc *adc_pmic = pmic_adc;
334 u8 data_amux_chan = 0, data_arb_rsv = 0, data_dig_param = 0;
335 int rc;
336
337 data_amux_chan |= chan_prop->amux_channel << PM8XXX_ADC_AMUX_SEL;
338
339 if (chan_prop->amux_mpp_channel)
340 data_amux_chan |= chan_prop->amux_mpp_channel <<
341 PM8XXX_ADC_AMUX_MPP_SEL;
342
343 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_USRP_AMUX_CNTRL,
344 data_amux_chan);
345 if (rc < 0)
346 return rc;
347
Siddartha Mohanadoss866fe9f2011-12-13 23:01:40 -0800348 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_USRP_RSV, &data_arb_rsv);
349 if (rc < 0)
350 return rc;
351
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700352 data_arb_rsv &= (PM8XXX_ADC_ARB_USRP_RSV_RST |
353 PM8XXX_ADC_ARB_USRP_RSV_DTEST0 |
354 PM8XXX_ADC_ARB_USRP_RSV_DTEST1 |
Siddartha Mohanadoss866fe9f2011-12-13 23:01:40 -0800355 PM8XXX_ADC_ARB_USRP_RSV_OP);
356 data_arb_rsv |= (chan_prop->amux_ip_rsv << PM8XXX_ADC_RSV_IP_SEL |
357 PM8XXX_ADC_ARB_USRP_RSV_TRM);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700358
359 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_USRP_RSV, data_arb_rsv);
360 if (rc < 0)
361 return rc;
362
363 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_USRP_DIG_PARAM,
364 &data_dig_param);
365 if (rc < 0)
366 return rc;
367
368 /* Default 2.4Mhz clock rate */
369 /* Client chooses the decimation */
370 switch (chan_prop->decimation) {
371 case ADC_DECIMATION_TYPE1:
372 data_dig_param |= PM8XXX_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0;
373 break;
374 case ADC_DECIMATION_TYPE2:
375 data_dig_param |= (PM8XXX_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0
376 | PM8XXX_ADC_ARB_USRP_DIG_PARAM_DEC_RATE1);
377 break;
378 default:
379 data_dig_param |= PM8XXX_ADC_ARB_USRP_DIG_PARAM_DEC_RATE0;
380 break;
381 }
382 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_USRP_DIG_PARAM,
383 PM8XXX_ADC_ARB_ANA_DIG);
384 if (rc < 0)
385 return rc;
386
387 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_USRP_ANA_PARAM,
388 PM8XXX_ADC_ARB_ANA_DIG);
389 if (rc < 0)
390 return rc;
391
392 if (!pm8xxx_adc_calib_first_adc)
393 enable_irq(adc_pmic->adc_irq);
394
395 rc = pm8xxx_adc_arb_cntrl(1, data_amux_chan);
396 if (rc < 0) {
397 pr_err("Configuring ADC Arbiter"
398 "enable failed with %d\n", rc);
399 return rc;
400 }
401
402 return 0;
403}
404
405static uint32_t pm8xxx_adc_read_adc_code(int32_t *data)
406{
407 struct pm8xxx_adc *adc_pmic = pmic_adc;
408 uint8_t rslt_lsb, rslt_msb;
409 int32_t rc, max_ideal_adc_code = 1 << adc_pmic->adc_prop->bitresolution;
410
411 rc = pm8xxx_readb(adc_pmic->dev->parent,
412 PM8XXX_ADC_ARB_USRP_DATA0, &rslt_lsb);
413 if (rc < 0) {
414 pr_err("PM8xxx adc result read failed with %d\n", rc);
415 return rc;
416 }
417
418 rc = pm8xxx_readb(adc_pmic->dev->parent,
419 PM8XXX_ADC_ARB_USRP_DATA1, &rslt_msb);
420 if (rc < 0) {
421 pr_err("PM8xxx adc result read failed with %d\n", rc);
422 return rc;
423 }
424
425 *data = (rslt_msb << 8) | rslt_lsb;
426
427 /* Use the midpoint to determine underflow or overflow */
428 if (*data > max_ideal_adc_code + (max_ideal_adc_code >> 1))
429 *data |= ((1 << (8 * sizeof(*data) -
430 adc_pmic->adc_prop->bitresolution)) - 1) <<
431 adc_pmic->adc_prop->bitresolution;
432
433 /* Default value for switching off the arbiter after reading
434 the ADC value. Bit 0 set to 0. */
435 rc = pm8xxx_adc_arb_cntrl(0, CHANNEL_NONE);
436 if (rc < 0) {
437 pr_err("%s: Configuring ADC Arbiter disable"
438 "failed\n", __func__);
439 return rc;
440 }
441
442 return 0;
443}
444
445static void pm8xxx_adc_btm_warm_scheduler_fn(struct work_struct *work)
446{
447 struct pm8xxx_adc *adc_pmic = container_of(work, struct pm8xxx_adc,
448 warm_work);
449 unsigned long flags = 0;
450 bool warm_status;
451
452 spin_lock_irqsave(&adc_pmic->btm_lock, flags);
453 warm_status = irq_read_line(adc_pmic->btm_warm_irq);
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800454 if (adc_pmic->batt.btm_warm_fn != NULL)
455 adc_pmic->batt.btm_warm_fn(warm_status);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700456 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
457}
458
459static void pm8xxx_adc_btm_cool_scheduler_fn(struct work_struct *work)
460{
461 struct pm8xxx_adc *adc_pmic = container_of(work, struct pm8xxx_adc,
462 cool_work);
463 unsigned long flags = 0;
464 bool cool_status;
465
466 spin_lock_irqsave(&adc_pmic->btm_lock, flags);
467 cool_status = irq_read_line(adc_pmic->btm_cool_irq);
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800468 if (adc_pmic->batt.btm_cool_fn != NULL)
469 adc_pmic->batt.btm_cool_fn(cool_status);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700470 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
471}
472
473static irqreturn_t pm8xxx_adc_isr(int irq, void *dev_id)
474{
475 struct pm8xxx_adc *adc_8xxx = dev_id;
476
477 disable_irq_nosync(adc_8xxx->adc_irq);
478
479 if (pm8xxx_adc_calib_first_adc)
480 return IRQ_HANDLED;
481 /* TODO Handle spurius interrupt condition */
482 complete(&adc_8xxx->adc_rslt_completion);
483
484 return IRQ_HANDLED;
485}
486
487static irqreturn_t pm8xxx_btm_warm_isr(int irq, void *dev_id)
488{
489 struct pm8xxx_adc *btm_8xxx = dev_id;
490
491 schedule_work(&btm_8xxx->warm_work);
492
493 return IRQ_HANDLED;
494}
495
496static irqreturn_t pm8xxx_btm_cool_isr(int irq, void *dev_id)
497{
498 struct pm8xxx_adc *btm_8xxx = dev_id;
499
500 schedule_work(&btm_8xxx->cool_work);
501
502 return IRQ_HANDLED;
503}
504
505static uint32_t pm8xxx_adc_calib_device(void)
506{
507 struct pm8xxx_adc *adc_pmic = pmic_adc;
508 struct pm8xxx_adc_amux_properties conv;
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800509 int rc, calib_read_1, calib_read_2;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700510 u8 data_arb_usrp_cntrl1 = 0;
511
512 conv.amux_channel = CHANNEL_125V;
513 conv.decimation = ADC_DECIMATION_TYPE2;
514 conv.amux_ip_rsv = AMUX_RSV1;
515 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
516 pm8xxx_adc_calib_first_adc = true;
517 rc = pm8xxx_adc_configure(&conv);
518 if (rc) {
519 pr_err("pm8xxx_adc configure failed with %d\n", rc);
520 goto calib_fail;
521 }
522
523 while (data_arb_usrp_cntrl1 != (PM8XXX_ADC_ARB_USRP_CNTRL1_EOC |
524 PM8XXX_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
525 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_USRP_CNTRL1,
526 &data_arb_usrp_cntrl1);
527 if (rc < 0)
528 return rc;
529 usleep_range(PM8XXX_ADC_CONV_TIME_MIN,
530 PM8XXX_ADC_CONV_TIME_MAX);
531 }
532 data_arb_usrp_cntrl1 = 0;
533
534 rc = pm8xxx_adc_read_adc_code(&calib_read_1);
535 if (rc) {
536 pr_err("pm8xxx_adc read adc failed with %d\n", rc);
537 pm8xxx_adc_calib_first_adc = false;
538 goto calib_fail;
539 }
540 pm8xxx_adc_calib_first_adc = false;
541
542 conv.amux_channel = CHANNEL_625MV;
543 conv.decimation = ADC_DECIMATION_TYPE2;
544 conv.amux_ip_rsv = AMUX_RSV1;
545 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
546 pm8xxx_adc_calib_first_adc = true;
547 rc = pm8xxx_adc_configure(&conv);
548 if (rc) {
549 pr_err("pm8xxx_adc configure failed with %d\n", rc);
550 goto calib_fail;
551 }
552
553 while (data_arb_usrp_cntrl1 != (PM8XXX_ADC_ARB_USRP_CNTRL1_EOC |
554 PM8XXX_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
555 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_USRP_CNTRL1,
556 &data_arb_usrp_cntrl1);
557 if (rc < 0)
558 return rc;
559 usleep_range(PM8XXX_ADC_CONV_TIME_MIN,
560 PM8XXX_ADC_CONV_TIME_MAX);
561 }
562 data_arb_usrp_cntrl1 = 0;
563
564 rc = pm8xxx_adc_read_adc_code(&calib_read_2);
565 if (rc) {
566 pr_err("pm8xxx_adc read adc failed with %d\n", rc);
567 pm8xxx_adc_calib_first_adc = false;
568 goto calib_fail;
569 }
570 pm8xxx_adc_calib_first_adc = false;
571
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700572 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].dy =
573 (calib_read_1 - calib_read_2);
574 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].dx
Siddartha Mohanadoss37e6fc02011-11-16 16:57:03 -0800575 = PM8XXX_CHANNEL_ADC_625_UV;
576 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].adc_vref =
577 calib_read_1;
578 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd =
579 calib_read_2;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700580 rc = pm8xxx_adc_arb_cntrl(0, CHANNEL_NONE);
581 if (rc < 0) {
582 pr_err("%s: Configuring ADC Arbiter disable"
583 "failed\n", __func__);
584 return rc;
585 }
586 /* Ratiometric Calibration */
587 conv.amux_channel = CHANNEL_MUXOFF;
588 conv.decimation = ADC_DECIMATION_TYPE2;
589 conv.amux_ip_rsv = AMUX_RSV5;
590 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
591 pm8xxx_adc_calib_first_adc = true;
592 rc = pm8xxx_adc_configure(&conv);
593 if (rc) {
594 pr_err("pm8xxx_adc configure failed with %d\n", rc);
595 goto calib_fail;
596 }
597
598 while (data_arb_usrp_cntrl1 != (PM8XXX_ADC_ARB_USRP_CNTRL1_EOC |
599 PM8XXX_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
600 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_USRP_CNTRL1,
601 &data_arb_usrp_cntrl1);
602 if (rc < 0)
603 return rc;
604 usleep_range(PM8XXX_ADC_CONV_TIME_MIN,
605 PM8XXX_ADC_CONV_TIME_MAX);
606 }
607 data_arb_usrp_cntrl1 = 0;
608
609 rc = pm8xxx_adc_read_adc_code(&calib_read_1);
610 if (rc) {
611 pr_err("pm8xxx_adc read adc failed with %d\n", rc);
612 pm8xxx_adc_calib_first_adc = false;
613 goto calib_fail;
614 }
615 pm8xxx_adc_calib_first_adc = false;
616
617 conv.amux_channel = CHANNEL_MUXOFF;
618 conv.decimation = ADC_DECIMATION_TYPE2;
619 conv.amux_ip_rsv = AMUX_RSV4;
620 conv.amux_mpp_channel = PREMUX_MPP_SCALE_0;
621 pm8xxx_adc_calib_first_adc = true;
622 rc = pm8xxx_adc_configure(&conv);
623 if (rc) {
624 pr_err("pm8xxx_adc configure failed with %d\n", rc);
625 goto calib_fail;
626 }
627
628 while (data_arb_usrp_cntrl1 != (PM8XXX_ADC_ARB_USRP_CNTRL1_EOC |
629 PM8XXX_ADC_ARB_USRP_CNTRL1_EN_ARB)) {
630 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_USRP_CNTRL1,
631 &data_arb_usrp_cntrl1);
632 if (rc < 0)
633 return rc;
634 usleep_range(PM8XXX_ADC_CONV_TIME_MIN,
635 PM8XXX_ADC_CONV_TIME_MAX);
636 }
637 data_arb_usrp_cntrl1 = 0;
638
639 rc = pm8xxx_adc_read_adc_code(&calib_read_2);
640 if (rc) {
641 pr_err("pm8xxx_adc read adc failed with %d\n", rc);
642 pm8xxx_adc_calib_first_adc = false;
643 goto calib_fail;
644 }
645 pm8xxx_adc_calib_first_adc = false;
646
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700647 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dy =
648 (calib_read_1 - calib_read_2);
649 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dx =
650 adc_pmic->adc_prop->adc_vdd_reference;
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800651 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].adc_vref =
652 calib_read_1;
653 adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd =
654 calib_read_2;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700655calib_fail:
656 rc = pm8xxx_adc_arb_cntrl(0, CHANNEL_NONE);
657 if (rc < 0) {
658 pr_err("%s: Configuring ADC Arbiter disable"
659 "failed\n", __func__);
660 }
661
662 return rc;
663}
664
665uint32_t pm8xxx_adc_read(enum pm8xxx_adc_channels channel,
666 struct pm8xxx_adc_chan_result *result)
667{
668 struct pm8xxx_adc *adc_pmic = pmic_adc;
669 int i = 0, rc = 0, rc_fail, amux_prescaling, scale_type;
670 enum pm8xxx_adc_premux_mpp_scale_type mpp_scale;
671
672 if (!pm8xxx_adc_initialized)
673 return -ENODEV;
674
675 if (!pm8xxx_adc_calib_device_init) {
676 if (pm8xxx_adc_calib_device() == 0)
677 pm8xxx_adc_calib_device_init = true;
678 }
679
680 mutex_lock(&adc_pmic->adc_lock);
681
682 for (i = 0; i < adc_pmic->adc_num_channel; i++) {
683 if (channel == adc_pmic->adc_channel[i].channel_name)
684 break;
685 }
686
687 if (i == adc_pmic->adc_num_channel) {
688 rc = -EBADF;
689 goto fail_unlock;
690 }
691
692 if (channel < PM8XXX_CHANNEL_MPP_SCALE1_IDX) {
693 mpp_scale = PREMUX_MPP_SCALE_0;
694 adc_pmic->conv->amux_channel = channel;
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800695 } else if (channel >= PM8XXX_CHANNEL_MPP_SCALE1_IDX &&
696 channel < PM8XXX_CHANNEL_MPP_SCALE3_IDX) {
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700697 mpp_scale = PREMUX_MPP_SCALE_1;
698 adc_pmic->conv->amux_channel = channel %
699 PM8XXX_CHANNEL_MPP_SCALE1_IDX;
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800700 } else {
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700701 mpp_scale = PREMUX_MPP_SCALE_1_DIV3;
702 adc_pmic->conv->amux_channel = channel %
703 PM8XXX_CHANNEL_MPP_SCALE3_IDX;
704 }
705
706 adc_pmic->conv->amux_mpp_channel = mpp_scale;
707 adc_pmic->conv->amux_ip_rsv = adc_pmic->adc_channel[i].adc_rsv;
708 adc_pmic->conv->decimation = adc_pmic->adc_channel[i].adc_decimation;
709 amux_prescaling = adc_pmic->adc_channel[i].chan_path_prescaling;
710
711 adc_pmic->conv->chan_prop->offset_gain_numerator =
712 pm8xxx_amux_scaling_ratio[amux_prescaling].num;
713 adc_pmic->conv->chan_prop->offset_gain_denominator =
714 pm8xxx_amux_scaling_ratio[amux_prescaling].den;
715
716 rc = pm8xxx_adc_channel_power_enable(channel, true);
717 if (rc) {
718 rc = -EINVAL;
719 goto fail_unlock;
720 }
721
722 rc = pm8xxx_adc_configure(adc_pmic->conv);
723 if (rc) {
724 rc = -EINVAL;
725 goto fail;
726 }
727
728 wait_for_completion(&adc_pmic->adc_rslt_completion);
729
730 rc = pm8xxx_adc_read_adc_code(&result->adc_code);
731 if (rc) {
732 rc = -EINVAL;
733 goto fail;
734 }
735
736 scale_type = adc_pmic->adc_channel[i].adc_scale_fn;
737 if (scale_type >= ADC_SCALE_NONE) {
738 rc = -EBADF;
739 goto fail;
740 }
741
742 adc_scale_fn[scale_type].chan(result->adc_code,
743 adc_pmic->adc_prop, adc_pmic->conv->chan_prop, result);
744
745 rc = pm8xxx_adc_channel_power_enable(channel, false);
746 if (rc) {
747 rc = -EINVAL;
748 goto fail_unlock;
749 }
750
751 mutex_unlock(&adc_pmic->adc_lock);
752
753 return 0;
754fail:
755 rc_fail = pm8xxx_adc_channel_power_enable(channel, false);
756 if (rc_fail)
757 pr_err("pm8xxx adc power disable failed\n");
758fail_unlock:
759 mutex_unlock(&adc_pmic->adc_lock);
760 pr_err("pm8xxx adc error with %d\n", rc);
761 return rc;
762}
763EXPORT_SYMBOL_GPL(pm8xxx_adc_read);
764
765uint32_t pm8xxx_adc_mpp_config_read(uint32_t mpp_num,
766 enum pm8xxx_adc_channels channel,
767 struct pm8xxx_adc_chan_result *result)
768{
769 struct pm8xxx_adc *adc_pmic = pmic_adc;
770 int rc = 0;
771
772 if (!adc_pmic->mpp_base) {
773 rc = -EINVAL;
774 pr_info("PM8xxx MPP base invalid with error %d\n", rc);
775 return rc;
776 }
777
778 if (mpp_num == PM8XXX_AMUX_MPP_8) {
779 rc = -EINVAL;
780 pr_info("PM8xxx MPP8 is already configured "
781 "to AMUX8. Use pm8xxx_adc_read() instead.\n");
782 return rc;
783 }
784
785 mutex_lock(&adc_pmic->mpp_adc_lock);
786
787 rc = pm8xxx_mpp_config(((mpp_num - 1) + adc_pmic->mpp_base),
788 &pm8xxx_adc_mpp_config);
789 if (rc < 0) {
790 pr_err("pm8xxx adc mpp config error with %d\n", rc);
791 goto fail;
792 }
793
794 usleep_range(PM8XXX_ADC_MPP_SETTLE_TIME_MIN,
795 PM8XXX_ADC_MPP_SETTLE_TIME_MAX);
796
797 rc = pm8xxx_adc_read(channel, result);
798 if (rc < 0)
799 pr_err("pm8xxx adc read error with %d\n", rc);
800
801 rc = pm8xxx_mpp_config(((mpp_num - 1) + adc_pmic->mpp_base),
802 &pm8xxx_adc_mpp_unconfig);
803 if (rc < 0)
804 pr_err("pm8xxx adc mpp config error with %d\n", rc);
805fail:
806 mutex_unlock(&adc_pmic->mpp_adc_lock);
807
808 return rc;
809}
810EXPORT_SYMBOL_GPL(pm8xxx_adc_mpp_config_read);
811
812uint32_t pm8xxx_adc_btm_configure(struct pm8xxx_adc_arb_btm_param *btm_param)
813{
814 struct pm8xxx_adc *adc_pmic = pmic_adc;
815 u8 data_btm_cool_thr0, data_btm_cool_thr1;
816 u8 data_btm_warm_thr0, data_btm_warm_thr1;
817 u8 arb_btm_cntrl1;
818 unsigned long flags = 0;
819 int rc;
820
821 if (adc_pmic == NULL) {
822 pr_err("PMIC ADC not valid\n");
823 return -EINVAL;
824 }
825
826 if ((btm_param->btm_cool_fn == NULL) &&
827 (btm_param->btm_warm_fn == NULL)) {
828 pr_err("No BTM warm/cool notification??\n");
829 return -EINVAL;
830 }
831
Siddartha Mohanadossae39c902011-11-09 17:54:31 -0800832 rc = pm8xxx_adc_batt_scaler(btm_param, adc_pmic->adc_prop,
833 adc_pmic->conv->chan_prop);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700834 if (rc < 0) {
835 pr_err("Failed to lookup the BTM thresholds\n");
836 return rc;
837 }
838
Siddartha Mohanadoss68ceac12011-12-09 16:04:41 -0800839 if (btm_param->interval > PM8XXX_ADC_BTM_INTERVAL_MAX) {
840 pr_info("Bug in PMIC BTM interval time and cannot set"
841 " a value greater than 0x14 %x\n", btm_param->interval);
842 btm_param->interval = PM8XXX_ADC_BTM_INTERVAL_MAX;
843 }
844
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700845 spin_lock_irqsave(&adc_pmic->btm_lock, flags);
846
847 data_btm_cool_thr0 = ((btm_param->low_thr_voltage << 24) >> 24);
848 data_btm_cool_thr1 = ((btm_param->low_thr_voltage << 16) >> 24);
849 data_btm_warm_thr0 = ((btm_param->high_thr_voltage << 24) >> 24);
850 data_btm_warm_thr1 = ((btm_param->high_thr_voltage << 16) >> 24);
851
852 if (btm_param->btm_cool_fn != NULL) {
853 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_BAT_COOL_THR0,
854 data_btm_cool_thr0);
855 if (rc < 0)
856 goto write_err;
857
858 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_BAT_COOL_THR1,
859 data_btm_cool_thr1);
860 if (rc < 0)
861 goto write_err;
862
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800863 adc_pmic->batt.btm_cool_fn = btm_param->btm_cool_fn;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700864 }
865
866 if (btm_param->btm_warm_fn != NULL) {
867 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_BAT_WARM_THR0,
868 data_btm_warm_thr0);
869 if (rc < 0)
870 goto write_err;
871
872 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_BAT_WARM_THR1,
873 data_btm_warm_thr1);
874 if (rc < 0)
875 goto write_err;
876
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800877 adc_pmic->batt.btm_warm_fn = btm_param->btm_warm_fn;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700878 }
879
880 rc = pm8xxx_adc_read_reg(PM8XXX_ADC_ARB_BTM_CNTRL1, &arb_btm_cntrl1);
881 if (rc < 0)
882 goto bail_out;
883
884 btm_param->interval &= PM8XXX_ADC_BTM_INTERVAL_SEL_MASK;
885 arb_btm_cntrl1 |=
886 btm_param->interval << PM8XXX_ADC_BTM_INTERVAL_SEL_SHIFT;
887
888 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_CNTRL1, arb_btm_cntrl1);
889 if (rc < 0)
890 goto write_err;
891
892 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
893
894 return rc;
895bail_out:
896write_err:
897 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
898 pr_debug("%s: with error code %d\n", __func__, rc);
899 return rc;
900}
901EXPORT_SYMBOL_GPL(pm8xxx_adc_btm_configure);
902
903static uint32_t pm8xxx_adc_btm_read(uint32_t channel)
904{
905 struct pm8xxx_adc *adc_pmic = pmic_adc;
906 int rc, i;
907 u8 arb_btm_dig_param, arb_btm_ana_param, arb_btm_rsv;
908 u8 arb_btm_amux_cntrl, data_arb_btm_cntrl = 0;
909 unsigned long flags;
910
911 arb_btm_amux_cntrl = channel << PM8XXX_ADC_BTM_CHANNEL_SEL;
912 arb_btm_rsv = adc_pmic->adc_channel[channel].adc_rsv;
913 arb_btm_dig_param = arb_btm_ana_param = PM8XXX_ADC_ARB_ANA_DIG;
914
915 spin_lock_irqsave(&adc_pmic->btm_lock, flags);
916
917 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_AMUX_CNTRL,
918 arb_btm_amux_cntrl);
919 if (rc < 0)
920 goto write_err;
921
922 arb_btm_rsv = PM8XXX_ADC_BTM_RSV;
923
924 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_RSV, arb_btm_rsv);
925 if (rc < 0)
926 goto write_err;
927
928 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_DIG_PARAM,
929 arb_btm_dig_param);
930 if (rc < 0)
931 goto write_err;
932
933 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_ANA_PARAM,
934 arb_btm_ana_param);
935 if (rc < 0)
936 goto write_err;
937
938 data_arb_btm_cntrl |= PM8XXX_ADC_ARB_BTM_CNTRL1_EN_BTM;
939
940 for (i = 0; i < 2; i++) {
941 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_CNTRL1,
942 data_arb_btm_cntrl);
943 if (rc < 0)
944 goto write_err;
945 }
946
947 data_arb_btm_cntrl |= PM8XXX_ADC_ARB_BTM_CNTRL1_REQ
948 | PM8XXX_ADC_ARB_BTM_CNTRL1_SEL_OP_MODE;
949
950 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_CNTRL1,
951 data_arb_btm_cntrl);
952 if (rc < 0)
953 goto write_err;
954
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800955 if (pmic_adc->batt.btm_warm_fn != NULL)
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700956 enable_irq(adc_pmic->btm_warm_irq);
957
Siddartha Mohanadoss402673e2012-01-06 16:31:44 -0800958 if (pmic_adc->batt.btm_cool_fn != NULL)
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700959 enable_irq(adc_pmic->btm_cool_irq);
960
961write_err:
962 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
963 return rc;
964}
965
966uint32_t pm8xxx_adc_btm_start(void)
967{
968 return pm8xxx_adc_btm_read(CHANNEL_BATT_THERM);
969}
970EXPORT_SYMBOL_GPL(pm8xxx_adc_btm_start);
971
972uint32_t pm8xxx_adc_btm_end(void)
973{
974 struct pm8xxx_adc *adc_pmic = pmic_adc;
975 int i, rc;
Siddartha Mohanadoss6217da02011-12-13 20:23:05 -0800976 u8 data_arb_btm_cntrl = 0;
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700977 unsigned long flags;
978
979 disable_irq_nosync(adc_pmic->btm_warm_irq);
980 disable_irq_nosync(adc_pmic->btm_cool_irq);
981
982 spin_lock_irqsave(&adc_pmic->btm_lock, flags);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700983
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -0700984 /* Write twice to the CNTRL register for the arbiter settings
985 to take into effect */
986 for (i = 0; i < 2; i++) {
987 rc = pm8xxx_adc_write_reg(PM8XXX_ADC_ARB_BTM_CNTRL1,
988 data_arb_btm_cntrl);
989 if (rc < 0) {
990 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
991 return rc;
992 }
993 }
994
995 spin_unlock_irqrestore(&adc_pmic->btm_lock, flags);
996
997 return rc;
998}
999EXPORT_SYMBOL_GPL(pm8xxx_adc_btm_end);
1000
1001static ssize_t pm8xxx_adc_show(struct device *dev,
1002 struct device_attribute *devattr, char *buf)
1003{
1004 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1005 struct pm8xxx_adc *adc_pmic = pmic_adc;
1006 struct pm8xxx_adc_chan_result result;
1007 int rc = -1;
1008
1009 if (attr->index < adc_pmic->adc_num_channel)
1010 rc = pm8xxx_adc_read(attr->index, &result);
1011
1012 if (rc)
1013 return 0;
1014
Siddartha Mohanadossae39c902011-11-09 17:54:31 -08001015 return snprintf(buf, PM8XXX_ADC_HWMON_NAME_LENGTH,
1016 "Result:%lld Raw:%d\n", result.physical, result.adc_code);
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -07001017}
1018
1019static int get_adc(void *data, u64 *val)
1020{
1021 struct pm8xxx_adc_chan_result result;
1022 int i = (int)data;
1023 int rc;
1024
1025 rc = pm8xxx_adc_read(i, &result);
1026 if (!rc)
1027 pr_info("ADC value raw:%x physical:%lld\n",
1028 result.adc_code, result.physical);
1029 *val = result.physical;
1030
1031 return 0;
1032}
1033DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_adc, NULL, "%llu\n");
1034
1035static int get_mpp_adc(void *data, u64 *val)
1036{
1037 struct pm8xxx_adc_chan_result result;
1038 int i = (int)data;
1039 int rc;
1040
1041 rc = pm8xxx_adc_mpp_config_read(i,
1042 ADC_MPP_1_AMUX6, &result);
1043 if (!rc)
1044 pr_info("ADC MPP value raw:%x physical:%lld\n",
1045 result.adc_code, result.physical);
1046 *val = result.physical;
1047
1048 return 0;
1049}
1050DEFINE_SIMPLE_ATTRIBUTE(reg_mpp_fops, get_mpp_adc, NULL, "%llu\n");
1051
1052#ifdef CONFIG_DEBUG_FS
1053static void create_debugfs_entries(void)
1054{
1055 int i = 0;
1056 pmic_adc->dent = debugfs_create_dir("pm8xxx_adc", NULL);
1057
1058 if (IS_ERR(pmic_adc->dent)) {
1059 pr_err("pmic adc debugfs dir not created\n");
1060 return;
1061 }
1062
1063 for (i = 0; i < pmic_adc->adc_num_board_channel; i++)
1064 debugfs_create_file(pmic_adc->adc_channel[i].name,
1065 0644, pmic_adc->dent,
1066 (void *)pmic_adc->adc_channel[i].channel_name,
1067 &reg_fops);
1068}
1069#else
1070static inline void create_debugfs_entries(void)
1071{
1072}
1073#endif
1074static struct sensor_device_attribute pm8xxx_adc_attr =
1075 SENSOR_ATTR(NULL, S_IRUGO, pm8xxx_adc_show, NULL, 0);
1076
1077static int32_t pm8xxx_adc_init_hwmon(struct platform_device *pdev)
1078{
1079 struct pm8xxx_adc *adc_pmic = pmic_adc;
1080 int rc = 0, i;
1081
1082 for (i = 0; i < pmic_adc->adc_num_board_channel; i++) {
1083 pm8xxx_adc_attr.index = adc_pmic->adc_channel[i].channel_name;
1084 pm8xxx_adc_attr.dev_attr.attr.name =
1085 adc_pmic->adc_channel[i].name;
1086 memcpy(&adc_pmic->sens_attr[i], &pm8xxx_adc_attr,
1087 sizeof(pm8xxx_adc_attr));
1088 rc = device_create_file(&pdev->dev,
1089 &adc_pmic->sens_attr[i].dev_attr);
1090 if (rc) {
1091 dev_err(&pdev->dev, "device_create_file failed for "
1092 "dev %s\n",
1093 adc_pmic->adc_channel[i].name);
1094 goto hwmon_err_sens;
1095 }
1096 }
1097
1098 return 0;
1099hwmon_err_sens:
1100 pr_info("Init HWMON failed for pm8xxx_adc with %d\n", rc);
1101 return rc;
1102}
1103
1104#ifdef CONFIG_PM
1105static int pm8xxx_adc_suspend_noirq(struct device *dev)
1106{
1107 struct pm8xxx_adc *adc_pmic = pmic_adc;
1108
1109 adc_pmic->msm_suspend_check = 1;
1110
1111 return 0;
1112}
1113
1114static int pm8xxx_adc_resume_noirq(struct device *dev)
1115{
1116 struct pm8xxx_adc *adc_pmic = pmic_adc;
1117
1118 adc_pmic->msm_suspend_check = 0;
1119
1120 return 0;
1121}
1122
1123static const struct dev_pm_ops pm8xxx_adc_dev_pm_ops = {
1124 .suspend_noirq = pm8xxx_adc_suspend_noirq,
1125 .resume_noirq = pm8xxx_adc_resume_noirq,
1126};
1127
1128#define PM8XXX_ADC_DEV_PM_OPS (&pm8xxx_adc_dev_pm_ops)
1129#else
1130#define PM8XXX_ADC_DEV_PM_OPS NULL
1131#endif
1132
1133static int __devexit pm8xxx_adc_teardown(struct platform_device *pdev)
1134{
1135 struct pm8xxx_adc *adc_pmic = pmic_adc;
1136 int i;
1137
1138 wake_lock_destroy(&adc_pmic->adc_wakelock);
1139 platform_set_drvdata(pdev, NULL);
1140 pmic_adc = NULL;
1141 for (i = 0; i < adc_pmic->adc_num_board_channel; i++)
1142 device_remove_file(adc_pmic->dev,
1143 &adc_pmic->sens_attr[i].dev_attr);
1144 pm8xxx_adc_initialized = false;
1145
1146 return 0;
1147}
1148
1149static int __devinit pm8xxx_adc_probe(struct platform_device *pdev)
1150{
1151 const struct pm8xxx_adc_platform_data *pdata = pdev->dev.platform_data;
1152 struct pm8xxx_adc *adc_pmic;
1153 struct pm8xxx_adc_amux_properties *adc_amux_prop;
1154 int rc = 0;
1155
1156 if (!pdata) {
1157 dev_err(&pdev->dev, "no platform data?\n");
1158 return -EINVAL;
1159 }
1160
1161 adc_pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8xxx_adc) +
Siddartha Mohanadoss17607d22011-10-05 10:36:20 -07001162 (sizeof(struct sensor_device_attribute) *
1163 pdata->adc_num_board_channel), GFP_KERNEL);
1164 if (!adc_pmic) {
1165 dev_err(&pdev->dev, "Unable to allocate memory\n");
1166 return -ENOMEM;
1167 }
1168
1169 adc_amux_prop = devm_kzalloc(&pdev->dev,
1170 sizeof(struct pm8xxx_adc_amux_properties) +
1171 sizeof(struct pm8xxx_adc_chan_properties)
1172 , GFP_KERNEL);
1173 if (!adc_amux_prop) {
1174 dev_err(&pdev->dev, "Unable to allocate memory\n");
1175 return -ENOMEM;
1176 }
1177
1178 adc_pmic->dev = &pdev->dev;
1179 adc_pmic->adc_prop = pdata->adc_prop;
1180 adc_pmic->conv = adc_amux_prop;
1181 init_completion(&adc_pmic->adc_rslt_completion);
1182 adc_pmic->adc_channel = pdata->adc_channel;
1183 adc_pmic->adc_num_board_channel = pdata->adc_num_board_channel;
1184 adc_pmic->adc_num_channel = ADC_MPP_2_CHANNEL_NONE;
1185 adc_pmic->mpp_base = pdata->adc_mpp_base;
1186
1187 mutex_init(&adc_pmic->adc_lock);
1188 mutex_init(&adc_pmic->mpp_adc_lock);
1189 spin_lock_init(&adc_pmic->btm_lock);
1190
1191 adc_pmic->adc_irq = platform_get_irq(pdev, PM8XXX_ADC_IRQ_0);
1192 if (adc_pmic->adc_irq < 0)
1193 return adc_pmic->adc_irq;
1194
1195 rc = devm_request_irq(&pdev->dev, adc_pmic->adc_irq,
1196 pm8xxx_adc_isr,
1197 IRQF_TRIGGER_RISING, "pm8xxx_adc_interrupt", adc_pmic);
1198 if (rc) {
1199 dev_err(&pdev->dev, "failed to request adc irq "
1200 "with error %d\n", rc);
1201 }
1202
1203 disable_irq_nosync(adc_pmic->adc_irq);
1204
1205 adc_pmic->btm_warm_irq = platform_get_irq(pdev, PM8XXX_ADC_IRQ_1);
1206 if (adc_pmic->btm_warm_irq < 0)
1207 return adc_pmic->btm_warm_irq;
1208
1209 rc = devm_request_irq(&pdev->dev, adc_pmic->btm_warm_irq,
1210 pm8xxx_btm_warm_isr,
1211 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1212 "pm8xxx_btm_warm_interrupt", adc_pmic);
1213 if (rc) {
1214 pr_err("btm warm irq failed %d with interrupt number %d\n",
1215 rc, adc_pmic->btm_warm_irq);
1216 dev_err(&pdev->dev, "failed to request btm irq\n");
1217 }
1218
1219 disable_irq_nosync(adc_pmic->btm_warm_irq);
1220
1221 adc_pmic->btm_cool_irq = platform_get_irq(pdev, PM8XXX_ADC_IRQ_2);
1222 if (adc_pmic->btm_cool_irq < 0)
1223 return adc_pmic->btm_cool_irq;
1224
1225 rc = devm_request_irq(&pdev->dev, adc_pmic->btm_cool_irq,
1226 pm8xxx_btm_cool_isr,
1227 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1228 "pm8xxx_btm_cool_interrupt", adc_pmic);
1229 if (rc) {
1230 pr_err("btm cool irq failed with return %d and number %d\n",
1231 rc, adc_pmic->btm_cool_irq);
1232 dev_err(&pdev->dev, "failed to request btm irq\n");
1233 }
1234
1235 disable_irq_nosync(adc_pmic->btm_cool_irq);
1236 platform_set_drvdata(pdev, adc_pmic);
1237 wake_lock_init(&adc_pmic->adc_wakelock, WAKE_LOCK_SUSPEND,
1238 "pm8xxx_adc_wakelock");
1239 adc_pmic->msm_suspend_check = 0;
1240 pmic_adc = adc_pmic;
1241
1242 INIT_WORK(&adc_pmic->warm_work, pm8xxx_adc_btm_warm_scheduler_fn);
1243 INIT_WORK(&adc_pmic->cool_work, pm8xxx_adc_btm_cool_scheduler_fn);
1244 create_debugfs_entries();
1245 pm8xxx_adc_calib_first_adc = false;
1246 pm8xxx_adc_calib_device_init = false;
1247 pm8xxx_adc_initialized = true;
1248
1249 rc = pm8xxx_adc_init_hwmon(pdev);
1250 if (rc) {
1251 pr_err("pm8xxx adc init hwmon failed with %d\n", rc);
1252 dev_err(&pdev->dev, "failed to initialize pm8xxx hwmon adc\n");
1253 }
1254 adc_pmic->hwmon = hwmon_device_register(adc_pmic->dev);
1255 return 0;
1256}
1257
1258static struct platform_driver pm8xxx_adc_driver = {
1259 .probe = pm8xxx_adc_probe,
1260 .remove = __devexit_p(pm8xxx_adc_teardown),
1261 .driver = {
1262 .name = PM8XXX_ADC_DEV_NAME,
1263 .owner = THIS_MODULE,
1264 .pm = PM8XXX_ADC_DEV_PM_OPS,
1265 },
1266};
1267
1268static int __init pm8xxx_adc_init(void)
1269{
1270 return platform_driver_register(&pm8xxx_adc_driver);
1271}
1272module_init(pm8xxx_adc_init);
1273
1274static void __exit pm8xxx_adc_exit(void)
1275{
1276 platform_driver_unregister(&pm8xxx_adc_driver);
1277}
1278module_exit(pm8xxx_adc_exit);
1279
1280MODULE_ALIAS("platform:" PM8XXX_ADC_DEV_NAME);
1281MODULE_DESCRIPTION("PMIC8921/8018 ADC driver");
1282MODULE_LICENSE("GPL v2");