Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: typec: ucsi: Add support for READ_POWER_LEVEL command

Add support for UCSI READ_POWER_LEVEL command as per
UCSI specification v2.1 and above to debugfs.

Following power related fields will be exposed as files in debugfs:-
peak_current (Peak current),
avg_current (Average current) and
vbus_voltage (VBUS voltage)

These files will be updated either when a READ_POWER_LEVEL
command is sent from OS or when a device is connected.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Venkat Jayaraman <venkat.jayaraman@intel.com>
Link: https://lore.kernel.org/r/20250814163028.18058-1-venkat.jayaraman@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Venkat Jayaraman and committed by
Greg Kroah-Hartman
c851b71f c0485e86

+60
+31
drivers/usb/typec/ucsi/debugfs.c
··· 35 35 case UCSI_SET_SINK_PATH: 36 36 case UCSI_SET_NEW_CAM: 37 37 case UCSI_SET_USB: 38 + case UCSI_READ_POWER_LEVEL: 38 39 ret = ucsi_send_command(ucsi, val, NULL, 0); 39 40 break; 40 41 case UCSI_GET_CAPABILITY: ··· 81 80 } 82 81 DEFINE_SHOW_ATTRIBUTE(ucsi_resp); 83 82 83 + static int ucsi_peak_curr_show(struct seq_file *m, void *v) 84 + { 85 + struct ucsi *ucsi = m->private; 86 + 87 + seq_printf(m, "%u mA\n", ucsi->connector->peak_current); 88 + return 0; 89 + } 90 + DEFINE_SHOW_ATTRIBUTE(ucsi_peak_curr); 91 + 92 + static int ucsi_avg_curr_show(struct seq_file *m, void *v) 93 + { 94 + struct ucsi *ucsi = m->private; 95 + 96 + seq_printf(m, "%u mA\n", ucsi->connector->avg_current); 97 + return 0; 98 + } 99 + DEFINE_SHOW_ATTRIBUTE(ucsi_avg_curr); 100 + 101 + static int ucsi_vbus_volt_show(struct seq_file *m, void *v) 102 + { 103 + struct ucsi *ucsi = m->private; 104 + 105 + seq_printf(m, "%u mV\n", ucsi->connector->vbus_voltage); 106 + return 0; 107 + } 108 + DEFINE_SHOW_ATTRIBUTE(ucsi_vbus_volt); 109 + 84 110 void ucsi_debugfs_register(struct ucsi *ucsi) 85 111 { 86 112 ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL); ··· 117 89 ucsi->debugfs->dentry = debugfs_create_dir(dev_name(ucsi->dev), ucsi_debugfs_root); 118 90 debugfs_create_file("command", 0200, ucsi->debugfs->dentry, ucsi, &ucsi_cmd_fops); 119 91 debugfs_create_file("response", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_resp_fops); 92 + debugfs_create_file("peak_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_peak_curr_fops); 93 + debugfs_create_file("avg_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_avg_curr_fops); 94 + debugfs_create_file("vbus_voltage", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_vbus_volt_fops); 120 95 } 121 96 122 97 void ucsi_debugfs_unregister(struct ucsi *ucsi)
+16
drivers/usb/typec/ucsi/ucsi.c
··· 1217 1217 struct ucsi_connector *con = container_of(work, struct ucsi_connector, 1218 1218 work); 1219 1219 struct ucsi *ucsi = con->ucsi; 1220 + u8 curr_scale, volt_scale; 1220 1221 enum typec_role role; 1221 1222 u16 change; 1222 1223 int ret; 1224 + u32 val; 1223 1225 1224 1226 mutex_lock(&con->lock); 1225 1227 ··· 1292 1290 1293 1291 if (change & UCSI_CONSTAT_BC_CHANGE) 1294 1292 ucsi_port_psy_changed(con); 1293 + 1294 + if (UCSI_CONSTAT(con, PWR_READING_READY_V2_1)) { 1295 + curr_scale = UCSI_CONSTAT(con, CURRENT_SCALE_V2_1); 1296 + volt_scale = UCSI_CONSTAT(con, VOLTAGE_SCALE_V2_1); 1297 + 1298 + val = UCSI_CONSTAT(con, PEAK_CURRENT_V2_1); 1299 + con->peak_current = UCSI_CONSTAT_CURR_SCALE_MULT * curr_scale * val; 1300 + 1301 + val = UCSI_CONSTAT(con, AVG_CURRENT_V2_1); 1302 + con->avg_current = UCSI_CONSTAT_CURR_SCALE_MULT * curr_scale * val; 1303 + 1304 + val = UCSI_CONSTAT(con, VBUS_VOLTAGE_V2_1); 1305 + con->vbus_voltage = UCSI_CONSTAT_VOLT_SCALE_MULT * volt_scale * val; 1306 + } 1295 1307 1296 1308 out_unlock: 1297 1309 mutex_unlock(&con->lock);
+13
drivers/usb/typec/ucsi/ucsi.h
··· 131 131 #define UCSI_GET_PD_MESSAGE 0x15 132 132 #define UCSI_GET_CAM_CS 0x18 133 133 #define UCSI_SET_SINK_PATH 0x1c 134 + #define UCSI_READ_POWER_LEVEL 0x1e 134 135 #define UCSI_SET_USB 0x21 135 136 #define UCSI_GET_LPM_PPM_INFO 0x22 136 137 ··· 360 359 #define UCSI_CONSTAT_BC_SLOW_CHARGING 2 361 360 #define UCSI_CONSTAT_BC_TRICKLE_CHARGING 3 362 361 #define UCSI_CONSTAT_PD_VERSION_V1_2 UCSI_DECLARE_BITFIELD_V1_2(70, 16) 362 + #define UCSI_CONSTAT_PWR_READING_READY_V2_1 UCSI_DECLARE_BITFIELD_V2_1(89, 1) 363 + #define UCSI_CONSTAT_CURRENT_SCALE_V2_1 UCSI_DECLARE_BITFIELD_V2_1(90, 3) 364 + #define UCSI_CONSTAT_PEAK_CURRENT_V2_1 UCSI_DECLARE_BITFIELD_V2_1(93, 16) 365 + #define UCSI_CONSTAT_AVG_CURRENT_V2_1 UCSI_DECLARE_BITFIELD_V2_1(109, 16) 366 + #define UCSI_CONSTAT_VOLTAGE_SCALE_V2_1 UCSI_DECLARE_BITFIELD_V2_1(125, 4) 367 + #define UCSI_CONSTAT_VBUS_VOLTAGE_V2_1 UCSI_DECLARE_BITFIELD_V2_1(129, 16) 368 + #define UCSI_CONSTAT_CURR_SCALE_MULT 5 369 + #define UCSI_CONSTAT_VOLT_SCALE_MULT 5 363 370 364 371 /* Connector Status Change Bits. */ 365 372 #define UCSI_CONSTAT_EXT_SUPPLY_CHANGE BIT(1) ··· 527 518 u32 rdo; 528 519 u32 src_pdos[PDO_MAX_OBJECTS]; 529 520 int num_pdos; 521 + 522 + u32 peak_current; 523 + u32 avg_current; 524 + u32 vbus_voltage; 530 525 531 526 /* USB PD objects */ 532 527 struct usb_power_delivery *pd;