<commit_before>/* Copyright 2020 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Silicon Mitus SM5803 Buck-Boost Charger
 */
#include "atomic.h"
#include "battery.h"
#include "battery_smart.h"
#include "charger.h"
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
#include "sm5803.h"
#include "throttle_ap.h"
#include "timer.h"
#include "usb_charge.h"
#include "usb_pd.h"
#include "util.h"
#include "watchdog.h"

#ifndef CONFIG_CHARGER_NARROW_VDC
#error "SM5803 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC."
#endif

/* Console output macros */
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)

#define UNKNOWN_DEV_ID -1
static int dev_id = UNKNOWN_DEV_ID;

static const struct charger_info sm5803_charger_info = {
	.name         = CHARGER_NAME,
	.voltage_max  = CHARGE_V_MAX,
	.voltage_min  = CHARGE_V_MIN,
	.voltage_step = CHARGE_V_STEP,
	.current_max  = CHARGE_I_MAX,
	.current_min  = CHARGE_I_MIN,
	.current_step = CHARGE_I_STEP,
	.input_current_max  = INPUT_I_MAX,
	.input_current_min  = INPUT_I_MIN,
	.input_current_step = INPUT_I_STEP,
};

static uint32_t irq_pending; /* Bitmask of chips with interrupts pending */

static struct mutex flow1_access_lock[CHARGER_NUM];

static int charger_vbus[CHARGER_NUM];

static int sm5803_is_sourcing_otg_power(int chgnum, int port);

static inline enum ec_error_list chg_read8(int chgnum, int offset, int *value)
{
	return i2c_read8(chg_chips[chgnum].i2c_port,
			 chg_chips[chgnum].i2c_addr_flags,
			 offset, value);
}

static inline enum ec_error_list chg_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			  chg_chips[chgnum].i2c_addr_flags,
			  offset, value);
}

static inline enum ec_error_list meas_read8(int chgnum, int offset, int *value)
{
	return i2c_read8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MEAS_FLAGS,
			 offset, value);
}

static inline enum ec_error_list meas_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MEAS_FLAGS,
			 offset, value);
}

static inline enum ec_error_list main_read8(int chgnum, int offset, int *value)
{
	return i2c_read8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MAIN_FLAGS,
			 offset, value);
}

static inline enum ec_error_list main_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MAIN_FLAGS,
			 offset, value);
}

static inline enum ec_error_list test_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_TEST_FLAGS,
			 offset, value);
}

static inline enum ec_error_list test_update8(int chgnum, const int offset,
					      const uint8_t mask,
					const enum mask_update_action action)
{
	return i2c_update8(chg_chips[chgnum].i2c_port,
			   SM5803_ADDR_TEST_FLAGS, offset, mask, action);
}

int sm5803_is_vbus_present(int chgnum)
{
	return charger_vbus[chgnum];
}

enum ec_error_list sm5803_configure_gpio0(int chgnum,
					  enum sm5803_gpio0_modes mode, int od)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
	if (rv)
		return rv;

	reg &= ~SM5803_GPIO0_MODE_MASK;
	reg |= mode << 1;

	if (od)
		reg |= SM5803_GPIO0_OPEN_DRAIN_EN;
	else
		reg &= ~SM5803_GPIO0_OPEN_DRAIN_EN;

	rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
	return rv;
}

enum ec_error_list sm5803_set_gpio0_level(int chgnum, int level)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
	if (rv)
		return rv;

	if (level)
		reg |= SM5803_GPIO0_VAL;
	else
		reg &= ~SM5803_GPIO0_VAL;

	rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
	return rv;
}

enum ec_error_list sm5803_configure_chg_det_od(int chgnum, int enable)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
	if (rv)
		return rv;

	if (enable)
		reg |= SM5803_CHG_DET_OPEN_DRAIN_EN;
	else
		reg &= ~SM5803_CHG_DET_OPEN_DRAIN_EN;

	rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
	return rv;
}

enum ec_error_list sm5803_get_chg_det(int chgnum, int *chg_det)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_STATUS1, &reg);
	if (rv)
		return rv;

	*chg_det = (reg & SM5803_STATUS1_CHG_DET) != 0;

	return EC_SUCCESS;
}

enum ec_error_list sm5803_set_vbus_disch(int chgnum, int enable)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_PORTS_CTRL, &reg);
	if (rv)
		return rv;

	if (enable)
		reg |= SM5803_PORTS_VBUS_DISCH;
	else
		reg &= ~SM5803_PORTS_VBUS_DISCH;

	rv = main_write8(chgnum, SM5803_REG_PORTS_CTRL, reg);
	return rv;
}

static void sm5803_init(int chgnum)
{
	enum ec_error_list rv;
	int reg;
	int vbus_mv;
	const struct battery_info *batt_info;
	int pre_term;
	int cells;

	/*
	 * If a charger is not currently present, disable switching per OCPC
	 * requirements
	 */
	rv = charger_get_vbus_voltage(chgnum, &vbus_mv);
	if (rv == EC_SUCCESS) {
		if (vbus_mv < 4000) {
			/*
			 * No charger connected, disable CHG_EN
			 * (note other bits default to 0)
			 */
			rv = chg_write8(chgnum, SM5803_FLOW1_CHG_EN,
					0);
		} else if (!sm5803_is_sourcing_otg_power(chgnum, chgnum)) {
			charger_vbus[chgnum] = 1;
		}
	} else {
		CPRINTS("%s %d: Failed to read VBUS voltage during init",
			CHARGER_NAME, chgnum);
		return;
	}

	rv |= charger_device_id(&reg);
	if (reg == 0x02) {
		/* --- Special register init ---
		 * For early silicon (ID 2) with 3S batteries
		 */
		rv |= main_write8(chgnum, 0x20, 0x08);
		rv |= main_write8(chgnum, 0x30, 0xC0);
		rv |= main_write8(chgnum, 0x80, 0x01);

		rv |= meas_write8(chgnum, 0x08, 0xC2);

		rv |= chg_write8(chgnum, 0x1D, 0x40);
		rv |= chg_write8(chgnum, 0x1F, 0x09);

		rv |= chg_write8(chgnum, 0x22, 0xB3);
		rv |= chg_write8(chgnum, 0x23, 0x81);
		rv |= chg_write8(chgnum, 0x28, 0xB7);

		rv |= chg_write8(chgnum, 0x4A, 0x82);
		rv |= chg_write8(chgnum, 0x4B, 0xA3);
		rv |= chg_write8(chgnum, 0x4C, 0xA8);
		rv |= chg_write8(chgnum, 0x4D, 0xCA);
		rv |= chg_write8(chgnum, 0x4E, 0x07);
		rv |= chg_write8(chgnum, 0x4F, 0xFF);

		rv |= chg_write8(chgnum, 0x50, 0x98);
		rv |= chg_write8(chgnum, 0x51, 0x00);
		rv |= chg_write8(chgnum, 0x52, 0x77);
		rv |= chg_write8(chgnum, 0x53, 0xD2);
		rv |= chg_write8(chgnum, 0x54, 0x02);
		rv |= chg_write8(chgnum, 0x55, 0xD1);
		rv |= chg_write8(chgnum, 0x56, 0x7F);
		rv |= chg_write8(chgnum, 0x57, 0x02);
		rv |= chg_write8(chgnum, 0x58, 0xD1);
		rv |= chg_write8(chgnum, 0x59, 0x7F);
		rv |= chg_write8(chgnum, 0x5A, 0x13);
		rv |= chg_write8(chgnum, 0x5B, 0x50);
		rv |= chg_write8(chgnum, 0x5C, 0x5B);
		rv |= chg_write8(chgnum, 0x5D, 0xB0);
		rv |= chg_write8(chgnum, 0x5E, 0x3C);
		rv |= chg_write8(chgnum, 0x5F, 0x3C);

		rv |= chg_write8(chgnum, 0x60, 0x44);
		rv |= chg_write8(chgnum, 0x61, 0x20);
		rv |= chg_write8(chgnum, 0x65, 0x35);
		rv |= chg_write8(chgnum, 0x66, 0x29);
		rv |= chg_write8(chgnum, 0x67, 0x64);
		rv |= chg_write8(chgnum, 0x68, 0x88);
		rv |= chg_write8(chgnum, 0x69, 0xC7);

		/* Inits to access page 0x37 and enable trickle charging */
		rv |= main_write8(chgnum, 0x1F, 0x01);
		rv |= test_update8(chgnum, 0x8E, BIT(5), MASK_SET);
		rv |= main_write8(chgnum, 0x1F, 0x00);
	} else if (reg == 0x03) {
		uint32_t platform_id;

		rv = main_read8(chgnum, SM5803_REG_PLATFORM, &platform_id);
		if (rv) {
			CPRINTS("%s %d: Failed to read platform during init",
							CHARGER_NAME, chgnum);
			return;
		}
		platform_id &= SM5803_PLATFORM_ID;

		if (platform_id >= 0x0E && platform_id <= 0x16) {
			/* 3S Battery inits */
			rv |= main_write8(chgnum, 0x30, 0xC0);
			rv |= main_write8(chgnum, 0x80, 0x01);
			rv |= main_write8(chgnum, 0x1A, 0x08);

			rv |= meas_write8(chgnum, 0x08, 0xC2);

			rv |= chg_write8(chgnum, 0x1D, 0x40);

			rv |= chg_write8(chgnum, 0x22, 0xB3);

			rv |= chg_write8(chgnum, 0x4F, 0xBF);

			rv |= chg_write8(chgnum, 0x52, 0x77);
			rv |= chg_write8(chgnum, 0x53, 0xD2);
			rv |= chg_write8(chgnum, 0x54, 0x02);
			rv |= chg_write8(chgnum, 0x55, 0xD1);
			rv |= chg_write8(chgnum, 0x56, 0x7F);
			rv |= chg_write8(chgnum, 0x57, 0x02);
			rv |= chg_write8(chgnum, 0x58, 0xD1);
			rv |= chg_write8(chgnum, 0x59, 0x7F);
			rv |= chg_write8(chgnum, 0x5A, 0x13);
			rv |= chg_write8(chgnum, 0x5B, 0x50);
			rv |= chg_write8(chgnum, 0x5D, 0xB0);

			rv |= chg_write8(chgnum, 0x60, 0x44);
			rv |= chg_write8(chgnum, 0x65, 0x35);
			rv |= chg_write8(chgnum, 0x66, 0x29);

			rv |= chg_write8(chgnum, 0x7D, 0x67);
			rv |= chg_write8(chgnum, 0x7E, 0x04);

			rv |= chg_write8(chgnum, 0x33, 0x3C);

			rv |= chg_write8(chgnum, 0x5C, 0x7A);
		} else if (platform_id >= 0x06 && platform_id <= 0x0D) {
			/* 2S Battery inits */
			rv |= main_write8(chgnum, 0x30, 0xC0);
			rv |= main_write8(chgnum, 0x80, 0x01);
			rv |= main_write8(chgnum, 0x1A, 0x08);

			rv |= meas_write8(chgnum, 0x08, 0xC2);

			rv |= chg_write8(chgnum, 0x1D, 0x40);

			rv |= chg_write8(chgnum, 0x22, 0xB3);

			rv |= chg_write8(chgnum, 0x4F, 0xBF);

			rv |= chg_write8(chgnum, 0x52, 0x77);
			rv |= chg_write8(chgnum, 0x53, 0xD2);
			rv |= chg_write8(chgnum, 0x54, 0x02);
			rv |= chg_write8(chgnum, 0x55, 0xD1);
			rv |= chg_write8(chgnum, 0x56, 0x7F);
			rv |= chg_write8(chgnum, 0x57, 0x02);
			rv |= chg_write8(chgnum, 0x58, 0xD1);
			rv |= chg_write8(chgnum, 0x59, 0x7F);
			rv |= chg_write8(chgnum, 0x5A, 0x13);
			rv |= chg_write8(chgnum, 0x5B, 0x50);
			rv |= chg_write8(chgnum, 0x5D, 0xD0);

			rv |= chg_write8(chgnum, 0x60, 0x44);
			rv |= chg_write8(chgnum, 0x65, 0x35);
			rv |= chg_write8(chgnum, 0x66, 0x29);

			rv |= chg_write8(chgnum, 0x7D, 0x97);
			rv |= chg_write8(chgnum, 0x7E, 0x07);

			rv |= chg_write8(chgnum, 0x33, 0x3C);

			rv |= chg_write8(chgnum, 0x5C, 0x7A);
		}

		rv |= chg_write8(chgnum, 0x73, 0x22);
		rv |= chg_write8(chgnum, 0x50, 0x88);
		rv |= chg_read8(chgnum, 0x34, &reg);
		reg |= BIT(7);
		rv |= chg_write8(chgnum, 0x34, reg);
		rv |= main_write8(chgnum, 0x1F, 0x1);
		rv |= test_write8(chgnum, 0x43, 0x10);
		rv |= test_write8(chgnum, 0x47, 0x10);
		rv |= test_write8(chgnum, 0x48, 0x04);
		rv |= main_write8(chgnum, 0x1F, 0x0);
	}

	/* Disable Ibus PROCHOT comparator */
	rv = chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
	reg &= ~SM5803_PHOT1_IBUS_PHOT_COMP_EN;
	rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
<commit_msg>SM5803: Update inits<commit_after>/* Copyright 2020 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Silicon Mitus SM5803 Buck-Boost Charger
 */
#include "atomic.h"
#include "battery.h"
#include "battery_smart.h"
#include "charger.h"
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
#include "sm5803.h"
#include "throttle_ap.h"
#include "timer.h"
#include "usb_charge.h"
#include "usb_pd.h"
#include "util.h"
#include "watchdog.h"

#ifndef CONFIG_CHARGER_NARROW_VDC
#error "SM5803 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC."
#endif

/* Console output macros */
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)

#define UNKNOWN_DEV_ID -1
static int dev_id = UNKNOWN_DEV_ID;

static const struct charger_info sm5803_charger_info = {
	.name         = CHARGER_NAME,
	.voltage_max  = CHARGE_V_MAX,
	.voltage_min  = CHARGE_V_MIN,
	.voltage_step = CHARGE_V_STEP,
	.current_max  = CHARGE_I_MAX,
	.current_min  = CHARGE_I_MIN,
	.current_step = CHARGE_I_STEP,
	.input_current_max  = INPUT_I_MAX,
	.input_current_min  = INPUT_I_MIN,
	.input_current_step = INPUT_I_STEP,
};

static uint32_t irq_pending; /* Bitmask of chips with interrupts pending */

static struct mutex flow1_access_lock[CHARGER_NUM];

static int charger_vbus[CHARGER_NUM];

static int sm5803_is_sourcing_otg_power(int chgnum, int port);

static inline enum ec_error_list chg_read8(int chgnum, int offset, int *value)
{
	return i2c_read8(chg_chips[chgnum].i2c_port,
			 chg_chips[chgnum].i2c_addr_flags,
			 offset, value);
}

static inline enum ec_error_list chg_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			  chg_chips[chgnum].i2c_addr_flags,
			  offset, value);
}

static inline enum ec_error_list meas_read8(int chgnum, int offset, int *value)
{
	return i2c_read8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MEAS_FLAGS,
			 offset, value);
}

static inline enum ec_error_list meas_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MEAS_FLAGS,
			 offset, value);
}

static inline enum ec_error_list main_read8(int chgnum, int offset, int *value)
{
	return i2c_read8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MAIN_FLAGS,
			 offset, value);
}

static inline enum ec_error_list main_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_MAIN_FLAGS,
			 offset, value);
}

static inline enum ec_error_list test_write8(int chgnum, int offset, int value)
{
	return i2c_write8(chg_chips[chgnum].i2c_port,
			 SM5803_ADDR_TEST_FLAGS,
			 offset, value);
}

static inline enum ec_error_list test_update8(int chgnum, const int offset,
					      const uint8_t mask,
					const enum mask_update_action action)
{
	return i2c_update8(chg_chips[chgnum].i2c_port,
			   SM5803_ADDR_TEST_FLAGS, offset, mask, action);
}

int sm5803_is_vbus_present(int chgnum)
{
	return charger_vbus[chgnum];
}

enum ec_error_list sm5803_configure_gpio0(int chgnum,
					  enum sm5803_gpio0_modes mode, int od)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
	if (rv)
		return rv;

	reg &= ~SM5803_GPIO0_MODE_MASK;
	reg |= mode << 1;

	if (od)
		reg |= SM5803_GPIO0_OPEN_DRAIN_EN;
	else
		reg &= ~SM5803_GPIO0_OPEN_DRAIN_EN;

	rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
	return rv;
}

enum ec_error_list sm5803_set_gpio0_level(int chgnum, int level)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
	if (rv)
		return rv;

	if (level)
		reg |= SM5803_GPIO0_VAL;
	else
		reg &= ~SM5803_GPIO0_VAL;

	rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
	return rv;
}

enum ec_error_list sm5803_configure_chg_det_od(int chgnum, int enable)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
	if (rv)
		return rv;

	if (enable)
		reg |= SM5803_CHG_DET_OPEN_DRAIN_EN;
	else
		reg &= ~SM5803_CHG_DET_OPEN_DRAIN_EN;

	rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
	return rv;
}

enum ec_error_list sm5803_get_chg_det(int chgnum, int *chg_det)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_STATUS1, &reg);
	if (rv)
		return rv;

	*chg_det = (reg & SM5803_STATUS1_CHG_DET) != 0;

	return EC_SUCCESS;
}

enum ec_error_list sm5803_set_vbus_disch(int chgnum, int enable)
{
	enum ec_error_list rv;
	int reg;

	rv = main_read8(chgnum, SM5803_REG_PORTS_CTRL, &reg);
	if (rv)
		return rv;

	if (enable)
		reg |= SM5803_PORTS_VBUS_DISCH;
	else
		reg &= ~SM5803_PORTS_VBUS_DISCH;

	rv = main_write8(chgnum, SM5803_REG_PORTS_CTRL, reg);
	return rv;
}

static void sm5803_init(int chgnum)
{
	enum ec_error_list rv;
	int reg;
	int vbus_mv;
	const struct battery_info *batt_info;
	int pre_term;
	int cells;

	/*
	 * If a charger is not currently present, disable switching per OCPC
	 * requirements
	 */
	rv = charger_get_vbus_voltage(chgnum, &vbus_mv);
	if (rv == EC_SUCCESS) {
		if (vbus_mv < 4000) {
			/*
			 * No charger connected, disable CHG_EN
			 * (note other bits default to 0)
			 */
			rv = chg_write8(chgnum, SM5803_FLOW1_CHG_EN,
					0);
		} else if (!sm5803_is_sourcing_otg_power(chgnum, chgnum)) {
			charger_vbus[chgnum] = 1;
		}
	} else {
		CPRINTS("%s %d: Failed to read VBUS voltage during init",
			CHARGER_NAME, chgnum);
		return;
	}

	rv |= charger_device_id(&reg);
	if (reg == 0x02) {
		/* --- Special register init ---
		 * For early silicon (ID 2) with 3S batteries
		 */
		rv |= main_write8(chgnum, 0x20, 0x08);
		rv |= main_write8(chgnum, 0x30, 0xC0);
		rv |= main_write8(chgnum, 0x80, 0x01);

		rv |= meas_write8(chgnum, 0x08, 0xC2);

		rv |= chg_write8(chgnum, 0x1D, 0x40);
		rv |= chg_write8(chgnum, 0x1F, 0x09);

		rv |= chg_write8(chgnum, 0x22, 0xB3);
		rv |= chg_write8(chgnum, 0x23, 0x81);
		rv |= chg_write8(chgnum, 0x28, 0xB7);

		rv |= chg_write8(chgnum, 0x4A, 0x82);
		rv |= chg_write8(chgnum, 0x4B, 0xA3);
		rv |= chg_write8(chgnum, 0x4C, 0xA8);
		rv |= chg_write8(chgnum, 0x4D, 0xCA);
		rv |= chg_write8(chgnum, 0x4E, 0x07);
		rv |= chg_write8(chgnum, 0x4F, 0xFF);

		rv |= chg_write8(chgnum, 0x50, 0x98);
		rv |= chg_write8(chgnum, 0x51, 0x00);
		rv |= chg_write8(chgnum, 0x52, 0x77);
		rv |= chg_write8(chgnum, 0x53, 0xD2);
		rv |= chg_write8(chgnum, 0x54, 0x02);
		rv |= chg_write8(chgnum, 0x55, 0xD1);
		rv |= chg_write8(chgnum, 0x56, 0x7F);
		rv |= chg_write8(chgnum, 0x57, 0x02);
		rv |= chg_write8(chgnum, 0x58, 0xD1);
		rv |= chg_write8(chgnum, 0x59, 0x7F);
		rv |= chg_write8(chgnum, 0x5A, 0x13);
		rv |= chg_write8(chgnum, 0x5B, 0x50);
		rv |= chg_write8(chgnum, 0x5C, 0x5B);
		rv |= chg_write8(chgnum, 0x5D, 0xB0);
		rv |= chg_write8(chgnum, 0x5E, 0x3C);
		rv |= chg_write8(chgnum, 0x5F, 0x3C);

		rv |= chg_write8(chgnum, 0x60, 0x44);
		rv |= chg_write8(chgnum, 0x61, 0x20);
		rv |= chg_write8(chgnum, 0x65, 0x35);
		rv |= chg_write8(chgnum, 0x66, 0x29);
		rv |= chg_write8(chgnum, 0x67, 0x64);
		rv |= chg_write8(chgnum, 0x68, 0x88);
		rv |= chg_write8(chgnum, 0x69, 0xC7);

		/* Inits to access page 0x37 and enable trickle charging */
		rv |= main_write8(chgnum, 0x1F, 0x01);
		rv |= test_update8(chgnum, 0x8E, BIT(5), MASK_SET);
		rv |= main_write8(chgnum, 0x1F, 0x00);
	} else if (reg == 0x03) {
		uint32_t platform_id;

		rv = main_read8(chgnum, SM5803_REG_PLATFORM, &platform_id);
		if (rv) {
			CPRINTS("%s %d: Failed to read platform during init",
							CHARGER_NAME, chgnum);
			return;
		}
		platform_id &= SM5803_PLATFORM_ID;

		if (platform_id >= 0x0E && platform_id <= 0x16) {
			/* 3S Battery inits */
			rv |= main_write8(chgnum, 0x30, 0xC0);
			rv |= main_write8(chgnum, 0x80, 0x01);
			rv |= main_write8(chgnum, 0x1A, 0x08);

			rv |= meas_write8(chgnum, 0x08, 0xC2);

			rv |= chg_write8(chgnum, 0x1D, 0x40);

			rv |= chg_write8(chgnum, 0x22, 0xB3);

			rv |= chg_write8(chgnum, 0x4B, 0xA6);
			rv |= chg_write8(chgnum, 0x4F, 0xBF);

			rv |= chg_write8(chgnum, 0x52, 0x77);
			rv |= chg_write8(chgnum, 0x53, 0xD2);
			rv |= chg_write8(chgnum, 0x54, 0x02);
			rv |= chg_write8(chgnum, 0x55, 0xD1);
			rv |= chg_write8(chgnum, 0x56, 0x7F);
			rv |= chg_write8(chgnum, 0x57, 0x01);
			rv |= chg_write8(chgnum, 0x58, 0x50);
			rv |= chg_write8(chgnum, 0x59, 0x7F);
			rv |= chg_write8(chgnum, 0x5A, 0x13);
			rv |= chg_write8(chgnum, 0x5B, 0x50);
			rv |= chg_write8(chgnum, 0x5D, 0xB0);

			rv |= chg_write8(chgnum, 0x60, 0x44);
			rv |= chg_write8(chgnum, 0x65, 0x35);
			rv |= chg_write8(chgnum, 0x66, 0x29);

			rv |= chg_write8(chgnum, 0x7D, 0x67);
			rv |= chg_write8(chgnum, 0x7E, 0x04);

			rv |= chg_write8(chgnum, 0x33, 0x3C);

			rv |= chg_write8(chgnum, 0x5C, 0x7A);
		} else if (platform_id >= 0x06 && platform_id <= 0x0D) {
			/* 2S Battery inits */
			rv |= main_write8(chgnum, 0x30, 0xC0);
			rv |= main_write8(chgnum, 0x80, 0x01);
			rv |= main_write8(chgnum, 0x1A, 0x08);

			rv |= meas_write8(chgnum, 0x08, 0xC2);

			rv |= chg_write8(chgnum, 0x1D, 0x40);

			rv |= chg_write8(chgnum, 0x22, 0xB3);

			rv |= chg_write8(chgnum, 0x4F, 0xBF);

			rv |= chg_write8(chgnum, 0x52, 0x77);
			rv |= chg_write8(chgnum, 0x53, 0xD2);
			rv |= chg_write8(chgnum, 0x54, 0x02);
			rv |= chg_write8(chgnum, 0x55, 0xD1);
			rv |= chg_write8(chgnum, 0x56, 0x7F);
			rv |= chg_write8(chgnum, 0x57, 0x01);
			rv |= chg_write8(chgnum, 0x58, 0x50);
			rv |= chg_write8(chgnum, 0x59, 0x7F);
			rv |= chg_write8(chgnum, 0x5A, 0x13);
			rv |= chg_write8(chgnum, 0x5B, 0x52);
			rv |= chg_write8(chgnum, 0x5D, 0xD0);

			rv |= chg_write8(chgnum, 0x60, 0x44);
			rv |= chg_write8(chgnum, 0x65, 0x35);
			rv |= chg_write8(chgnum, 0x66, 0x29);

			rv |= chg_write8(chgnum, 0x7D, 0x97);
			rv |= chg_write8(chgnum, 0x7E, 0x07);

			rv |= chg_write8(chgnum, 0x33, 0x3C);

			rv |= chg_write8(chgnum, 0x5C, 0x7A);
		}

		rv |= chg_write8(chgnum, 0x73, 0x22);
		rv |= chg_write8(chgnum, 0x50, 0x88);
		rv |= chg_read8(chgnum, 0x34, &reg);
		reg |= BIT(7);
		rv |= chg_write8(chgnum, 0x34, reg);
		rv |= main_write8(chgnum, 0x1F, 0x1);
		rv |= test_write8(chgnum, 0x43, 0x10);
		rv |= test_write8(chgnum, 0x47, 0x10);
		rv |= test_write8(chgnum, 0x48, 0x04);
		rv |= main_write8(chgnum, 0x1F, 0x0);
	}

	/* Disable Ibus PROCHOT comparator */
	rv = chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
	reg &= ~SM5803_PHOT1_IBUS_PHOT_COMP_EN;
	rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);

{'fraction_non_alphanumeric': 0.13045137894837294, 'fraction_numerical': 0.08631548811909533, 'mean_word_length': 4.428386428386428, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '885640', 'n_tokens_mistral': 11117, 'n_tokens_neox': 9797, 'n_words': 1994}