Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/power/bm92t36.c
1476 views
1
/*
2
* USB-PD driver for Nintendo Switch's TI BM92T36
3
*
4
* Copyright (c) 2020-2023 CTCaer
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms and conditions of the GNU General Public License,
8
* version 2, as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <string.h>
20
21
#include "bm92t36.h"
22
#include <soc/i2c.h>
23
#include <utils/util.h>
24
25
#define ALERT_STATUS_REG 0x2
26
#define STATUS1_REG 0x3
27
#define STATUS2_REG 0x4
28
#define COMMAND_REG 0x5
29
#define CONFIG1_REG 0x6
30
#define DEV_CAPS_REG 0x7
31
#define READ_PDOS_SRC_REG 0x8
32
#define CONFIG2_REG 0x17
33
#define DP_STATUS_REG 0x18
34
#define DP_ALERT_EN_REG 0x19
35
#define VENDOR_CONFIG_REG 0x1A
36
#define AUTO_NGT_FIXED_REG 0x20
37
#define AUTO_NGT_BATT_REG 0x23
38
#define SYS_CONFIG1_REG 0x26
39
#define SYS_CONFIG2_REG 0x27
40
#define CURRENT_PDO_REG 0x28
41
#define CURRENT_RDO_REG 0x2B
42
#define ALERT_ENABLE_REG 0x2E
43
#define SYS_CONFIG3_REG 0x2F
44
#define SET_RDO_REG 0x30
45
#define PDOS_SNK_REG 0x33
46
#define PDOS_SRC_PROV_REG 0x3C
47
#define FW_TYPE_REG 0x4B
48
#define FW_REVISION_REG 0x4C
49
#define MAN_ID_REG 0x4D
50
#define DEV_ID_REG 0x4E
51
#define REV_ID_REG 0x4F
52
#define INCOMING_VDM_REG 0x50
53
#define OUTGOING_VDM_REG 0x60
54
55
#define STATUS1_INSERT BIT(7) // Cable inserted.
56
57
typedef struct _pd_object_t {
58
unsigned int amp:10;
59
unsigned int volt:10;
60
unsigned int info:10;
61
unsigned int type:2;
62
} __attribute__((packed)) pd_object_t;
63
64
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
65
{
66
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
67
}
68
69
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
70
{
71
u8 buf[32];
72
pd_object_t pdos[7];
73
74
if (inserted)
75
{
76
memset(buf, 0, sizeof(buf));
77
_bm92t36_read_reg(buf, 2, STATUS1_REG);
78
*inserted = (buf[0] & STATUS1_INSERT) ? true : false;
79
}
80
81
if (usb_pd)
82
{
83
memset(buf, 0, sizeof(buf));
84
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
85
memcpy(pdos, &buf[1], 28);
86
87
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
88
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
89
90
if (usb_pd->pdo_no > 7)
91
usb_pd->pdo_no = 7;
92
93
for (u32 i = 0; i < usb_pd->pdo_no; i++)
94
{
95
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
96
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
97
}
98
99
_bm92t36_read_reg(buf, 5, CURRENT_PDO_REG);
100
memcpy(pdos, &buf[1], 4);
101
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
102
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
103
}
104
}
105
106