blob: bcc85f3efbd81e72ceb388ecd5979ded1e9d22bd [file] [log] [blame]
Siddartha Mohanadoss31f60962012-11-27 14:11:02 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/kernel.h>
17#include <linux/of.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/types.h>
24#include <linux/hwmon.h>
25#include <linux/module.h>
26#include <linux/debugfs.h>
27#include <linux/spmi.h>
28#include <linux/of_irq.h>
29#include <linux/wakelock.h>
30#include <linux/interrupt.h>
31#include <linux/completion.h>
32#include <linux/hwmon-sysfs.h>
33#include <linux/qpnp/qpnp-adc.h>
34#include <linux/thermal.h>
35#include <linux/platform_device.h>
36
37/* QPNP VADC TM register definition */
38#define QPNP_STATUS1 0x8
39#define QPNP_STATUS1_OP_MODE 4
40#define QPNP_STATUS1_MEAS_INTERVAL_EN_STS BIT(2)
41#define QPNP_STATUS1_REQ_STS BIT(1)
42#define QPNP_STATUS1_EOC BIT(0)
43#define QPNP_STATUS2 0x9
44#define QPNP_STATUS2_CONV_SEQ_STATE 6
45#define QPNP_STATUS2_FIFO_NOT_EMPTY_FLAG BIT(1)
46#define QPNP_STATUS2_CONV_SEQ_TIMEOUT_STS BIT(0)
47#define QPNP_CONV_TIMEOUT_ERR 2
48
49#define QPNP_MODE_CTL 0x40
50#define QPNP_OP_MODE_SHIFT 3
51#define QPNP_VREF_XO_THM_FORCE BIT(2)
52#define QPNP_AMUX_TRIM_EN BIT(1)
53#define QPNP_ADC_TRIM_EN BIT(0)
54#define QPNP_EN_CTL1 0x46
55#define QPNP_ADC_TM_EN BIT(7)
56#define QPNP_ADC_CH_SEL_CTL 0x48
57#define QPNP_ADC_DIG_PARAM 0x50
58#define QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT 3
59#define QPNP_HW_SETTLE_DELAY 0x51
60#define QPNP_CONV_REQ 0x52
61#define QPNP_CONV_REQ_SET BIT(7)
62#define QPNP_CONV_SEQ_CTL 0x54
63#define QPNP_CONV_SEQ_HOLDOFF_SHIFT 4
64#define QPNP_CONV_SEQ_TRIG_CTL 0x55
65#define QPNP_ADC_TM_MEAS_INTERVAL_CTL 0x57
66#define QPNP_ADC_TM_MEAS_INTERVAL_TIME_SHIFT 0x3
67#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2 0x58
68#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT 0x4
69#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2_MASK 0xf0
70#define QPNP_ADC_TM_MEAS_INTERVAL_CTL3_MASK 0xf
71
72#define QPNP_ADC_MEAS_INTERVAL_OP_CTL 0x59
73#define QPNP_ADC_MEAS_INTERVAL_OP BIT(7)
74
75#define QPNP_FAST_AVG_CTL 0x5a
76#define QPNP_FAST_AVG_EN 0x5b
77
78#define QPNP_M0_LOW_THR_LSB 0x5c
79#define QPNP_M0_LOW_THR_MSB 0x5d
80#define QPNP_M0_HIGH_THR_LSB 0x5e
81#define QPNP_M0_HIGH_THR_MSB 0x5f
82#define QPNP_M1_LOW_THR_LSB 0x69
83#define QPNP_M1_LOW_THR_MSB 0x6a
84#define QPNP_M1_HIGH_THR_LSB 0x6b
85#define QPNP_M1_HIGH_THR_MSB 0x6c
86#define QPNP_M2_LOW_THR_LSB 0x71
87#define QPNP_M2_LOW_THR_MSB 0x72
88#define QPNP_M2_HIGH_THR_LSB 0x7b
89#define QPNP_M2_HIGH_THR_MSB 0x7c
90#define QPNP_M3_LOW_THR_LSB 0x79
91#define QPNP_M3_LOW_THR_MSB 0x7a
92#define QPNP_M3_HIGH_THR_LSB 0x7b
93#define QPNP_M3_HIGH_THR_MSB 0x7c
94#define QPNP_M4_LOW_THR_LSB 0x81
95#define QPNP_M4_LOW_THR_MSB 0x82
96#define QPNP_M4_HIGH_THR_LSB 0x83
97#define QPNP_M4_HIGH_THR_MSB 0x84
98
99#define QPNP_ADC_TM_MULTI_MEAS_EN 0x41
100#define QPNP_ADC_TM_MULTI_MEAS_EN_M0 BIT(0)
101#define QPNP_ADC_TM_MULTI_MEAS_EN_M1 BIT(1)
102#define QPNP_ADC_TM_MULTI_MEAS_EN_M2 BIT(2)
103#define QPNP_ADC_TM_MULTI_MEAS_EN_M3 BIT(3)
104#define QPNP_ADC_TM_MULTI_MEAS_EN_M4 BIT(4)
105#define QPNP_ADC_TM_LOW_THR_INT_EN 0x42
106#define QPNP_ADC_TM_LOW_THR_INT_EN_M0 BIT(0)
107#define QPNP_ADC_TM_LOW_THR_INT_EN_M1 BIT(1)
108#define QPNP_ADC_TM_LOW_THR_INT_EN_M2 BIT(2)
109#define QPNP_ADC_TM_LOW_THR_INT_EN_M3 BIT(3)
110#define QPNP_ADC_TM_LOW_THR_INT_EN_M4 BIT(4)
111#define QPNP_ADC_TM_HIGH_THR_INT_EN 0x43
112#define QPNP_ADC_TM_HIGH_THR_INT_EN_M0 BIT(0)
113#define QPNP_ADC_TM_HIGH_THR_INT_EN_M1 BIT(1)
114#define QPNP_ADC_TM_HIGH_THR_INT_EN_M2 BIT(2)
115#define QPNP_ADC_TM_HIGH_THR_INT_EN_M3 BIT(3)
116#define QPNP_ADC_TM_HIGH_THR_INT_EN_M4 BIT(4)
117
118#define QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL 0x57
119#define QPNP_ADC_TM_M1_MEAS_INTERVAL_CTL 0x6d
120#define QPNP_ADC_TM_M2_MEAS_INTERVAL_CTL 0x75
121#define QPNP_ADC_TM_M3_MEAS_INTERVAL_CTL 0x7d
122#define QPNP_ADC_TM_M4_MEAS_INTERVAL_CTL 0x85
123#define QPNP_ADC_TM_STATUS1 0x8
124#define QPNP_ADC_TM_STATUS_LOW 0xa
125#define QPNP_ADC_TM_STATUS_HIGH 0xb
126
127#define QPNP_ADC_TM_M0_LOW_THR 0x5d5c
128#define QPNP_ADC_TM_M0_HIGH_THR 0x5f5e
129#define QPNP_ADC_TM_MEAS_INTERVAL 0x0
130
131#define QPNP_ADC_TM_THR_LSB_MASK(val) (val & 0xff)
132#define QPNP_ADC_TM_THR_MSB_MASK(val) ((val & 0xff00) >> 8)
133
134struct qpnp_adc_tm_sensor {
135 struct thermal_zone_device *tz_dev;
136 enum thermal_device_mode mode;
137 uint32_t sensor_num;
138 enum qpnp_adc_meas_timer_select timer_select;
139 uint32_t meas_interval;
140 uint32_t low_thr;
141 uint32_t high_thr;
142 uint32_t btm_channel_num;
143 struct work_struct work;
144};
145
146struct qpnp_adc_tm_drv {
147 struct qpnp_adc_drv *adc;
148 struct qpnp_adc_tm_usbid_param *usb_id_param;
149 struct work_struct usbid_work;
150 struct qpnp_adc_tm_btm_param *battery_param;
151 struct work_struct batt_work;
152 bool adc_tm_initialized;
153 struct qpnp_adc_tm_sensor sensor[0];
154};
155
156struct qpnp_adc_tm_drv *qpnp_adc_tm;
157
158struct qpnp_adc_tm_trip_reg_type {
159 uint16_t low_thr_lsb_addr;
160 uint16_t low_thr_msb_addr;
161 uint16_t high_thr_lsb_addr;
162 uint16_t high_thr_msb_addr;
163 u8 multi_meas_en;
164 u8 low_thr_int_chan_en;
165 u8 high_thr_int_chan_en;
166};
167
168static struct qpnp_adc_tm_trip_reg_type adc_tm_data[] = {
169 [QPNP_ADC_TM_M0_ADC_CH_SEL_CTL] = {QPNP_M0_LOW_THR_LSB,
170 QPNP_M0_LOW_THR_MSB, QPNP_M0_HIGH_THR_LSB,
171 QPNP_M0_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M0,
172 QPNP_ADC_TM_LOW_THR_INT_EN_M0, QPNP_ADC_TM_HIGH_THR_INT_EN_M0},
173 [QPNP_ADC_TM_M1_ADC_CH_SEL_CTL] = {QPNP_M1_LOW_THR_LSB,
174 QPNP_M1_LOW_THR_MSB, QPNP_M1_HIGH_THR_LSB,
175 QPNP_M1_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M1,
176 QPNP_ADC_TM_LOW_THR_INT_EN_M1, QPNP_ADC_TM_HIGH_THR_INT_EN_M1},
177 [QPNP_ADC_TM_M2_ADC_CH_SEL_CTL] = {QPNP_M2_LOW_THR_LSB,
178 QPNP_M2_LOW_THR_MSB, QPNP_M2_HIGH_THR_LSB,
179 QPNP_M2_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M2,
180 QPNP_ADC_TM_LOW_THR_INT_EN_M2, QPNP_ADC_TM_HIGH_THR_INT_EN_M2},
181 [QPNP_ADC_TM_M3_ADC_CH_SEL_CTL] = {QPNP_M3_LOW_THR_LSB,
182 QPNP_M3_LOW_THR_MSB, QPNP_M3_HIGH_THR_LSB,
183 QPNP_M3_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M3,
184 QPNP_ADC_TM_LOW_THR_INT_EN_M3, QPNP_ADC_TM_HIGH_THR_INT_EN_M3},
185 [QPNP_ADC_TM_M4_ADC_CH_SEL_CTL] = {QPNP_M4_LOW_THR_LSB,
186 QPNP_M4_LOW_THR_MSB, QPNP_M4_HIGH_THR_LSB,
187 QPNP_M4_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M4,
188 QPNP_ADC_TM_LOW_THR_INT_EN_M4, QPNP_ADC_TM_HIGH_THR_INT_EN_M4},
189};
190
191static int32_t qpnp_adc_tm_read_reg(int16_t reg, u8 *data)
192{
193 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
194 int rc = 0;
195
196 rc = spmi_ext_register_readl(adc_tm->adc->spmi->ctrl,
197 adc_tm->adc->slave, (adc_tm->adc->offset + reg), data, 1);
198 if (rc < 0)
199 pr_err("adc-tm read reg %d failed with %d\n", reg, rc);
200
201 return rc;
202}
203
204static int32_t qpnp_adc_tm_write_reg(int16_t reg, u8 data)
205{
206 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
207 int rc = 0;
208 u8 *buf;
209
210 buf = &data;
211
212 rc = spmi_ext_register_writel(adc_tm->adc->spmi->ctrl,
213 adc_tm->adc->slave, (adc_tm->adc->offset + reg), buf, 1);
214 if (rc < 0)
215 pr_err("adc-tm write reg %d failed with %d\n", reg, rc);
216
217 return rc;
218}
219
220static int32_t qpnp_adc_tm_enable(bool state)
221{
222 int rc = 0;
223 u8 data = 0, enable_check = 0;
224
225 if (state) {
226 data = QPNP_ADC_TM_EN;
227 rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1,
228 data);
229 if (rc < 0)
230 pr_err("adc-tm enable failed\n");
231 } else {
232 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
233 &enable_check);
234 if (rc < 0) {
235 pr_err("multi measurement read failed\n");
236 return rc;
237 }
238
239 if (!enable_check) {
240 data = 0;
241 rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
242 if (rc < 0)
243 pr_err("adc-tm disable failed\n");
244 }
245 }
246
247 return rc;
248}
249
250static int32_t qpnp_adc_tm_enable_req_sts_check(void)
251{
252 u8 status1;
253 int rc;
254
255 /* The VADC_TM bank needs to be disabled for new conversion request */
256 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS1, &status1);
257 if (rc) {
258 pr_err("adc-tm read status1 failed\n");
259 return rc;
260 }
261
262 /* Disable the bank if a conversion is occuring */
263 if (status1 & QPNP_STATUS1_REQ_STS) {
264 rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, 0);
265 if (rc < 0)
266 pr_err("adc-tm disable failed\n");
267 }
268
269 return rc;
270}
271
272static int32_t qpnp_adc_tm_mode_select(u8 mode_ctl)
273{
274 int rc;
275
276 /* VADC_BTM current sets mode to recurring measurements */
277 rc = qpnp_adc_tm_write_reg(QPNP_MODE_CTL, mode_ctl);
278 if (rc < 0)
279 pr_err("adc-tm write mode selection err\n");
280
281 return rc;
282}
283
284static int32_t qpnp_adc_tm_timer_interval_select(
285 struct qpnp_vadc_chan_properties *chan_prop)
286{
287 int rc;
288 u8 meas_interval_timer2 = 0;
289
290 /* Configure USB_ID to timer1, batt_therm to timer2 */
291 switch (chan_prop->timer_select) {
292 case ADC_MEAS_TIMER_SELECT1:
293 rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL,
294 chan_prop->meas_interval1);
295 if (rc < 0) {
296 pr_err("timer1 configure failed\n");
297 return rc;
298 }
299 break;
300 case ADC_MEAS_TIMER_SELECT2:
301 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
302 &meas_interval_timer2);
303 if (rc < 0) {
304 pr_err("timer2 configure read failed\n");
305 return rc;
306 }
307 meas_interval_timer2 |=
308 (chan_prop->meas_interval2 <<
309 QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT);
310 rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
311 meas_interval_timer2);
312 if (rc < 0) {
313 pr_err("timer2 configure failed\n");
314 return rc;
315 }
316 break;
317 case ADC_MEAS_TIMER_SELECT3:
318 /* Thermal channels uses timer3, default to 1 second */
319 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
320 &meas_interval_timer2);
321 if (rc < 0) {
322 pr_err("timer3 read failed\n");
323 return rc;
324 }
325 chan_prop->meas_interval2 = ADC_MEAS3_INTERVAL_1S;
326 meas_interval_timer2 |= chan_prop->meas_interval2;
327 rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
328 meas_interval_timer2);
329 if (rc < 0) {
330 pr_err("timer3 configure failed\n");
331 return rc;
332 }
333 break;
334 default:
335 pr_err("Invalid timer selection\n");
336 return -EINVAL;
337 }
338
339 return rc;
340}
341
342static int32_t qpnp_adc_tm_meas_int_update(uint16_t reg_addr_src,
343 u8 reg_addr_dst, bool state)
344{
345 u8 bit_mask_check = 0;
346 int rc = 0;
347
348 rc = qpnp_adc_tm_read_reg(reg_addr_src, &bit_mask_check);
349 if (rc < 0) {
350 pr_err("read failed for addr:%x\n", reg_addr_src);
351 return rc;
352 }
353
354 if (state)
355 bit_mask_check |= reg_addr_dst;
356 else
357 bit_mask_check &= ~reg_addr_dst;
358
359 rc = qpnp_adc_tm_write_reg(reg_addr_src, bit_mask_check);
360 if (rc < 0)
361 pr_err("write failed for addr:%x\n", reg_addr_src);
362
363 return rc;
364}
365
366static int32_t qpnp_adc_tm_usbid_btm_thr_en(uint32_t btm_chan,
367 struct qpnp_vadc_chan_properties *chan_prop)
368{
369 int rc = 0;
370
371 rc = qpnp_adc_tm_write_reg(
372 adc_tm_data[btm_chan].low_thr_lsb_addr,
373 QPNP_ADC_TM_THR_LSB_MASK(chan_prop->low_thr));
374 if (rc < 0) {
375 pr_err("low threshold lsb setting failed\n");
376 return rc;
377 }
378
379 rc = qpnp_adc_tm_write_reg(
380 adc_tm_data[btm_chan].low_thr_msb_addr,
381 QPNP_ADC_TM_THR_MSB_MASK(chan_prop->low_thr));
382 if (rc < 0) {
383 pr_err("low threshold msb setting failed\n");
384 return rc;
385 }
386
387 rc = qpnp_adc_tm_write_reg(
388 adc_tm_data[btm_chan].high_thr_lsb_addr,
389 QPNP_ADC_TM_THR_LSB_MASK(chan_prop->high_thr));
390 if (rc < 0) {
391 pr_err("high threshold lsb setting failed\n");
392 return rc;
393 }
394
395 rc = qpnp_adc_tm_write_reg(
396 adc_tm_data[btm_chan].high_thr_msb_addr,
397 QPNP_ADC_TM_THR_MSB_MASK(chan_prop->high_thr));
398 if (rc < 0)
399 pr_err("high threshold msb setting failed\n");
400
401 return rc;
402}
403
404static int32_t qpnp_adc_tm_channel_configure(uint32_t btm_chan,
405 struct qpnp_vadc_chan_properties *chan_prop,
406 uint32_t amux_channel)
407{
408 int rc = 0;
409
410 switch (btm_chan) {
411 case QPNP_ADC_TM_M0_ADC_CH_SEL_CTL:
412 case QPNP_ADC_TM_M1_ADC_CH_SEL_CTL:
413 /* Update low and high notification thresholds */
414 rc = qpnp_adc_tm_usbid_btm_thr_en(btm_chan,
415 chan_prop);
416 if (rc < 0) {
417 pr_err("setting chan:%d threshold failed\n", btm_chan);
418 return rc;
419 }
420
421 if ((chan_prop->state_request ==
422 ADC_TM_LOW_THR_ENABLE) ||
423 (chan_prop->state_request ==
424 ADC_TM_HIGH_LOW_THR_ENABLE)) {
425 /* Enable low threshold's interrupt */
426 rc = qpnp_adc_tm_meas_int_update(
427 QPNP_ADC_TM_LOW_THR_INT_EN,
428 adc_tm_data[btm_chan].low_thr_int_chan_en,
429 true);
430 if (rc < 0) {
431 pr_err("low thr enable err:%d\n", btm_chan);
432 return rc;
433 }
434 }
435
436 if ((chan_prop->state_request ==
437 ADC_TM_HIGH_THR_ENABLE) ||
438 (chan_prop->state_request ==
439 ADC_TM_HIGH_LOW_THR_ENABLE)) {
440 /* Enable high threshold's interrupt */
441 rc = qpnp_adc_tm_meas_int_update(
442 QPNP_ADC_TM_HIGH_THR_INT_EN,
443 adc_tm_data[btm_chan].high_thr_int_chan_en,
444 true);
445 if (rc < 0) {
446 pr_err("high thr enable err:%d\n", btm_chan);
447 return rc;
448 }
449 }
450 /* intention fall through to configure common chan meas */
451 case QPNP_ADC_TM_M2_ADC_CH_SEL_CTL:
452 case QPNP_ADC_TM_M3_ADC_CH_SEL_CTL:
453 case QPNP_ADC_TM_M4_ADC_CH_SEL_CTL:
454 /* Configure AMUX control register for channel selection */
455 rc = qpnp_adc_tm_write_reg(btm_chan, amux_channel);
456 if (rc < 0) {
457 pr_err("btm_chan:%d selection failed\n", btm_chan);
458 return rc;
459 }
460
461 /* Enable corresponding BTM channel measurement */
462 rc = qpnp_adc_tm_meas_int_update(
463 QPNP_ADC_TM_MULTI_MEAS_EN,
464 adc_tm_data[btm_chan].multi_meas_en, true);
465 if (rc < 0) {
466 pr_err("multi measurement en failed\n");
467 return rc;
468 }
469 break;
470 default:
471 return -EINVAL;
472 }
473
474 return rc;
475}
476
477static int32_t qpnp_adc_tm_configure(
478 struct qpnp_adc_amux_properties *chan_prop)
479{
480 u8 decimation = 0;
481 int rc = 0;
482 uint32_t btm_chan = 0;
483
484 /* Check if a conversion is in progress */
485 rc = qpnp_adc_tm_enable_req_sts_check();
486 if (rc < 0) {
487 pr_err("adc-tm req_sts check failed\n");
488 return rc;
489 }
490
491 /* Set measurement in recurring mode */
492 rc = qpnp_adc_tm_mode_select(chan_prop->mode_sel);
493 if (rc < 0) {
494 pr_err("adc-tm mode select failed\n");
495 return rc;
496 }
497
498 /* Configure AMUX channel */
499 rc = qpnp_adc_tm_write_reg(QPNP_ADC_CH_SEL_CTL,
500 chan_prop->amux_channel);
501 if (rc < 0) {
502 pr_err("adc-tm channel selection err\n");
503 return rc;
504 }
505
506 /* Digital paramater setup */
507 decimation |= chan_prop->decimation <<
508 QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT;
509 rc = qpnp_adc_tm_write_reg(QPNP_ADC_DIG_PARAM, decimation);
510 if (rc < 0) {
511 pr_err("adc-tm digital parameter setup err\n");
512 return rc;
513 }
514
515 /* Hardware setting time */
516 rc = qpnp_adc_tm_write_reg(QPNP_HW_SETTLE_DELAY,
517 chan_prop->hw_settle_time);
518 if (rc < 0) {
519 pr_err("adc-tm hw settling time setup err\n");
520 return rc;
521 }
522
523 /* Fast averaging setup */
524 rc = qpnp_adc_tm_write_reg(QPNP_FAST_AVG_CTL,
525 chan_prop->fast_avg_setup);
526 if (rc < 0) {
527 pr_err("adc-tm fast-avg setup err\n");
528 return rc;
529 }
530
531 /* Measurement interval setup */
532 rc = qpnp_adc_tm_timer_interval_select(chan_prop->chan_prop);
533 if (rc < 0) {
534 pr_err("adc-tm timer select failed\n");
535 return rc;
536 }
537
538 /* Channel configuration setup */
539 btm_chan = chan_prop->chan_prop->tm_channel_select;
540 rc = qpnp_adc_tm_channel_configure(btm_chan, chan_prop->chan_prop,
541 chan_prop->amux_channel);
542 if (rc < 0) {
543 pr_err("adc-tm channel configure failed\n");
544 return rc;
545 }
546
547 /* Enable bank */
548 rc = qpnp_adc_tm_enable(true);
549 if (rc)
550 return rc;
551
552 /* Recurring interval measurement enable */
553 rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_MEAS_INTERVAL_OP_CTL,
554 QPNP_ADC_MEAS_INTERVAL_OP, true);
555 if (rc < 0) {
556 pr_err("adc-tm meas interval op configure failed\n");
557 return rc;
558 }
559
560 /* Request conversion */
561 rc = qpnp_adc_tm_write_reg(QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
562 if (rc < 0) {
563 pr_err("adc-tm request conversion failed\n");
564 return rc;
565 }
566
567 return 0;
568}
569
570static int qpnp_adc_tm_get_mode(struct thermal_zone_device *thermal,
571 enum thermal_device_mode *mode)
572{
573 struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
574
575 if (!adc_tm || !mode)
576 return -EINVAL;
577
578 *mode = adc_tm->mode;
579
580 return 0;
581}
582
583static int qpnp_adc_tm_set_mode(struct thermal_zone_device *thermal,
584 enum thermal_device_mode mode)
585{
586 struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
587 struct qpnp_adc_tm_drv *adc_drv = qpnp_adc_tm;
588 int rc = 0, channel;
589
590 if (!adc_tm)
591 return -EINVAL;
592
593 if (mode == THERMAL_DEVICE_ENABLED) {
594 adc_drv->adc->amux_prop->amux_channel = adc_tm->sensor_num;
595 channel = adc_tm->sensor_num;
596 adc_drv->adc->amux_prop->decimation =
597 adc_drv->adc->adc_channels[channel].adc_decimation;
598 adc_drv->adc->amux_prop->hw_settle_time =
599 adc_drv->adc->adc_channels[channel].hw_settle_time;
600 adc_drv->adc->amux_prop->fast_avg_setup =
601 adc_drv->adc->adc_channels[channel].fast_avg_setup;
602 adc_drv->adc->amux_prop->mode_sel =
603 ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
604 adc_drv->adc->amux_prop->chan_prop->timer_select =
605 ADC_MEAS_TIMER_SELECT1;
606 adc_drv->adc->amux_prop->chan_prop->meas_interval1 =
607 ADC_MEAS1_INTERVAL_1S;
608 adc_drv->adc->amux_prop->chan_prop->low_thr = adc_tm->low_thr;
609 adc_drv->adc->amux_prop->chan_prop->high_thr = adc_tm->high_thr;
610 adc_drv->adc->amux_prop->chan_prop->tm_channel_select =
611 adc_tm->btm_channel_num;
612
613 rc = qpnp_adc_tm_configure(adc_drv->adc->amux_prop);
614 if (rc) {
615 pr_err("adc-tm tm configure failed with %d\n", rc);
616 return -EINVAL;
617 }
618 } else if (mode == THERMAL_DEVICE_DISABLED) {
619 rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_MULTI_MEAS_EN,
620 adc_tm_data[adc_tm->btm_channel_num].multi_meas_en,
621 false);
622 if (rc < 0) {
623 pr_err("multi measurement update failed\n");
624 return rc;
625 }
626
627 rc = qpnp_adc_tm_enable(false);
628 if (rc < 0) {
629 pr_err("adc-tm disable failed\n");
630 return rc;
631 }
632 }
633
634 adc_tm->mode = mode;
635
636 return 0;
637}
638
639static int qpnp_adc_tm_get_trip_type(struct thermal_zone_device *thermal,
640 int trip, enum thermal_trip_type *type)
641{
642 struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
643
644 if (!adc_tm || !type || type < 0)
645 return -EINVAL;
646
647 switch (trip) {
648 case ADC_TM_TRIP_HIGH_WARM:
649 *type = THERMAL_TRIP_CONFIGURABLE_HI;
650 break;
651 case ADC_TM_TRIP_LOW_COOL:
652 *type = THERMAL_TRIP_CONFIGURABLE_LOW;
653 break;
654 default:
655 return -EINVAL;
656 }
657
658 return 0;
659}
660
661static int qpnp_adc_tm_get_trip_temp(struct thermal_zone_device *thermal,
662 int trip, unsigned long *temp)
663{
664 struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
665 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
666 int64_t result = 0;
667 u8 trip_cool_thr0, trip_cool_thr1, trip_warm_thr0, trip_warm_thr1;
668 unsigned int reg, rc = 0, btm_channel_num;
669 uint16_t reg_low_thr_lsb, reg_low_thr_msb;
670 uint16_t reg_high_thr_lsb, reg_high_thr_msb;
671
672 if (!adc_tm)
673 return -EINVAL;
674
675 btm_channel_num = adc_tm_sensor->btm_channel_num;
676 reg_low_thr_lsb = adc_tm_data[btm_channel_num].low_thr_lsb_addr;
677 reg_low_thr_msb = adc_tm_data[btm_channel_num].low_thr_msb_addr;
678 reg_high_thr_lsb = adc_tm_data[btm_channel_num].high_thr_lsb_addr;
679 reg_high_thr_msb = adc_tm_data[btm_channel_num].high_thr_msb_addr;
680
681 switch (trip) {
682 case ADC_TM_TRIP_HIGH_WARM:
683 rc = qpnp_adc_tm_read_reg(reg_low_thr_lsb, &trip_warm_thr0);
684 if (rc) {
685 pr_err("adc-tm low_thr_lsb err\n");
686 return rc;
687 }
688
689 rc = qpnp_adc_tm_read_reg(reg_low_thr_msb, &trip_warm_thr1);
690 if (rc) {
691 pr_err("adc-tm low_thr_msb err\n");
692 return rc;
693 }
694 reg = (trip_warm_thr1 << 8) | trip_warm_thr0;
695 break;
696 case ADC_TM_TRIP_LOW_COOL:
697 rc = qpnp_adc_tm_read_reg(reg_high_thr_lsb, &trip_cool_thr0);
698 if (rc) {
699 pr_err("adc-tm_tm high_thr_lsb err\n");
700 return rc;
701 }
702
703 rc = qpnp_adc_tm_read_reg(reg_high_thr_msb, &trip_cool_thr1);
704 if (rc) {
705 pr_err("adc-tm_tm high_thr_lsb err\n");
706 return rc;
707 }
708 reg = (trip_cool_thr1 << 8) | trip_cool_thr0;
709 break;
710 default:
711 return -EINVAL;
712 }
713
714 rc = qpnp_adc_tm_scale_voltage_therm_pu2(reg, &result);
715 if (rc < 0) {
716 pr_err("Failed to lookup the therm thresholds\n");
717 return rc;
718 }
719
720 *temp = result;
721
722 return 0;
723}
724
725static int qpnp_adc_tm_set_trip_temp(struct thermal_zone_device *thermal,
726 int trip, long temp)
727{
728 struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
729 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
730 struct qpnp_adc_tm_config tm_config;
731 u8 trip_cool_thr0, trip_cool_thr1, trip_warm_thr0, trip_warm_thr1;
732 uint16_t reg_low_thr_lsb, reg_low_thr_msb;
733 uint16_t reg_high_thr_lsb, reg_high_thr_msb;
734 int rc = 0, btm_channel_num;
735
736 if (!adc_tm)
737 return -EINVAL;
738
739 tm_config.channel = adc_tm_sensor->sensor_num;
740 switch (trip) {
741 case ADC_TM_TRIP_HIGH_WARM:
742 tm_config.high_thr_temp = temp;
743 break;
744 case ADC_TM_TRIP_LOW_COOL:
745 tm_config.low_thr_temp = temp;
746 break;
747 default:
748 return -EINVAL;
749 }
750
751 rc = qpnp_adc_tm_scale_therm_voltage_pu2(&tm_config);
752 if (rc < 0) {
753 pr_err("Failed to lookup the adc-tm thresholds\n");
754 return rc;
755 }
756
757 trip_warm_thr0 = ((tm_config.low_thr_voltage << 24) >> 24);
758 trip_warm_thr1 = ((tm_config.low_thr_voltage << 16) >> 24);
759 trip_cool_thr0 = ((tm_config.high_thr_voltage << 24) >> 24);
760 trip_cool_thr1 = ((tm_config.high_thr_voltage << 16) >> 24);
761
762 btm_channel_num = adc_tm_sensor->btm_channel_num;
763 reg_low_thr_lsb = adc_tm_data[btm_channel_num].low_thr_lsb_addr;
764 reg_low_thr_msb = adc_tm_data[btm_channel_num].low_thr_msb_addr;
765 reg_high_thr_lsb = adc_tm_data[btm_channel_num].high_thr_lsb_addr;
766 reg_high_thr_msb = adc_tm_data[btm_channel_num].high_thr_msb_addr;
767
768 switch (trip) {
769 case ADC_TM_TRIP_HIGH_WARM:
770 rc = qpnp_adc_tm_write_reg(reg_low_thr_lsb, trip_cool_thr0);
771 if (rc) {
772 pr_err("adc-tm_tm read threshold err\n");
773 return rc;
774 }
775
776 rc = qpnp_adc_tm_write_reg(reg_low_thr_msb, trip_cool_thr1);
777 if (rc) {
778 pr_err("adc-tm_tm read threshold err\n");
779 return rc;
780 }
781 adc_tm_sensor->low_thr = tm_config.high_thr_voltage;
782 break;
783 case ADC_TM_TRIP_LOW_COOL:
784 rc = qpnp_adc_tm_write_reg(reg_high_thr_lsb, trip_warm_thr0);
785 if (rc) {
786 pr_err("adc-tm_tm read threshold err\n");
787 return rc;
788 }
789
790 rc = qpnp_adc_tm_write_reg(reg_high_thr_msb, trip_warm_thr1);
791 if (rc) {
792 pr_err("adc-tm_tm read threshold err\n");
793 return rc;
794 }
795 adc_tm_sensor->high_thr = tm_config.low_thr_voltage;
796 break;
797 default:
798 return -EINVAL;
799 }
800
801 return 0;
802}
803
804static void notify_uspace_qpnp_adc_tm_fn(struct work_struct *work)
805{
806 struct qpnp_adc_tm_sensor *adc_tm = container_of(work,
807 struct qpnp_adc_tm_sensor, work);
808
809 sysfs_notify(&adc_tm->tz_dev->device.kobj,
810 NULL, "btm");
811}
812
813static void notify_usb_fn(struct work_struct *work)
814{
815 struct qpnp_adc_tm_drv *adc_tm = container_of(work,
816 struct qpnp_adc_tm_drv, usbid_work);
817 int rc;
818 u8 status_low, status_high;
819
820 if (adc_tm->usb_id_param->threshold_notification != NULL) {
821 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW,
822 &status_low);
823 if (rc) {
824 pr_err("adc-tm read low status failed\n");
825 return;
826 }
827
828 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH,
829 &status_high);
830 if (rc) {
831 pr_err("adc-tm read high status failed\n");
832 return;
833 }
834
835 if (status_low & 1)
836 adc_tm->usb_id_param->threshold_notification(
837 ADC_TM_LOW_STATE, adc_tm->usb_id_param->usbid_ctx);
838 else if (status_high & 1)
839 adc_tm->usb_id_param->threshold_notification(
840 ADC_TM_HIGH_STATE, adc_tm->usb_id_param->usbid_ctx);
841 }
842
843 return;
844}
845
846static void notify_batt_fn(struct work_struct *work)
847{
848 struct qpnp_adc_tm_drv *adc_tm = container_of(work,
849 struct qpnp_adc_tm_drv, batt_work);
850 int rc;
851 u8 status_low, status_high;
852
853 if (adc_tm->battery_param->threshold_notification != NULL) {
854 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW,
855 &status_low);
856 if (rc) {
857 pr_err("adc-tm read low status failed\n");
858 return;
859 }
860
861 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH,
862 &status_high);
863 if (rc) {
864 pr_err("adc-tm read high status failed\n");
865 return;
866 }
867
868 if (status_low & QPNP_ADC_TM_LOW_THR_INT_EN_M1)
869 adc_tm->battery_param->threshold_notification(
870 ADC_TM_LOW_STATE);
871 else if (status_high & QPNP_ADC_TM_HIGH_THR_INT_EN_M1)
872 adc_tm->battery_param->threshold_notification(
873 ADC_TM_HIGH_STATE);
874 }
875
876 return;
877}
878
879static int qpnp_adc_tm_activate_trip_type_fn(uint32_t btm_channel_num,
880 enum thermal_trip_activation_mode mode, u8 *data, uint32_t reg)
881{
882 u8 thr_int = 0;
883 int rc = 0;
884
885 rc = qpnp_adc_tm_read_reg(reg, &thr_int);
886 if (rc) {
887 pr_err("multi meas read failed\n");
888 return rc;
889 }
890
891 thr_int = adc_tm_data[btm_channel_num].low_thr_int_chan_en;
892
893 if (mode == THERMAL_TRIP_ACTIVATION_ENABLED)
894 thr_int |= *data;
895 else
896 thr_int &= ~*data;
897
898 rc = qpnp_adc_tm_write_reg(reg, thr_int);
899 if (rc)
900 pr_err("multi meas write failed\n");
901
902 return rc;
903}
904
905static int qpnp_adc_tm_activate_trip_type(struct thermal_zone_device *thermal,
906 int trip, enum thermal_trip_activation_mode mode)
907{
908 struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
909 int rc = 0;
910 u8 thr_int_en = 0;
911
912 if (!adc_tm)
913 return -EINVAL;
914
915 switch (trip) {
916 case ADC_TM_TRIP_HIGH_WARM:
917 thr_int_en = adc_tm_data[adc_tm->btm_channel_num].
918 low_thr_int_chan_en;
919 rc = qpnp_adc_tm_activate_trip_type_fn(adc_tm->btm_channel_num,
920 mode, &thr_int_en, QPNP_ADC_TM_LOW_THR_INT_EN);
921 if (rc)
922 pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
923 break;
924 case ADC_TM_TRIP_LOW_COOL:
925 thr_int_en = adc_tm_data[adc_tm->btm_channel_num].
926 high_thr_int_chan_en;
927 rc = qpnp_adc_tm_activate_trip_type_fn(adc_tm->btm_channel_num,
928 mode, &thr_int_en, QPNP_ADC_TM_HIGH_THR_INT_EN);
929 if (rc)
930 pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
931 break;
932 default:
933 return -EINVAL;
934 }
935
936 return rc;
937}
938
939static int qpnp_adc_tm_read_status(void)
940{
941 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
942 u8 status_low = 0, status_high = 0, qpnp_adc_tm_meas_en = 0;
943 u8 adc_tm_low_enable = 0, adc_tm_high_enable = 0;
944 u8 thr_int_disable = 0;
945 int rc = 0, sensor_notify_num = 0;
946
947 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW, &status_low);
948 if (rc) {
949 pr_err("adc-tm-tm read status low failed with %d\n", rc);
950 goto fail;
951 }
952
953 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH, &status_high);
954 if (rc) {
955 pr_err("adc-tm-tm read status high failed with %d\n", rc);
956 goto fail;
957 }
958
959 /* Check which interrupt threshold is lower and measure against the
960 * enabled channel */
961 rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
962 &qpnp_adc_tm_meas_en);
963 if (rc) {
964 pr_err("adc-tm-tm read status high failed with %d\n", rc);
965 goto fail;
966 }
967
968 adc_tm_low_enable = qpnp_adc_tm_meas_en & status_low;
969 adc_tm_high_enable = qpnp_adc_tm_meas_en & status_high;
970
971 if (adc_tm_high_enable) {
972 sensor_notify_num = (adc_tm_high_enable >> 3);
973 switch (adc_tm_high_enable) {
974 case 1:
975 case 2:
976 {
977 if (adc_tm_high_enable == 1)
978 thr_int_disable =
979 QPNP_ADC_TM_HIGH_THR_INT_EN_M0;
980 else if (adc_tm_high_enable == 2)
981 thr_int_disable =
982 QPNP_ADC_TM_HIGH_THR_INT_EN_M1;
983
984 rc = qpnp_adc_tm_meas_int_update(
985 QPNP_ADC_TM_HIGH_THR_INT_EN,
986 thr_int_disable, false);
987 if (rc < 0) {
988 pr_err("high threshold int read failed\n");
989 goto fail;
990 }
991
992 if (adc_tm_high_enable == 1)
993 schedule_work(&adc_tm->usbid_work);
994 else if (adc_tm_high_enable == 2)
995 schedule_work(&adc_tm->batt_work);
996 }
997 break;
998 case 4:
999 case 8:
1000 case 16:
1001 {
1002 /* High voltage threshold is triggered by low temp */
1003 rc = qpnp_adc_tm_activate_trip_type(
1004 adc_tm->sensor[sensor_notify_num].tz_dev,
1005 ADC_TM_TRIP_LOW_COOL,
1006 THERMAL_TRIP_ACTIVATION_DISABLED);
1007 if (rc < 0) {
1008 pr_err("notify error:%d\n", sensor_notify_num);
1009 goto fail;
1010 }
1011 schedule_work(&adc_tm->sensor[sensor_notify_num].work);
1012 }
1013 break;
1014 default:
1015 rc = -EINVAL;
1016 }
1017 }
1018
1019 if (adc_tm_low_enable) {
1020 sensor_notify_num = (adc_tm_low_enable >> 3);
1021 switch (adc_tm_low_enable) {
1022 case 1:
1023 case 2:
1024 {
1025 if (adc_tm_low_enable == 1)
1026 thr_int_disable = QPNP_ADC_TM_LOW_THR_INT_EN_M0;
1027 else if (adc_tm_low_enable == 2)
1028 thr_int_disable = QPNP_ADC_TM_LOW_THR_INT_EN_M1;
1029
1030 rc = qpnp_adc_tm_meas_int_update(
1031 QPNP_ADC_TM_LOW_THR_INT_EN,
1032 thr_int_disable, false);
1033 if (rc < 0) {
1034 pr_err("low threshold int disable failed\n");
1035 goto fail;
1036 }
1037
1038 if (adc_tm_low_enable == 1)
1039 schedule_work(&adc_tm->usbid_work);
1040 else if (adc_tm_low_enable == 2)
1041 schedule_work(&adc_tm->batt_work);
1042 }
1043 break;
1044 case 4:
1045 case 8:
1046 case 16:
1047 {
1048 /* Low voltage threshold is triggered by high temp */
1049 rc = qpnp_adc_tm_activate_trip_type(
1050 adc_tm->sensor[sensor_notify_num].tz_dev,
1051 ADC_TM_TRIP_HIGH_WARM,
1052 THERMAL_TRIP_ACTIVATION_DISABLED);
1053 if (rc < 0) {
1054 pr_err("notify error:%d\n", sensor_notify_num);
1055 goto fail;
1056 }
1057 schedule_work(&adc_tm->sensor[sensor_notify_num].work);
1058 }
1059 break;
1060 default:
1061 rc = -EINVAL;
1062 }
1063 }
1064
1065fail:
1066 return rc;
1067}
1068
1069static void qpnp_adc_tm_high_thr_work(struct work_struct *work)
1070{
1071 int rc;
1072
1073 rc = qpnp_adc_tm_read_status();
1074
1075 return;
1076}
1077DECLARE_WORK(trigger_completion_adc_tm_high_thr_work,
1078 qpnp_adc_tm_high_thr_work);
1079
1080static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
1081{
1082 schedule_work(&trigger_completion_adc_tm_high_thr_work);
1083
1084 return IRQ_HANDLED;
1085}
1086
1087static void qpnp_adc_tm_low_thr_work(struct work_struct *work)
1088{
1089 int rc;
1090
1091 rc = qpnp_adc_tm_read_status();
1092
1093 return;
1094}
1095DECLARE_WORK(trigger_completion_adc_tm_low_thr_work, qpnp_adc_tm_low_thr_work);
1096
1097static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
1098{
1099 schedule_work(&trigger_completion_adc_tm_low_thr_work);
1100
1101 return IRQ_HANDLED;
1102}
1103
1104static irqreturn_t qpnp_adc_tm_isr(int irq, void *dev_id)
1105{
1106 struct qpnp_adc_tm_drv *adc_tm = dev_id;
1107
1108 complete(&adc_tm->adc->adc_rslt_completion);
1109
1110 return IRQ_HANDLED;
1111}
1112
1113static int qpnp_adc_read_temp(struct thermal_zone_device *thermal,
1114 unsigned long *temp)
1115{
1116 struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
1117 struct qpnp_vadc_result result;
1118 int rc = 0;
1119
1120 rc = qpnp_vadc_read(adc_tm_sensor->sensor_num, &result);
1121 if (rc)
1122 return rc;
1123
1124 *temp = result.physical;
1125
1126 return rc;
1127}
1128
1129static struct thermal_zone_device_ops qpnp_adc_tm_thermal_ops = {
1130 .get_temp = qpnp_adc_read_temp,
1131 .get_mode = qpnp_adc_tm_get_mode,
1132 .set_mode = qpnp_adc_tm_set_mode,
1133 .get_trip_type = qpnp_adc_tm_get_trip_type,
1134 .activate_trip_type = qpnp_adc_tm_activate_trip_type,
1135 .get_trip_temp = qpnp_adc_tm_get_trip_temp,
1136 .set_trip_temp = qpnp_adc_tm_set_trip_temp,
1137};
1138
1139int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_usbid_param *param)
1140{
1141 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
1142 uint32_t channel;
1143 int rc = 0;
1144
1145 if (!adc_tm || !adc_tm->adc_tm_initialized)
1146 return -ENODEV;
1147
1148 if (param->threshold_notification == NULL) {
1149 pr_err("No USB_ID high/low voltage notificaton??\n");
1150 return -EINVAL;
1151 }
1152
1153 mutex_lock(&adc_tm->adc->adc_lock);
1154
1155 adc_tm->adc->amux_prop->amux_channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
1156 channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
1157 adc_tm->adc->amux_prop->decimation =
1158 adc_tm->adc->adc_channels[channel].adc_decimation;
1159 adc_tm->adc->amux_prop->hw_settle_time =
1160 adc_tm->adc->adc_channels[channel].hw_settle_time;
1161 adc_tm->adc->amux_prop->fast_avg_setup =
1162 adc_tm->adc->adc_channels[channel].fast_avg_setup;
1163 adc_tm->adc->amux_prop->mode_sel =
1164 ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
1165 adc_tm->adc->amux_prop->chan_prop->meas_interval1 =
1166 ADC_MEAS1_INTERVAL_1S;
1167 qpnp_adc_usb_scaler(param, &adc_tm->adc->amux_prop->chan_prop->low_thr,
1168 &adc_tm->adc->amux_prop->chan_prop->high_thr);
1169 adc_tm->adc->amux_prop->chan_prop->tm_channel_select =
1170 QPNP_ADC_TM_M0_ADC_CH_SEL_CTL;
1171 adc_tm->adc->amux_prop->chan_prop->timer_select =
1172 ADC_MEAS_TIMER_SELECT1;
1173 adc_tm->adc->amux_prop->chan_prop->state_request =
1174 param->state_request;
1175 rc = qpnp_adc_tm_configure(adc_tm->adc->amux_prop);
1176 if (rc) {
1177 pr_err("adc-tm configure failed with %d\n", rc);
1178 goto fail_unlock;
1179 }
1180
1181 adc_tm->usb_id_param = param;
1182
1183fail_unlock:
1184 mutex_unlock(&adc_tm->adc->adc_lock);
1185
1186 return rc;
1187}
1188EXPORT_SYMBOL(qpnp_adc_tm_usbid_configure);
1189
1190static int32_t qpnp_adc_tm_chan_usbid_chan_btm_end(
1191 uint32_t btm_chan_num)
1192{
1193 int32_t rc = 0;
1194
1195 rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_LOW_THR_INT_EN,
1196 adc_tm_data[btm_chan_num].low_thr_int_chan_en,
1197 false);
1198 if (rc < 0) {
1199 pr_err("low threshold int write failed\n");
1200 return rc;
1201 }
1202
1203 rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_HIGH_THR_INT_EN,
1204 adc_tm_data[btm_chan_num].high_thr_int_chan_en,
1205 false);
1206 if (rc < 0) {
1207 pr_err("high threshold int enable failed\n");
1208 return rc;
1209 }
1210
1211 rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_MULTI_MEAS_EN,
1212 adc_tm_data[btm_chan_num].multi_meas_en,
1213 false);
1214 if (rc < 0) {
1215 pr_err("multi measurement en failed\n");
1216 return rc;
1217 }
1218
1219 rc = qpnp_adc_tm_enable(false);
1220 if (rc < 0)
1221 pr_err("TM disable failed\n");
1222
1223 return rc;
1224}
1225
1226int32_t qpnp_adc_tm_usbid_end(void)
1227{
1228 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
1229 int rc = 0;
1230
1231 if (!adc_tm || !adc_tm->adc_tm_initialized)
1232 return -ENODEV;
1233
1234 mutex_lock(&adc_tm->adc->adc_lock);
1235
1236 rc = qpnp_adc_tm_chan_usbid_chan_btm_end(
1237 QPNP_ADC_TM_M0_ADC_CH_SEL_CTL);
1238 if (rc < 0)
1239 pr_err("disabling thresholds for usb channel failed\n");
1240
1241 mutex_unlock(&adc_tm->adc->adc_lock);
1242
1243 return rc;
1244}
1245EXPORT_SYMBOL(qpnp_adc_tm_usbid_end);
1246
1247int32_t qpnp_adc_tm_btm_configure(struct qpnp_adc_tm_btm_param *param)
1248{
1249 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
1250 uint32_t channel;
1251 int rc = 0;
1252
1253 if (!adc_tm || !adc_tm->adc_tm_initialized)
1254 return -ENODEV;
1255
1256 if (param->threshold_notification == NULL) {
1257 pr_err("No battery high/low temp notificaton??\n");
1258 return -EINVAL;
1259 }
1260
1261 mutex_lock(&adc_tm->adc->adc_lock);
1262
1263 adc_tm->adc->amux_prop->amux_channel = LR_MUX1_BATT_THERM;
1264 channel = LR_MUX1_BATT_THERM;
1265 adc_tm->adc->amux_prop->decimation =
1266 adc_tm->adc->adc_channels[channel].adc_decimation;
1267 adc_tm->adc->amux_prop->hw_settle_time =
1268 adc_tm->adc->adc_channels[channel].hw_settle_time;
1269 adc_tm->adc->amux_prop->fast_avg_setup =
1270 adc_tm->adc->adc_channels[channel].fast_avg_setup;
1271 adc_tm->adc->amux_prop->mode_sel =
1272 ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
1273 adc_tm->adc->amux_prop->chan_prop->meas_interval2 =
1274 ADC_MEAS2_INTERVAL_1S;
1275 qpnp_adc_btm_scaler(param, &adc_tm->adc->amux_prop->chan_prop->low_thr,
1276 &adc_tm->adc->amux_prop->chan_prop->high_thr);
1277 adc_tm->adc->amux_prop->chan_prop->tm_channel_select =
1278 QPNP_ADC_TM_M1_ADC_CH_SEL_CTL;
1279 adc_tm->adc->amux_prop->chan_prop->timer_select =
1280 ADC_MEAS_TIMER_SELECT2;
1281 adc_tm->adc->amux_prop->chan_prop->state_request =
1282 param->state_request;
1283 rc = qpnp_adc_tm_configure(adc_tm->adc->amux_prop);
1284 if (rc) {
1285 pr_err("adc-tm configure failed with %d\n", rc);
1286 goto fail_unlock;
1287 }
1288
1289 adc_tm->battery_param = param;
1290
1291fail_unlock:
1292 mutex_unlock(&adc_tm->adc->adc_lock);
1293
1294 return rc;
1295}
1296EXPORT_SYMBOL(qpnp_adc_tm_btm_configure);
1297
1298int32_t qpnp_adc_tm_btm_end(void)
1299{
1300 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
1301 int rc = 0;
1302
1303 if (!adc_tm || !adc_tm->adc_tm_initialized)
1304 return -ENODEV;
1305
1306 mutex_lock(&adc_tm->adc->adc_lock);
1307
1308 rc = qpnp_adc_tm_chan_usbid_chan_btm_end(
1309 QPNP_ADC_TM_M1_ADC_CH_SEL_CTL);
1310 if (rc < 0)
1311 pr_err("disabling thresholds for batt channel failed\n");
1312
1313 mutex_unlock(&adc_tm->adc->adc_lock);
1314
1315 return rc;
1316}
1317EXPORT_SYMBOL(qpnp_adc_tm_btm_end);
1318
1319int32_t qpnp_adc_tm_is_ready(void)
1320{
1321 struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
1322
1323 if (!adc_tm || !adc_tm->adc_tm_initialized)
1324 return -EPROBE_DEFER;
1325 else
1326 return 0;
1327}
1328EXPORT_SYMBOL(qpnp_adc_tm_is_ready);
1329
1330static int __devinit qpnp_adc_tm_probe(struct spmi_device *spmi)
1331{
1332 struct device_node *node = spmi->dev.of_node, *child;
1333 struct qpnp_adc_tm_drv *adc_tm;
1334 struct qpnp_adc_drv *adc_qpnp;
1335 int32_t count_adc_channel_list = 0, rc, i = 0, j = 0;
1336 u8 thr_init = 0;
1337
1338 if (!node)
1339 return -EINVAL;
1340
1341 if (qpnp_adc_tm) {
1342 pr_err("adc-tm already in use\n");
1343 return -EBUSY;
1344 }
1345
1346 for_each_child_of_node(node, child)
1347 count_adc_channel_list++;
1348
1349 if (!count_adc_channel_list) {
1350 pr_err("No channel listing\n");
1351 return -EINVAL;
1352 }
1353
1354 adc_tm = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_tm_drv) +
1355 (count_adc_channel_list *
1356 sizeof(struct qpnp_adc_tm_sensor)),
1357 GFP_KERNEL);
1358 if (!adc_tm) {
1359 dev_err(&spmi->dev, "Unable to allocate memory\n");
1360 return -ENOMEM;
1361 }
1362
1363 adc_qpnp = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_drv),
1364 GFP_KERNEL);
1365 if (!adc_qpnp) {
1366 dev_err(&spmi->dev, "Unable to allocate memory\n");
1367 return -ENOMEM;
1368 }
1369
1370 adc_tm->adc = adc_qpnp;
1371
1372 rc = qpnp_adc_get_devicetree_data(spmi, adc_tm->adc);
1373 if (rc) {
1374 dev_err(&spmi->dev, "failed to read device tree\n");
1375 return rc;
1376 }
1377
1378 /* Register the ADC peripheral interrupt */
1379 adc_tm->adc->adc_high_thr_irq = spmi_get_irq_byname(spmi,
1380 NULL, "high-thr-en-set");
1381 if (adc_tm->adc->adc_high_thr_irq < 0) {
1382 pr_err("Invalid irq\n");
1383 return -ENXIO;
1384 }
1385
1386 adc_tm->adc->adc_low_thr_irq = spmi_get_irq_byname(spmi,
1387 NULL, "low-thr-en-set");
1388 if (adc_tm->adc->adc_low_thr_irq < 0) {
1389 pr_err("Invalid irq\n");
1390 return -ENXIO;
1391 }
1392
1393 rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_irq_eoc,
1394 qpnp_adc_tm_isr, IRQF_TRIGGER_RISING,
1395 "qpnp_adc_tm_interrupt", adc_tm);
1396 if (rc) {
1397 dev_err(&spmi->dev,
1398 "failed to request adc irq with error %d\n", rc);
1399 return rc;
1400 } else {
1401 enable_irq_wake(adc_tm->adc->adc_irq_eoc);
1402 }
1403
1404 rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_high_thr_irq,
1405 qpnp_adc_tm_high_thr_isr,
1406 IRQF_TRIGGER_RISING, "qpnp_adc_tm_high_interrupt", adc_tm);
1407 if (rc) {
1408 dev_err(&spmi->dev, "failed to request adc irq\n");
1409 return rc;
1410 } else {
1411 enable_irq_wake(adc_tm->adc->adc_high_thr_irq);
1412 }
1413
1414 rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_low_thr_irq,
1415 qpnp_adc_tm_low_thr_isr,
1416 IRQF_TRIGGER_RISING, "qpnp_adc_tm_low_interrupt", adc_tm);
1417 if (rc) {
1418 dev_err(&spmi->dev, "failed to request adc irq\n");
1419 return rc;
1420 } else {
1421 enable_irq_wake(adc_tm->adc->adc_low_thr_irq);
1422 }
1423
1424 for_each_child_of_node(node, child) {
1425 char name[25];
1426 int btm_channel_num;
1427 rc = of_property_read_u32(child,
1428 "qcom,btm-channel-number", &btm_channel_num);
1429 if (rc) {
1430 pr_err("Invalid btm channel number\n");
1431 return -EINVAL;
1432 }
1433
1434 if ((btm_channel_num != QPNP_ADC_TM_M0_ADC_CH_SEL_CTL) &&
1435 (btm_channel_num != QPNP_ADC_TM_M1_ADC_CH_SEL_CTL)) {
1436 /* Register with the thermal zone */
1437 adc_tm->sensor[i].mode = THERMAL_DEVICE_DISABLED;
1438 snprintf(name, sizeof(name), "qpnp_adc_tm_sensor%d", i);
1439 adc_tm->sensor[i].sensor_num =
1440 adc_tm->adc->adc_channels[j].channel_num;
1441 adc_tm->sensor[i].btm_channel_num = btm_channel_num;
1442 adc_tm->sensor[i].meas_interval =
1443 QPNP_ADC_TM_MEAS_INTERVAL;
1444 adc_tm->sensor[i].low_thr = QPNP_ADC_TM_M0_LOW_THR;
1445 adc_tm->sensor[i].high_thr = QPNP_ADC_TM_M0_HIGH_THR;
1446 adc_tm->sensor[i].tz_dev =
1447 thermal_zone_device_register(name,
1448 ADC_TM_TRIP_NUM,
1449 &adc_tm->sensor[i],
1450 &qpnp_adc_tm_thermal_ops, 0, 0, 0, 0);
1451 if (IS_ERR(adc_tm->sensor[i].tz_dev))
1452 pr_err("thermal device register failed.\n");
1453 INIT_WORK(&adc_tm->sensor[i].work,
1454 notify_uspace_qpnp_adc_tm_fn);
1455 i++;
1456 }
1457 j++;
1458 }
1459 INIT_WORK(&adc_tm->usbid_work, notify_usb_fn);
1460 INIT_WORK(&adc_tm->batt_work, notify_batt_fn);
1461 qpnp_adc_tm = adc_tm;
1462 dev_set_drvdata(&spmi->dev, adc_tm);
1463 rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_HIGH_THR_INT_EN, thr_init);
1464 if (rc < 0) {
1465 pr_err("high thr init failed\n");
1466 return rc;
1467 }
1468
1469 rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_LOW_THR_INT_EN, thr_init);
1470 if (rc < 0) {
1471 pr_err("low thr init failed\n");
1472 return rc;
1473 }
1474
1475 rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MULTI_MEAS_EN, thr_init);
1476 if (rc < 0) {
1477 pr_err("multi meas en failed\n");
1478 return rc;
1479 }
1480
1481 adc_tm->adc_tm_initialized = true;
1482
1483 return 0;
1484}
1485
1486static int __devexit qpnp_adc_tm_remove(struct spmi_device *spmi)
1487{
1488 struct qpnp_adc_tm_drv *adc_tm = dev_get_drvdata(&spmi->dev);
1489 struct device_node *node = spmi->dev.of_node;
1490 struct device_node *child;
1491 int i = 0;
1492
1493 for_each_child_of_node(node, child) {
1494 thermal_zone_device_unregister(adc_tm->sensor[i].tz_dev);
1495 i++;
1496 }
1497
1498 adc_tm->adc_tm_initialized = false;
1499 dev_set_drvdata(&spmi->dev, NULL);
1500
1501 return 0;
1502}
1503
1504static const struct of_device_id qpnp_adc_tm_match_table[] = {
1505 { .compatible = "qcom,qpnp-adc-tm" },
1506 {}
1507};
1508
1509static struct spmi_driver qpnp_adc_tm_driver = {
1510 .driver = {
1511 .name = "qcom,qpnp-adc-tm",
1512 .of_match_table = qpnp_adc_tm_match_table,
1513 },
1514 .probe = qpnp_adc_tm_probe,
1515 .remove = qpnp_adc_tm_remove,
1516};
1517
1518static int __init qpnp_adc_tm_init(void)
1519{
1520 return spmi_driver_register(&qpnp_adc_tm_driver);
1521}
1522module_init(qpnp_adc_tm_init);
1523
1524static void __exit qpnp_adc_tm_exit(void)
1525{
1526 spmi_driver_unregister(&qpnp_adc_tm_driver);
1527}
1528module_exit(qpnp_adc_tm_exit);
1529
1530MODULE_DESCRIPTION("QPNP PMIC ADC Threshold Monitoring driver");
1531MODULE_LICENSE("GPL v2");