mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 01:50:53 +00:00
Change the zinger software version returned by VDO_CMD_READ_INFO to report the commit count portion of the version string to make the software version automatically change. This software version is important for debugging and is printed to PD console every time a zinger is attached. BUG=none BRANCH=none TEST=load onto zinger and samus, plug in zinger and see: Dev:1 SW:2147 RW:0 compare to the version string in zinger binary and we see: zinger_v1.1.2147-... Change-Id: Ieafe89b4b16cee076be17bcbc6774bbd7fc24f8e Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/214428 Reviewed-by: Todd Broch <tbroch@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
542 lines
15 KiB
C
542 lines
15 KiB
C
/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
/* USB Power delivery module */
|
|
|
|
#ifndef __USB_PD_H
|
|
#define __USB_PD_H
|
|
|
|
#include "common.h"
|
|
|
|
enum pd_errors {
|
|
PD_ERR_INVAL = -1, /* Invalid packet */
|
|
PD_ERR_HARD_RESET = -2, /* Got a Hard-Reset packet */
|
|
PD_ERR_CRC = -3, /* CRC mismatch */
|
|
PD_ERR_ID = -4, /* Invalid ID number */
|
|
};
|
|
|
|
/* incoming packet event (for the USB PD task) */
|
|
#define PD_EVENT_RX (1<<2)
|
|
|
|
/* --- PD data message helpers --- */
|
|
#define PDO_MAX_OBJECTS 7
|
|
|
|
/* PDO : Power Data Object */
|
|
/*
|
|
* 1. The vSafe5V Fixed Supply Object shall always be the first object.
|
|
* 2. The remaining Fixed Supply Objects,
|
|
* if present, shall be sent in voltage order; lowest to highest.
|
|
* 3. The Battery Supply Objects,
|
|
* if present shall be sent in Minimum Voltage order; lowest to highest.
|
|
* 4. The Variable Supply (non battery) Objects,
|
|
* if present, shall be sent in Minimum Voltage order; lowest to highest.
|
|
*/
|
|
#define PDO_TYPE_FIXED (0 << 30)
|
|
#define PDO_TYPE_BATTERY (1 << 30)
|
|
#define PDO_TYPE_VARIABLE (2 << 30)
|
|
#define PDO_TYPE_MASK (3 << 30)
|
|
|
|
#define PDO_FIXED_DUAL_ROLE (1 << 29) /* Dual role device */
|
|
#define PDO_FIXED_SUSPEND (1 << 28) /* USB Suspend supported */
|
|
#define PDO_FIXED_EXTERNAL (1 << 27) /* Externally powered */
|
|
#define PDO_FIXED_COMM_CAP (1 << 26) /* USB Communications Capable */
|
|
#define PDO_FIXED_PEAK_CURR () /* [21..20] Peak current */
|
|
#define PDO_FIXED_VOLT(mv) (((mv)/50) << 10) /* Voltage in 50mV units */
|
|
#define PDO_FIXED_CURR(ma) (((ma)/10) << 0) /* Max current in 10mA units */
|
|
|
|
#define PDO_FIXED(mv, ma, flags) (PDO_FIXED_VOLT(mv) |\
|
|
PDO_FIXED_CURR(ma) | (flags))
|
|
|
|
#define PDO_VAR_MAX_VOLT(mv) ((((mv) / 50) & 0x3FF) << 20)
|
|
#define PDO_VAR_MIN_VOLT(mv) ((((mv) / 50) & 0x3FF) << 10)
|
|
#define PDO_VAR_OP_CURR(ma) ((((ma) / 10) & 0x3FF) << 0)
|
|
|
|
#define PDO_VAR(min_mv, max_mv, op_ma) \
|
|
(PDO_VAR_MIN_VOLT(min_mv) | \
|
|
PDO_VAR_MAX_VOLT(max_mv) | \
|
|
PDO_VAR_OP_CURR(op_ma))
|
|
|
|
#define PDO_BATT_MAX_VOLT(mv) ((((mv) / 50) & 0x3FF) << 20)
|
|
#define PDO_BATT_MIN_VOLT(mv) ((((mv) / 50) & 0x3FF) << 10)
|
|
#define PDO_BATT_OP_POWER(mw) ((((mw) / 10) & 0x3FF) << 0)
|
|
|
|
#define PDO_BATT(min_mv, max_mv, op_mw) \
|
|
(PDO_BATT_MIN_VOLT(min_mv) | \
|
|
PDO_BATT_MAX_VOLT(max_mv) | \
|
|
PDO_BATT_OP_POWER(op_mw))
|
|
|
|
/* RDO : Request Data Object */
|
|
#define RDO_OBJ_POS(n) (((n) & 0x7) << 28)
|
|
#define RDO_GIVE_BACK (1 << 27)
|
|
#define RDO_CAP_MISMATCH (1 << 26)
|
|
#define RDO_COMM_CAP (1 << 25)
|
|
#define RDO_NO_SUSPEND (1 << 24)
|
|
#define RDO_FIXED_VAR_OP_CURR(ma) ((((ma) / 10) & 0x3FF) << 10)
|
|
#define RDO_FIXED_VAR_MAX_CURR(ma) ((((ma) / 10) & 0x3FF) << 0)
|
|
|
|
#define RDO_BATT_OP_POWER(mw) ((((mw) / 250) & 0x3FF) << 10)
|
|
#define RDO_BATT_MAX_POWER(mw) ((((mw) / 250) & 0x3FF) << 10)
|
|
|
|
#define RDO_FIXED(n, op_ma, max_ma, flags) \
|
|
(RDO_OBJ_POS(n) | (flags) | \
|
|
RDO_FIXED_VAR_OP_CURR(op_ma) | \
|
|
RDO_FIXED_VAR_MAX_CURR(max_ma))
|
|
|
|
|
|
#define RDO_BATT(n, op_mw, max_mw, flags) \
|
|
(RDO_OBJ_POS(n) | (flags) | \
|
|
RDO_BATT_OP_POWER(op_mw) | \
|
|
RDO_BATT_MAX_POWER(max_mw))
|
|
|
|
/* BDO : BIST Data Object */
|
|
#define BDO_MODE_RECV (0 << 28)
|
|
#define BDO_MODE_TRANSMIT (1 << 28)
|
|
#define BDO_MODE_COUNTERS (2 << 28)
|
|
#define BDO_MODE_CARRIER0 (3 << 28)
|
|
#define BDO_MODE_CARRIER1 (4 << 28)
|
|
#define BDO_MODE_CARRIER2 (5 << 28)
|
|
#define BDO_MODE_CARRIER3 (6 << 28)
|
|
#define BDO_MODE_EYE (7 << 28)
|
|
|
|
#define BDO(mode, cnt) ((mode) | ((cnt) & 0xFFFF))
|
|
|
|
/* VDO : Vendor Defined Message Object */
|
|
#define VDO(vid, custom) (((vid) << 16) | ((custom) & 0xFFFF))
|
|
#define VDO_MAX_SIZE 7
|
|
|
|
#define VDO_ACK (0 << 6)
|
|
#define VDO_NAK (1 << 6)
|
|
#define VDO_PENDING (2 << 6)
|
|
|
|
#define VDO_SRC_INITIATOR (0 << 5)
|
|
#define VDO_SRC_RESPONDER (1 << 5)
|
|
|
|
#define VDO_CMD_DISCOVER_VID (1 << 0)
|
|
#define VDO_CMD_DISCOVER_ALT (2 << 0)
|
|
#define VDO_CMD_AUTHENTICATE (3 << 0)
|
|
#define VDO_CMD_ENTER_ALT (4 << 0)
|
|
#define VDO_CMD_EXIT_ALT (5 << 0)
|
|
#define VDO_CMD_VENDOR(x) (((10 + (x)) & 0x1f))
|
|
|
|
/* ChromeOS specific commands */
|
|
#define VDO_CMD_VERSION VDO_CMD_VENDOR(0)
|
|
#define VDO_CMD_READ_INFO VDO_CMD_VENDOR(2)
|
|
#define VDO_CMD_REBOOT VDO_CMD_VENDOR(5)
|
|
#define VDO_CMD_FLASH_ERASE VDO_CMD_VENDOR(6)
|
|
#define VDO_CMD_FLASH_WRITE VDO_CMD_VENDOR(7)
|
|
#define VDO_CMD_FLASH_HASH VDO_CMD_VENDOR(8)
|
|
#define VDO_CMD_PING_ENABLE VDO_CMD_VENDOR(10)
|
|
#define VDO_CMD_CURRENT VDO_CMD_VENDOR(11)
|
|
|
|
#define PD_VDO_VID(vdo) ((vdo) >> 16)
|
|
#define PD_VDO_CMD(vdo) ((vdo) & 0x1f)
|
|
|
|
/*
|
|
* ChromeOS specific VDO_CMD_READ_INFO responds with device info including:
|
|
* RW Hash: sha1 of RW hash (20 bytes)
|
|
* HW Device ID: unique descriptor for each ChromeOS model (2 bytes)
|
|
* SW Debug Version: Software version useful for debugging (15 bits)
|
|
* IS RW: True if currently in RW, False otherwise (1 bit)
|
|
*/
|
|
#define VDO_INFO(id, ver, is_rw) ((id) << 16 \
|
|
| ((ver) & 0x7fff) << 1 \
|
|
| ((is_rw) & 1))
|
|
#define VDO_INFO_HW_DEV_ID(x) ((x) >> 16)
|
|
#define VDO_INFO_SW_DBG_VER(x) (((x) >> 1) & 0x7fff)
|
|
#define VDO_INFO_IS_RW(x) ((x) & 1)
|
|
|
|
/* USB Vendor ID assigned to Google Inc. */
|
|
#define USB_VID_GOOGLE 0x18d1
|
|
|
|
/* Timeout for message receive in microseconds */
|
|
#define USB_PD_RX_TMOUT_US 2700
|
|
|
|
/* --- Protocol layer functions --- */
|
|
|
|
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
|
enum pd_dual_role_states {
|
|
PD_DRP_TOGGLE_ON,
|
|
PD_DRP_TOGGLE_OFF,
|
|
PD_DRP_FORCE_SINK,
|
|
PD_DRP_FORCE_SOURCE
|
|
};
|
|
/**
|
|
* Set dual role state, from among enum pd_dual_role_states
|
|
*
|
|
* @param state New state of dual-role port, selected from
|
|
* enum pd_dual_role_states
|
|
*/
|
|
void pd_set_dual_role(enum pd_dual_role_states state);
|
|
#endif
|
|
|
|
/* Control Message type */
|
|
enum pd_ctrl_msg_type {
|
|
/* 0 Reserved */
|
|
PD_CTRL_GOOD_CRC = 1,
|
|
PD_CTRL_GOTO_MIN = 2,
|
|
PD_CTRL_ACCEPT = 3,
|
|
PD_CTRL_REJECT = 4,
|
|
PD_CTRL_PING = 5,
|
|
PD_CTRL_PS_RDY = 6,
|
|
PD_CTRL_GET_SOURCE_CAP = 7,
|
|
PD_CTRL_GET_SINK_CAP = 8,
|
|
PD_CTRL_PROTOCOL_ERR = 9,
|
|
PD_CTRL_SWAP = 10,
|
|
/* 11 Reserved */
|
|
PD_CTRL_WAIT = 12,
|
|
PD_CTRL_SOFT_RESET = 13,
|
|
/* 14-15 Reserved */
|
|
};
|
|
|
|
/* Data message type */
|
|
enum pd_data_msg_type {
|
|
/* 0 Reserved */
|
|
PD_DATA_SOURCE_CAP = 1,
|
|
PD_DATA_REQUEST = 2,
|
|
PD_DATA_BIST = 3,
|
|
PD_DATA_SINK_CAP = 4,
|
|
/* 5-14 Reserved */
|
|
PD_DATA_VENDOR_DEF = 15,
|
|
};
|
|
|
|
/* Protocol revision */
|
|
#define PD_REV10 0
|
|
|
|
/* BMC-supported bit : we are using the baseband variant of the protocol */
|
|
#define PD_BMC_SUPPORTED (1 << 15)
|
|
|
|
/* Port role */
|
|
#define PD_ROLE_SINK 0
|
|
#define PD_ROLE_SOURCE 1
|
|
|
|
/* build message header */
|
|
#define PD_HEADER(type, role, id, cnt) \
|
|
((type) | (PD_REV10 << 6) | \
|
|
((role) << 8) | ((id) << 9) | ((cnt) << 12) | \
|
|
PD_BMC_SUPPORTED)
|
|
|
|
#define PD_HEADER_CNT(header) (((header) >> 12) & 7)
|
|
#define PD_HEADER_TYPE(header) ((header) & 0xF)
|
|
#define PD_HEADER_ID(header) (((header) >> 9) & 7)
|
|
|
|
/* K-codes for special symbols */
|
|
#define PD_SYNC1 0x18
|
|
#define PD_SYNC2 0x11
|
|
#define PD_RST1 0x07
|
|
#define PD_RST2 0x19
|
|
#define PD_EOP 0x0D
|
|
|
|
/* Issue PD soft reset */
|
|
void pd_soft_reset(void);
|
|
|
|
/* --- Policy layer functions --- */
|
|
|
|
/**
|
|
* Decide which voltage to use from the source capabilities.
|
|
*
|
|
* @param cnt the number of Power Data Objects.
|
|
* @param src_caps Power Data Objects representing the source capabilities.
|
|
* @param rdo requested Request Data Object.
|
|
* @return <0 if invalid, else value is the current limit of the RDO data
|
|
*/
|
|
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo);
|
|
|
|
/**
|
|
* Put a cap on the max voltage requested as a sink.
|
|
* @param mv maximum voltage in millivolts.
|
|
*/
|
|
void pd_set_max_voltage(unsigned mv);
|
|
|
|
/**
|
|
* Request a new operating voltage.
|
|
*
|
|
* @param rdo Request Data Object with the selected operating point.
|
|
* @return EC_SUCCESS if we can get the requested voltage/OP, <0 else.
|
|
*/
|
|
int pd_request_voltage(uint32_t rdo);
|
|
|
|
/**
|
|
* Go back to the default/safe state of the power supply
|
|
*
|
|
* @param port USB-C port number
|
|
*/
|
|
void pd_power_supply_reset(int port);
|
|
|
|
/**
|
|
* Enable the power supply output after the ready delay.
|
|
*
|
|
* @param port USB-C port number
|
|
* @return EC_SUCCESS if the power supply is ready, <0 else.
|
|
*/
|
|
int pd_set_power_supply_ready(int port);
|
|
|
|
/**
|
|
* Ask the specified voltage from the PD source.
|
|
*
|
|
* It triggers a new negotiation sequence with the source.
|
|
* @param port USB-C port number
|
|
* @param mv request voltage in millivolts.
|
|
*/
|
|
void pd_request_source_voltage(int port, int mv);
|
|
|
|
/**
|
|
* Set the input current limit.
|
|
*
|
|
* @max_ma Maximum current limit
|
|
*/
|
|
void pd_set_input_current_limit(uint32_t max_ma);
|
|
|
|
/**
|
|
* Verify board specific health status : current, voltages...
|
|
*
|
|
* @return EC_SUCCESS if the board is good, <0 else.
|
|
*/
|
|
int pd_board_checks(void);
|
|
|
|
/**
|
|
* Handle Vendor Defined Message with our vendor ID.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param cnt number of data objects in the payload.
|
|
* @param payload payload data.
|
|
* @param rpayload pointer to the data to send back.
|
|
* @return if >0, number of VDOs to send back.
|
|
*/
|
|
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload);
|
|
|
|
/**
|
|
* Store RW hash of device
|
|
*
|
|
* @param port USB-C port number
|
|
* @param rw_hash pointer to sha1 rw_hash
|
|
*/
|
|
void pd_dev_store_rw_hash(int port, uint32_t *rw_hash);
|
|
|
|
/**
|
|
* Send Vendor Defined Message
|
|
*
|
|
* @param port USB-C port number
|
|
* @param vid Vendor ID
|
|
* @param cmd VDO command number
|
|
* @param data Pointer to payload to send
|
|
* @param data number of data objects in payload
|
|
*/
|
|
void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data,
|
|
int count);
|
|
|
|
/* Power Data Objects for the source and the sink */
|
|
extern const uint32_t pd_src_pdo[];
|
|
extern const int pd_src_pdo_cnt;
|
|
extern const uint32_t pd_snk_pdo[];
|
|
extern const int pd_snk_pdo_cnt;
|
|
|
|
/**
|
|
* Get PD source power data objects.
|
|
*
|
|
* @param src_pdo pointer to the data to return.
|
|
* @return number of PDOs returned.
|
|
*/
|
|
int pd_get_source_pdo(const uint32_t **src_pdo);
|
|
|
|
/* Muxing for the USB type C */
|
|
enum typec_mux {
|
|
TYPEC_MUX_NONE,
|
|
TYPEC_MUX_USB,
|
|
TYPEC_MUX_DP,
|
|
TYPEC_MUX_DOCK,
|
|
};
|
|
|
|
/**
|
|
* Configure superspeed muxes on type-C port.
|
|
*
|
|
* @param port port number.
|
|
* @param mux selected function.
|
|
* @param polarity plug polarity (0=CC1, 1=CC2).
|
|
*/
|
|
void board_set_usb_mux(int port, enum typec_mux mux, int polarity);
|
|
|
|
/**
|
|
* Query superspeed mux status on type-C port.
|
|
*
|
|
* @param port port number.
|
|
* @param dp_str pointer to the DP string to return.
|
|
* @param usb_str pointer to the USB string to return.
|
|
* @return Non-zero if superspeed connection is enabled; otherwise, zero.
|
|
*/
|
|
int board_get_usb_mux(int port, const char **dp_str, const char **usb_str);
|
|
|
|
/* --- Physical layer functions : chip specific --- */
|
|
|
|
/* Packet preparation/retrieval */
|
|
|
|
/**
|
|
* Prepare packet reading state machine.
|
|
*
|
|
* @param port USB-C port number
|
|
*/
|
|
void pd_init_dequeue(int port);
|
|
|
|
/**
|
|
* Prepare packet reading state machine.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param off current position in the packet buffer.
|
|
* @param len minimum size to read in bits.
|
|
* @param val the read bits.
|
|
* @return new position in the packet buffer.
|
|
*/
|
|
int pd_dequeue_bits(int port, int off, int len, uint32_t *val);
|
|
|
|
/**
|
|
* Advance until the end of the preamble.
|
|
*
|
|
* @param port USB-C port number
|
|
* @return new position in the packet buffer.
|
|
*/
|
|
int pd_find_preamble(int port);
|
|
|
|
/**
|
|
* Write the preamble in the TX buffer.
|
|
*
|
|
* @param port USB-C port number
|
|
* @return new position in the packet buffer.
|
|
*/
|
|
int pd_write_preamble(int port);
|
|
|
|
/**
|
|
* Write one 10-period symbol in the TX packet.
|
|
* corresponding to a quartet with 4b5b encoding
|
|
* and Biphase Mark Coding.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param bit_off current position in the packet buffer.
|
|
* @param val10 the 10-bit integer.
|
|
* @return new position in the packet buffer.
|
|
*/
|
|
int pd_write_sym(int port, int bit_off, uint32_t val10);
|
|
|
|
|
|
/**
|
|
* Ensure that we have an edge after EOP and we end up at level 0,
|
|
* also fill the last byte.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param bit_off current position in the packet buffer.
|
|
* @return new position in the packet buffer.
|
|
*/
|
|
int pd_write_last_edge(int port, int bit_off);
|
|
|
|
/**
|
|
* Dump the current PD packet on the console for debug.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param msg context string.
|
|
*/
|
|
void pd_dump_packet(int port, const char *msg);
|
|
|
|
/**
|
|
* Change the TX data clock frequency.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param freq frequency in hertz.
|
|
*/
|
|
void pd_set_clock(int port, int freq);
|
|
|
|
/* TX/RX callbacks */
|
|
|
|
/**
|
|
* Start sending over the wire the prepared packet.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param polarity plug polarity (0=CC1, 1=CC2).
|
|
* @param bit_len size of the packet in bits.
|
|
*/
|
|
void pd_start_tx(int port, int polarity, int bit_len);
|
|
|
|
/**
|
|
* Set PD TX DMA to use circular mode. Call this before pd_start_tx() to
|
|
* continually loop over the transmit buffer given in pd_start_tx().
|
|
*
|
|
* @param port USB-C port number
|
|
*/
|
|
void pd_tx_set_circular_mode(int port);
|
|
|
|
/**
|
|
* Call when we are done sending a packet.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param polarity plug polarity (0=CC1, 1=CC2).
|
|
*/
|
|
void pd_tx_done(int port, int polarity);
|
|
|
|
/**
|
|
* Check whether the PD reception is started.
|
|
*
|
|
* @param port USB-C port number
|
|
* @return true if the reception is on-going.
|
|
*/
|
|
int pd_rx_started(int port);
|
|
|
|
/**
|
|
* Suspend the PD task.
|
|
* @param port USB-C port number
|
|
* @param enable pass 0 to resume, anything else to suspend
|
|
*/
|
|
void pd_set_suspend(int port, int enable);
|
|
|
|
/* Callback when the hardware has detected an incoming packet */
|
|
void pd_rx_event(int port);
|
|
/* Start sampling the CC line for reception */
|
|
void pd_rx_start(int port);
|
|
/* Call when we are done reading a packet */
|
|
void pd_rx_complete(int port);
|
|
|
|
/* restart listening to the CC wire */
|
|
void pd_rx_enable_monitoring(int port);
|
|
/* stop listening to the CC wire during transmissions */
|
|
void pd_rx_disable_monitoring(int port);
|
|
|
|
/**
|
|
* Deinitialize the hardware used for PD.
|
|
*
|
|
* @param port USB-C port number
|
|
*/
|
|
void pd_hw_release(int port);
|
|
|
|
/**
|
|
* Initialize the hardware used for PD RX/TX.
|
|
*
|
|
* @param port USB-C port number
|
|
*/
|
|
void pd_hw_init(int port);
|
|
|
|
/**
|
|
* Get port polarity.
|
|
*
|
|
* @param port USB-C port number
|
|
*/
|
|
int pd_get_polarity(int port);
|
|
|
|
/**
|
|
* Set the PD communication enabled flag. When communication is disabled,
|
|
* the port can still detect connection and source power but will not
|
|
* send or respond to any PD communication.
|
|
*
|
|
* @param enable Enable flag to set
|
|
*/
|
|
void pd_comm_enable(int enable);
|
|
|
|
/**
|
|
* Set the PD pings enabled flag. When source has negotiated power over
|
|
* PD successfully, it can optionally send pings periodically based on
|
|
* this enable flag.
|
|
*
|
|
* @param port USB-C port number
|
|
* @param enable Enable flag to set
|
|
*/
|
|
void pd_ping_enable(int port, int enable);
|
|
|
|
#endif /* __USB_PD_H */
|