// Copyright 2023 The Fuchsia Authors.
//
// SPDX-License-Identifier:    BSD-2-Clause

#include <fusb302-sink.h>

#include <common.h>
#include <i2c.h>

// The comments in this file reference the datasheet from onsemi titled
// "FUSB302B Programmable USB Type‐C Controller w/PD", order number FUSB302B/D,
// downloadable at https://www.onsemi.com/pdf/datasheet/fusb302b-d.pdf
//
// The section and page numbers reference Revision 5, published August 2021.

struct fusb302_device_info {
	// Populated by fusb302_initialize_i2c(), used by other I/O code.
	uint8_t i2c_address;
};

// Global that coordinates I/O.
static struct fusb302_device_info g_info = { .i2c_address = 0 };

// The result of a `fusb302_read_register()` call.
struct read_result {
	int error; // Zero if no error occurred
	uint8_t value; // Only meaningful if `error` is zero.
};

// Reads a single byte from an I2C-addressable register.
//
// This is the intended access method for most registers. The only exception is
// the FIFO register, which accepts burst reads / writes.
//
// The caller may assume that a descriptive message has been logged if an error
// is reported.
//
// Must only be called after `fusb302_initialize_i2c()` succeeds.
static struct read_result fusb302_read_register(uint8_t register_index)
{
	struct read_result return_value = { .error = 0, .value = 0 };

	return_value.error = i2c_read(g_info.i2c_address, register_index,
				      /*address_length=*/1, &return_value.value,
				      sizeof(return_value.value));
	if (return_value.error != 0) {
		error("fusb302-sink: I2C error reading from register 0x%02x - %d",
		      (int)register_index, return_value.error);
	}
	return return_value;
}

// Writes a single byte to an I2C-addressable register.
//
// Returns 0 for success, an error code otherwise. The caller may assume that a
// descriptive message has been logged if an error is returned
//
// This is the intended access method for most registers. The only exception is
// the FIFO register, which accepts burst reads / writes.
//
// Must only be called after `fusb302_initialize_i2c()` succeeds.
static int fusb302_write_register(uint8_t register_index, uint8_t value)
{
	int write_result = i2c_write(g_info.i2c_address, register_index,
				     /*address_length=*/1, &value,
				     sizeof(value));
	if (write_result != 0) {
		error("fusb302-sink: I2C error writing 0x%02x to register 0x%02x - %d",
		      (int)value, (int)register_index, write_result);
	}
	return write_result;
}

// Returns 0 for success, an error code otherwise.
//
// The caller may assume that a descriptive message has been logged if an error
// is returned.
static int fusb302_initialize_i2c(void)
{
	static const int i2c_speed = 0;

	// The board does not act as an I2C device.
	static const int board_i2c_device_address = 0;

	i2c_init(i2c_speed, board_i2c_device_address);

	// From Table 15 in the datasheet.
	//
	// We currently hard-code the I2C address for the FUSB302BMPX chip in the VIM3
	// board. Some FUSB302B models use the addresses 0x23 / 0x24 / 0x25. We could
	// iterate over all the I2C addresses until we get a response.
	static const uint8_t fusb302_i2c_device_address = 0x22;
	int probe_result = i2c_probe(fusb302_i2c_device_address);
	if (probe_result != 0) {
		error("fusb302-sink: I2C probe failed - %d", probe_result);
		return probe_result;
	}
	g_info.i2c_address = fusb302_i2c_device_address;
	return 0;
}

// Returns 0 for success, an error code otherwise.
//
// The caller may assume that a descriptive message has been logged if an error
// is returned.
static int fusb302_log_device_id(void)
{
	// From Table 17 in the datasheet.
	static const uint8_t device_id_address = 0x01;
	struct read_result device_id_read_result =
		fusb302_read_register(device_id_address);
	if (device_id_read_result.error != 0) {
		// `fusb302_read_register()` already logged an error.
		return device_id_read_result.error;
	}
	printf("fusb302-sink: device ID 0x%02x\n", device_id_read_result.value);
	return 0;
}

struct fusb302_register_assignment {
	uint8_t reg_index;
	uint8_t mask;
	uint8_t expected_value;
};

// The values of all control registers after a software reset.
//
// From Table 16 in the datasheet.
static struct fusb302_register_assignment g_reset_state[] = {
	// The reset configuration has CC1 and CC2 connected to 5.1 kOhm pull-down
	// resistors (Rd), which means we're advertising as a Sink.
	//
	// Until the OS driver takes over, we'll appear to be a Sink that doesn't
	// implement the USB PD protocol, which allows us to consume up to 15 W (5V @
	// 3A) of power. The OS driver can attempt to negotiate a PD Contract that
	// gives us more power.
	{ .reg_index = 0x02, .mask = 0xff, .expected_value = 0x03 }, // Switches0
	{ .reg_index = 0x03, .mask = 0xf7, .expected_value = 0x20 }, // Switches1
	{ .reg_index = 0x04, .mask = 0x7f, .expected_value = 0x31 }, // Measure
	{ .reg_index = 0x05, .mask = 0xff, .expected_value = 0x60 }, // Slice
	{ .reg_index = 0x06, .mask = 0x6f, .expected_value = 0x24 }, // Control0
	{ .reg_index = 0x07, .mask = 0x77, .expected_value = 0x00 }, // Control1
	{ .reg_index = 0x08, .mask = 0xef, .expected_value = 0x02 }, // Control2
	{ .reg_index = 0x09, .mask = 0x7f, .expected_value = 0x06 }, // Control3

	{ .reg_index = 0x0a, .mask = 0xff, .expected_value = 0x00 }, // Mask1
	{ .reg_index = 0x0b, .mask = 0x0f, .expected_value = 0x01 }, // Power
	{ .reg_index = 0x0d, .mask = 0x0f, .expected_value = 0x0f }, // OCPreg
	{ .reg_index = 0x0e, .mask = 0xff, .expected_value = 0x00 }, // Maska
	{ .reg_index = 0x0f, .mask = 0x01, .expected_value = 0x00 }, // Maskb
	{ .reg_index = 0x10, .mask = 0x01, .expected_value = 0x00 }, // Control4
};

// Checks the control registers against the documented reset values.

// Returns 0 for success, an error code otherwise. The caller may assume that a
// descriptive message has been logged if an error is returned.
static int fusb302_initialize_registers(void)
{
	const int assignment_count =
		sizeof(g_reset_state) / sizeof(g_reset_state[0]);
	for (int i = 0; i < assignment_count; ++i) {
		const uint8_t register_index = g_reset_state[i].reg_index;
		const uint8_t defined_bits_mask = g_reset_state[i].mask;
		const uint8_t expected_value = g_reset_state[i].expected_value;

		const struct read_result read_result =
			fusb302_read_register(register_index);
		if (read_result.error != 0) {
			// `fusb302_read_register()` already logged an error.
			return read_result.error;
		}

		const uint8_t normalized_value = read_result.value &
						 defined_bits_mask;
		if (normalized_value == expected_value) {
			continue;
		}

		debug("fusb302-sink: control register 0x%02x has normalized value 0x%02x, "
		      "expected 0x%02x\n",
		      (int)register_index, (int)normalized_value,
		      (int)expected_value);

		// Leave the undefined bits as they were, set the defined bits to their
		// documented reset values.
		const uint8_t reset_value =
			(read_result.value & ~defined_bits_mask) |
			expected_value;
		const int write_result =
			fusb302_write_register(register_index, reset_value);
		if (write_result != 0) {
			// `fusb302_write_register()` already logged an error.
			return write_result;
		}
	}

	return 0;
}

int fusb302_sink_init(void)
{
	const int i2c_init_result = fusb302_initialize_i2c();
	if (i2c_init_result != 0) {
		return i2c_init_result;
	}

	const int device_id_init_result = fusb302_log_device_id();
	if (device_id_init_result != 0) {
		return device_id_init_result;
	}

	const int register_init_result = fusb302_initialize_registers();
	if (register_init_result != 0) {
		return register_init_result;
	}

	printf("fusb302-sink: initialized\n");
	return 0;
}
