blob: c985b90577f60da75febaca354cef361d5dfc627 [file] [log] [blame]
Arun Murthydae2db32011-02-22 10:11:13 +01001/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * License Terms: GNU General Public License v2
5 * Author: Arun R Murthy <arun.murthy@stericsson.com>
Daniel Willerud63219922011-03-05 11:46:13 +01006 * Author: Daniel Willerud <daniel.willerud@stericsson.com>
Johan Palsson586f3312011-03-05 11:46:37 +01007 * Author: Johan Palsson <johan.palsson@stericsson.com>
Arun Murthydae2db32011-02-22 10:11:13 +01008 */
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/delay.h>
Lee Jones5f8aaef2013-02-04 08:33:13 +000015#include <linux/pm_runtime.h>
Arun Murthydae2db32011-02-22 10:11:13 +010016#include <linux/platform_device.h>
17#include <linux/completion.h>
18#include <linux/regulator/consumer.h>
19#include <linux/err.h>
20#include <linux/slab.h>
Daniel Willerud63219922011-03-05 11:46:13 +010021#include <linux/list.h>
Arun Murthydae2db32011-02-22 10:11:13 +010022#include <linux/mfd/abx500.h>
Linus Walleijee66e652011-12-02 14:16:33 +010023#include <linux/mfd/abx500/ab8500.h>
24#include <linux/mfd/abx500/ab8500-gpadc.h>
Arun Murthydae2db32011-02-22 10:11:13 +010025
26/*
27 * GPADC register offsets
28 * Bank : 0x0A
29 */
30#define AB8500_GPADC_CTRL1_REG 0x00
31#define AB8500_GPADC_CTRL2_REG 0x01
32#define AB8500_GPADC_CTRL3_REG 0x02
33#define AB8500_GPADC_AUTO_TIMER_REG 0x03
34#define AB8500_GPADC_STAT_REG 0x04
35#define AB8500_GPADC_MANDATAL_REG 0x05
36#define AB8500_GPADC_MANDATAH_REG 0x06
37#define AB8500_GPADC_AUTODATAL_REG 0x07
38#define AB8500_GPADC_AUTODATAH_REG 0x08
39#define AB8500_GPADC_MUX_CTRL_REG 0x09
Lee Jonese4bffe82013-02-11 10:38:00 +000040#define AB8540_GPADC_MANDATA2L_REG 0x09
41#define AB8540_GPADC_MANDATA2H_REG 0x0A
42#define AB8540_GPADC_APEAAX_REG 0x10
43#define AB8540_GPADC_APEAAT_REG 0x11
44#define AB8540_GPADC_APEAAM_REG 0x12
45#define AB8540_GPADC_APEAAH_REG 0x13
46#define AB8540_GPADC_APEAAL_REG 0x14
Arun Murthydae2db32011-02-22 10:11:13 +010047
Johan Palsson586f3312011-03-05 11:46:37 +010048/*
49 * OTP register offsets
50 * Bank : 0x15
51 */
52#define AB8500_GPADC_CAL_1 0x0F
53#define AB8500_GPADC_CAL_2 0x10
54#define AB8500_GPADC_CAL_3 0x11
55#define AB8500_GPADC_CAL_4 0x12
56#define AB8500_GPADC_CAL_5 0x13
57#define AB8500_GPADC_CAL_6 0x14
58#define AB8500_GPADC_CAL_7 0x15
Lee Jonese4bffe82013-02-11 10:38:00 +000059/* New calibration for 8540 */
60#define AB8540_GPADC_OTP4_REG_7 0x38
61#define AB8540_GPADC_OTP4_REG_6 0x39
62#define AB8540_GPADC_OTP4_REG_5 0x3A
Johan Palsson586f3312011-03-05 11:46:37 +010063
Arun Murthydae2db32011-02-22 10:11:13 +010064/* gpadc constants */
65#define EN_VINTCORE12 0x04
66#define EN_VTVOUT 0x02
67#define EN_GPADC 0x01
68#define DIS_GPADC 0x00
Lee Jones73482342013-02-26 10:06:55 +000069#define AVG_1 0x00
70#define AVG_4 0x20
71#define AVG_8 0x40
72#define AVG_16 0x60
Arun Murthydae2db32011-02-22 10:11:13 +010073#define ADC_SW_CONV 0x04
Karl Komierowski4aad5a92011-03-05 11:46:45 +010074#define EN_ICHAR 0x80
Johan Palssoned139412011-05-08 00:55:43 +020075#define BTEMP_PULL_UP 0x08
Arun Murthydae2db32011-02-22 10:11:13 +010076#define EN_BUF 0x40
77#define DIS_ZERO 0x00
78#define GPADC_BUSY 0x01
Lee Jones73482342013-02-26 10:06:55 +000079#define EN_FALLING 0x10
80#define EN_TRIG_EDGE 0x02
Lee Jonese4bffe82013-02-11 10:38:00 +000081#define EN_VBIAS_XTAL_TEMP 0x02
Arun Murthydae2db32011-02-22 10:11:13 +010082
Johan Palsson586f3312011-03-05 11:46:37 +010083/* GPADC constants from AB8500 spec, UM0836 */
84#define ADC_RESOLUTION 1024
85#define ADC_CH_BTEMP_MIN 0
86#define ADC_CH_BTEMP_MAX 1350
87#define ADC_CH_DIETEMP_MIN 0
88#define ADC_CH_DIETEMP_MAX 1350
89#define ADC_CH_CHG_V_MIN 0
90#define ADC_CH_CHG_V_MAX 20030
91#define ADC_CH_ACCDET2_MIN 0
92#define ADC_CH_ACCDET2_MAX 2500
93#define ADC_CH_VBAT_MIN 2300
94#define ADC_CH_VBAT_MAX 4800
95#define ADC_CH_CHG_I_MIN 0
96#define ADC_CH_CHG_I_MAX 1500
97#define ADC_CH_BKBAT_MIN 0
98#define ADC_CH_BKBAT_MAX 3200
99
Lee Jonese4bffe82013-02-11 10:38:00 +0000100/* GPADC constants from AB8540 spec */
101#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat*/
102#define ADC_CH_IBAT_MAX 6000
103#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
104#define ADC_CH_IBAT_MAX_V 60
105#define IBAT_VDROP_L (-56) /* mV */
106#define IBAT_VDROP_H 56
107
Johan Palsson586f3312011-03-05 11:46:37 +0100108/* This is used to not lose precision when dividing to get gain and offset */
Lee Jonese4bffe82013-02-11 10:38:00 +0000109#define CALIB_SCALE 1000
110/*
111 * Number of bits shift used to not lose precision
112 * when dividing to get ibat gain.
113 */
114#define CALIB_SHIFT_IBAT 20
Johan Palsson586f3312011-03-05 11:46:37 +0100115
Lee Jones5f8aaef2013-02-04 08:33:13 +0000116/* Time in ms before disabling regulator */
117#define GPADC_AUDOSUSPEND_DELAY 1
118
Lee Jonesf825ebe2013-01-28 09:20:45 +0000119#define CONVERSION_TIME 500 /* ms */
120
Johan Palsson586f3312011-03-05 11:46:37 +0100121enum cal_channels {
122 ADC_INPUT_VMAIN = 0,
123 ADC_INPUT_BTEMP,
124 ADC_INPUT_VBAT,
Lee Jonese4bffe82013-02-11 10:38:00 +0000125 ADC_INPUT_IBAT,
Johan Palsson586f3312011-03-05 11:46:37 +0100126 NBR_CAL_INPUTS,
127};
128
Arun Murthydae2db32011-02-22 10:11:13 +0100129/**
Johan Palsson586f3312011-03-05 11:46:37 +0100130 * struct adc_cal_data - Table for storing gain and offset for the calibrated
131 * ADC channels
132 * @gain: Gain of the ADC channel
133 * @offset: Offset of the ADC channel
134 */
135struct adc_cal_data {
Lee Jonese4bffe82013-02-11 10:38:00 +0000136 s64 gain;
137 s64 offset;
Johan Palsson586f3312011-03-05 11:46:37 +0100138};
139
140/**
141 * struct ab8500_gpadc - AB8500 GPADC device information
Arun Murthydae2db32011-02-22 10:11:13 +0100142 * @dev: pointer to the struct device
Daniel Willerud63219922011-03-05 11:46:13 +0100143 * @node: a list of AB8500 GPADCs, hence prepared for
144 reentrance
Michel JAOUEN20bf4282012-02-09 12:06:47 +0100145 * @parent: pointer to the struct ab8500
Arun Murthydae2db32011-02-22 10:11:13 +0100146 * @ab8500_gpadc_complete: pointer to the struct completion, to indicate
147 * the completion of gpadc conversion
148 * @ab8500_gpadc_lock: structure of type mutex
149 * @regu: pointer to the struct regulator
Lee Jones73482342013-02-26 10:06:55 +0000150 * @irq_sw: interrupt number that is used by gpadc for Sw
151 * conversion
152 * @irq_hw: interrupt number that is used by gpadc for Hw
153 * conversion
Johan Palsson586f3312011-03-05 11:46:37 +0100154 * @cal_data array of ADC calibration data structs
Arun Murthydae2db32011-02-22 10:11:13 +0100155 */
Daniel Willerud63219922011-03-05 11:46:13 +0100156struct ab8500_gpadc {
Arun Murthydae2db32011-02-22 10:11:13 +0100157 struct device *dev;
Daniel Willerud63219922011-03-05 11:46:13 +0100158 struct list_head node;
Michel JAOUEN20bf4282012-02-09 12:06:47 +0100159 struct ab8500 *parent;
Arun Murthydae2db32011-02-22 10:11:13 +0100160 struct completion ab8500_gpadc_complete;
161 struct mutex ab8500_gpadc_lock;
162 struct regulator *regu;
Lee Jones73482342013-02-26 10:06:55 +0000163 int irq_sw;
164 int irq_hw;
Johan Palsson586f3312011-03-05 11:46:37 +0100165 struct adc_cal_data cal_data[NBR_CAL_INPUTS];
Daniel Willerud63219922011-03-05 11:46:13 +0100166};
167
168static LIST_HEAD(ab8500_gpadc_list);
169
170/**
171 * ab8500_gpadc_get() - returns a reference to the primary AB8500 GPADC
172 * (i.e. the first GPADC in the instance list)
173 */
174struct ab8500_gpadc *ab8500_gpadc_get(char *name)
175{
176 struct ab8500_gpadc *gpadc;
177
178 list_for_each_entry(gpadc, &ab8500_gpadc_list, node) {
179 if (!strcmp(name, dev_name(gpadc->dev)))
180 return gpadc;
181 }
182
183 return ERR_PTR(-ENOENT);
184}
185EXPORT_SYMBOL(ab8500_gpadc_get);
Arun Murthydae2db32011-02-22 10:11:13 +0100186
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200187/**
188 * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
189 */
190int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
Johan Palsson586f3312011-03-05 11:46:37 +0100191 int ad_value)
192{
193 int res;
194
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200195 switch (channel) {
Johan Palsson586f3312011-03-05 11:46:37 +0100196 case MAIN_CHARGER_V:
197 /* For some reason we don't have calibrated data */
198 if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
199 res = ADC_CH_CHG_V_MIN + (ADC_CH_CHG_V_MAX -
200 ADC_CH_CHG_V_MIN) * ad_value /
201 ADC_RESOLUTION;
202 break;
203 }
204 /* Here we can use the calibrated data */
205 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VMAIN].gain +
206 gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE;
207 break;
208
Lee Jonese4bffe82013-02-11 10:38:00 +0000209 case XTAL_TEMP:
Johan Palsson586f3312011-03-05 11:46:37 +0100210 case BAT_CTRL:
211 case BTEMP_BALL:
212 case ACC_DETECT1:
213 case ADC_AUX1:
214 case ADC_AUX2:
215 /* For some reason we don't have calibrated data */
216 if (!gpadc->cal_data[ADC_INPUT_BTEMP].gain) {
217 res = ADC_CH_BTEMP_MIN + (ADC_CH_BTEMP_MAX -
218 ADC_CH_BTEMP_MIN) * ad_value /
219 ADC_RESOLUTION;
220 break;
221 }
222 /* Here we can use the calibrated data */
223 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_BTEMP].gain +
224 gpadc->cal_data[ADC_INPUT_BTEMP].offset) / CALIB_SCALE;
225 break;
226
227 case MAIN_BAT_V:
Lee Jonese4bffe82013-02-11 10:38:00 +0000228 case VBAT_TRUE_MEAS:
Johan Palsson586f3312011-03-05 11:46:37 +0100229 /* For some reason we don't have calibrated data */
230 if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) {
231 res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX -
232 ADC_CH_VBAT_MIN) * ad_value /
233 ADC_RESOLUTION;
234 break;
235 }
236 /* Here we can use the calibrated data */
237 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VBAT].gain +
238 gpadc->cal_data[ADC_INPUT_VBAT].offset) / CALIB_SCALE;
239 break;
240
241 case DIE_TEMP:
242 res = ADC_CH_DIETEMP_MIN +
243 (ADC_CH_DIETEMP_MAX - ADC_CH_DIETEMP_MIN) * ad_value /
244 ADC_RESOLUTION;
245 break;
246
247 case ACC_DETECT2:
248 res = ADC_CH_ACCDET2_MIN +
249 (ADC_CH_ACCDET2_MAX - ADC_CH_ACCDET2_MIN) * ad_value /
250 ADC_RESOLUTION;
251 break;
252
253 case VBUS_V:
254 res = ADC_CH_CHG_V_MIN +
255 (ADC_CH_CHG_V_MAX - ADC_CH_CHG_V_MIN) * ad_value /
256 ADC_RESOLUTION;
257 break;
258
259 case MAIN_CHARGER_C:
260 case USB_CHARGER_C:
261 res = ADC_CH_CHG_I_MIN +
262 (ADC_CH_CHG_I_MAX - ADC_CH_CHG_I_MIN) * ad_value /
263 ADC_RESOLUTION;
264 break;
265
266 case BK_BAT_V:
267 res = ADC_CH_BKBAT_MIN +
268 (ADC_CH_BKBAT_MAX - ADC_CH_BKBAT_MIN) * ad_value /
269 ADC_RESOLUTION;
270 break;
271
Lee Jonese4bffe82013-02-11 10:38:00 +0000272 case IBAT_VIRTUAL_CHANNEL:
273 /* For some reason we don't have calibrated data */
274 if (!gpadc->cal_data[ADC_INPUT_IBAT].gain) {
275 res = ADC_CH_IBAT_MIN + (ADC_CH_IBAT_MAX -
276 ADC_CH_IBAT_MIN) * ad_value /
277 ADC_RESOLUTION;
278 break;
279 }
280 /* Here we can use the calibrated data */
281 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_IBAT].gain +
282 gpadc->cal_data[ADC_INPUT_IBAT].offset)
283 >> CALIB_SHIFT_IBAT;
284 break;
285
Johan Palsson586f3312011-03-05 11:46:37 +0100286 default:
287 dev_err(gpadc->dev,
288 "unknown channel, not possible to convert\n");
289 res = -EINVAL;
290 break;
291
292 }
293 return res;
294}
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200295EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage);
Johan Palsson586f3312011-03-05 11:46:37 +0100296
Arun Murthydae2db32011-02-22 10:11:13 +0100297/**
Lee Jones73482342013-02-26 10:06:55 +0000298 * ab8500_gpadc_sw_hw_convert() - gpadc conversion
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200299 * @channel: analog channel to be converted to digital data
Lee Jones73482342013-02-26 10:06:55 +0000300 * @avg_sample: number of ADC sample to average
301 * @trig_egde: selected ADC trig edge
302 * @trig_timer: selected ADC trigger delay timer
303 * @conv_type: selected conversion type (HW or SW conversion)
Arun Murthydae2db32011-02-22 10:11:13 +0100304 *
305 * This function converts the selected analog i/p to digital
Johan Palsson586f3312011-03-05 11:46:37 +0100306 * data.
Arun Murthydae2db32011-02-22 10:11:13 +0100307 */
Lee Jones73482342013-02-26 10:06:55 +0000308int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel,
309 u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type)
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200310{
311 int ad_value;
312 int voltage;
313
Lee Jones73482342013-02-26 10:06:55 +0000314 ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample,
315 trig_edge, trig_timer, conv_type);
316/* On failure retry a second time */
Jonas Aabergd89cc5a2012-04-17 16:10:46 +0200317 if (ad_value < 0)
Lee Jones73482342013-02-26 10:06:55 +0000318 ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample,
319 trig_edge, trig_timer, conv_type);
320if (ad_value < 0) {
321 dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
322 channel);
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200323 return ad_value;
324 }
325
326 voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value);
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200327 if (voltage < 0)
328 dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
329 " %d AD: 0x%x\n", channel, ad_value);
330
331 return voltage;
332}
333EXPORT_SYMBOL(ab8500_gpadc_convert);
334
335/**
336 * ab8500_gpadc_read_raw() - gpadc read
337 * @channel: analog channel to be read
Lee Jones73482342013-02-26 10:06:55 +0000338 * @avg_sample: number of ADC sample to average
339 * @trig_edge: selected trig edge
340 * @trig_timer: selected ADC trigger delay timer
341 * @conv_type: selected conversion type (HW or SW conversion)
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200342 *
Lee Jones73482342013-02-26 10:06:55 +0000343 * This function obtains the raw ADC value for an hardware conversion,
344 * this then needs to be converted by calling ab8500_gpadc_ad_to_voltage()
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200345 */
Lee Jones73482342013-02-26 10:06:55 +0000346int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
347 u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type)
Arun Murthydae2db32011-02-22 10:11:13 +0100348{
Lee Jonese4bffe82013-02-11 10:38:00 +0000349 int raw_data;
350 raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
351 avg_sample, trig_edge, trig_timer, conv_type, NULL);
352 return raw_data;
353}
354
355int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
356 u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type,
357 int *ibat)
358{
Arun Murthydae2db32011-02-22 10:11:13 +0100359 int ret;
Arun Murthydae2db32011-02-22 10:11:13 +0100360 int looplimit = 0;
Lee Jonese4bffe82013-02-11 10:38:00 +0000361 u8 val, low_data, high_data, low_data2, high_data2;
Arun Murthydae2db32011-02-22 10:11:13 +0100362
Daniel Willerud63219922011-03-05 11:46:13 +0100363 if (!gpadc)
Arun Murthydae2db32011-02-22 10:11:13 +0100364 return -ENODEV;
365
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000366 /* check if convertion is supported */
367 if ((gpadc->irq_sw < 0) && (conv_type == ADC_SW))
368 return -ENOTSUPP;
369 if ((gpadc->irq_hw < 0) && (conv_type == ADC_HW))
370 return -ENOTSUPP;
371
Daniel Willerud63219922011-03-05 11:46:13 +0100372 mutex_lock(&gpadc->ab8500_gpadc_lock);
Arun Murthydae2db32011-02-22 10:11:13 +0100373 /* Enable VTVout LDO this is required for GPADC */
Lee Jones5f8aaef2013-02-04 08:33:13 +0000374 pm_runtime_get_sync(gpadc->dev);
Arun Murthydae2db32011-02-22 10:11:13 +0100375
376 /* Check if ADC is not busy, lock and proceed */
377 do {
Daniel Willerud63219922011-03-05 11:46:13 +0100378 ret = abx500_get_register_interruptible(gpadc->dev,
379 AB8500_GPADC, AB8500_GPADC_STAT_REG, &val);
Arun Murthydae2db32011-02-22 10:11:13 +0100380 if (ret < 0)
381 goto out;
382 if (!(val & GPADC_BUSY))
383 break;
384 msleep(10);
385 } while (++looplimit < 10);
386 if (looplimit >= 10 && (val & GPADC_BUSY)) {
Daniel Willerud63219922011-03-05 11:46:13 +0100387 dev_err(gpadc->dev, "gpadc_conversion: GPADC busy");
Arun Murthydae2db32011-02-22 10:11:13 +0100388 ret = -EINVAL;
389 goto out;
390 }
391
392 /* Enable GPADC */
Daniel Willerud63219922011-03-05 11:46:13 +0100393 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
394 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC);
Arun Murthydae2db32011-02-22 10:11:13 +0100395 if (ret < 0) {
Daniel Willerud63219922011-03-05 11:46:13 +0100396 dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
Arun Murthydae2db32011-02-22 10:11:13 +0100397 goto out;
398 }
Karl Komierowskic9c95132011-05-08 00:55:31 +0200399
Lee Jones73482342013-02-26 10:06:55 +0000400 /* Select the channel source and set average samples */
401 switch (avg_sample) {
402 case SAMPLE_1:
403 val = channel | AVG_1;
404 break;
405 case SAMPLE_4:
406 val = channel | AVG_4;
407 break;
408 case SAMPLE_8:
409 val = channel | AVG_8;
410 break;
411 default:
412 val = channel | AVG_16;
413 break;
Lee Jones73482342013-02-26 10:06:55 +0000414 }
415
416 if (conv_type == ADC_HW)
417 ret = abx500_set_register_interruptible(gpadc->dev,
418 AB8500_GPADC, AB8500_GPADC_CTRL3_REG, val);
419 else
420 ret = abx500_set_register_interruptible(gpadc->dev,
421 AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val);
Arun Murthydae2db32011-02-22 10:11:13 +0100422 if (ret < 0) {
Daniel Willerud63219922011-03-05 11:46:13 +0100423 dev_err(gpadc->dev,
Arun Murthydae2db32011-02-22 10:11:13 +0100424 "gpadc_conversion: set avg samples failed\n");
425 goto out;
426 }
Karl Komierowskic9c95132011-05-08 00:55:31 +0200427
Karl Komierowski4aad5a92011-03-05 11:46:45 +0100428 /*
429 * Enable ADC, buffering, select rising edge and enable ADC path
Karl Komierowskic9c95132011-05-08 00:55:31 +0200430 * charging current sense if it needed, ABB 3.0 needs some special
431 * treatment too.
Karl Komierowski4aad5a92011-03-05 11:46:45 +0100432 */
Lee Jones73482342013-02-26 10:06:55 +0000433 if ((conv_type == ADC_HW) && (trig_edge)) {
434 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
435 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
436 EN_FALLING, EN_FALLING);
Lee Jones73482342013-02-26 10:06:55 +0000437 }
Lee Jonese4bffe82013-02-11 10:38:00 +0000438
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200439 switch (channel) {
Karl Komierowski4aad5a92011-03-05 11:46:45 +0100440 case MAIN_CHARGER_C:
441 case USB_CHARGER_C:
Lee Jones73482342013-02-26 10:06:55 +0000442 if (conv_type == ADC_HW)
Karl Komierowskic9c95132011-05-08 00:55:31 +0200443 ret = abx500_mask_and_set_register_interruptible(
444 gpadc->dev,
445 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
Lee Jones73482342013-02-26 10:06:55 +0000446 EN_BUF | EN_ICHAR | EN_TRIG_EDGE,
447 EN_BUF | EN_ICHAR | EN_TRIG_EDGE);
448 else
449 ret = abx500_mask_and_set_register_interruptible(
450 gpadc->dev,
451 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
452 EN_BUF | EN_ICHAR,
453 EN_BUF | EN_ICHAR);
454 break;
Lee Jonese4bffe82013-02-11 10:38:00 +0000455
456 case XTAL_TEMP:
457 if (conv_type == ADC_HW)
458 ret = abx500_mask_and_set_register_interruptible(
459 gpadc->dev,
460 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
461 EN_BUF | EN_TRIG_EDGE,
462 EN_BUF | EN_TRIG_EDGE);
463 else
464 ret = abx500_mask_and_set_register_interruptible(
465 gpadc->dev,
466 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
467 EN_BUF ,
468 EN_BUF);
469 break;
470
471 case VBAT_TRUE_MEAS:
472 if (conv_type == ADC_HW)
473 ret = abx500_mask_and_set_register_interruptible(
474 gpadc->dev,
475 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
476 EN_BUF | EN_TRIG_EDGE,
477 EN_BUF | EN_TRIG_EDGE);
478 else
479 ret = abx500_mask_and_set_register_interruptible(
480 gpadc->dev,
481 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
482 EN_BUF ,
483 EN_BUF);
484 break;
485
486 case BAT_CTRL_AND_IBAT:
487 case VBAT_MEAS_AND_IBAT:
488 case VBAT_TRUE_MEAS_AND_IBAT:
489 case BAT_TEMP_AND_IBAT:
490 if (conv_type == ADC_HW)
491 ret = abx500_mask_and_set_register_interruptible(
492 gpadc->dev,
493 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
494 EN_TRIG_EDGE,
495 EN_TRIG_EDGE);
496 else
497 ret = abx500_mask_and_set_register_interruptible(
498 gpadc->dev,
499 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
500 EN_BUF,
501 0);
502 break;
503
Lee Jones73482342013-02-26 10:06:55 +0000504 case BTEMP_BALL:
505 if (!is_ab8500_2p0_or_earlier(gpadc->parent)) {
506 if (conv_type == ADC_HW)
507 /* Turn on btemp pull-up on ABB 3.0 */
508 ret = abx500_mask_and_set_register_interruptible
509 (gpadc->dev,
510 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
511 EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE,
512 EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE);
513 else
514 ret = abx500_mask_and_set_register_interruptible
515 (gpadc->dev,
516 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
517 EN_BUF | BTEMP_PULL_UP,
518 EN_BUF | BTEMP_PULL_UP);
Karl Komierowskic9c95132011-05-08 00:55:31 +0200519
520 /*
521 * Delay might be needed for ABB8500 cut 3.0, if not, remove
Masanari Iida5a4432b2012-08-13 21:00:25 +0900522 * when hardware will be available
Karl Komierowskic9c95132011-05-08 00:55:31 +0200523 */
Lee Jonesd0b32fa2011-08-29 08:32:36 +0200524 usleep_range(1000, 1000);
Karl Komierowskic9c95132011-05-08 00:55:31 +0200525 break;
526 }
527 /* Intentional fallthrough */
Karl Komierowski4aad5a92011-03-05 11:46:45 +0100528 default:
Lee Jones73482342013-02-26 10:06:55 +0000529 if (conv_type == ADC_HW)
530 ret = abx500_mask_and_set_register_interruptible(
531 gpadc->dev,
532 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
533 EN_BUF | EN_TRIG_EDGE,
534 EN_BUF | EN_TRIG_EDGE);
535 else
536 ret = abx500_mask_and_set_register_interruptible(
537 gpadc->dev,
538 AB8500_GPADC,
539 AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
Karl Komierowski4aad5a92011-03-05 11:46:45 +0100540 break;
541 }
Arun Murthydae2db32011-02-22 10:11:13 +0100542 if (ret < 0) {
Daniel Willerud63219922011-03-05 11:46:13 +0100543 dev_err(gpadc->dev,
Arun Murthydae2db32011-02-22 10:11:13 +0100544 "gpadc_conversion: select falling edge failed\n");
545 goto out;
546 }
Karl Komierowskic9c95132011-05-08 00:55:31 +0200547
Lee Jones73482342013-02-26 10:06:55 +0000548 /* Set trigger delay timer */
549 if (conv_type == ADC_HW) {
550 ret = abx500_set_register_interruptible(gpadc->dev,
551 AB8500_GPADC, AB8500_GPADC_AUTO_TIMER_REG, trig_timer);
552 if (ret < 0) {
553 dev_err(gpadc->dev,
554 "gpadc_conversion: trig timer failed\n");
555 goto out;
556 }
Arun Murthydae2db32011-02-22 10:11:13 +0100557 }
Lee Jones73482342013-02-26 10:06:55 +0000558
559 /* Start SW conversion */
560 if (conv_type == ADC_SW) {
561 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
562 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
563 ADC_SW_CONV, ADC_SW_CONV);
564 if (ret < 0) {
565 dev_err(gpadc->dev,
566 "gpadc_conversion: start s/w conv failed\n");
567 goto out;
568 }
569 }
570
Arun Murthydae2db32011-02-22 10:11:13 +0100571 /* wait for completion of conversion */
Lee Jones73482342013-02-26 10:06:55 +0000572 if (conv_type == ADC_HW) {
573 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete,
Lee Jonese4bffe82013-02-11 10:38:00 +0000574 2 * HZ)) {
575 dev_err(gpadc->dev,
576 "timeout didn't receive hw GPADC conv interrupt\n");
577 ret = -EINVAL;
578 goto out;
Lee Jones73482342013-02-26 10:06:55 +0000579 }
580 } else {
581 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete,
Lee Jonese4bffe82013-02-11 10:38:00 +0000582 msecs_to_jiffies(CONVERSION_TIME))) {
583 dev_err(gpadc->dev,
584 "timeout didn't receive sw GPADC conv interrupt\n");
585 ret = -EINVAL;
586 goto out;
Lee Jones73482342013-02-26 10:06:55 +0000587 }
Arun Murthydae2db32011-02-22 10:11:13 +0100588 }
589
590 /* Read the converted RAW data */
Lee Jones73482342013-02-26 10:06:55 +0000591 if (conv_type == ADC_HW) {
592 ret = abx500_get_register_interruptible(gpadc->dev,
593 AB8500_GPADC, AB8500_GPADC_AUTODATAL_REG, &low_data);
594 if (ret < 0) {
595 dev_err(gpadc->dev,
596 "gpadc_conversion: read hw low data failed\n");
597 goto out;
598 }
Arun Murthydae2db32011-02-22 10:11:13 +0100599
Lee Jones73482342013-02-26 10:06:55 +0000600 ret = abx500_get_register_interruptible(gpadc->dev,
601 AB8500_GPADC, AB8500_GPADC_AUTODATAH_REG, &high_data);
602 if (ret < 0) {
603 dev_err(gpadc->dev,
604 "gpadc_conversion: read hw high data failed\n");
605 goto out;
606 }
607 } else {
608 ret = abx500_get_register_interruptible(gpadc->dev,
609 AB8500_GPADC, AB8500_GPADC_MANDATAL_REG, &low_data);
610 if (ret < 0) {
611 dev_err(gpadc->dev,
612 "gpadc_conversion: read sw low data failed\n");
613 goto out;
614 }
615
616 ret = abx500_get_register_interruptible(gpadc->dev,
617 AB8500_GPADC, AB8500_GPADC_MANDATAH_REG, &high_data);
618 if (ret < 0) {
619 dev_err(gpadc->dev,
620 "gpadc_conversion: read sw high data failed\n");
621 goto out;
622 }
Arun Murthydae2db32011-02-22 10:11:13 +0100623 }
Lee Jonese4bffe82013-02-11 10:38:00 +0000624 /* Check if double convertion is required */
625 if ((channel == BAT_CTRL_AND_IBAT) ||
626 (channel == VBAT_MEAS_AND_IBAT) ||
627 (channel == VBAT_TRUE_MEAS_AND_IBAT) ||
628 (channel == BAT_TEMP_AND_IBAT)) {
629
630 if (conv_type == ADC_HW) {
631 /* not supported */
632 ret = -ENOTSUPP;
633 dev_err(gpadc->dev,
634 "gpadc_conversion: only SW double conversion supported\n");
635 goto out;
636 } else {
637 /* Read the converted RAW data 2 */
638 ret = abx500_get_register_interruptible(gpadc->dev,
639 AB8500_GPADC, AB8540_GPADC_MANDATA2L_REG,
640 &low_data2);
641 if (ret < 0) {
642 dev_err(gpadc->dev,
643 "gpadc_conversion: read sw low data 2 failed\n");
644 goto out;
645 }
646
647 ret = abx500_get_register_interruptible(gpadc->dev,
648 AB8500_GPADC, AB8540_GPADC_MANDATA2H_REG,
649 &high_data2);
650 if (ret < 0) {
651 dev_err(gpadc->dev,
652 "gpadc_conversion: read sw high data 2 failed\n");
653 goto out;
654 }
655 if (ibat != NULL) {
656 *ibat = (high_data2 << 8) | low_data2;
657 } else {
658 dev_warn(gpadc->dev,
659 "gpadc_conversion: ibat not stored\n");
660 }
661
662 }
663 }
Arun Murthydae2db32011-02-22 10:11:13 +0100664
Arun Murthydae2db32011-02-22 10:11:13 +0100665 /* Disable GPADC */
Daniel Willerud63219922011-03-05 11:46:13 +0100666 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
Arun Murthydae2db32011-02-22 10:11:13 +0100667 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
668 if (ret < 0) {
Daniel Willerud63219922011-03-05 11:46:13 +0100669 dev_err(gpadc->dev, "gpadc_conversion: disable gpadc failed\n");
Arun Murthydae2db32011-02-22 10:11:13 +0100670 goto out;
671 }
Lee Jones5f8aaef2013-02-04 08:33:13 +0000672
Lee Jones73482342013-02-26 10:06:55 +0000673 /* Disable VTVout LDO this is required for GPADC */
Lee Jones5f8aaef2013-02-04 08:33:13 +0000674 pm_runtime_mark_last_busy(gpadc->dev);
675 pm_runtime_put_autosuspend(gpadc->dev);
676
Daniel Willerud63219922011-03-05 11:46:13 +0100677 mutex_unlock(&gpadc->ab8500_gpadc_lock);
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200678
679 return (high_data << 8) | low_data;
Arun Murthydae2db32011-02-22 10:11:13 +0100680
681out:
682 /*
683 * It has shown to be needed to turn off the GPADC if an error occurs,
684 * otherwise we might have problem when waiting for the busy bit in the
685 * GPADC status register to go low. In V1.1 there wait_for_completion
686 * seems to timeout when waiting for an interrupt.. Not seen in V2.0
687 */
Daniel Willerud63219922011-03-05 11:46:13 +0100688 (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
Arun Murthydae2db32011-02-22 10:11:13 +0100689 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
Lee Jones5f8aaef2013-02-04 08:33:13 +0000690 pm_runtime_put(gpadc->dev);
Daniel Willerud63219922011-03-05 11:46:13 +0100691 mutex_unlock(&gpadc->ab8500_gpadc_lock);
692 dev_err(gpadc->dev,
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200693 "gpadc_conversion: Failed to AD convert channel %d\n", channel);
Arun Murthydae2db32011-02-22 10:11:13 +0100694 return ret;
695}
Karl Komierowskibd4a40b2011-08-10 15:09:43 +0200696EXPORT_SYMBOL(ab8500_gpadc_read_raw);
Arun Murthydae2db32011-02-22 10:11:13 +0100697
698/**
Lee Jones73482342013-02-26 10:06:55 +0000699 * ab8500_bm_gpadcconvend_handler() - isr for gpadc conversion completion
Arun Murthydae2db32011-02-22 10:11:13 +0100700 * @irq: irq number
701 * @data: pointer to the data passed during request irq
702 *
Lee Jones73482342013-02-26 10:06:55 +0000703 * This is a interrupt service routine for gpadc conversion completion.
Arun Murthydae2db32011-02-22 10:11:13 +0100704 * Notifies the gpadc completion is completed and the converted raw value
705 * can be read from the registers.
706 * Returns IRQ status(IRQ_HANDLED)
707 */
Lee Jones73482342013-02-26 10:06:55 +0000708static irqreturn_t ab8500_bm_gpadcconvend_handler(int irq, void *_gpadc)
Arun Murthydae2db32011-02-22 10:11:13 +0100709{
Daniel Willerud63219922011-03-05 11:46:13 +0100710 struct ab8500_gpadc *gpadc = _gpadc;
Arun Murthydae2db32011-02-22 10:11:13 +0100711
712 complete(&gpadc->ab8500_gpadc_complete);
713
714 return IRQ_HANDLED;
715}
716
Johan Palsson586f3312011-03-05 11:46:37 +0100717static int otp_cal_regs[] = {
718 AB8500_GPADC_CAL_1,
719 AB8500_GPADC_CAL_2,
720 AB8500_GPADC_CAL_3,
721 AB8500_GPADC_CAL_4,
722 AB8500_GPADC_CAL_5,
723 AB8500_GPADC_CAL_6,
724 AB8500_GPADC_CAL_7,
725};
726
Lee Jonese4bffe82013-02-11 10:38:00 +0000727static int otp4_cal_regs[] = {
728 AB8540_GPADC_OTP4_REG_7,
729 AB8540_GPADC_OTP4_REG_6,
730 AB8540_GPADC_OTP4_REG_5,
731};
732
Johan Palsson586f3312011-03-05 11:46:37 +0100733static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
734{
735 int i;
736 int ret[ARRAY_SIZE(otp_cal_regs)];
737 u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)];
Lee Jonese4bffe82013-02-11 10:38:00 +0000738 int ret_otp4[ARRAY_SIZE(otp4_cal_regs)];
739 u8 gpadc_otp4[ARRAY_SIZE(otp4_cal_regs)];
Johan Palsson586f3312011-03-05 11:46:37 +0100740 int vmain_high, vmain_low;
741 int btemp_high, btemp_low;
742 int vbat_high, vbat_low;
Lee Jonese4bffe82013-02-11 10:38:00 +0000743 int ibat_high, ibat_low;
744 s64 V_gain, V_offset, V2A_gain, V2A_offset;
745 struct ab8500 *ab8500;
746
747 ab8500 = gpadc->parent;
Johan Palsson586f3312011-03-05 11:46:37 +0100748
749 /* First we read all OTP registers and store the error code */
750 for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) {
751 ret[i] = abx500_get_register_interruptible(gpadc->dev,
752 AB8500_OTP_EMUL, otp_cal_regs[i], &gpadc_cal[i]);
753 if (ret[i] < 0)
754 dev_err(gpadc->dev, "%s: read otp reg 0x%02x failed\n",
755 __func__, otp_cal_regs[i]);
756 }
757
758 /*
759 * The ADC calibration data is stored in OTP registers.
760 * The layout of the calibration data is outlined below and a more
761 * detailed description can be found in UM0836
762 *
763 * vm_h/l = vmain_high/low
764 * bt_h/l = btemp_high/low
765 * vb_h/l = vbat_high/low
766 *
Lee Jonese4bffe82013-02-11 10:38:00 +0000767 * Data bits 8500/9540:
Johan Palsson586f3312011-03-05 11:46:37 +0100768 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
769 * |.......|.......|.......|.......|.......|.......|.......|.......
770 * | | vm_h9 | vm_h8
771 * |.......|.......|.......|.......|.......|.......|.......|.......
772 * | | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
773 * |.......|.......|.......|.......|.......|.......|.......|.......
774 * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
775 * |.......|.......|.......|.......|.......|.......|.......|.......
776 * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
777 * |.......|.......|.......|.......|.......|.......|.......|.......
778 * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
779 * |.......|.......|.......|.......|.......|.......|.......|.......
780 * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
781 * |.......|.......|.......|.......|.......|.......|.......|.......
782 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
783 * |.......|.......|.......|.......|.......|.......|.......|.......
784 *
Lee Jonese4bffe82013-02-11 10:38:00 +0000785 * Data bits 8540:
786 * OTP2
787 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
788 * |.......|.......|.......|.......|.......|.......|.......|.......
789 * |
790 * |.......|.......|.......|.......|.......|.......|.......|.......
791 * | vm_h9 | vm_h8 | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
792 * |.......|.......|.......|.......|.......|.......|.......|.......
793 * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
794 * |.......|.......|.......|.......|.......|.......|.......|.......
795 * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
796 * |.......|.......|.......|.......|.......|.......|.......|.......
797 * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
798 * |.......|.......|.......|.......|.......|.......|.......|.......
799 * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
800 * |.......|.......|.......|.......|.......|.......|.......|.......
801 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
802 * |.......|.......|.......|.......|.......|.......|.......|.......
803 *
804 * Data bits 8540:
805 * OTP4
806 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
807 * |.......|.......|.......|.......|.......|.......|.......|.......
808 * | | ib_h9 | ib_h8 | ib_h7
809 * |.......|.......|.......|.......|.......|.......|.......|.......
810 * | ib_h6 | ib_h5 | ib_h4 | ib_h3 | ib_h2 | ib_h1 | ib_h0 | ib_l5
811 * |.......|.......|.......|.......|.......|.......|.......|.......
812 * | ib_l4 | ib_l3 | ib_l2 | ib_l1 | ib_l0 |
813 *
Johan Palsson586f3312011-03-05 11:46:37 +0100814 *
815 * Ideal output ADC codes corresponding to injected input voltages
816 * during manufacturing is:
817 *
818 * vmain_high: Vin = 19500mV / ADC ideal code = 997
819 * vmain_low: Vin = 315mV / ADC ideal code = 16
820 * btemp_high: Vin = 1300mV / ADC ideal code = 985
821 * btemp_low: Vin = 21mV / ADC ideal code = 16
822 * vbat_high: Vin = 4700mV / ADC ideal code = 982
823 * vbat_low: Vin = 2380mV / ADC ideal code = 33
824 */
825
Lee Jonese4bffe82013-02-11 10:38:00 +0000826 if (is_ab8540(ab8500)) {
827 /* Calculate gain and offset for VMAIN if all reads succeeded*/
828 if (!(ret[1] < 0 || ret[2] < 0)) {
829 vmain_high = (((gpadc_cal[1] & 0xFF) << 2) |
830 ((gpadc_cal[2] & 0xC0) >> 6));
831 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
832 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
833 (19500 - 315) / (vmain_high - vmain_low);
834 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE *
835 19500 - (CALIB_SCALE * (19500 - 315) /
836 (vmain_high - vmain_low)) * vmain_high;
837 } else {
Johan Palsson586f3312011-03-05 11:46:37 +0100838 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
Lee Jonese4bffe82013-02-11 10:38:00 +0000839 }
Johan Palsson586f3312011-03-05 11:46:37 +0100840
Lee Jonese4bffe82013-02-11 10:38:00 +0000841 /* Read IBAT calibration Data */
842 for (i = 0; i < ARRAY_SIZE(otp4_cal_regs); i++) {
843 ret_otp4[i] = abx500_get_register_interruptible(
844 gpadc->dev, AB8500_OTP_EMUL,
845 otp4_cal_regs[i], &gpadc_otp4[i]);
846 if (ret_otp4[i] < 0)
847 dev_err(gpadc->dev,
848 "%s: read otp4 reg 0x%02x failed\n",
849 __func__, otp4_cal_regs[i]);
850 }
851
852 /* Calculate gain and offset for IBAT if all reads succeeded */
853 if (!(ret_otp4[0] < 0 || ret_otp4[1] < 0 || ret_otp4[2] < 0)) {
854 ibat_high = (((gpadc_otp4[0] & 0x07) << 7) |
855 ((gpadc_otp4[1] & 0xFE) >> 1));
856 ibat_low = (((gpadc_otp4[1] & 0x01) << 5) |
857 ((gpadc_otp4[2] & 0xF8) >> 3));
858
859 V_gain = ((IBAT_VDROP_H - IBAT_VDROP_L)
860 << CALIB_SHIFT_IBAT) / (ibat_high - ibat_low);
861
862 V_offset = (IBAT_VDROP_H << CALIB_SHIFT_IBAT) -
863 (((IBAT_VDROP_H - IBAT_VDROP_L) <<
864 CALIB_SHIFT_IBAT) / (ibat_high - ibat_low))
865 * ibat_high;
866 /*
867 * Result obtained is in mV (at a scale factor),
868 * we need to calculate gain and offset to get mA
869 */
870 V2A_gain = (ADC_CH_IBAT_MAX - ADC_CH_IBAT_MIN)/
871 (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V);
872 V2A_offset = ((ADC_CH_IBAT_MAX_V * ADC_CH_IBAT_MIN -
873 ADC_CH_IBAT_MAX * ADC_CH_IBAT_MIN_V)
874 << CALIB_SHIFT_IBAT)
875 / (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V);
876
877 gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
878 gpadc->cal_data[ADC_INPUT_IBAT].offset = V_offset *
879 V2A_gain + V2A_offset;
880 } else {
881 gpadc->cal_data[ADC_INPUT_IBAT].gain = 0;
882 }
883
884 dev_dbg(gpadc->dev, "IBAT gain %llu offset %llu\n",
885 gpadc->cal_data[ADC_INPUT_IBAT].gain,
886 gpadc->cal_data[ADC_INPUT_IBAT].offset);
887 } else {
888 /* Calculate gain and offset for VMAIN if all reads succeeded */
889 if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) {
890 vmain_high = (((gpadc_cal[0] & 0x03) << 8) |
891 ((gpadc_cal[1] & 0x3F) << 2) |
892 ((gpadc_cal[2] & 0xC0) >> 6));
893 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
894
895 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
896 (19500 - 315) / (vmain_high - vmain_low);
897
898 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE *
899 19500 - (CALIB_SCALE * (19500 - 315) /
900 (vmain_high - vmain_low)) * vmain_high;
901 } else {
902 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
903 }
904 }
Johan Palsson586f3312011-03-05 11:46:37 +0100905 /* Calculate gain and offset for BTEMP if all reads succeeded */
906 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) {
907 btemp_high = (((gpadc_cal[2] & 0x01) << 9) |
Lee Jonese4bffe82013-02-11 10:38:00 +0000908 (gpadc_cal[3] << 1) | ((gpadc_cal[4] & 0x80) >> 7));
Johan Palsson586f3312011-03-05 11:46:37 +0100909 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2);
910
911 gpadc->cal_data[ADC_INPUT_BTEMP].gain =
912 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low);
Johan Palsson586f3312011-03-05 11:46:37 +0100913 gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 -
Lee Jonese4bffe82013-02-11 10:38:00 +0000914 (CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low))
915 * btemp_high;
Johan Palsson586f3312011-03-05 11:46:37 +0100916 } else {
917 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0;
918 }
919
920 /* Calculate gain and offset for VBAT if all reads succeeded */
921 if (!(ret[4] < 0 || ret[5] < 0 || ret[6] < 0)) {
922 vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]);
923 vbat_low = ((gpadc_cal[6] & 0xFC) >> 2);
924
925 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE *
926 (4700 - 2380) / (vbat_high - vbat_low);
Johan Palsson586f3312011-03-05 11:46:37 +0100927 gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 -
928 (CALIB_SCALE * (4700 - 2380) /
929 (vbat_high - vbat_low)) * vbat_high;
930 } else {
931 gpadc->cal_data[ADC_INPUT_VBAT].gain = 0;
932 }
933
934 dev_dbg(gpadc->dev, "VMAIN gain %llu offset %llu\n",
935 gpadc->cal_data[ADC_INPUT_VMAIN].gain,
936 gpadc->cal_data[ADC_INPUT_VMAIN].offset);
937
938 dev_dbg(gpadc->dev, "BTEMP gain %llu offset %llu\n",
939 gpadc->cal_data[ADC_INPUT_BTEMP].gain,
940 gpadc->cal_data[ADC_INPUT_BTEMP].offset);
941
942 dev_dbg(gpadc->dev, "VBAT gain %llu offset %llu\n",
943 gpadc->cal_data[ADC_INPUT_VBAT].gain,
944 gpadc->cal_data[ADC_INPUT_VBAT].offset);
945}
946
Lee Jones5f8aaef2013-02-04 08:33:13 +0000947static int ab8500_gpadc_runtime_suspend(struct device *dev)
948{
949 struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
950
951 regulator_disable(gpadc->regu);
952 return 0;
953}
954
955static int ab8500_gpadc_runtime_resume(struct device *dev)
956{
957 struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
958
959 regulator_enable(gpadc->regu);
960 return 0;
961}
962
963static int ab8500_gpadc_runtime_idle(struct device *dev)
964{
Lee Jones5f8aaef2013-02-04 08:33:13 +0000965 pm_runtime_suspend(dev);
966 return 0;
967}
968
Daniel WILLERUD774c50a2012-04-12 08:15:05 +0200969static int ab8500_gpadc_suspend(struct device *dev)
970{
971 struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
972
973 mutex_lock(&gpadc->ab8500_gpadc_lock);
974
975 pm_runtime_get_sync(dev);
976
977 regulator_disable(gpadc->regu);
978 return 0;
979}
980
981static int ab8500_gpadc_resume(struct device *dev)
982{
983 struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
984
985 regulator_enable(gpadc->regu);
986
987 pm_runtime_mark_last_busy(gpadc->dev);
988 pm_runtime_put_autosuspend(gpadc->dev);
989
990 mutex_unlock(&gpadc->ab8500_gpadc_lock);
991 return 0;
992}
993
Bill Pembertonf791be42012-11-19 13:23:04 -0500994static int ab8500_gpadc_probe(struct platform_device *pdev)
Arun Murthydae2db32011-02-22 10:11:13 +0100995{
996 int ret = 0;
997 struct ab8500_gpadc *gpadc;
998
999 gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL);
1000 if (!gpadc) {
1001 dev_err(&pdev->dev, "Error: No memory\n");
1002 return -ENOMEM;
1003 }
1004
Lee Jones73482342013-02-26 10:06:55 +00001005 gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END");
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001006 if (gpadc->irq_sw < 0)
1007 dev_err(gpadc->dev, "failed to get platform sw_conv_end irq\n");
Lee Jones73482342013-02-26 10:06:55 +00001008
1009 gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END");
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001010 if (gpadc->irq_hw < 0)
1011 dev_err(gpadc->dev, "failed to get platform hw_conv_end irq\n");
Arun Murthydae2db32011-02-22 10:11:13 +01001012
1013 gpadc->dev = &pdev->dev;
Michel JAOUEN20bf4282012-02-09 12:06:47 +01001014 gpadc->parent = dev_get_drvdata(pdev->dev.parent);
Daniel Willerud63219922011-03-05 11:46:13 +01001015 mutex_init(&gpadc->ab8500_gpadc_lock);
Arun Murthydae2db32011-02-22 10:11:13 +01001016
1017 /* Initialize completion used to notify completion of conversion */
1018 init_completion(&gpadc->ab8500_gpadc_complete);
1019
Lee Jones73482342013-02-26 10:06:55 +00001020 /* Register interrupts */
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001021 if (gpadc->irq_sw >= 0) {
1022 ret = request_threaded_irq(gpadc->irq_sw, NULL,
1023 ab8500_bm_gpadcconvend_handler,
1024 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw",
1025 gpadc);
1026 if (ret < 0) {
1027 dev_err(gpadc->dev,
1028 "Failed to register interrupt irq: %d\n",
1029 gpadc->irq_sw);
1030 goto fail;
1031 }
Lee Jones73482342013-02-26 10:06:55 +00001032 }
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001033
1034 if (gpadc->irq_hw >= 0) {
1035 ret = request_threaded_irq(gpadc->irq_hw, NULL,
1036 ab8500_bm_gpadcconvend_handler,
1037 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw",
1038 gpadc);
1039 if (ret < 0) {
1040 dev_err(gpadc->dev,
1041 "Failed to register interrupt irq: %d\n",
1042 gpadc->irq_hw);
1043 goto fail_irq;
1044 }
Arun Murthydae2db32011-02-22 10:11:13 +01001045 }
1046
1047 /* VTVout LDO used to power up ab8500-GPADC */
1048 gpadc->regu = regulator_get(&pdev->dev, "vddadc");
1049 if (IS_ERR(gpadc->regu)) {
1050 ret = PTR_ERR(gpadc->regu);
1051 dev_err(gpadc->dev, "failed to get vtvout LDO\n");
Daniel Willerud633e0fa2011-03-05 11:46:27 +01001052 goto fail_irq;
Arun Murthydae2db32011-02-22 10:11:13 +01001053 }
Lee Jones5f8aaef2013-02-04 08:33:13 +00001054
1055 platform_set_drvdata(pdev, gpadc);
1056
1057 regulator_enable(gpadc->regu);
1058
1059 pm_runtime_set_autosuspend_delay(gpadc->dev, GPADC_AUDOSUSPEND_DELAY);
1060 pm_runtime_use_autosuspend(gpadc->dev);
1061 pm_runtime_set_active(gpadc->dev);
1062 pm_runtime_enable(gpadc->dev);
1063
Johan Palsson586f3312011-03-05 11:46:37 +01001064 ab8500_gpadc_read_calibration_data(gpadc);
Daniel Willerud63219922011-03-05 11:46:13 +01001065 list_add_tail(&gpadc->node, &ab8500_gpadc_list);
Arun Murthydae2db32011-02-22 10:11:13 +01001066 dev_dbg(gpadc->dev, "probe success\n");
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001067
Arun Murthydae2db32011-02-22 10:11:13 +01001068 return 0;
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001069
Daniel Willerud633e0fa2011-03-05 11:46:27 +01001070fail_irq:
Lee Jones73482342013-02-26 10:06:55 +00001071 free_irq(gpadc->irq_sw, gpadc);
1072 free_irq(gpadc->irq_hw, gpadc);
Arun Murthydae2db32011-02-22 10:11:13 +01001073fail:
1074 kfree(gpadc);
1075 gpadc = NULL;
1076 return ret;
1077}
1078
Bill Pemberton4740f732012-11-19 13:26:01 -05001079static int ab8500_gpadc_remove(struct platform_device *pdev)
Arun Murthydae2db32011-02-22 10:11:13 +01001080{
1081 struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
1082
Daniel Willerud63219922011-03-05 11:46:13 +01001083 /* remove this gpadc entry from the list */
1084 list_del(&gpadc->node);
Arun Murthydae2db32011-02-22 10:11:13 +01001085 /* remove interrupt - completion of Sw ADC conversion */
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001086 if (gpadc->irq_sw >= 0)
1087 free_irq(gpadc->irq_sw, gpadc);
1088 if (gpadc->irq_hw >= 0)
1089 free_irq(gpadc->irq_hw, gpadc);
Lee Jones5f8aaef2013-02-04 08:33:13 +00001090
1091 pm_runtime_get_sync(gpadc->dev);
1092 pm_runtime_disable(gpadc->dev);
1093
1094 regulator_disable(gpadc->regu);
1095
1096 pm_runtime_set_suspended(gpadc->dev);
1097
1098 pm_runtime_put_noidle(gpadc->dev);
1099
Arun Murthydae2db32011-02-22 10:11:13 +01001100 kfree(gpadc);
1101 gpadc = NULL;
1102 return 0;
1103}
1104
Lee Jones5f8aaef2013-02-04 08:33:13 +00001105static const struct dev_pm_ops ab8500_gpadc_pm_ops = {
1106 SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend,
1107 ab8500_gpadc_runtime_resume,
1108 ab8500_gpadc_runtime_idle)
Daniel WILLERUD774c50a2012-04-12 08:15:05 +02001109 SET_SYSTEM_SLEEP_PM_OPS(ab8500_gpadc_suspend,
1110 ab8500_gpadc_resume)
1111
Lee Jones5f8aaef2013-02-04 08:33:13 +00001112};
1113
Arun Murthydae2db32011-02-22 10:11:13 +01001114static struct platform_driver ab8500_gpadc_driver = {
1115 .probe = ab8500_gpadc_probe,
Bill Pemberton84449212012-11-19 13:20:24 -05001116 .remove = ab8500_gpadc_remove,
Arun Murthydae2db32011-02-22 10:11:13 +01001117 .driver = {
1118 .name = "ab8500-gpadc",
1119 .owner = THIS_MODULE,
Lee Jones5f8aaef2013-02-04 08:33:13 +00001120 .pm = &ab8500_gpadc_pm_ops,
Arun Murthydae2db32011-02-22 10:11:13 +01001121 },
1122};
1123
1124static int __init ab8500_gpadc_init(void)
1125{
1126 return platform_driver_register(&ab8500_gpadc_driver);
1127}
1128
1129static void __exit ab8500_gpadc_exit(void)
1130{
1131 platform_driver_unregister(&ab8500_gpadc_driver);
1132}
1133
1134subsys_initcall_sync(ab8500_gpadc_init);
1135module_exit(ab8500_gpadc_exit);
1136
1137MODULE_LICENSE("GPL v2");
Lee Jones73482342013-02-26 10:06:55 +00001138MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
1139 "M'boumba Cedric Madianga");
Arun Murthydae2db32011-02-22 10:11:13 +01001140MODULE_ALIAS("platform:ab8500_gpadc");
1141MODULE_DESCRIPTION("AB8500 GPADC driver");