lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <g5w3ydcvtxwvcu5armmnt4v6y6wsymt7rothnvaesdql6kdscz@rhkxzx3y47iv>
Date: Mon, 23 Jun 2025 23:51:13 +0200
From: Sebastian Reichel <sebastian.reichel@...labora.com>
To: amitsd@...gle.com
Cc: Rob Herring <robh@...nel.org>, 
	Krzysztof Kozlowski <krzk+dt@...nel.org>, Conor Dooley <conor+dt@...nel.org>, 
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>, Badhri Jagan Sridharan <badhri@...gle.com>, 
	Heikki Krogerus <heikki.krogerus@...ux.intel.com>, "Rafael J. Wysocki" <rafael@...nel.org>, 
	Len Brown <len.brown@...el.com>, Pavel Machek <pavel@...nel.org>, Kyle Tso <kyletso@...gle.com>, 
	devicetree@...r.kernel.org, linux-kernel@...r.kernel.org, linux-usb@...r.kernel.org, 
	linux-pm@...r.kernel.org
Subject: Re: [PATCH v2 5/5] usb: typec: tcpm: Add support for Battery Cap
 response message

Hi,

On Wed, May 07, 2025 at 06:00:26PM -0700, Amit Sunil Dhamne via B4 Relay wrote:
> From: Amit Sunil Dhamne <amitsd@...gle.com>
> 
> Add support for responding to Get_Battery_Cap (extended) request with a
> a Battery_Capabilities (extended) msg. The requester will request
> Battery Cap for a specific battery using an index in Get_Battery_Cap. In
> case of failure to identify battery, TCPM shall reply with an
> appropriate message indicating so.
> 
> Support has been added only for fixed batteries and not hot swappable
> ones.
> 
> As the Battery Cap Data Block size is 9 Bytes (lesser than
> MaxExtendedMsgChunkLen of 26B), only a single chunk is required to
> complete the AMS.
> 
> Support for Battery_Capabilities message is required for sinks that
> contain battery as specified in USB PD Rev3.1 v1.8
> ("Applicability of Data Messages" section).
> 
> Signed-off-by: Amit Sunil Dhamne <amitsd@...gle.com>
> Reviewed-by: Badhri Jagan Sridharan <badhri@...gle.com>
> Reviewed-by: Kyle Tso <kyletso@...gle.com>
> ---
>  drivers/usb/typec/tcpm/tcpm.c | 96 +++++++++++++++++++++++++++++++++++++++++--
>  include/linux/usb/pd.h        | 31 ++++++++++++++
>  2 files changed, 123 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
> index 98df0c7ce00e43f6c95ab49237a414e1b4413369..4731126fbf19a50178be0cf8867b3fe08595724c 100644
> --- a/drivers/usb/typec/tcpm/tcpm.c
> +++ b/drivers/usb/typec/tcpm/tcpm.c
> @@ -228,7 +228,8 @@ enum pd_msg_request {
>  	PD_MSG_DATA_SINK_CAP,
>  	PD_MSG_DATA_SOURCE_CAP,
>  	PD_MSG_DATA_REV,
> -	PD_MSG_DATA_BATT_STATUS
> +	PD_MSG_DATA_BATT_STATUS,
> +	PD_MSG_EXT_BATT_CAP,
>  };
>  
>  enum adev_actions {
> @@ -597,8 +598,8 @@ struct tcpm_port {
>  	u8 fixed_batt_cnt;
>  
>  	/*
> -	 * Variable used to store battery_ref from the Get_Battery_Status
> -	 * request to process Battery_Status messages.
> +	 * Variable used to store battery_ref from the Get_Battery_Status &
> +	 * Get_Battery_Caps request to process Battery_Status messages.
>  	 */
>  	u8 batt_request;
>  #ifdef CONFIG_DEBUG_FS
> @@ -1414,6 +1415,81 @@ static int tcpm_pd_send_batt_status(struct tcpm_port *port)
>  	return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
>  }
>  
> +static int tcpm_pd_send_batt_cap(struct tcpm_port *port)
> +{
> +	struct pd_message msg;
> +	struct power_supply *batt;
> +	struct batt_cap_ext_msg bcdb;
> +	u32 batt_id = port->batt_request;
> +	int ret;
> +	union power_supply_propval val;
> +	bool batt_present = false;
> +	u16 batt_design_cap = BATTERY_PROPERTY_UNKNOWN;
> +	u16 batt_charge_cap = BATTERY_PROPERTY_UNKNOWN;
> +	u8 data_obj_cnt;
> +	/*
> +	 * As per USB PD Rev3.1 v1.8, if battery reference is incorrect,
> +	 * then set the VID field to 0xffff.
> +	 * If VID field is set to 0xffff, always set the PID field to
> +	 * 0x0000.
> +	 */
> +	u16 vid = BATTERY_PROPERTY_UNKNOWN;
> +	u16 pid = 0x0;
> +
> +	memset(&msg, 0, sizeof(msg));
> +
> +	if (batt_id < MAX_NUM_FIXED_BATT && port->fixed_batt[batt_id]) {
> +		batt_present = true;

This should also handle POWER_SUPPLY_PROP_PRESENT.

Greetings,

-- Sebastian

> +		batt = port->fixed_batt[batt_id];
> +		ret = power_supply_get_property(batt,
> +						POWER_SUPPLY_PROP_USBIF_VENDOR_ID,
> +						&val);
> +		if (!ret)
> +			vid = val.intval;
> +
> +		if (vid != BATTERY_PROPERTY_UNKNOWN) {
> +			ret = power_supply_get_property(batt,
> +							POWER_SUPPLY_PROP_USBIF_PRODUCT_ID,
> +							&val);
> +			if (!ret)
> +				pid = val.intval;
> +		}
> +
> +		ret = power_supply_get_property(batt,
> +						POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
> +						&val);
> +		if (!ret)
> +			batt_design_cap = (u16)UWH_TO_WH(val.intval * 10);
> +
> +		ret = power_supply_get_property(batt,
> +						POWER_SUPPLY_PROP_ENERGY_FULL,
> +						&val);
> +		if (!ret)
> +			batt_charge_cap = (u16)UWH_TO_WH(val.intval * 10);
> +	}
> +
> +	bcdb.vid = cpu_to_le16(vid);
> +	bcdb.pid = cpu_to_le16(pid);
> +	bcdb.batt_design_cap = cpu_to_le16(batt_design_cap);
> +	bcdb.batt_last_chg_cap = cpu_to_le16(batt_charge_cap);
> +	bcdb.batt_type = !batt_present ? BATT_CAP_BATT_TYPE_INVALID_REF : 0;
> +	memcpy(msg.ext_msg.data, &bcdb, sizeof(bcdb));
> +	msg.ext_msg.header = PD_EXT_HDR_LE(sizeof(bcdb),
> +					   0, /* Denotes if request chunk */
> +					   0, /* Chunk number */
> +					   1  /* Chunked */);
> +
> +	data_obj_cnt = count_chunked_data_objs(sizeof(bcdb));
> +	msg.header = cpu_to_le16(PD_HEADER(PD_EXT_BATT_CAP,
> +					   port->pwr_role,
> +					   port->data_role,
> +					   port->negotiated_rev,
> +					   port->message_id,
> +					   data_obj_cnt,
> +					   1 /* Denotes if ext header */));
> +	return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
> +}
> +
>  static void mod_tcpm_delayed_work(struct tcpm_port *port, unsigned int delay_ms)
>  {
>  	if (delay_ms) {
> @@ -3711,8 +3787,12 @@ static void tcpm_pd_ext_msg_request(struct tcpm_port *port,
>  		tcpm_pd_handle_msg(port, PD_MSG_DATA_BATT_STATUS,
>  				   GETTING_BATTERY_STATUS);
>  		break;
> -	case PD_EXT_SOURCE_CAP_EXT:
>  	case PD_EXT_GET_BATT_CAP:
> +		port->batt_request = ext_msg->data[0];
> +		tcpm_pd_handle_msg(port, PD_MSG_EXT_BATT_CAP,
> +				   GETTING_BATTERY_CAPABILITIES);
> +		break;
> +	case PD_EXT_SOURCE_CAP_EXT:
>  	case PD_EXT_BATT_CAP:
>  	case PD_EXT_GET_MANUFACTURER_INFO:
>  	case PD_EXT_MANUFACTURER_INFO:
> @@ -3921,6 +4001,14 @@ static bool tcpm_send_queued_message(struct tcpm_port *port)
>  					 ret);
>  			tcpm_ams_finish(port);
>  			break;
> +		case PD_MSG_EXT_BATT_CAP:
> +			ret = tcpm_pd_send_batt_cap(port);
> +			if (ret)
> +				tcpm_log(port,
> +					 "Failed to send battery cap ret=%d",
> +					 ret);
> +			tcpm_ams_finish(port);
> +			break;
>  		default:
>  			break;
>  		}
> diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h
> index 4efa7bfd9863915dfc8048da264116d9b05a447b..c89594177da57f4398b75c89c1991b4937614a70 100644
> --- a/include/linux/usb/pd.h
> +++ b/include/linux/usb/pd.h
> @@ -204,6 +204,37 @@ struct pd_message {
>  	};
>  } __packed;
>  
> +/*
> + * count_chunked_data_objs: Helper to calculate number of Data Objects on a 4
> + *   byte boundary.
> + * @size: Size of data block for extended message. Should *not* include extended
> + *   header size.
> + */
> +static inline u8 count_chunked_data_objs(u32 size)
> +{
> +	size += offsetof(struct pd_chunked_ext_message_data, data);
> +	return ((size / 4) + (size % 4 ? 1 : 0));
> +}
> +
> +/**
> + * batt_cap_ext_msg - Battery capability extended PD message
> + * @vid: Battery Vendor ID (assigned by USB-IF)
> + * @pid: Battery Product ID (assigned by battery or device vendor)
> + * @batt_design_cap: Battery design capacity in 0.1Wh
> + * @batt_last_chg_cap: Battery last full charge capacity in 0.1Wh
> + * @batt_type: Battery Type. bit0 when set indicates invalid battery reference.
> + *             Rest of the bits are reserved.
> + */
> +struct batt_cap_ext_msg {
> +	__le16 vid;
> +	__le16 pid;
> +	__le16 batt_design_cap;
> +	__le16 batt_last_chg_cap;
> +	u8 batt_type;
> +} __packed;
> +
> +#define BATT_CAP_BATT_TYPE_INVALID_REF			BIT(0)
> +
>  /* PDO: Power Data Object */
>  #define PDO_MAX_OBJECTS		7
>  
> 
> -- 
> 2.49.0.987.g0cc8ee98dc-goog
> 
> 

Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ