diff --git a/drivers/power/fet-control/Android.mk b/drivers/power/fet-control/Android.mk index 94f19f263f2c..842253aaa641 100755 --- a/drivers/power/fet-control/Android.mk +++ b/drivers/power/fet-control/Android.mk @@ -5,5 +5,5 @@ include $(CLEAR_VARS) LOCAL_MODULE := fet_control.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki include $(DLKM_DIR)/AndroidKernelModule.mk - diff --git a/drivers/power/fet-control/Kbuild b/drivers/power/fet-control/Kbuild index 633d79ac07dc..d95b919ec30c 100755 --- a/drivers/power/fet-control/Kbuild +++ b/drivers/power/fet-control/Kbuild @@ -1,5 +1,6 @@ # add -Wall to try to catch everything we can. EXTRA_CFLAGS += -Wall -EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include +EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/power/fet_control +EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include obj-m += fet_control.o diff --git a/drivers/power/fet-control/Makefile b/drivers/power/fet-control/Makefile new file mode 100755 index 000000000000..bfbdc14740ef --- /dev/null +++ b/drivers/power/fet-control/Makefile @@ -0,0 +1,14 @@ +all: modules + +modules: + $(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS) + +modules_install: + $(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(M) modules_install + +%: + $(MAKE) -C $(KERNEL_SRC) M=$(M) $@ $(KBUILD_OPTIONS) + +clean: + rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers + rm -rf .tmp_versions diff --git a/drivers/power/fet-control/fet_control.c b/drivers/power/fet-control/fet_control.c index 31183f033702..762645a89844 100755 --- a/drivers/power/fet-control/fet_control.c +++ b/drivers/power/fet-control/fet_control.c @@ -37,18 +37,18 @@ #include #define RBALANCE_VDIFF_MV 100 +#define MAIN_MV_MID_LO 3600 +#define MAIN_MV_MID_HI 3800 +#define MAIN_CURR_SWITCH 250 #define GPIO_SET_DELAY 50 #define CHRG_FULLCURR_EN 1 -#define CHRG_FULLCURR_DIS 0 -#define HBDLY_DISCHARGE_MS 30000 +#define HBDLY_DISCHARGE_MS 60000 #define HBDLY_CHARGE_MS 6000 static struct fet_control_data { struct device *dev; struct power_supply *flip_batt_psy; struct power_supply *main_batt_psy; - struct power_supply *usb_psy; - struct notifier_block ps_notif; struct delayed_work update; bool init_done; bool ps_is_present; @@ -57,13 +57,11 @@ static struct fet_control_data { int battplus_en_gpio; int balance_en_n_gpio; int chrg_fullcurr_en_gpio; - int flip_chrg_en_gpio; -} fet_control_data; +} fetControlData; int battplus_state = -1; int balance_state = -1; int fullcurr_state = -1; -int flip_chrg_en_state = -1; static int get_ps_int_prop(struct power_supply *psy, enum power_supply_property prop) { @@ -108,22 +106,22 @@ static int set_battplus_state(const char *val, const struct kernel_param *kp) int rc; long mode; - if (!fet_control_data.init_done) + if (!fetControlData.init_done) return -ENODEV; rc = kstrtol(val, 0, &mode); if (rc) return rc; - rc = update_state_gpio(fet_control_data.battplus_en_gpio, !!mode); + rc = update_state_gpio(fetControlData.battplus_en_gpio, !!mode); if (rc) { - pr_err("Update fet-ctl gpio [%d] failed\n", fet_control_data.battplus_en_gpio); + pr_err("Update fet-ctl gpio [%d] failed\n", fetControlData.battplus_en_gpio); return rc; } else { battplus_state = !!mode; pr_debug("Set using flip_battplus gpio[%d], VAL:[%d]\n", - fet_control_data.battplus_en_gpio, - gpio_get_value(fet_control_data.battplus_en_gpio)); + fetControlData.battplus_en_gpio, + gpio_get_value(fetControlData.battplus_en_gpio)); } return 0; @@ -134,22 +132,22 @@ static int set_balance_state(const char *val, const struct kernel_param *kp) int rc; long mode; - if (!fet_control_data.init_done) + if (!fetControlData.init_done) return -ENODEV; rc = kstrtol(val, 0, &mode); if (rc) return rc; - rc = update_state_gpio(fet_control_data.balance_en_n_gpio, !!mode); + rc = update_state_gpio(fetControlData.balance_en_n_gpio, !!mode); if (rc) { - pr_err("Update fet-ctl gpio [%d] failed\n", fet_control_data.balance_en_n_gpio); + pr_err("Update fet-ctl gpio [%d] failed\n", fetControlData.balance_en_n_gpio); return rc; } else { balance_state = !!mode; pr_debug("Set using flip_balance_enn gpio[%d], VAL:[%d]\n", - fet_control_data.balance_en_n_gpio, - gpio_get_value(fet_control_data.balance_en_n_gpio)); + fetControlData.balance_en_n_gpio, + gpio_get_value(fetControlData.balance_en_n_gpio)); } return 0; @@ -160,7 +158,7 @@ static int set_fullcurr_state(const char *val, const struct kernel_param *kp) int rc; long mode; - if (!fet_control_data.init_done) + if (!fetControlData.init_done) return -ENODEV; rc = kstrtol(val, 0, &mode); @@ -168,15 +166,15 @@ static int set_fullcurr_state(const char *val, const struct kernel_param *kp) return rc; - rc = update_state_gpio(fet_control_data.chrg_fullcurr_en_gpio, !!mode); + rc = update_state_gpio(fetControlData.chrg_fullcurr_en_gpio, !!mode); if (rc) { - pr_err("Update fet-ctl gpio [%d] failed\n", fet_control_data.chrg_fullcurr_en_gpio); + pr_err("Update fet-ctl gpio [%d] failed\n", fetControlData.chrg_fullcurr_en_gpio); return rc; } else { fullcurr_state = !!mode; pr_debug("Set using Chrg fullcurr_en gpio[%d], VAL:[%d]\n", - fet_control_data.chrg_fullcurr_en_gpio, - gpio_get_value(fet_control_data.chrg_fullcurr_en_gpio)); + fetControlData.chrg_fullcurr_en_gpio, + gpio_get_value(fetControlData.chrg_fullcurr_en_gpio)); } return 0; @@ -221,37 +219,20 @@ module_param_cb(fullcurr_state, static void update_work(struct work_struct *work) { struct fet_control_data *data = container_of(work, struct fet_control_data, update.work); - int flip_curr, main_curr, flip_mv, main_mv, usbtype; - int flip_dischg = 1; + int main_curr, main_mv; int main_dischg = 1; int hb_sched_time = HBDLY_DISCHARGE_MS; - bool weakchrg = 0; - const char * usb_types[] = {"UNKNOWN","SDP","DCP","CDP","ACA","Type-C","PD","PD_DRP"}; - usbtype = get_ps_int_prop(data->usb_psy, - POWER_SUPPLY_PROP_USB_TYPE); - pr_info("USB-TYPE found:%d [%s]\n", usbtype,usb_types[usbtype] ); - if (usbtype == POWER_SUPPLY_USB_TYPE_SDP) { - pr_info("USB_TYPE WEAK-CHRG\n"); - weakchrg = 1; - } + fullcurr_state = CHRG_FULLCURR_EN; - flip_mv = get_ps_int_prop(data->flip_batt_psy, + /*flip_mv = get_ps_int_prop(data->flip_batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW); - flip_mv /= 1000; + flip_mv /= 1000;*/ main_mv = get_ps_int_prop(data->main_batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW); main_mv /= 1000; - flip_curr = get_ps_int_prop(data->flip_batt_psy, - POWER_SUPPLY_PROP_CURRENT_NOW); - flip_curr /= 1000; - if (flip_curr < 0) { - pr_info("Charging Flip\n"); - flip_dischg = -1; - } - /* Main current sysfs already in mA */ main_curr = get_ps_int_prop(data->main_batt_psy, POWER_SUPPLY_PROP_CURRENT_NOW); @@ -260,15 +241,6 @@ static void update_work(struct work_struct *work) main_dischg = -1; } - /* Max Allowed Charge Curr= 1C */ - data->flip_chg_curr_max = get_ps_int_prop(data->flip_batt_psy, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN); - data->flip_chg_curr_max /= 1000; - if (data->flip_chg_curr_max < 0) { - pr_err("Failed to get Flip Max chrg curr\n"); - return; - } - data->main_chg_curr_max = get_ps_int_prop(data->main_batt_psy, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN); data->main_chg_curr_max /= 1000; @@ -277,144 +249,71 @@ static void update_work(struct work_struct *work) return; } - if (flip_dischg * flip_curr > data->flip_chg_curr_max || - main_dischg * main_curr > data->main_chg_curr_max) { - fullcurr_state = CHRG_FULLCURR_DIS; - } else { - fullcurr_state = CHRG_FULLCURR_EN; - } - - pr_info("Flip_curr:%d, flip_Ichg_MAX:%d, fullcurr state:%d\n", - flip_curr, data->flip_chg_curr_max, fullcurr_state); + /*pr_info("Flip_curr:%d, flip_Ichg_MAX:%d, fullcurr state:%d\n", + flip_curr, data->flip_chg_curr_max, fullcurr_state);*/ pr_info("Main_curr:%d, main_Ichg_MAX:%d\n", main_curr, data->main_chg_curr_max); - pr_info("Flip-Vbatt:%d, Main-Vbatt: %d\n", flip_mv, main_mv); + pr_info("Flip-Vbatt: --, Main-Vbatt: %d\n", main_mv); /* FET paths set in Batt discharge state */ - if (weakchrg || (flip_dischg ==1 && main_dischg ==1)) { + if (main_dischg == 1) { /* Leave Balance dflt-en & toggle in/out parallel low-Z battplus fet */ balance_state = 0; - if ((main_mv - flip_mv) < RBALANCE_VDIFF_MV) { + /* if ((main_mv - flip_mv) < RBALANCE_VDIFF_MV) { */ + /* MMI_STOPSHIP power: Temproary W/A for EVB, without ADC Input + * Switch battplus_en Low-Z path at MAIN-Mid-Vbatt*/ + if ( (main_mv >= MAIN_MV_MID_LO && main_mv <= MAIN_MV_MID_HI) && + (main_curr/1000 < MAIN_CURR_SWITCH) ) { battplus_state = 1; pr_info("battplus-EN: %d\n", battplus_state); } else { battplus_state = 0; pr_info("battplus-DIS: %d\n", battplus_state); + schedule_delayed_work(&data->update, msecs_to_jiffies(hb_sched_time)); } - - if (weakchrg) { - // Only pm8350b enabled for weak charger type: - hb_sched_time = HBDLY_CHARGE_MS; - flip_chrg_en_state = 0; - } - } else { - hb_sched_time = HBDLY_CHARGE_MS; - battplus_state = 0; - balance_state = 1; - flip_chrg_en_state = 1; - pr_info("FASTCHG: battfets-OPEN\n"); } - pr_info("Flip chrg_en state: %d\n", flip_chrg_en_state); /* Update GPIO controls */ - update_state_gpio(fet_control_data.battplus_en_gpio, battplus_state); - update_state_gpio(fet_control_data.balance_en_n_gpio, balance_state); - update_state_gpio(fet_control_data.chrg_fullcurr_en_gpio, fullcurr_state); - update_state_gpio(fet_control_data.flip_chrg_en_gpio, flip_chrg_en_state); - - schedule_delayed_work(&data->update, msecs_to_jiffies(hb_sched_time)); -} - -static int ps_notify_callback(struct notifier_block *nb, - unsigned long event, void *p) -{ - struct fet_control_data *data = container_of(nb, struct fet_control_data, ps_notif); - struct power_supply *psy = p; - union power_supply_propval pval = {0}; - int retval; - bool present_ps; - - if ((event == PSY_EVENT_PROP_CHANGED) && - psy && psy->desc->get_property && psy->desc->name && - !strncmp(psy->desc->name, "usb", sizeof("usb")) && data) { - pr_info("psy notif: event = %lu\n", event); - - retval = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, - &pval); - if (retval) { - pr_err("%s psy get property failed, ERR: %d\n", psy->desc->name, retval); - return retval; - } - present_ps = (pval.intval) ? true : false; - pr_info("%s is %s\n", psy->desc->name, - (present_ps) ? "present" : "not present"); - - if (event == PSY_EVENT_PROP_CHANGED) { - if (data->ps_is_present == present_ps) { - pr_info("ps present state unchanged\n"); - return 0; - } - } - data->ps_is_present = present_ps; - - /* FETS OPEN prior to reading Vbatt levels */ - battplus_state = 0; - balance_state = 1; - update_state_gpio(fet_control_data.battplus_en_gpio, battplus_state); - update_state_gpio(fet_control_data.balance_en_n_gpio, balance_state); - pr_info("VBATT CHK... battfets-OPEN\n"); - - cancel_delayed_work(&data->update); - schedule_delayed_work(&data->update, msecs_to_jiffies(3000)); - } - - return 0; + update_state_gpio(fetControlData.battplus_en_gpio, battplus_state); + update_state_gpio(fetControlData.balance_en_n_gpio, balance_state); + update_state_gpio(fetControlData.chrg_fullcurr_en_gpio, fullcurr_state); } static int parse_dt(struct device_node *node) { int rc = 0; - const char *flip_batt_psy_name, *main_batt_psy_name; + const char *main_batt_psy_name; - rc = of_property_read_string(node, "mmi,flip-batt-psy", &flip_batt_psy_name); rc |= of_property_read_string(node, "mmi,main-batt-psy", &main_batt_psy_name); - if (!rc && flip_batt_psy_name && main_batt_psy_name) { - fet_control_data.flip_batt_psy = power_supply_get_by_name(flip_batt_psy_name); - fet_control_data.main_batt_psy = power_supply_get_by_name(main_batt_psy_name); - if (!fet_control_data.flip_batt_psy || !fet_control_data.main_batt_psy) { + if (!rc && main_batt_psy_name) { + fetControlData.main_batt_psy = power_supply_get_by_name(main_batt_psy_name); + if (!fetControlData.main_batt_psy) { pr_debug("Could not get flip batt psy and main batt psy, maybe we are early - defer."); return -EPROBE_DEFER; } } - fet_control_data.battplus_en_gpio = of_get_named_gpio(node, + fetControlData.battplus_en_gpio = of_get_named_gpio(node, "mmi,flip_battplus_en_gpio", 0); - if (!gpio_is_valid(fet_control_data.battplus_en_gpio)) { + if (!gpio_is_valid(fetControlData.battplus_en_gpio)) { pr_err("battplus_en_gpio is not valid!\n"); return -ENODEV; } - fet_control_data.balance_en_n_gpio = of_get_named_gpio(node, + fetControlData.balance_en_n_gpio = of_get_named_gpio(node, "mmi,flip_balance_en_n_gpio", 0); - if (!gpio_is_valid(fet_control_data.balance_en_n_gpio)) { + if (!gpio_is_valid(fetControlData.balance_en_n_gpio)) { pr_err("balance_en_n_gpio is not valid!\n"); return -ENODEV; } - fet_control_data.chrg_fullcurr_en_gpio = of_get_named_gpio(node, + fetControlData.chrg_fullcurr_en_gpio = of_get_named_gpio(node, "mmi,chrg-fullcurr-en-gpio", 0); - if (!gpio_is_valid(fet_control_data.chrg_fullcurr_en_gpio)) { + if (!gpio_is_valid(fetControlData.chrg_fullcurr_en_gpio)) { pr_err("chrg-fullcurr-en-gpio is not valid!\n"); return -ENODEV; } - fet_control_data.flip_chrg_en_gpio = of_get_named_gpio(node, - "mmi,flip-chrg-en-gpios", 0); - if (!gpio_is_valid(fet_control_data.flip_chrg_en_gpio)) { - pr_err("flip-chrg-en-gpios is not valid!\n"); - return -ENODEV; - } - return rc; } @@ -422,102 +321,73 @@ static int fet_control_probe(struct platform_device *pdev) { int rc = 1; - fet_control_data.init_done = 0; - fet_control_data.dev = &pdev->dev; + fetControlData.init_done = 0; + fetControlData.dev = &pdev->dev; - rc = parse_dt(fet_control_data.dev->of_node); + rc = parse_dt(fetControlData.dev->of_node); if (rc) { if (rc != -EPROBE_DEFER) pr_err("Failed to parse device tree\n"); goto fail; } - fet_control_data.usb_psy = power_supply_get_by_name("usb"); - if (!fet_control_data.usb_psy) { - pr_debug("Could not get usb psy, maybe we are early - defer."); - return -EPROBE_DEFER; - } - - rc = gpio_request(fet_control_data.flip_chrg_en_gpio, "mmi,flip-chrg-en-gpios"); - if (rc) { - pr_err("Failed request flip-chrg-en-gpios\n"); - goto fail; - } - - rc = gpio_request(fet_control_data.battplus_en_gpio, "mmi,flip_battplus_en_gpio"); + rc = gpio_request(fetControlData.battplus_en_gpio, "mmi,flip_battplus_en_gpio"); if (rc) { pr_err("Failed request battplus_en_gpio\n"); goto fail; } - rc = gpio_request(fet_control_data.balance_en_n_gpio, "mmi,flip_balance_en_n_gpio"); + rc = gpio_request(fetControlData.balance_en_n_gpio, "mmi,flip_balance_en_n_gpio"); if (rc) { pr_err("Failed request balance_en_n_gpio\n"); goto fail; } - rc = gpio_request(fet_control_data.chrg_fullcurr_en_gpio, "mmi,chrg-fullcurr-en-gpio"); + rc = gpio_request(fetControlData.chrg_fullcurr_en_gpio, "mmi,chrg-fullcurr-en-gpio"); if (rc) { pr_err("Failed request chrg-fullcurr-en-gpio\n"); goto fail; } - /* Enable Flip BQ Chrg */ - rc = gpio_direction_output(fet_control_data.flip_chrg_en_gpio, 1); - if (rc) { - pr_err("Unable to set bq25898_en [%d]\n", fet_control_data.flip_chrg_en_gpio); - goto fail; - } - /* Set default Flip Battery Path FETs: battplus path disable*/ - rc = gpio_direction_output(fet_control_data.battplus_en_gpio, 0); //Path Disabled + rc = gpio_direction_output(fetControlData.battplus_en_gpio, 0); //Path Disabled if (rc) { - pr_err("Unable to set DIR flip_battplus_en [%d]\n", fet_control_data.battplus_en_gpio); + pr_err("Unable to set DIR flip_battplus_en [%d]\n", fetControlData.battplus_en_gpio); goto fail; } battplus_state = 0; /* Set Flip Rbalance path enable */ - rc = gpio_direction_output(fet_control_data.balance_en_n_gpio, 0); // Path Enabled + rc = gpio_direction_output(fetControlData.balance_en_n_gpio, 0); // Path Enabled if (rc) { - pr_err("Unable to set DIR/VAL Flip_balance_en_n [%d]\n", fet_control_data.balance_en_n_gpio); + pr_err("Unable to set DIR/VAL Flip_balance_en_n [%d]\n", fetControlData.balance_en_n_gpio); goto fail; } balance_state = 0; /* Set charger fullcurr enable */ - rc = gpio_direction_output(fet_control_data.chrg_fullcurr_en_gpio, 0); // ChrgFullCurr dflt Disable + rc = gpio_direction_output(fetControlData.chrg_fullcurr_en_gpio, 1); // ChrgFullCurr dflt Enable if (rc) { - pr_err("Unable to set DIR/VAL chrg_fullcurr_en_gpio [%d]\n", fet_control_data.chrg_fullcurr_en_gpio); + pr_err("Unable to set DIR/VAL chrg_fullcurr_en_gpio [%d]\n", fetControlData.chrg_fullcurr_en_gpio); goto fail; } - fullcurr_state = 0; + fullcurr_state = CHRG_FULLCURR_EN; pr_info("Flip_battplus_en Init GPIO:[%d], VAL:[%d]\n", - fet_control_data.battplus_en_gpio, - gpio_get_value(fet_control_data.battplus_en_gpio) ); + fetControlData.battplus_en_gpio, + gpio_get_value(fetControlData.battplus_en_gpio) ); pr_info("Flip_balance_en_n Init GPIO:[%d], VAL:[%d]\n", - fet_control_data.balance_en_n_gpio, - gpio_get_value(fet_control_data.balance_en_n_gpio) ); + fetControlData.balance_en_n_gpio, + gpio_get_value(fetControlData.balance_en_n_gpio) ); pr_info("chrg_fullcurr Init GPIO:[%d], VAL:[%d]\n", - fet_control_data.chrg_fullcurr_en_gpio, - gpio_get_value(fet_control_data.chrg_fullcurr_en_gpio) ); - pr_info("Flip charge_en Init GPIO:[%d], VAL:[%d]\n", - fet_control_data.flip_chrg_en_gpio, - gpio_get_value(fet_control_data.flip_chrg_en_gpio) ); - - // Notify on plug/unplug - fet_control_data.ps_notif.notifier_call = ps_notify_callback; - if (power_supply_reg_notifier(&fet_control_data.ps_notif)) { - pr_err("Failed to register notifier\n"); - goto fail; - } + fetControlData.chrg_fullcurr_en_gpio, + gpio_get_value(fetControlData.chrg_fullcurr_en_gpio) ); // Work to update the fet & charge current states. - INIT_DELAYED_WORK(&fet_control_data.update, update_work); - schedule_delayed_work(&fet_control_data.update, 1); + INIT_DELAYED_WORK(&fetControlData.update, update_work); + schedule_delayed_work(&fetControlData.update, 10); - fet_control_data.init_done = true; + fetControlData.init_done = true; return 0; fail: return rc; @@ -526,13 +396,11 @@ fail: static int fet_control_remove(struct platform_device *pdev) { - if (fet_control_data.init_done) { - cancel_delayed_work(&fet_control_data.update); - power_supply_unreg_notifier(&fet_control_data.ps_notif); - gpio_free(fet_control_data.battplus_en_gpio); - gpio_free(fet_control_data.balance_en_n_gpio); - gpio_free(fet_control_data.chrg_fullcurr_en_gpio); - gpio_free(fet_control_data.flip_chrg_en_gpio); + if (fetControlData.init_done) { + cancel_delayed_work(&fetControlData.update); + gpio_free(fetControlData.battplus_en_gpio); + gpio_free(fetControlData.balance_en_n_gpio); + gpio_free(fetControlData.chrg_fullcurr_en_gpio); } return 0;