static int bq2425x_getreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, FAR uint8_t *regval) { uint8_t val; int ret; /* Set the I2C address and address size */ I2C_SETADDRESS(priv->i2c, priv->addr, 7); /* Write the register address */ ret = I2C_WRITE(priv->i2c, ®addr, 1); if (ret < 0) { batdbg("I2C_WRITE failed: %d\n", ret); return ret; } /* Restart and read 8-bits from the register */ ret = I2C_READ(priv->i2c, &val, 1); if (ret < 0) { batdbg("I2C_READ failed: %d\n", ret); return ret; } /* Copy 8-bit value to be returned */ *regval = val; return OK; }
static inline int bq2425x_watchdog(FAR struct bq2425x_dev_s *priv, bool enable) { int ret; uint8_t regval; ret = bq2425x_getreg8(priv, BQ2425X_REG_1, ®val); if (ret < 0) { batdbg("Error reading from BQ2425X! Error = %d\n", ret); return ret; } if (enable) { regval |= BQ2425X_WD_EN; } else { regval &= ~(BQ2425X_WD_EN); } ret = bq2425x_putreg8(priv, BQ2425X_REG_1, regval); if (ret < 0) { batdbg("Error writing to BQ2425X! Error = %d\n", ret); return ret; } return OK; }
static int max1704x_getreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr, FAR uint16_t *regval) { uint8_t buffer[2]; int ret; /* Set the I2C address and address size */ I2C_SETADDRESS(priv->i2c, priv->addr, 7); /* Write the register address */ ret = I2C_WRITE(priv->i2c, ®addr, 1); if (ret < 0) { batdbg("I2C_WRITE failed: %d\n", ret); return ret; } /* Restart and read 16-bits from the register */ ret = I2C_READ(priv->i2c, buffer, 2); if (ret < 0) { batdbg("I2C_READ failed: %d\n", ret); return ret; } /* Return the 16-bit value */ return (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1]; return OK; }
FAR struct battery_charger_dev_s *bq2425x_initialize(FAR struct i2c_dev_s *i2c, uint8_t addr, uint32_t frequency) { FAR struct bq2425x_dev_s *priv; int ret; /* Initialize the BQ2425x device structure */ priv = (FAR struct bq2425x_dev_s *)kmm_zalloc(sizeof(struct bq2425x_dev_s)); if (priv) { /* Initialize the BQ2425x device structure */ sem_init(&priv->batsem, 0, 1); priv->ops = &g_bq2425xops; priv->i2c = i2c; priv->addr = addr; priv->frequency = frequency; /* Set the I2C frequency (ignoring the returned, actual frequency) */ (void)I2C_SETFREQUENCY(i2c, priv->frequency); /* Reset the BQ2425x */ ret = bq2425x_reset(priv); if (ret < 0) { batdbg("Failed to reset the BQ2425x: %d\n", ret); kmm_free(priv); return NULL; } /* Disable watchdog otherwise BQ2425x returns to StandAlone mode */ ret = bq2425x_watchdog(priv, false); if (ret < 0) { batdbg("Failed to disable BQ2425x watchdog: %d\n", ret); kmm_free(priv); return NULL; } /* Define that our power supply can offer 2000mA to the charger */ ret = bq2425x_powersupply(priv, 2000); if (ret < 0) { batdbg("Failed to set BQ2425x power supply current: %d\n", ret); kmm_free(priv); return NULL; } } return (FAR struct battery_charger_dev_s *)priv; }
static inline int bq2425x_reset(FAR struct bq2425x_dev_s *priv) { int ret; uint8_t regval; /* Read current register value */ ret = bq2425x_getreg8(priv, BQ2425X_REG_2, ®val); if (ret < 0) { batdbg("Error reading from BQ2425X! Error = %d\n", ret); return ret; } /* Send reset command */ regval |= BQ2425X_RESET; ret = bq2425x_putreg8(priv, BQ2425X_REG_2, regval); if (ret < 0) { batdbg("Error writing to BQ2425X! Error = %d\n", ret); return ret; } /* Wait a little bit to clear registers */ usleep(500); /* There is a BUG in BQ2425X the RESET bit is always read as 1 */ regval &= ~(BQ2425X_RESET); ret = bq2425x_putreg8(priv, BQ2425X_REG_2, regval); if (ret < 0) { batdbg("Error writing to BQ2425X! Error = %d\n", ret); return ret; } return OK; }
static inline int bq2425x_setcurr(FAR struct bq2425x_dev_s *priv, int current) { uint8_t regval; int ret, idx; /* Verify if voltage is in the acceptable range */ if (current < BQ2425X_CURR_MIN || current > BQ2425X_CURR_MAX) { batdbg("Current %d mA is out of range.\n", volts); return -EINVAL; } ret = bq2425x_getreg8(priv, BQ2425X_REG_4, ®val); if (ret < 0) { batdbg("Error reading from BQ2425X! Error = %d\n", ret); return ret; } /* Current starts at 500mV and increases in steps of 50mA */ idx = current - BQ2425X_CURR_MIN; idx = idx / 50; /* Clear previous current and set new value */ regval &= ~(BQ2425X_CHG_CURRENT_MASK); regval |= (idx << BQ2425X_CHG_CURRENT_SHIFT); ret = bq2425x_putreg8(priv, BQ2425X_REG_4, regval); if (ret < 0) { batdbg("Error writing to BQ2425X! Error = %d\n", ret); return ret; } return OK; }
static inline int bq2425x_setvolt(FAR struct bq2425x_dev_s *priv, int volts) { uint8_t regval; int ret, idx; /* Verify if voltage is in the acceptable range */ if (volts < BQ2425X_VOLT_MIN || volts > BQ2425X_VOLT_MAX) { batdbg("Voltage %d mV is out of range.\n", volts); return -EINVAL; } ret = bq2425x_getreg8(priv, BQ2425X_REG_3, ®val); if (ret < 0) { batdbg("Error reading from BQ2425X! Error = %d\n", ret); return ret; } /* Voltage starts at 3500mV and increases in steps of 20mV */ idx = volts - BQ2425X_VOLT_MIN; idx = idx / 20; /* Clear previous voltage */ regval &= ~(BQ2425X_BAT_VOLT_MASK); regval |= (idx << BQ2425X_BAT_VOLT_SHIFT); ret = bq2425x_putreg8(priv, BQ2425X_REG_3, regval); if (ret < 0) { batdbg("Error writing to BQ2425X! Error = %d\n", ret); return ret; } return OK; }
static int bq2425x_getreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, FAR uint8_t *regval) { struct i2c_config_s config; uint8_t val; int ret; /* Set up the I2C configuration */ config.frequency = priv->frequency; config.address = priv->addr; config.addrlen = 7; /* Write the register address */ ret = i2c_write(priv->i2c, &config, ®addr, 1); if (ret < 0) { batdbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 8-bits from the register */ ret = i2c_read(priv->i2c, &config, &val, 1); if (ret < 0) { batdbg("i2c_read failed: %d\n", ret); return ret; } /* Copy 8-bit value to be returned */ *regval = val; return OK; }
static int bq2425x_current(struct battery_charger_dev_s *dev, int value) { FAR struct bq2425x_dev_s *priv = (FAR struct bq2425x_dev_s *)dev; int ret; /* Set current to battery charger */ ret = bq2425x_setcurr(priv, value); if (ret < 0) { batdbg("Error setting current to BQ2425X! Error = %d\n", ret); return ret; } return OK; }
static int bq2425x_putreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, uint8_t regval) { uint8_t buffer[2]; batdbg("addr: %02x regval: %08x\n", regaddr, regval); /* Set up a 3 byte message to send */ buffer[0] = regaddr; buffer[1] = regval; /* Set the I2C address and address size */ I2C_SETADDRESS(priv->i2c, priv->addr, 7); /* Write the register address followed by the data (no RESTART) */ return I2C_WRITE(priv->i2c, buffer, 2); }
static int max1704x_putreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr, uint16_t regval) { uint8_t buffer[3]; batdbg("addr: %02x regval: %08x\n", regaddr, regval); /* Set up a 3 byte message to send */ buffer[0] = regaddr; buffer[1] = (uint8_t)(regval >> 8); buffer[2] = (uint8_t)(regval & 0xff); /* Set the I2C address and address size */ I2C_SETADDRESS(priv->i2c, priv->addr, 7); /* Write the register address followed by the data (no RESTART) */ return I2C_WRITE(priv->i2c, buffer, 3); }
FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c, uint8_t addr, uint32_t frequency) { FAR struct max1704x_dev_s *priv; #if 0 int ret; #endif /* Initialize the MAX1704x device structure */ priv = (FAR struct max1704x_dev_s *)kzalloc(sizeof(struct max1704x_dev_s)); if (priv) { /* Initialize the MAX1704x device structure */ sem_init(&priv->batsem, 0, 1); priv->ops = &g_max1704xops; priv->i2c = i2c; priv->addr = addr; priv->frequency = frequency; /* Set the I2C frequency (ignoring the returned, actual frequency) */ (void)I2C_SETFREQUENCY(i2c, priv->frequency); /* Reset the MAX1704x (mostly just to make sure that we can talk to it) */ #if 0 ret = max1704x_reset(priv); if (ret < 0) { batdbg("Failed to reset the MAX1704x: %d\n", ret); kfree(priv); return NULL; } #endif } return (FAR struct battery_dev_s *)priv; }
static int bq2425x_putreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, uint8_t regval) { struct i2c_config_s config; uint8_t buffer[2]; /* Set up the I2C configuration */ config.frequency = priv->frequency; config.address = priv->addr; config.addrlen = 7; batdbg("addr: %02x regval: %08x\n", regaddr, regval); /* Set up a 3 byte message to send */ buffer[0] = regaddr; buffer[1] = regval; /* Write the register address followed by the data (no RESTART) */ return i2c_write(priv->i2c, &config, buffer, 2); }
static inline int bq2425x_powersupply(FAR struct bq2425x_dev_s *priv, int current) { uint8_t regval; int ret, idx; switch (current) { case 100: idx = BQ2425X_INP_CURR_LIM_100MA; break; case 150: idx = BQ2425X_INP_CURR_LIM_150MA; break; case 500: idx = BQ2425X_INP_CURR_LIM_500MA; break; case 900: idx = BQ2425X_INP_CURR_LIM_900MA; break; case 1500: idx = BQ2425X_INP_CURR_LIM_1500MA; break; case 2000: idx = BQ2425X_INP_CURR_LIM_2000MA; break; default: batdbg("Current not supported, setting default to 100mA.!\n"); idx = BQ2425X_INP_CURR_LIM_100MA; break; } /* Read current register */ ret = bq2425x_getreg8(priv, BQ2425X_REG_2, ®val); if (ret < 0) { batdbg("Error reading from BQ2425X! Error = %d\n", ret); return ret; } /* Clear previous current and set new value */ regval &= ~(BQ2425X_INP_CURR_LIM_MASK); regval |= idx; /* Also clear Reset bit to avoid the resetting BUG */ regval &= ~(BQ2425X_RESET); ret = bq2425x_putreg8(priv, BQ2425X_REG_2, regval); if (ret < 0) { batdbg("Error writing to BQ2425X! Error = %d\n", ret); return ret; } return OK; }