+static void rk_lowerpower_check(struct rk30_adc_battery_data *bat)
+{
+ int adc_val;
+ int i;
+ int check_data[NUM_VOLTAGE_SAMPLE];
+
+ for(i=0; i< NUM_VOLTAGE_SAMPLE; i++){
+ mdelay(10);
+ bat->adc_val = rk_adc_battery_iio_read(bat->pdata);
+ check_data[i] = bat->adc_val;
+
+ adc_val += check_data[i];
+ }
+ adc_val /=NUM_VOLTAGE_SAMPLE;
+
+ DBG(">>>>>>>>>>>one>>>%d, two<<<<<%d<<<<\n",bat->adc_value,adc_val);
+ DBG(">>>>>>>>>>>firset-value>>>%d, second-value<<<<<%d<<<<\n",rk_adc_voltage(bat, bat->adc_value),rk_adc_voltage(bat, adc_val));
+
+ if((adc_val >= bat->adc_value+5) &&(bat->bat_status == POWER_SUPPLY_STATUS_NOT_CHARGING ) )//
+ {
+ printk("%d,%d\n",adc_val,bat->adc_value);
+ printk("lower-power shutdown");
+ kernel_power_off();
+ }
+
+}
+static void rk_adc_battery_check_work(struct work_struct *work)
+{
+ struct rk30_adc_battery_data *bat =
+ container_of((work), struct
+ rk30_adc_battery_data, check_work.work);
+
+ if(1 == get_ac_status(bat)){
+ bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
+ bat -> ac_charging = 1;
+ }
+
+ power_supply_changed(&bat ->ac);
+ if(bat->stop_check != 1)
+ queue_delayed_work(bat ->wq, &bat ->check_work, msecs_to_jiffies(TIMER_MS_COUNTS));
+
+}
+static void poweron_lowerpoer_handle(struct rk30_adc_battery_data *bat)
+{
+#ifdef CONFIG_LOGO_LOWERPOWER_WARNING
+ if((1 == get_battery_status())&&(bat->bat_status == POWER_SUPPLY_STATUS_NOT_CHARGING )){
+ mdelay (1500);
+ kernel_power_off();
+ }
+#endif
+
+}
+static int battery_notifier_call(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct rk30_adc_battery_data *bat=
+ container_of(nb, struct rk30_adc_battery_data, battery_nb);
+
+ switch (event) {
+ case 1:
+ rk_lowerpower_check(bat);
+ break;
+
+ case 2:
+ poweron_lowerpoer_handle(bat);
+ break;
+ default:
+ return NOTIFY_OK;
+ }
+ return NOTIFY_OK;
+}
+
+#ifdef CONFIG_OF
+static int rk31_adcbat_parse_dt(struct platform_device *pdev, struct
+rk30_adc_battery_platform_data *data)
+{
+ struct device_node *node = pdev->dev.of_node;
+ enum of_gpio_flags flags;
+ struct property *prop;
+ int length;
+ u32 value;
+ int ret;
+ int i;
+ size_t size;
+
+ 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;
+
+ 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);
+ if (!prop)
+ return -EINVAL;
+
+ length /= sizeof(u32);
+
+ if (length > 0) {
+ size = (sizeof(*data->dts_batt_table)) * length;
+ data->dts_batt_table =
+ devm_kzalloc(&(pdev->dev), size, GFP_KERNEL);
+ if (!data->dts_batt_table)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(node
+ , "bat_table", data->dts_batt_table, length);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 4; i < length; i++) {
+ batt_table[i] = data->dts_batt_table[i];
+
+ pr_info("data->dts_batt_table[ %d ] %d %d\n", i
+ , data->dts_batt_table[i], batt_table[i]);
+ }
+ data->dc_det_pin = of_get_named_gpio_flags(node
+ , "dc_det_gpio", 0, &flags);
+ if (data->dc_det_pin == -EPROBE_DEFER)
+ pr_info("%s dc_det_gpio error\n", __func__);
+
+ if (batt_gpio_is_valid(data->dc_det_pin))
+ data->dc_det_level = (flags & OF_GPIO_ACTIVE_LOW)
+ ? RK30_GPIO_LOW : RK30_GPIO_HIGH;
+
+ data->batt_low_pin = of_get_named_gpio_flags(node
+ , "bat_low_gpio", 0, &flags);
+ if (data->batt_low_pin == -EPROBE_DEFER)
+ pr_info("%s bat_low_gpio error\n", __func__);
+
+ if (batt_gpio_is_valid(data->batt_low_pin))
+ data->batt_low_level = (flags & OF_GPIO_ACTIVE_LOW)
+ ? RK30_GPIO_LOW : RK30_GPIO_HIGH;
+
+ data->charge_ok_pin = of_get_named_gpio_flags(node
+ , "chg_ok_gpio", 0, &flags);
+ if (data->charge_ok_pin == -EPROBE_DEFER)
+ pr_info("%s chg_ok_gpio error\n", __func__);
+
+ if (batt_gpio_is_valid(data->charge_ok_pin))
+ data->charge_ok_level = (flags & OF_GPIO_ACTIVE_LOW)
+ ? RK30_GPIO_LOW : RK30_GPIO_HIGH;
+
+ ret = of_property_read_u32(node, "is_dc_charge", &value);
+ if (ret < 0) {
+ pr_info("%s:hardware unsupport dc charge\n", __func__);
+ value = 0;
+ }
+ data->is_dc_charge = value;
+
+ ret = of_property_read_u32(node, "is_usb_charge"
+ , &value);
+ if (ret < 0) {
+ pr_err("%s:hardware unsupport usb charge\n", __func__);
+ value = 0;
+ }
+ data->is_usb_charge = value;
+
+ pr_info("rk30 battery:support %s %s charger\n",
+ data->is_dc_charge ? "DC" : ""
+ , data->is_usb_charge ? "USB" : "");
+
+ return 0;
+}
+#else
+static int rk31_adcbat_parse_dt(struct platform_device
+*dev, struct rk30_adc_battery_platform_data *data)
+{
+ return -ENODEV;
+}
+#endif
+