static int bq2419x_resume(struct device *dev) { int ret = 0; struct bq2419x_chip *bq2419x = dev_get_drvdata(dev); unsigned int val; ret = regmap_read(bq2419x->regmap, BQ2419X_FAULT_REG, &val); if (ret < 0) { dev_err(bq2419x->dev, "FAULT_REG read failed %d\n", ret); return ret; } if (val & BQ2419x_FAULT_WATCHDOG_FAULT) { dev_err(bq2419x->dev, "Charging Fault: Watchdog Timer Expired\n"); ret = bq2419x_watchdog_init(bq2419x, bq2419x->wdt_time_sec, "RESUME"); if (ret < 0) { dev_err(bq2419x->dev, "BQWDT init failed %d\n", ret); return ret; } } ret = bq2419x_fault_clear_sts(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "fault clear status failed %d\n", ret); return ret; } ret = bq2419x_charger_init(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "Charger init failed: %d\n", ret); return ret; } ret = bq2419x_init(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "bq2419x init failed: %d\n", ret); return ret; } mutex_lock(&bq2419x->mutex); bq2419x->suspended = 0; mutex_unlock(&bq2419x->mutex); if (gpio_is_valid(bq2419x->gpio_otg_iusb)) gpio_set_value(bq2419x->gpio_otg_iusb, 1); enable_irq(bq2419x->irq); return 0; };
static int bq2419x_set_charging_current(struct regulator_dev *rdev, int min_uA, int max_uA) { struct bq2419x_chip *bq_charger = rdev_get_drvdata(rdev); int ret = 0; int val; dev_info(bq_charger->dev, "Setting charging current %d\n", max_uA/1000); msleep(200); bq_charger->status = 0; ret = bq2419x_charger_enable(bq_charger); if (ret < 0) { dev_err(bq_charger->dev, "Charger enable failed %d", ret); return ret; } ret = regmap_read(bq_charger->regmap, BQ2419X_SYS_STAT_REG, &val); if (ret < 0) dev_err(bq_charger->dev, "error reading reg: 0x%x\n", BQ2419X_SYS_STAT_REG); if (max_uA == 0 && val != 0) return ret; bq_charger->in_current_limit = max_uA/1000; if ((val & BQ2419x_VBUS_STAT) == BQ2419x_VBUS_UNKNOWN) { bq_charger->in_current_limit = 500; bq_charger->status = 0; } else { bq_charger->status = 1; } ret = bq2419x_init(bq_charger); if (ret < 0) goto error; if (bq_charger->update_status) bq_charger->update_status(bq_charger->status, 0); return 0; error: dev_err(bq_charger->dev, "Charger enable failed, err = %d\n", ret); return ret; }
static irqreturn_t bq2419x_irq(int irq, void *data) { struct bq2419x_chip *bq2419x = data; int ret; unsigned int val; int check_chg_state = 0; ret = regmap_read(bq2419x->regmap, BQ2419X_FAULT_REG, &val); if (ret < 0) { dev_err(bq2419x->dev, "FAULT_REG read failed %d\n", ret); return ret; } dev_info(bq2419x->dev, "%s() Irq %d status 0x%02x\n", __func__, irq, val); if (val & BQ2419x_FAULT_WATCHDOG_FAULT) { dev_err(bq2419x->dev, "Charging Fault: Watchdog Timer Expired\n"); ret = bq2419x_watchdog_init(bq2419x, bq2419x->wdt_time_sec, "ISR"); if (ret < 0) { dev_err(bq2419x->dev, "BQWDT init failed %d\n", ret); return ret; } ret = bq2419x_charger_init(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "Charger init failed: %d\n", ret); return ret; } ret = bq2419x_init(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "bq2419x init failed: %d\n", ret); return ret; } } if (val & BQ2419x_FAULT_BOOST_FAULT) dev_err(bq2419x->dev, "Charging Fault: VBUS Overloaded\n"); switch (val & BQ2419x_FAULT_CHRG_FAULT_MASK) { case BQ2419x_FAULT_CHRG_INPUT: dev_err(bq2419x->dev, "Charging Fault: " "Input Fault (VBUS OVP or VBAT<VBUS<3.8V)\n"); break; case BQ2419x_FAULT_CHRG_THERMAL: dev_err(bq2419x->dev, "Charging Fault: Thermal shutdown\n"); check_chg_state = 1; break; case BQ2419x_FAULT_CHRG_SAFTY: dev_err(bq2419x->dev, "Charging Fault: Safety timer expiration\n"); bq2419x->chg_restart_timeout = bq2419x->chg_restart_time / bq2419x->wdt_refresh_timeout; ret = bq2419x_reset_safety_timer(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "Reset safety timer failed %d\n", ret); return ret; } check_chg_state = 1; break; default: break; } if (val & BQ2419x_FAULT_NTC_FAULT) { dev_err(bq2419x->dev, "Charging Fault: NTC fault %d\n", val & BQ2419x_FAULT_NTC_FAULT); check_chg_state = 1; } ret = bq2419x_fault_clear_sts(bq2419x); if (ret < 0) { dev_err(bq2419x->dev, "fault clear status failed %d\n", ret); return ret; } ret = regmap_read(bq2419x->regmap, BQ2419X_SYS_STAT_REG, &val); if (ret < 0) { dev_err(bq2419x->dev, "SYS_STAT_REG read failed %d\n", ret); return ret; } if ((val & BQ2419x_CHRG_STATE_MASK) == BQ2419x_CHRG_STATE_CHARGE_DONE) { bq2419x->chg_restart_timeout = bq2419x->chg_restart_time / bq2419x->wdt_refresh_timeout; dev_info(bq2419x->dev, "Charging completed\n"); bq2419x->status = 4; if (bq2419x->update_status) bq2419x->update_status(bq2419x->status, 0); } /* * Update Charging status based on STAT register */ if (check_chg_state) { if ((val & BQ2419x_CHRG_STATE_MASK) == BQ2419x_CHRG_STATE_NOTCHARGING) { bq2419x->status = 0; if (bq2419x->update_status) bq2419x->update_status(bq2419x->status, 0); } } return IRQ_HANDLED; }
static int bq2419x_set_charging_current(struct regulator_dev *rdev, int min_uA, int max_uA) { struct bq2419x_chip *bq_charger = rdev_get_drvdata(rdev); int ret = 0; int val; dev_info(bq_charger->dev, "Setting charging current %d\n", max_uA/1000); msleep(200); bq_charger->usb_online = 0; bq_charger->ac_online = 0; bq_charger->status = 0; ret = bq2419x_charger_enable(bq_charger); if (ret < 0) { dev_err(bq_charger->dev, "Charger enable failed %d", ret); return ret; } ret = regmap_read(bq_charger->regmap, BQ2419X_SYS_STAT_REG, &val); if (ret < 0) dev_err(bq_charger->dev, "error reading reg: 0x%x\n", BQ2419X_SYS_STAT_REG); if (max_uA == 0 && val != 0) return ret; bq_charger->in_current_limit = max_uA/1000; if ((val & BQ2419x_VBUS_STAT) == BQ2419x_VBUS_UNKNOWN) { bq_charger->status = 0; bq_charger->usb_online = 0; bq_charger->in_current_limit = 500; ret = bq2419x_init(bq_charger); if (ret < 0) goto error; if (bq_charger->update_status) bq_charger->update_status (bq_charger->status, 0); } else if (bq_charger->in_current_limit == 500) { bq_charger->status = 1; bq_charger->usb_online = 1; ret = bq2419x_init(bq_charger); if (ret < 0) goto error; if (bq_charger->update_status) bq_charger->update_status (bq_charger->status, 2); } else if (bq_charger->in_current_limit > 500) { bq_charger->status = 1; bq_charger->ac_online = 1; ret = bq2419x_init(bq_charger); if (ret < 0) goto error; if (bq_charger->update_status) bq_charger->update_status (bq_charger->status, 1); } if (bq_charger->ac_online) { if ((bq_charger->in_current_limit == 1500)) bq_charger->ac.type = POWER_SUPPLY_TYPE_USB_CDP; else bq_charger->ac.type = POWER_SUPPLY_TYPE_MAINS; } if (ret == 0) { if (bq_charger->use_mains) power_supply_changed(&bq_charger->ac); if (bq_charger->use_usb) power_supply_changed(&bq_charger->usb); } return 0; error: dev_err(bq_charger->dev, "Charger enable failed, err = %d\n", ret); return ret; }
int8_t pmu_init(void) { int8_t ret; bool battery_present; state = OFF; /* make panic button an input */ io_input_pin(PANICn); panic_last = io_test_pin(PANICn); /* make the LED outputs */ io_output_pin(CHARGE); io_output_pin(POWER_LED); /* initialize the ADC, so we can sense the battery */ adc_init(); /* initialize TPS54478 for core power */ tps54478_init(true); /* wiggle USB and FTDI pins */ io_input_pin(USB_RESETn); io_output_pin(FTDI_RESETn); io_output_pin(USB_CLK_EN); io_input_pin(FTDI_CBUS3); /* make OVERTEMP input pin */ io_input_pin(OVERTEMP); /* initialize the charger */ ret = bq2419x_init(); if (ret) goto fail_bq2419x; /* wait a sec */ _delay_ms(1000); /* wdt setup */ cli(); WDTCSR |= BIT(WDCE) | BIT(WDE); WDTCSR = BIT(WDIE); sei(); /* see if we got a battery */ battery_present = pmu_battery_present(); battery_present_last = battery_present; if (battery_present) { last_full_charge = eeprom_get_last_full(); ret = ltc294x_init(LTC294X_MODEL_2942); } if (ret) return ret; ret = ltc3675_init(); if (ret) goto fail_ltc3675; /* need to hold them low until power is stable */ io_output_pin(PS_POR); io_output_pin(PS_SRST); io_clear_pin(PS_POR); io_clear_pin(PS_SRST); /* TODO: Not sure if needed */ io_input_pin(AVR_RESET); /* TODO: This will probably need to change */ io_input_pin(AVR_IRQ); io_set_pin(AVR_IRQ); // enable pull-up ? /* configure and enable interrupts */ interrupt_init(); /* initialize the timers */ timer0_init(); timer1_init(); state = OFF; return 0; fail_ltc3675: fail_bq2419x: return -1; }