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");