From: 许盛飞 Date: Mon, 3 Nov 2014 02:05:29 +0000 (+0800) Subject: adc-battery: add the function of auto-calibration the reference-voltage X-Git-Tag: firefly_0821_release~4508 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7dd68f0d2ba2010fca26910562a7403bf68177ab;p=firefly-linux-kernel-4.4.55.git adc-battery: add the function of auto-calibration the reference-voltage Signed-off-by: 许盛飞 --- diff --git a/arch/arm/boot/dts/rk3126-86v.dts b/arch/arm/boot/dts/rk3126-86v.dts index f01125c3b6ce..7b55a15fbc57 100644 --- a/arch/arm/boot/dts/rk3126-86v.dts +++ b/arch/arm/boot/dts/rk3126-86v.dts @@ -246,22 +246,22 @@ }; - - adc-battery { - compatible = "rk30-adc-battery"; - io-channels = <&adc 0>; - dc_det_gpio = <&gpio2 GPIO_B1 GPIO_ACTIVE_LOW>; - //bat_low_gpio = <&gpio0 GPIO_A7 GPIO_ACTIVE_LOW>; - //chg_ok_gpio = <&gpio0 GPIO_B1 GPIO_ACTIVE_HIGH>; - bat_table = <0 0 0 0 100 100 + adc-battery { + compatible = "rk30-adc-battery"; + io-channels = <&adc 0>, <&adc 3>; + dc_det_gpio = <&gpio2 GPIO_B1 GPIO_ACTIVE_LOW>; + auto_calibration = <0>; + ref_voltage = <3300>; + //bat_low_gpio = <&gpio0 GPIO_A7 GPIO_ACTIVE_LOW>; + //chg_ok_gpio = <&gpio0 GPIO_B1 GPIO_ACTIVE_HIGH>; + bat_table = <0 0 0 0 100 100 3500 3619 3678 3734 3742 3783 3813 3884 3968 4110 4220 3750 3710 3770 3830 3850 3880 3910 3980 4060 4240 4300 >; - is_dc_charge = <1>; - is_usb_charge = <0>; - - }; + is_dc_charge = <1>; + is_usb_charge = <0>; + }; }; diff --git a/drivers/power/rk30_factory_adc_battery.c b/drivers/power/rk30_factory_adc_battery.c index 5b4d36cdb984..d6d05de74048 100755 --- a/drivers/power/rk30_factory_adc_battery.c +++ b/drivers/power/rk30_factory_adc_battery.c @@ -756,41 +756,50 @@ static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat) return charge_level; } + +static int rk_adc_battery_iio_read_refvol(struct rk30_adc_battery_platform_data *data) +{ + struct iio_channel *channel = data->ref_voltage_chan; + int val, ret; + + ret = iio_read_channel_raw(channel, &val); + if (ret < 0) { + pr_err("read channel() error: %d\n", ret); + return ret; + } + return val; +} + +static int get_ref_voltage(struct rk30_adc_battery_data *bat) +{ + int data_value; + struct regulator *logic; + int voltage, ref_voltage; + + logic = regulator_get(NULL, "vdd_arm"); + voltage = regulator_get_voltage(logic); + data_value = rk_adc_battery_iio_read_refvol(bat->pdata); + ref_voltage = voltage*1024/data_value/1000; + + return ref_voltage; +} static int rk_adc_voltage(struct rk30_adc_battery_data *bat, int value) { int voltage; - - int ref_voltage; //reference_voltage - int pullup_res; - int pulldown_res; + int ref_voltage; ref_voltage = bat ->pdata->reference_voltage; - pullup_res = bat ->pdata->pull_up_res; - pulldown_res = bat ->pdata->pull_down_res; - - if(ref_voltage && pullup_res && pulldown_res){ -#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) - ref_voltage = adc_get_curr_ref_volt(); -#endif - voltage = ((value * ref_voltage * (pullup_res + pulldown_res)) / (1024 * pulldown_res)); - DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage); + + if (ref_voltage) { + if (bat->pdata->auto_calibration == 1) + ref_voltage = get_ref_voltage(bat); + voltage = (value * ref_voltage * (batt_table[4] + batt_table[5])) / (1024 * batt_table[5]); + DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage); }else{ -#if 0 - if(bat ->capacitytmp < 5) - ref_voltage = adc_get_curr_ref_volt(); - else - ref_voltage = adc_get_def_ref_volt(); -#endif -#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) - ref_voltage = adc_get_curr_ref_volt(); - voltage = (value * ref_voltage * (batt_table[4] +batt_table[5])) / (1024 *batt_table[5]); -#else voltage = adc_to_voltage(value); -#endif } - - DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage); + DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage); return voltage; } @@ -1358,16 +1367,9 @@ static void rk30_adc_battery_poweron_capacity_check(struct rk30_adc_battery_data } else if (bat ->bat_status != POWER_SUPPLY_STATUS_NOT_CHARGING){ //chargeing state - - if( bat ->pdata->is_reboot_charging == 1) - bat ->bat_capacity = (old_capacity < 10) ?(old_capacity+2):old_capacity; - else - bat ->bat_capacity = (new_capacity > old_capacity) ? new_capacity : old_capacity; + bat->bat_capacity = (old_capacity < 10) ? (old_capacity + 2) : old_capacity; }else{ - if(new_capacity > old_capacity + 50 ) bat ->bat_capacity = old_capacity + 5; - else - bat ->bat_capacity = (new_capacity < old_capacity) ? new_capacity : old_capacity; //avoid the value of capacity increase if(bat->bat_capacity == 100) bat->bat_capacity = 99; if(bat->bat_capacity == 0) @@ -2114,15 +2116,31 @@ rk30_adc_battery_platform_data *data) int ret; int i; size_t size; - struct iio_channel *chan; - if (!node) - return -ENODEV; + struct iio_channel *channels; + int num = 0; + + channels = iio_channel_get_all(&pdev->dev); + if (IS_ERR(channels)) + pr_err("get adc channels fails\n"); + while (channels[num].indio_dev) + num++; + data->chan = &channels[0]; + if (num > 1) + data->ref_voltage_chan = &channels[1]; + ret = of_property_read_u32(node, "auto_calibration", &value); + if (ret < 0) { + pr_info("%s:unsupport auto_calibration\n", __func__); + value = 0; + } + data->auto_calibration = value; - chan = iio_channel_get(&pdev->dev, NULL); - if (IS_ERR(chan)) - pr_err("iio_channel_get fail\n"); - data->chan = chan; + ret = of_property_read_u32(node, "ref_voltage", &value); + if (ret < 0) { + pr_info("%s:unsupport ref_voltage\n", __func__); + value = 0; + } + data->reference_voltage = value; /* determine the number of config info */ prop = of_find_property(node, "bat_table", &length); diff --git a/include/linux/power/rockchip-adc-battery.h b/include/linux/power/rockchip-adc-battery.h index d6e7f6290020..353403a9e52f 100755 --- a/include/linux/power/rockchip-adc-battery.h +++ b/include/linux/power/rockchip-adc-battery.h @@ -73,6 +73,8 @@ struct rk30_adc_battery_platform_data { int is_dc_charge; int is_usb_charge; + int auto_calibration; struct iio_channel *chan; + struct iio_channel *ref_voltage_chan; }; #endif