blob: b15d08c3dce0c8146b3a51f48a141a8de012e851 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include <linux/init.h> /* For init/exit macros */
2#include <linux/module.h> /* For MODULE_ marcros */
3#include <linux/interrupt.h>
4#include <linux/spinlock.h>
5#include <linux/platform_device.h>
6
7#include <linux/device.h>
8#include <linux/fs.h>
9#include <linux/cdev.h>
10#include <linux/delay.h>
11#include <linux/mutex.h>
12#include <linux/kthread.h>
13#include <linux/rtc.h>
14#include <linux/mfd/zx234290.h>
15#include <mach/spinlock.h>
16#include <linux/wakelock.h>
17
18#define ZX234290_VBAT_ADC_COMPENDATE_VALUE 50
19typedef enum adc_channel
20{
21 ADC_CHANNEL_VBAT_ADC = 0,
22 ADC_CHANNEL_VADC2 = 1, /* 01 */
23 ADC_CHANNEL_VADC1 = 2, /* 10 */
24 MAX_ADC_CHANNEL
25}zx234290_adc_channel;
26
27/*******************************************************************************
28 * Function:zx234290_adc_correspond
29 * Description:adjust battery voltage according to compensate value
30 * Parameters:
31 * Input:
32 * channel: adc channel
33 * value:battery voltage needed be compensated
34 * Output:
35 *
36 * Returns:
37 * 0: success
38 * -1:failed
39 *
40 * Others:
41 ********************************************************************************/
42static int zx234290_adc_correspond(zx234290_adc_channel channel, int *value)
43{
44 int nTemp;
45
46 switch (channel)
47 {
48 case ADC_CHANNEL_VBAT_ADC:
49 {
50 nTemp = (int)((uint64_t)(5000-0)*(*value)/4096);
51 *value = nTemp + 0;//ZX234290_VBAT_ADC_COMPENDATE_VALUE; // compensate the battery voltage value
52 break;
53 }
54 case ADC_CHANNEL_VADC1:
55 {
56 nTemp = (int)((uint64_t)(5000-0)*(*value)/4096);
57 *value = nTemp + 0;
58 break;
59 }
60
61 case ADC_CHANNEL_VADC2:
62 {
63 nTemp = (int)((uint64_t)(5000-0)*(*value)/4096);
64 *value = nTemp + 0;
65 break;
66 }
67 default:
68 {
69 return -1;
70 }
71 }
72
73
74 return 0;
75
76}
77
78/*******************************************************************************
79 * Function:zx234290_adc_read_vbat
80 * Description:read vbat adc value
81 * Parameters:
82 * Input:
83 *
84 * Output:
85 *
86 * Returns:
87 * nTempAdc:the value of vbat adc
88 * Others:
89 ********************************************************************************/
90static int zx234290_adc_read_vbat(void)
91{
92 int nRet;
93 int nTempAdc = 0;
94 unsigned char msb=0, lsb=0;
95
96 /* read msb */
97 //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC_VBATMSB, &msb);
98 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_VBATADC_MSB, &msb);
99 if (nRet != 0)
100 {
101 return nRet;
102 }
103
104 /* read lsb */
105 //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC_VBATLSB, &lsb);
106 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_VBATADC_LSB, &lsb);
107 if (nRet != 0)
108 {
109 return nRet;
110 }
111 nTempAdc = (int)msb;
112 nTempAdc = ((nTempAdc<<4)|lsb>>4);
113
114 return nTempAdc;
115}
116
117/*******************************************************************************
118 * Function:zx234290_adc_read_adc1
119 * Description:read the channel of adc1 value
120 * Parameters:
121 * Input:
122 *
123 * Output:
124 *
125 * Returns:
126 * nTempAdc:the value of adc1 channel
127 * Others:
128 ********************************************************************************/
129static int zx234290_adc_read_adc1(void)
130{
131 int nRet;
132 int nTempAdc = 0;
133 unsigned char msb=0, lsb=0;
134
135 /* read msb */
136 //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1MSB, &msb);
137 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1_MSB, &msb);
138 if (nRet != 0)
139 {
140 return nRet;
141 }
142
143 /* read lsb */
144 //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1LSB, &lsb);
145 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1_LSB, &lsb);
146 if (nRet != 0)
147 {
148 return nRet;
149 }
150
151 nTempAdc = (int)msb;
152 nTempAdc = ((nTempAdc<<4)|lsb>>4);
153
154 return nTempAdc;
155}
156
157/*******************************************************************************
158 * Function:zx234290_adc_read_adc2
159 * Description:read the channel of adc2value
160 * Parameters:
161 * Input:
162 *
163 * Output:
164 *
165 * Returns:
166 * nTempAdc:the value of adc2 channel
167 * Others:
168 ********************************************************************************/
169static int zx234290_adc_read_adc2(void)
170{
171 int nRet;
172 int nTempAdc = 0;
173 unsigned char msb=0, lsb=0;
174
175 /* read msb */
176 //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2MSB, &msb);
177 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2_MSB, &msb);
178 if (nRet != 0)
179 {
180 return nRet;
181 }
182
183 /* read lsb */
184 //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2LSB, &lsb);
185 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2_LSB, &lsb);
186 if (nRet != 0)
187 {
188 return nRet;
189 }
190
191 nTempAdc = (int)msb;
192 nTempAdc = ((nTempAdc<<4)|lsb>>4);
193
194 return nTempAdc;
195}
196
197
198/**************************************************************************
199* Function: zx234290_adc_read
200* Description: read ADC value according to adc channel
201* Parameters:
202* Input:
203* channel:which channel want to be read
204*
205* Output:
206* value:the adc value correspond to channel
207* Returns:
208* 0 if success, not 0 if faile
209* Others: None
210**************************************************************************/
211extern struct wake_lock adc_wake_lock;
212static int zx234290_adc_read(zx234290_adc_channel channel, int *value)
213{
214 int nRet = 0;
215 int nTempAdc = 0;
216 int reg_val=0, mask=0;
217 int num=1;
218 unsigned char status_a=0;
219 unsigned char content =0;
220 if(channel >= MAX_ADC_CHANNEL)
221 {
222 return -1;
223 }
224
225 soft_spin_lock(ADC_SFLOCK);
226 wake_lock(&adc_wake_lock);
227 if (channel != ADC_CHANNEL_VBAT_ADC)
228 {
229 /* select channel */
230 reg_val = channel << 3; /* ×óÒÆ3λ£¬Î»¿í 2λ */
231 mask = 0x18;
232 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
233 if (nRet != 0)
234 {
235 wake_unlock(&adc_wake_lock);
236 soft_spin_unlock(ADC_SFLOCK);
237 return nRet;
238 }
239 content &= ~mask;
240 content |= reg_val;
241 nRet = zx234290_i2c_write_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
242 if (nRet != 0)
243 {
244 wake_unlock(&adc_wake_lock);
245 soft_spin_unlock(ADC_SFLOCK);
246 return nRet;
247 }
248 }
249#if 0
250 /* set start bit */
251 reg_val = 1 << 5; /* ¸ÃλÖà 1 */
252 mask = 0x20;
253 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
254 if (nRet != 0)
255 {
256 return nRet;
257 }
258 content &= ~mask;
259 content |= reg_val;
260 nRet = zx234290_i2c_write_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
261 if (nRet != 0)
262 {
263 return nRet;
264 }
265
266 msleep(30); /* ÑÓʱ30ms */
267#else
268 reg_val = 1 << 5; /* ¸ÃλÖà 1 */
269 mask = 0x20;
270 for(num=1; num <= 50; num++)
271 {
272 /* set start bit */
273 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
274 if (nRet != 0)
275 {
276 wake_unlock(&adc_wake_lock);
277 soft_spin_unlock(ADC_SFLOCK);
278 return nRet;
279 }
280 content &= ~mask;
281 content |= reg_val;
282 nRet = zx234290_i2c_write_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
283 if (nRet != 0)
284 {
285 wake_unlock(&adc_wake_lock);
286 soft_spin_unlock(ADC_SFLOCK);
287 return nRet;
288 }
289 udelay(500);
290 /*read status_A*/
291 nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_STSA, &status_a);
292 if (nRet != 0)
293 {
294 wake_unlock(&adc_wake_lock);
295 soft_spin_unlock(ADC_SFLOCK);
296 return nRet;
297 }
298 if(status_a & 0x04)
299 {
300// printk( "get adc,break num =%d ...\n", num);
301 break;
302 }
303 }
304#endif
305 /* ÕâÀïÒªµÈÖжÏÀ´ ²ÅÄܶÁ */
306 switch (channel) {
307 case ADC_CHANNEL_VBAT_ADC:
308 nTempAdc = zx234290_adc_read_vbat();
309 break;
310 case ADC_CHANNEL_VADC1:
311 nTempAdc = zx234290_adc_read_adc1();
312 break;
313 case ADC_CHANNEL_VADC2:
314 nTempAdc = zx234290_adc_read_adc2();
315 break;
316 default:
317 break;
318 }
319
320 if (nTempAdc < 0)
321 {
322 wake_unlock(&adc_wake_lock);
323 soft_spin_unlock(ADC_SFLOCK);
324 return 0;
325 }
326
327 /* ת»» */
328 zx234290_adc_correspond(channel, &nTempAdc);
329 *value = (int)nTempAdc;
330 wake_unlock(&adc_wake_lock);
331 soft_spin_unlock(ADC_SFLOCK);
332 //pmic_AdcUnlock();
333 return nRet;
334}
335
336
337
338/**************************************************************************
339* Function: get_battery_voltage
340* Description: get battery voltage
341* Parameters:
342* Input:
343*
344*
345* Output:
346*
347* Returns:
348* avgValue:battery voltage
349* Others: None
350**************************************************************************/
351uint get_battery_voltage(void)
352{
353 int counter = 3;
354 int index=0;
355 int tmpValue=0,totalValue=0;
356 uint avgValue;
xf.li6236ea72023-07-26 04:58:33 -0700357
lh9ed821d2023-04-07 01:36:19 -0700358 for(index = 0; index < counter; index++)
359 {
360 zx234290_adc_read(ADC_CHANNEL_VBAT_ADC, &tmpValue);
361 totalValue += tmpValue;
362 }
363 avgValue = (uint)(totalValue / counter);
364 return avgValue;
365}
366EXPORT_SYMBOL(get_battery_voltage);
367
368/**************************************************************************
369* Function: get_adc1_voltage
370* Description: get adc1 voltage
371* Parameters:
372* Input:
373*
374*
375* Output:
376*
377* Returns:
378* avgValue:adc voltage
379* Others: None
380**************************************************************************/
381uint get_adc1_voltage(void)
382{
383 int counter = 3;
384 int index=0;
385 int tmpValue=0,totalValue=0;
386 uint avgValue;
xf.li6236ea72023-07-26 04:58:33 -0700387
lh9ed821d2023-04-07 01:36:19 -0700388 for(index = 0; index < counter; index++)
389 {
390 zx234290_adc_read(ADC_CHANNEL_VADC1, &tmpValue);
391 totalValue += tmpValue;
392 }
393 avgValue = (uint)(totalValue / counter);
394 return avgValue;
395}
396EXPORT_SYMBOL(get_adc1_voltage);
397
398/**************************************************************************
399* Function: get_adc2_voltage
400* Description: get adc2 voltage
401* Parameters:
402* Input:
403*
404*
405* Output:
406*
407* Returns:
408* avgValue:adc2 voltage
409* Others: None
410**************************************************************************/
411//extern struct wake_lock adc_wake_lock;
412uint get_adc2_voltage(void)
413{
414 int counter = 3;
415 int index=0;
416 int tmpValue=0,totalValue=0;
417 uint avgValue;
xf.li6236ea72023-07-26 04:58:33 -0700418
lh9ed821d2023-04-07 01:36:19 -0700419 //wake_lock(&adc_wake_lock);
420 for(index = 0; index < counter; index++)
421 {
422 zx234290_adc_read(ADC_CHANNEL_VADC2, &tmpValue);
423 totalValue += tmpValue;
424 }
425 //wake_unlock(&adc_wake_lock);
426 avgValue = (uint)(totalValue / counter);
427 return avgValue;
428}
429EXPORT_SYMBOL(get_adc2_voltage);