Baseline update from LYNQ_SDK_ASR_T108_V05.03.01.00(kernel build error.)

Change-Id: I56fc72cd096e82c589920026553170e5cb9692eb
diff --git a/marvell/linux/drivers/misc/asr_adc.c b/marvell/linux/drivers/misc/asr_adc.c
new file mode 100755
index 0000000..dd5bbac
--- /dev/null
+++ b/marvell/linux/drivers/misc/asr_adc.c
@@ -0,0 +1,259 @@
+/*
+ * Battery driver for ASR PM802 PMIC
+ *
+ * Copyright 2018 ASR Microelectronics (Shanghai) Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/88pm80x.h>
+#include <linux/mfd/pm802.h>
+#include <linux/mfd/pm813.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/of_device.h>
+
+
+static int channel_value = 0;
+static int adc_channel;
+static u32 g_ADC0_conversion_coefficient = 1000; //1.0
+static u32 g_ADC1_conversion_coefficient = 1000; //1.0
+static int g_board_adc0_channel = 0;
+static int g_board_adc1_channel = 1;
+
+#if defined(CONFIG_MFD_PM803) && defined(CONFIG_POWER_SUPPLY)
+#define VABT_DEFAULT_PAIR 20
+extern void update_vbat_default_caldata(u8 adc_id, u32 *table,u16 count);
+extern void pm803_start_sample_adc(int op,int delay_read_time_ms,u32 read_interval_ms,u16 read_wait_ms);
+#endif
+
+
+static ssize_t pm80x_adc_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+
+	sscanf(buf, "%d", &adc_channel);
+    channel_value = 0;
+	
+#if defined(CONFIG_MFD_PM803) && defined(CONFIG_POWER_SUPPLY)
+	pm803_start_sample_adc(1,500,100,20);
+#endif
+	
+    if (adc_channel == 1)
+    {
+        channel_value = extern_get_gpadc_volt(g_board_adc1_channel);
+    }else if (adc_channel == 0){
+        channel_value = extern_get_gpadc_volt(g_board_adc0_channel);
+    }
+	else{
+        channel_value = 0;
+    }
+
+#if defined(CONFIG_MFD_PM803) && defined(CONFIG_POWER_SUPPLY)
+		pm803_start_sample_adc(2,0,0,0); //restore adc update parameters
+#endif	
+
+	return strnlen(buf, PAGE_SIZE);
+}
+
+ 	
+
+/*
+
+1806 auxadc linux接口:
+	extern_get_auxadc_volt(ASR_AUXADC1);
+param:
+     
+	ASR_AUXADC1 = 5 
+	ASR_AUXADC2 = 6
+	ASR_AUXADC3 = 7
+	ASR_AUXADC4 = 8
+	ASR_AUXADC5 = 9
+ */
+
+static ssize_t pm80x_adc_shown(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int s = 0;
+	unsigned long level;
+	u32 coefficient = 1000;
+
+/* for MBTK_PROJECT_L509 :upper resistance 750k + low resistance 270k*/
+    if(adc_channel == 0)
+	{
+           coefficient = g_ADC0_conversion_coefficient;
+	}
+	else if(adc_channel == 1)
+	{
+           coefficient = g_ADC1_conversion_coefficient;
+	}
+
+	//level = channel_value * 1020 / 270; for L509
+    level = (channel_value *coefficient)/1000;
+
+	s += sprintf(buf, "adc_channel%d=%d\n", adc_channel, level);
+	return s;
+}
+
+
+
+static ssize_t asr1806adc_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+
+	sscanf(buf, "%d", &adc_channel);
+   
+
+    if (adc_channel == 0)
+    {
+      channel_value = extern_get_auxadc_volt(5);
+    }else if (adc_channel == 1){
+        channel_value = extern_get_auxadc_volt(8);
+    }else if (adc_channel == 2){
+        channel_value = extern_get_auxadc_volt(6);
+
+    }else{
+    	 channel_value = 0;
+    }
+
+	return strnlen(buf, PAGE_SIZE);
+}
+
+static ssize_t asr1806adc_shown(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int s = 0;
+
+	s += sprintf(buf, "adc_channel%d=%d\n", adc_channel, channel_value);
+	return s;
+}
+
+static DEVICE_ATTR(pm80x_adc, 0644,  pm80x_adc_shown, pm80x_adc_store);
+static DEVICE_ATTR(aux_adc, 0644,  asr1806adc_shown, asr1806adc_store);
+
+static __refdata struct attribute *adc_attrs[] = {
+	&dev_attr_pm80x_adc.attr,
+	&dev_attr_aux_adc.attr,
+	NULL,
+};
+
+static __refdata struct attribute_group adc_attr_group = {
+	.attrs = adc_attrs,
+};
+
+
+
+
+static int asr_adc_probe(struct platform_device *pdev)
+{
+
+	int ret;
+	struct device_node *np = pdev->dev.of_node;
+	
+#if defined(CONFIG_MFD_PM803) && defined(CONFIG_POWER_SUPPLY)
+    u32  adc0_table[VABT_DEFAULT_PAIR];
+	u32  adc1_table[VABT_DEFAULT_PAIR];
+/*从dts中读取默认校准数据,这只是默认值,还是需要校准的,这个节点用处不大,实际uboot会把默认参数或者校准数据传递到kernel,但如果没有在fal_con_p401.h中开启CONFIG_PM803_GPADC宏
+* 则不会从uboot 拷贝默认校准数据,会导致adc采样异常,暂时保留,建议dts数据跟marvell\uboot\drivers\power\pmic\pmic_mrvl_common.c里的数组保持一致
+*/
+    ret = of_property_read_u32_array(np, "vbat_def_pair_table-adc0", adc0_table,VABT_DEFAULT_PAIR);
+
+	if(!ret)
+	{
+		update_vbat_default_caldata(0,adc0_table,VABT_DEFAULT_PAIR/2);
+	}
+                      
+    ret = of_property_read_u32_array(np, "vbat_def_pair_table-adc1", adc1_table,VABT_DEFAULT_PAIR);
+
+	if(!ret)
+	{
+		update_vbat_default_caldata(1,adc1_table,VABT_DEFAULT_PAIR/2);
+	}	
+
+	//pm803_adc_init();
+#endif
+
+/*mbtk_tanggaoyou add: 有些模块内部有分压电路,则需要设置分压电路的转换系数,注意是针对模块内部的分压电路,不是客户外部的分压电路*/
+    ret = of_property_read_u32(np, "conversion_coefficient-adc0", &g_ADC0_conversion_coefficient);
+    if(ret != 0)
+	{
+		g_ADC0_conversion_coefficient = 1000;//1.0
+	}
+    ret = of_property_read_u32(np, "conversion_coefficient-adc1", &g_ADC1_conversion_coefficient);
+    if(ret != 0)
+	{
+		g_ADC1_conversion_coefficient = 1000;//1.0
+	}
+
+/*mbtk_tanggaoyou add: 添加adc0_channel和adc1_channel是为了解决L508硬件管脚ADC1对应的是软件的adc1,而ADC2对应的是adc0,需要交换一下*/
+	ret = of_property_read_u32(np, "adc0_channel", &g_board_adc0_channel); //get ADC0's channel
+    if(ret != 0)
+	{
+		g_board_adc0_channel = 0; //RTN of PM803
+	}
+    ret = of_property_read_u32(np, "adc1_channel", &g_board_adc1_channel);//get ADC1's channel
+    if(ret != 0)
+	{
+		g_board_adc1_channel = 1; //RTP of PM803
+	}
+/*mbtk_tanggaoyou add end */
+
+   	printk("--->%s/L%d,ADC%d,%d,coefficient=%d %d", __FUNCTION__, __LINE__,g_board_adc0_channel,g_board_adc1_channel,g_ADC0_conversion_coefficient,g_ADC1_conversion_coefficient);
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &adc_attr_group);
+	if (ret) {
+		printk("--->%s/L%d", __FUNCTION__, __LINE__);
+		dev_err(&pdev->dev, "adc create sysfs fail!\n");
+		return ret;
+	}
+	return 0;
+}
+
+
+static int asr_adc_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+
+static const struct of_device_id asr_adc_dt_match[] = {
+	{ .compatible = "asr,adc", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, asr_adc_dt_match);
+
+static struct platform_driver asr_adc_driver = {
+	.driver		= {
+		.name	= "asr-adc",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(asr_adc_dt_match),
+	},
+	.probe		= asr_adc_probe,
+	.remove		= asr_adc_remove,
+};
+
+static int __init asr_adc_init(void)
+{
+	return platform_driver_register(&asr_adc_driver);
+}
+module_init(asr_adc_init);
+
+static void __exit asr_adc_exit(void)
+{
+	platform_driver_unregister(&asr_adc_driver);
+}
+module_exit(asr_adc_exit);
+
+MODULE_DESCRIPTION("ASR PM802 Adc driver");
+MODULE_LICENSE("GPL");