#ifndef ICX3_H
#define ICX3_H

#include <stdint.h>
#include "evga-card.h"

#define ICX3_I2C_ADDR 0x2D

#define ICX3_REG_FANCONTROL 80
#define ICX3_REG_TEMPSENSOR 102
#define ICX3_REG_READINFORMATION 177
#define ICX3_REG_ENABLEWRITE 178

#define ICX3_FANCONTROL_SIZE 0x09
#define ICX3_TEMPSENSOR_SIZE 0x13
#define ICX3_READINFORMATION_SIZE 0x06
#define ICX3_ENABLEWRITE_SIZE 0x05

#define ICX3_MAX_FANS 4
#define ICX3_NUM_TEMP_SENSORS 9

#define ICX3_WRITE_ENABLED 0xFC
#define ICX3_WRITE_DISABLED 0xFE

struct icx3_fan_control {
	uint8_t length;
	uint8_t fanmode;
	uint16_t rpm_offset;
	uint8_t duty;
	uint8_t duty_status;
	uint16_t rpm_status;
};

struct icx3_temp_sensors {
	uint8_t length;
	uint8_t data[18];
};

struct icx3_info {
	uint8_t length;
	uint8_t reserved;
	uint8_t slave_address;
	uint8_t product_id;
	uint8_t major_version;
	uint8_t minor_version;
};

enum icx3_product_id {
	ICX3_PRODUCT_IAP = 160,
	ICX3_PRODUCT_E227_E228_FTW3 = 2,
	ICX3_PRODUCT_E230_FTW3 = 4,
	ICX3_PRODUCT_E227_E228_FTW3_HYBRID = 8,
	ICX3_PRODUCT_E227_E228_FTW3_HC = 9,
	ICX3_PRODUCT_E221_E222_XC3 = 1,
	ICX3_PRODUCT_E229_XC3 = 5,
	ICX3_PRODUCT_E221_E222_XC3_HYBRID = 6,
	ICX3_PRODUCT_E221_E222_XC3_HC = 7,
	ICX3_PRODUCT_IAP_KINGPIN = 161,
	ICX3_PRODUCT_E223_KINGPIN_HYBRID = 3,
	ICX3_PRODUCT_E223_KINGPIN_HC = 10,
	ICX3_PRODUCT_IAP_KINGPIN_E251 = 165,
	ICX3_PRODUCT_E251_KINGPIN_HYBRID = 19,
	ICX3_PRODUCT_E251_KINGPIN_HC = 26,
	ICX3_PRODUCT_IAP_LPC5516 = 164,
	ICX3_PRODUCT_E250_FTW3 = 50,
	ICX3_PRODUCT_E250_FTW3_HYBRID = 56,
	ICX3_PRODUCT_IAP_LPC54113 = 162,
	ICX3_PRODUCT_E227_E228_FTW3_LPC54113 = 18,
	ICX3_PRODUCT_E227_E228_FTW3_HYBRID_LPC54113 = 24,
	ICX3_PRODUCT_E230_FTW3_LPC54113 = 20,
	ICX3_PRODUCT_E222_XC3_LPC54113 = 17,
	ICX3_PRODUCT_E229_XC3_LPC54113 = 21,
	ICX3_PRODUCT_IAP_STM32L431 = 163,
	ICX3_PRODUCT_E230_E238_FTW3_STM32L431 = 36,
	ICX3_PRODUCT_E221_XC3_STM32L431 = 33,
	ICX3_PRODUCT_E229_E237_XC3_STM32L431 = 37,
	ICX3_PRODUCT_NONE = 0
};

enum icx3_fan_mode {
	ICX3_FANMODE_DEFAULT,
	ICX3_FANMODE_GPU_CONTROL,
	ICX3_FANMODE_RPM,
	ICX3_FANMODE_GPU_RPM_OFFSET,
	ICX3_FANMODE_MCU_CURVE,
	ICX3_FANMODE_MODE3,
};

static unsigned char icx3_write_enable[ICX3_ENABLEWRITE_SIZE] = {ICX3_ENABLEWRITE_SIZE-1, 198, 235, 234, 21};
static unsigned char icx3_write_disable[ICX3_ENABLEWRITE_SIZE] = {ICX3_ENABLEWRITE_SIZE-1, 144, 235, 203, 52};

static char *icx3_fan_names[] = {
	"Fan 0", 
	"Fan 1", 
	"Fan 2", 
	"Ext. fan"
};

static char *icx3_fan_mode_names[] = {
	"Default",
	"Auto",
	"Manual",
	"Offset",
	"MCU curve",
	"Mode 3"
};

static char *icx3_temp_sensor_names[] = {
	"GPU2",
	"MEM1",
	"MEM2",
	"MEM3",
	"PWR1",
	"PWR2",
	"PWR3",
	"PWR4",
	"PWR5",
};

int icx3_init(struct card_info *card);
void print_icx3_fans(struct card_info *card);
void print_icx3_fans_oneline(struct card_info *card);
void print_icx3_temps_oneline(struct card_info *card);
void get_available_fans(char *fans_avail, struct card_info *card);
void get_fan_status(struct icx3_fan_control *fans, struct card_info *card);
void get_temp_sensors(float *temps, struct card_info *card);
void enable_write(int enable, struct card_info *card);
void set_fan(int fan, char *setting, struct card_info *card);

#endif