bm92t30: Add proper info

The driver will now show more charger supported profiles and will also show selected profile.
This commit is contained in:
CTCaer 2020-10-20 10:42:57 +03:00
parent cb471162d2
commit 94235dd005
5 changed files with 120 additions and 81 deletions

View file

@ -1,65 +0,0 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T30
*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* TODO:
* This driver is a stub and relies on incorrect I2C requests.
* The I2C driver needs to be updated with proper multi-xfer support.
*
* For now it replies its whole register range, according to request
* size. That's because the IC does not support the classic single
* transfer request-response style.
*/
#include <string.h>
#include "bm92t30_stub.h"
#include <soc/i2c.h>
#include <utils/util.h>
#define STATUS1_INSERT 0x80
typedef struct _pdo_t{
u32 amp:10;
u32 volt:10;
u32 info:10;
u32 type:2;
} pdo_t;
void bm92t30_get_charger_type(bool *inserted, usb_pd_objects_t *usb_pd)
{
u8 buf[32];
pdo_t pdos[7];
i2c_recv_buf_big(buf, 32, I2C_1, BM92T30_I2C_ADDR, 0);
if (inserted)
*inserted = buf[6] & STATUS1_INSERT ? true : false;
memcpy(pdos, &buf[17], 15); // We can only get max 4 objects.
if (usb_pd)
{
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
usb_pd->pdo_no = MIN(buf[16] / sizeof(pdo_t), 4); // We can only get max 4 objects.
for (u32 i = 0; i < usb_pd->pdo_no; i++)
{
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
}
}
}

99
bdk/power/bm92t36.c Normal file
View file

@ -0,0 +1,99 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T36
*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "bm92t36.h"
#include <soc/i2c.h>
#include <utils/util.h>
#define ALERT_STATUS_REG 0x2
#define STATUS1_REG 0x3
#define STATUS2_REG 0x4
#define COMMAND_REG 0x5
#define CONFIG1_REG 0x6
#define DEV_CAPS_REG 0x7
#define READ_PDOS_SRC_REG 0x8
#define CONFIG2_REG 0x17
#define DP_STATUS_REG 0x18
#define DP_ALERT_EN_REG 0x19
#define VENDOR_CONFIG_REG 0x1A
#define AUTO_NGT_FIXED_REG 0x20
#define AUTO_NGT_BATT_REG 0x23
#define SYS_CONFIG1_REG 0x26
#define SYS_CONFIG2_REG 0x27
#define CURRENT_PDO_REG 0x28
#define CURRENT_RDO_REG 0x2B
#define ALERT_ENABLE_REG 0x2E
#define SYS_CONFIG3_REG 0x2F
#define SET_RDO_REG 0x30
#define PDOS_SNK_REG 0x33
#define PDOS_SRC_PROV_REG 0x3C
#define FW_TYPE_REG 0x4B
#define FW_REVISION_REG 0x4C
#define MAN_ID_REG 0x4D
#define DEV_ID_REG 0x4E
#define REV_ID_REG 0x4F
#define INCOMING_VDM_REG 0x50
#define OUTGOING_VDM_REG 0x60
#define STATUS1_INSERT BIT(7) // Cable inserted.
typedef struct _pd_object_t {
unsigned int amp:10;
unsigned int volt:10;
unsigned int info:10;
unsigned int type:2;
} __attribute__((packed)) pd_object_t;
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
{
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
}
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
{
u8 buf[32];
pd_object_t pdos[7];
if (inserted)
{
_bm92t36_read_reg(buf, 2, STATUS1_REG);
*inserted = buf[0] & STATUS1_INSERT ? true : false;
}
if (usb_pd)
{
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
memcpy(pdos, &buf[1], 28);
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
for (u32 i = 0; i < usb_pd->pdo_no; i++)
{
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
}
_bm92t36_read_reg(buf, 5, CURRENT_PDO_REG);
memcpy(pdos, &buf[1], 4);
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
}
}

View file

@ -1,5 +1,5 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T30
* USB-PD driver for Nintendo Switch's TI BM92T36
*
* Copyright (c) 2020 CTCaer
*
@ -16,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BM92T30_H_
#define __BM92T30_H_
#ifndef __BM92T36_H_
#define __BM92T36_H_
#include <utils/types.h>
#define BM92T30_I2C_ADDR 0x18
#define BM92T36_I2C_ADDR 0x18
typedef struct _usb_pd_object_t
{
@ -33,8 +33,9 @@ typedef struct _usb_pd_objects_t
{
u32 pdo_no;
usb_pd_object_t pdos[7];
usb_pd_object_t selected_pdo;
} usb_pd_objects_t;
void bm92t30_get_charger_type(bool *inserted, usb_pd_objects_t *usb_pd);
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
#endif

View file

@ -37,7 +37,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
fuse.o kfuse.o \
mc.o sdram.o minerva.o ramdisk.o \
sdmmc.o sdmmc_driver.o nx_emmc.o nx_emmc_bis.o nx_sd.o \
bm92t30_stub.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
touch.o joycon.o tmp451.o fan.o \
usbd.o usb_gadget_ums.o usb_gadget_hid.o \
hw_init.o \

View file

@ -28,7 +28,7 @@
#include <mem/heap.h>
#include <mem/sdram.h>
#include <mem/smmu.h>
#include <power/bm92t30_stub.h>
#include <power/bm92t36.h>
#include <power/bq24193.h>
#include <power/max17050.h>
#include <sec/se.h>
@ -1689,27 +1689,31 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
bool inserted;
u32 wattage = 0;
u32 max_voltage = 5;
usb_pd_objects_t usb_pd;
bm92t30_get_charger_type(&inserted, &usb_pd);
bm92t36_get_sink_info(&inserted, &usb_pd);
strcat(txt_buf, "\n\n\n");
strcat(txt_buf, inserted ? "Connected" : "Disconnected");
for (u32 i = 0; i < usb_pd.pdo_no; i++)
if (usb_pd.pdos[i].voltage <= 15)
max_voltage = usb_pd.pdos[i].voltage;
wattage = iinlim * max_voltage;
// Select 5V is no PD contract.
wattage = iinlim * (usb_pd.pdo_no ? usb_pd.selected_pdo.voltage : 5);
s_printf(txt_buf + strlen(txt_buf), "\n%d.%d W", wattage / 1000, (wattage % 1000) / 100);
if (!usb_pd.pdo_no)
strcat(txt_buf, "\nNon PD");
// Limit to 5 profiles so it can fit.
usb_pd.pdo_no = MIN(usb_pd.pdo_no, 5);
for (u32 i = 0; i < usb_pd.pdo_no; i++)
{
s_printf(txt_buf + strlen(txt_buf), "\n%d mA, %2d V",
usb_pd.pdos[i].amperage, usb_pd.pdos[i].voltage);
bool selected =
usb_pd.pdos[i].amperage == usb_pd.selected_pdo.amperage &&
usb_pd.pdos[i].voltage == usb_pd.selected_pdo.voltage;
s_printf(txt_buf + strlen(txt_buf), "\n%s%d mA, %2d V%s",
selected ? "#D4FF00 " : "",
usb_pd.pdos[i].amperage, usb_pd.pdos[i].voltage,
selected ? "#" : "");
}
lv_label_set_text(lb_val2, txt_buf);