summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/google/fizz/mainboard.c107
1 files changed, 92 insertions, 15 deletions
diff --git a/src/mainboard/google/fizz/mainboard.c b/src/mainboard/google/fizz/mainboard.c
index ce60283eaf..98c00782f7 100644
--- a/src/mainboard/google/fizz/mainboard.c
+++ b/src/mainboard/google/fizz/mainboard.c
@@ -37,9 +37,64 @@
*/
#define GET_TYPEC_PL2(w) (9 * (w) / 10)
+#define OEM_ID_COUNT 3
+#define SKU_ID_COUNT 7
+
+/* List of BJ adapters shipped with Fizz or its variants */
+enum bj_adapter {
+ BJ_UNKNOWN,
+ BJ_65W_19V,
+ BJ_90W_19V,
+ BJ_65W_19P5V,
+ BJ_90W_19P5V,
+ BJ_COUNT,
+};
+
+/* BJ adapter specs */
+static const struct {
+ uint16_t current_lim; /* in mA */
+ uint16_t voltage_lim; /* in mV */
+} bj_adapters[] = {
+ [BJ_65W_19V] = { .current_lim = 3420, .voltage_lim = 19000 },
+ [BJ_90W_19V] = { .current_lim = 4740, .voltage_lim = 19000 },
+ [BJ_65W_19P5V] = { .current_lim = 3330, .voltage_lim = 19500 },
+ [BJ_90W_19P5V] = { .current_lim = 4620, .voltage_lim = 19500 },
+};
+
+/*
+ * The table showing which device is shipped with which BJ adapter.
+ *
+ * | SKU0 SKU1 ...
+ * OEM0 | AdapterX AdapterZ ...
+ * OEM1 | AdapterY ...
+ * ... |
+ */
+static const enum bj_adapter bj_adapter_table[OEM_ID_COUNT][SKU_ID_COUNT] = {
+ { BJ_65W_19P5V, BJ_65W_19P5V, BJ_90W_19P5V, BJ_90W_19P5V,
+ BJ_90W_19P5V, BJ_90W_19P5V, BJ_65W_19P5V },
+ { BJ_65W_19V, BJ_65W_19V, BJ_UNKNOWN, BJ_UNKNOWN,
+ BJ_90W_19V, BJ_90W_19V, BJ_UNKNOWN },
+ { BJ_65W_19V, BJ_65W_19V, BJ_90W_19V, BJ_90W_19V,
+ BJ_90W_19V, BJ_90W_19V, BJ_65W_19V },
+};
+
static const char *oem_id = "GOOGLE";
static const char *oem_table_id = "FIZZ";
+static uint8_t board_sku_id(void)
+{
+ static int id = -1;
+ const gpio_t sku_id_gpios[] = {
+ GPIO_SKU_ID0,
+ GPIO_SKU_ID1,
+ GPIO_SKU_ID2,
+ GPIO_SKU_ID3,
+ };
+ if (id < 0)
+ id = gpio_base2_value(sku_id_gpios, ARRAY_SIZE(sku_id_gpios));
+ return id;
+}
+
/*
* mainboard_get_pl2
*
@@ -50,25 +105,16 @@ static const char *oem_table_id = "FIZZ";
*/
static u32 mainboard_get_pl2(void)
{
- const gpio_t sku_id_gpios[] = {
- GPIO_SKU_ID0,
- GPIO_SKU_ID1,
- GPIO_SKU_ID2,
- GPIO_SKU_ID3,
- };
enum usb_chg_type type;
u32 watts;
int rv = google_chromeec_get_usb_pd_power_info(&type, &watts);
- int sku_id;
/* If we can't get charger info or not PD charger, assume barrel jack */
if (rv != 0 || type != USB_CHG_TYPE_PD) {
/* using the barrel jack, get PL2 based on sku id */
watts = FIZZ_PL2_OTHERS;
- sku_id = gpio_base2_value(sku_id_gpios,
- ARRAY_SIZE(sku_id_gpios));
- if (sku_id == FIZZ_SKU_ID_I7_U42)
+ if (board_sku_id() == FIZZ_SKU_ID_I7_U42)
watts = FIZZ_PL2_I7_U42;
} else
watts = GET_TYPEC_PL2(watts);
@@ -78,16 +124,15 @@ static u32 mainboard_get_pl2(void)
static uint8_t board_oem_id(void)
{
- static int board_oem_id = -1;
+ static int id = -1;
const gpio_t oem_id_gpios[] = {
GPIO_OEM_ID1,
GPIO_OEM_ID2,
GPIO_OEM_ID3,
};
- if (board_oem_id < 0)
- board_oem_id = gpio_base2_value(oem_id_gpios,
- ARRAY_SIZE(oem_id_gpios));
- return board_oem_id;
+ if (id < 0)
+ id = gpio_base2_value(oem_id_gpios, ARRAY_SIZE(oem_id_gpios));
+ return id;
}
const char *smbios_mainboard_sku(void)
@@ -130,6 +175,36 @@ static unsigned long mainboard_write_acpi_tables(
return end_addr;
}
+/*
+ * Set max current and voltage for a barrel jack adapter based on {OEM, SKU}.
+ * If this fails, the limit will remain unchanged = default values, which make
+ * the system run under safe but under-rated power.
+ * If a BJ adapter isn't plugged, this is a no-op.
+ */
+static void set_bj_adapter_limit(void)
+{
+ uint8_t oem = board_oem_id();
+ uint8_t sku = board_sku_id();
+ enum bj_adapter bj;
+
+ if (oem >= OEM_ID_COUNT || sku >= SKU_ID_COUNT) {
+ printk(BIOS_ERR, "Unrecognized OEM or SKU: %d/%d\n", oem, sku);
+ return;
+ }
+
+ bj = bj_adapter_table[oem][sku];
+ if (bj <= BJ_UNKNOWN || BJ_COUNT <= bj) {
+ printk(BIOS_ERR, "Invalid BJ adapter ID: %d\n", bj);
+ return;
+ }
+ printk(BIOS_INFO, "Setting BJ limit: %dmA/%dmV\n",
+ bj_adapters[bj].current_lim, bj_adapters[bj].voltage_lim);
+ if (google_chromeec_override_dedicated_charger_limit(
+ bj_adapters[bj].current_lim,
+ bj_adapters[bj].voltage_lim))
+ printk(BIOS_ERR, "Failed to set BJ limit\n");
+}
+
static void mainboard_enable(device_t dev)
{
device_t root = SA_DEV_ROOT;
@@ -137,6 +212,8 @@ static void mainboard_enable(device_t dev)
conf->tdp_pl2_override = mainboard_get_pl2();
+ set_bj_adapter_limit();
+
dev->ops->init = mainboard_init;
dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator;
dev->ops->write_acpi_tables = mainboard_write_acpi_tables;