[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-adc.c b/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-adc.c
new file mode 100644
index 0000000..453cbb8
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-adc.c
@@ -0,0 +1,426 @@
+#include <linux/init.h> /* For init/exit macros */
+#include <linux/module.h> /* For MODULE_ marcros */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/rtc.h>
+#include <linux/mfd/zx234290.h>
+#include <mach/spinlock.h>
+#include <linux/wakelock.h>
+
+#define ZX234290_VBAT_ADC_COMPENDATE_VALUE 50
+typedef enum adc_channel
+{
+ ADC_CHANNEL_VBAT_ADC = 0,
+ ADC_CHANNEL_VADC2 = 1, /* 01 */
+ ADC_CHANNEL_VADC1 = 2, /* 10 */
+ MAX_ADC_CHANNEL
+}zx234290_adc_channel;
+
+/*******************************************************************************
+ * Function:zx234290_adc_correspond
+ * Description:adjust battery voltage according to compensate value
+ * Parameters:
+ * Input:
+ * channel: adc channel
+ * value:battery voltage needed be compensated
+ * Output:
+ *
+ * Returns:
+ * 0: success
+ * -1:failed
+ *
+ * Others:
+ ********************************************************************************/
+static int zx234290_adc_correspond(zx234290_adc_channel channel, int *value)
+{
+ int nTemp;
+
+ switch (channel)
+ {
+ case ADC_CHANNEL_VBAT_ADC:
+ {
+ nTemp = (int)((uint64_t)(5000-0)*(*value)/4096);
+ *value = nTemp + 0;//ZX234290_VBAT_ADC_COMPENDATE_VALUE; // compensate the battery voltage value
+ break;
+ }
+ case ADC_CHANNEL_VADC1:
+ {
+ nTemp = (int)((uint64_t)(5000-0)*(*value)/4096);
+ *value = nTemp + 0;
+ break;
+ }
+
+ case ADC_CHANNEL_VADC2:
+ {
+ nTemp = (int)((uint64_t)(5000-0)*(*value)/4096);
+ *value = nTemp + 0;
+ break;
+ }
+ default:
+ {
+ return -1;
+ }
+ }
+
+
+ return 0;
+
+}
+
+/*******************************************************************************
+ * Function:zx234290_adc_read_vbat
+ * Description:read vbat adc value
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * nTempAdc:the value of vbat adc
+ * Others:
+ ********************************************************************************/
+static int zx234290_adc_read_vbat(void)
+{
+ int nRet;
+ int nTempAdc = 0;
+ unsigned char msb=0, lsb=0;
+
+ /* read msb */
+ //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC_VBATMSB, &msb);
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_VBATADC_MSB, &msb);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+
+ /* read lsb */
+ //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC_VBATLSB, &lsb);
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_VBATADC_LSB, &lsb);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+ nTempAdc = (int)msb;
+ nTempAdc = ((nTempAdc<<4)|lsb>>4);
+
+ return nTempAdc;
+}
+
+/*******************************************************************************
+ * Function:zx234290_adc_read_adc1
+ * Description:read the channel of adc1 value
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * nTempAdc:the value of adc1 channel
+ * Others:
+ ********************************************************************************/
+static int zx234290_adc_read_adc1(void)
+{
+ int nRet;
+ int nTempAdc = 0;
+ unsigned char msb=0, lsb=0;
+
+ /* read msb */
+ //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1MSB, &msb);
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1_MSB, &msb);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+
+ /* read lsb */
+ //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1LSB, &lsb);
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC1_LSB, &lsb);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+
+ nTempAdc = (int)msb;
+ nTempAdc = ((nTempAdc<<4)|lsb>>4);
+
+ return nTempAdc;
+}
+
+/*******************************************************************************
+ * Function:zx234290_adc_read_adc2
+ * Description:read the channel of adc2value
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * nTempAdc:the value of adc2 channel
+ * Others:
+ ********************************************************************************/
+static int zx234290_adc_read_adc2(void)
+{
+ int nRet;
+ int nTempAdc = 0;
+ unsigned char msb=0, lsb=0;
+
+ /* read msb */
+ //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2MSB, &msb);
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2_MSB, &msb);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+
+ /* read lsb */
+ //nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2LSB, &lsb);
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_ADC2_LSB, &lsb);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+
+ nTempAdc = (int)msb;
+ nTempAdc = ((nTempAdc<<4)|lsb>>4);
+
+ return nTempAdc;
+}
+
+
+/**************************************************************************
+* Function: zx234290_adc_read
+* Description: read ADC value according to adc channel
+* Parameters:
+* Input:
+* channel:which channel want to be read
+*
+* Output:
+* value:the adc value correspond to channel
+* Returns:
+* 0 if success, not 0 if faile
+* Others: None
+**************************************************************************/
+extern struct wake_lock adc_wake_lock;
+static int zx234290_adc_read(zx234290_adc_channel channel, int *value)
+{
+ int nRet = 0;
+ int nTempAdc = 0;
+ int reg_val=0, mask=0;
+ int num=1;
+ unsigned char status_a=0;
+ unsigned char content =0;
+ if(channel >= MAX_ADC_CHANNEL)
+ {
+ return -1;
+ }
+
+ soft_spin_lock(ADC_SFLOCK);
+ wake_lock(&adc_wake_lock);
+ if (channel != ADC_CHANNEL_VBAT_ADC)
+ {
+ /* select channel */
+ reg_val = channel << 3; /* ×óÒÆ3λ£¬Î»¿í 2λ */
+ mask = 0x18;
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
+ if (nRet != 0)
+ {
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ return nRet;
+ }
+ content &= ~mask;
+ content |= reg_val;
+ nRet = zx234290_i2c_write_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
+ if (nRet != 0)
+ {
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ return nRet;
+ }
+ }
+#if 0
+ /* set start bit */
+ reg_val = 1 << 5; /* ¸ÃλÖà 1 */
+ mask = 0x20;
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+ content &= ~mask;
+ content |= reg_val;
+ nRet = zx234290_i2c_write_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
+ if (nRet != 0)
+ {
+ return nRet;
+ }
+
+ msleep(30); /* ÑÓʱ30ms */
+#else
+ reg_val = 1 << 5; /* ¸ÃλÖà 1 */
+ mask = 0x20;
+ for(num=1; num <= 50; num++)
+ {
+ /* set start bit */
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
+ if (nRet != 0)
+ {
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ return nRet;
+ }
+ content &= ~mask;
+ content |= reg_val;
+ nRet = zx234290_i2c_write_simple(ZX234290_REG_ADDR_SYS_CTRL, &content);
+ if (nRet != 0)
+ {
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ return nRet;
+ }
+ udelay(500);
+ /*read status_A*/
+ nRet = zx234290_i2c_read_simple(ZX234290_REG_ADDR_STSA, &status_a);
+ if (nRet != 0)
+ {
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ return nRet;
+ }
+ if(status_a & 0x04)
+ {
+// printk( "get adc,break num =%d ...\n", num);
+ break;
+ }
+ }
+#endif
+ /* ÕâÀïÒªµÈÖжÏÀ´ ²ÅÄܶÁ */
+ switch (channel) {
+ case ADC_CHANNEL_VBAT_ADC:
+ nTempAdc = zx234290_adc_read_vbat();
+ break;
+ case ADC_CHANNEL_VADC1:
+ nTempAdc = zx234290_adc_read_adc1();
+ break;
+ case ADC_CHANNEL_VADC2:
+ nTempAdc = zx234290_adc_read_adc2();
+ break;
+ default:
+ break;
+ }
+
+ if (nTempAdc < 0)
+ {
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ return 0;
+ }
+
+ /* ת»» */
+ zx234290_adc_correspond(channel, &nTempAdc);
+ *value = (int)nTempAdc;
+ wake_unlock(&adc_wake_lock);
+ soft_spin_unlock(ADC_SFLOCK);
+ //pmic_AdcUnlock();
+ return nRet;
+}
+
+
+
+/**************************************************************************
+* Function: get_battery_voltage
+* Description: get battery voltage
+* Parameters:
+* Input:
+*
+*
+* Output:
+*
+* Returns:
+* avgValue:battery voltage
+* Others: None
+**************************************************************************/
+uint get_battery_voltage(void)
+{
+ int counter = 3;
+ int index=0;
+ int tmpValue=0,totalValue=0;
+ uint avgValue;
+ for(index = 0; index < counter; index++)
+ {
+ zx234290_adc_read(ADC_CHANNEL_VBAT_ADC, &tmpValue);
+ totalValue += tmpValue;
+ }
+ avgValue = (uint)(totalValue / counter);
+ return avgValue;
+}
+EXPORT_SYMBOL(get_battery_voltage);
+
+/**************************************************************************
+* Function: get_adc1_voltage
+* Description: get adc1 voltage
+* Parameters:
+* Input:
+*
+*
+* Output:
+*
+* Returns:
+* avgValue:adc voltage
+* Others: None
+**************************************************************************/
+uint get_adc1_voltage(void)
+{
+ int counter = 3;
+ int index=0;
+ int tmpValue=0,totalValue=0;
+ uint avgValue;
+ for(index = 0; index < counter; index++)
+ {
+ zx234290_adc_read(ADC_CHANNEL_VADC1, &tmpValue);
+ totalValue += tmpValue;
+ }
+ avgValue = (uint)(totalValue / counter);
+ return avgValue;
+}
+EXPORT_SYMBOL(get_adc1_voltage);
+
+/**************************************************************************
+* Function: get_adc2_voltage
+* Description: get adc2 voltage
+* Parameters:
+* Input:
+*
+*
+* Output:
+*
+* Returns:
+* avgValue:adc2 voltage
+* Others: None
+**************************************************************************/
+//extern struct wake_lock adc_wake_lock;
+uint get_adc2_voltage(void)
+{
+ int counter = 3;
+ int index=0;
+ int tmpValue=0,totalValue=0;
+ uint avgValue;
+ //wake_lock(&adc_wake_lock);
+ for(index = 0; index < counter; index++)
+ {
+ zx234290_adc_read(ADC_CHANNEL_VADC2, &tmpValue);
+ totalValue += tmpValue;
+ }
+ //wake_unlock(&adc_wake_lock);
+ avgValue = (uint)(totalValue / counter);
+ return avgValue;
+}
+EXPORT_SYMBOL(get_adc2_voltage);