Commit 470ce43a authored by Heikki Krogerus's avatar Heikki Krogerus Committed by Greg Kroah-Hartman

usb: typec: ucsi: Remove struct ucsi_control

That data structure was used for constructing the commands
before executing them, but it was never really useful. Using
the structure just complicated the driver. The commands are
64-bit wide, so it is enough to simply fill a u64 variable.
No data structures needed.

This simplifies the driver considerable and makes it much
easier to for example add support for big endian systems
later on.
Signed-off-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Tested-by: default avatarAjay Gupta <ajayg@nvidia.com>
Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20191104142435.29960-16-heikki.krogerus@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2ede5546
...@@ -49,7 +49,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt) ...@@ -49,7 +49,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt)
{ {
struct ucsi_dp *dp = typec_altmode_get_drvdata(alt); struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
struct ucsi *ucsi = dp->con->ucsi; struct ucsi *ucsi = dp->con->ucsi;
struct ucsi_control ctrl; u64 command;
u8 cur = 0; u8 cur = 0;
int ret; int ret;
...@@ -64,7 +64,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt) ...@@ -64,7 +64,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt)
goto err_unlock; goto err_unlock;
} }
UCSI_CMD_GET_CURRENT_CAM(ctrl, dp->con->num); command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(dp->con->num);
ret = ucsi_send_command(ucsi, command, &cur, sizeof(cur)); ret = ucsi_send_command(ucsi, command, &cur, sizeof(cur));
if (ret < 0) { if (ret < 0) {
if (ucsi->version > 0x0100) if (ucsi->version > 0x0100)
...@@ -101,7 +101,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt) ...@@ -101,7 +101,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt)
static int ucsi_displayport_exit(struct typec_altmode *alt) static int ucsi_displayport_exit(struct typec_altmode *alt)
{ {
struct ucsi_dp *dp = typec_altmode_get_drvdata(alt); struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
struct ucsi_control ctrl; u64 command;
int ret = 0; int ret = 0;
mutex_lock(&dp->con->lock); mutex_lock(&dp->con->lock);
...@@ -115,8 +115,8 @@ static int ucsi_displayport_exit(struct typec_altmode *alt) ...@@ -115,8 +115,8 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
goto out_unlock; goto out_unlock;
} }
ctrl.raw_cmd = UCSI_CMD_SET_NEW_CAM(dp->con->num, 0, dp->offset, 0); command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 0, dp->offset, 0);
ret = ucsi_send_command(dp->con->ucsi, &ctrl, NULL, 0); ret = ucsi_send_command(dp->con->ucsi, command, NULL, 0);
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
...@@ -170,14 +170,14 @@ static int ucsi_displayport_status_update(struct ucsi_dp *dp) ...@@ -170,14 +170,14 @@ static int ucsi_displayport_status_update(struct ucsi_dp *dp)
static int ucsi_displayport_configure(struct ucsi_dp *dp) static int ucsi_displayport_configure(struct ucsi_dp *dp)
{ {
u32 pins = DP_CONF_GET_PIN_ASSIGN(dp->data.conf); u32 pins = DP_CONF_GET_PIN_ASSIGN(dp->data.conf);
struct ucsi_control ctrl; u64 command;
if (!dp->override) if (!dp->override)
return 0; return 0;
ctrl.raw_cmd = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins); command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins);
return ucsi_send_command(dp->con->ucsi, &ctrl, NULL, 0); return ucsi_send_command(dp->con->ucsi, command, NULL, 0);
} }
static int ucsi_displayport_vdm(struct typec_altmode *alt, static int ucsi_displayport_vdm(struct typec_altmode *alt,
......
...@@ -33,17 +33,6 @@ const char *ucsi_cmd_str(u64 raw_cmd) ...@@ -33,17 +33,6 @@ const char *ucsi_cmd_str(u64 raw_cmd)
return ucsi_cmd_strs[(cmd >= ARRAY_SIZE(ucsi_cmd_strs)) ? 0 : cmd]; return ucsi_cmd_strs[(cmd >= ARRAY_SIZE(ucsi_cmd_strs)) ? 0 : cmd];
} }
static const char * const ucsi_ack_strs[] = {
[0] = "",
[UCSI_ACK_EVENT] = "event",
[UCSI_ACK_CMD] = "command",
};
const char *ucsi_ack_str(u8 ack)
{
return ucsi_ack_strs[(ack >= ARRAY_SIZE(ucsi_ack_strs)) ? 0 : ack];
}
const char *ucsi_cci_str(u32 cci) const char *ucsi_cci_str(u32 cci)
{ {
if (cci & GENMASK(7, 0)) { if (cci & GENMASK(7, 0)) {
......
...@@ -10,54 +10,18 @@ ...@@ -10,54 +10,18 @@
#include <linux/usb/typec_altmode.h> #include <linux/usb/typec_altmode.h>
const char *ucsi_cmd_str(u64 raw_cmd); const char *ucsi_cmd_str(u64 raw_cmd);
const char *ucsi_ack_str(u8 ack);
const char *ucsi_cci_str(u32 cci); const char *ucsi_cci_str(u32 cci);
const char *ucsi_recipient_str(u8 recipient); const char *ucsi_recipient_str(u8 recipient);
DECLARE_EVENT_CLASS(ucsi_log_ack,
TP_PROTO(u8 ack),
TP_ARGS(ack),
TP_STRUCT__entry(
__field(u8, ack)
),
TP_fast_assign(
__entry->ack = ack;
),
TP_printk("ACK %s", ucsi_ack_str(__entry->ack))
);
DEFINE_EVENT(ucsi_log_ack, ucsi_ack,
TP_PROTO(u8 ack),
TP_ARGS(ack)
);
DECLARE_EVENT_CLASS(ucsi_log_control,
TP_PROTO(struct ucsi_control *ctrl),
TP_ARGS(ctrl),
TP_STRUCT__entry(
__field(u64, ctrl)
),
TP_fast_assign(
__entry->ctrl = ctrl->raw_cmd;
),
TP_printk("control=%08llx (%s)", __entry->ctrl,
ucsi_cmd_str(__entry->ctrl))
);
DEFINE_EVENT(ucsi_log_control, ucsi_command,
TP_PROTO(struct ucsi_control *ctrl),
TP_ARGS(ctrl)
);
DECLARE_EVENT_CLASS(ucsi_log_command, DECLARE_EVENT_CLASS(ucsi_log_command,
TP_PROTO(struct ucsi_control *ctrl, int ret), TP_PROTO(u64 command, int ret),
TP_ARGS(ctrl, ret), TP_ARGS(command, ret),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u64, ctrl) __field(u64, ctrl)
__field(int, ret) __field(int, ret)
), ),
TP_fast_assign( TP_fast_assign(
__entry->ctrl = ctrl->raw_cmd; __entry->ctrl = command;
__entry->ret = ret; __entry->ret = ret;
), ),
TP_printk("%s -> %s (err=%d)", ucsi_cmd_str(__entry->ctrl), TP_printk("%s -> %s (err=%d)", ucsi_cmd_str(__entry->ctrl),
...@@ -66,13 +30,13 @@ DECLARE_EVENT_CLASS(ucsi_log_command, ...@@ -66,13 +30,13 @@ DECLARE_EVENT_CLASS(ucsi_log_command,
); );
DEFINE_EVENT(ucsi_log_command, ucsi_run_command, DEFINE_EVENT(ucsi_log_command, ucsi_run_command,
TP_PROTO(struct ucsi_control *ctrl, int ret), TP_PROTO(u64 command, int ret),
TP_ARGS(ctrl, ret) TP_ARGS(command, ret)
); );
DEFINE_EVENT(ucsi_log_command, ucsi_reset_ppm, DEFINE_EVENT(ucsi_log_command, ucsi_reset_ppm,
TP_PROTO(struct ucsi_control *ctrl, int ret), TP_PROTO(u64 command, int ret),
TP_ARGS(ctrl, ret) TP_ARGS(command, ret)
); );
DECLARE_EVENT_CLASS(ucsi_log_connector_status, DECLARE_EVENT_CLASS(ucsi_log_connector_status,
......
...@@ -131,13 +131,13 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd) ...@@ -131,13 +131,13 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
return UCSI_CCI_LENGTH(cci); return UCSI_CCI_LENGTH(cci);
} }
static int ucsi_run_command(struct ucsi *ucsi, struct ucsi_control *ctrl, static int ucsi_run_command(struct ucsi *ucsi, u64 command,
void *data, size_t size) void *data, size_t size)
{ {
u8 length; u8 length;
int ret; int ret;
ret = ucsi_exec_command(ucsi, ctrl->raw_cmd); ret = ucsi_exec_command(ucsi, command);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -156,13 +156,13 @@ static int ucsi_run_command(struct ucsi *ucsi, struct ucsi_control *ctrl, ...@@ -156,13 +156,13 @@ static int ucsi_run_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
return length; return length;
} }
int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl, int ucsi_send_command(struct ucsi *ucsi, u64 command,
void *retval, size_t size) void *retval, size_t size)
{ {
int ret; int ret;
mutex_lock(&ucsi->ppm_lock); mutex_lock(&ucsi->ppm_lock);
ret = ucsi_run_command(ucsi, ctrl, retval, size); ret = ucsi_run_command(ucsi, command, retval, size);
mutex_unlock(&ucsi->ppm_lock); mutex_unlock(&ucsi->ppm_lock);
return ret; return ret;
...@@ -171,11 +171,12 @@ EXPORT_SYMBOL_GPL(ucsi_send_command); ...@@ -171,11 +171,12 @@ EXPORT_SYMBOL_GPL(ucsi_send_command);
int ucsi_resume(struct ucsi *ucsi) int ucsi_resume(struct ucsi *ucsi)
{ {
struct ucsi_control ctrl; u64 command;
/* Restore UCSI notification enable mask after system resume */ /* Restore UCSI notification enable mask after system resume */
UCSI_CMD_SET_NTFY_ENABLE(ctrl, UCSI_ENABLE_NTFY_ALL); command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
return ucsi_send_command(ucsi, &ctrl, NULL, 0);
return ucsi_send_command(ucsi, command, NULL, 0);
} }
EXPORT_SYMBOL_GPL(ucsi_resume); EXPORT_SYMBOL_GPL(ucsi_resume);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
...@@ -188,8 +189,8 @@ void ucsi_altmode_update_active(struct ucsi_connector *con) ...@@ -188,8 +189,8 @@ void ucsi_altmode_update_active(struct ucsi_connector *con)
u8 cur; u8 cur;
int i; int i;
UCSI_CMD_GET_CURRENT_CAM(ctrl, con->num); command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num);
ret = ucsi_run_command(con->ucsi, &ctrl, &cur, sizeof(cur)); ret = ucsi_run_command(con->ucsi, command, &cur, sizeof(cur));
if (ret < 0) { if (ret < 0) {
if (con->ucsi->version > 0x0100) { if (con->ucsi->version > 0x0100) {
dev_err(con->ucsi->dev, dev_err(con->ucsi->dev,
...@@ -307,7 +308,7 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient) ...@@ -307,7 +308,7 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
int max_altmodes = UCSI_MAX_ALTMODES; int max_altmodes = UCSI_MAX_ALTMODES;
struct typec_altmode_desc desc; struct typec_altmode_desc desc;
struct ucsi_altmode alt[2]; struct ucsi_altmode alt[2];
struct ucsi_control ctrl; u64 command;
int num = 1; int num = 1;
int ret; int ret;
int len; int len;
...@@ -325,8 +326,11 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient) ...@@ -325,8 +326,11 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
for (i = 0; i < max_altmodes;) { for (i = 0; i < max_altmodes;) {
memset(alt, 0, sizeof(alt)); memset(alt, 0, sizeof(alt));
UCSI_CMD_GET_ALTERNATE_MODES(ctrl, recipient, con->num, i, 1); command = UCSI_GET_ALTERNATE_MODES;
len = ucsi_run_command(con->ucsi, &ctrl, alt, sizeof(alt)); command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
command |= UCSI_GET_ALTMODE_OFFSET(i);
len = ucsi_run_command(con->ucsi, command, alt, sizeof(alt));
if (len <= 0) if (len <= 0)
return len; return len;
...@@ -487,13 +491,14 @@ static void ucsi_handle_connector_change(struct work_struct *work) ...@@ -487,13 +491,14 @@ static void ucsi_handle_connector_change(struct work_struct *work)
struct ucsi_connector *con = container_of(work, struct ucsi_connector, struct ucsi_connector *con = container_of(work, struct ucsi_connector,
work); work);
struct ucsi *ucsi = con->ucsi; struct ucsi *ucsi = con->ucsi;
struct ucsi_control ctrl; u64 command;
int ret; int ret;
mutex_lock(&con->lock); mutex_lock(&con->lock);
UCSI_CMD_GET_CONNECTOR_STATUS(ctrl, con->num); command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
ret = ucsi_send_command(ucsi, &ctrl, &con->status, sizeof(con->status)); ret = ucsi_send_command(ucsi, command, &con->status,
sizeof(con->status));
if (ret < 0) { if (ret < 0) {
dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n", dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n",
__func__, ret); __func__, ret);
...@@ -537,8 +542,9 @@ static void ucsi_handle_connector_change(struct work_struct *work) ...@@ -537,8 +542,9 @@ static void ucsi_handle_connector_change(struct work_struct *work)
* Running GET_CAM_SUPPORTED command just to make sure the PPM * Running GET_CAM_SUPPORTED command just to make sure the PPM
* does not get stuck in case it assumes we do so. * does not get stuck in case it assumes we do so.
*/ */
UCSI_CMD_GET_CAM_SUPPORTED(ctrl, con->num); command = UCSI_GET_CAM_SUPPORTED;
ucsi_run_command(con->ucsi, &ctrl, NULL, 0); command |= UCSI_CONNECTOR_NUMBER(con->num);
ucsi_run_command(con->ucsi, command, NULL, 0);
} }
if (con->status.change & UCSI_CONSTAT_PARTNER_CHANGE) if (con->status.change & UCSI_CONSTAT_PARTNER_CHANGE)
...@@ -573,11 +579,12 @@ EXPORT_SYMBOL_GPL(ucsi_connector_change); ...@@ -573,11 +579,12 @@ EXPORT_SYMBOL_GPL(ucsi_connector_change);
static int ucsi_reset_connector(struct ucsi_connector *con, bool hard) static int ucsi_reset_connector(struct ucsi_connector *con, bool hard)
{ {
struct ucsi_control ctrl; u64 command;
UCSI_CMD_CONNECTOR_RESET(ctrl, con, hard); command = UCSI_CONNECTOR_RESET | UCSI_CONNECTOR_NUMBER(con->num);
command |= hard ? UCSI_CONNECTOR_RESET_HARD : 0;
return ucsi_send_command(con->ucsi, &ctrl, NULL, 0); return ucsi_send_command(con->ucsi, command, NULL, 0);
} }
static int ucsi_reset_ppm(struct ucsi *ucsi) static int ucsi_reset_ppm(struct ucsi *ucsi)
...@@ -617,21 +624,21 @@ static int ucsi_reset_ppm(struct ucsi *ucsi) ...@@ -617,21 +624,21 @@ static int ucsi_reset_ppm(struct ucsi *ucsi)
return 0; return 0;
} }
static int ucsi_role_cmd(struct ucsi_connector *con, struct ucsi_control *ctrl) static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
{ {
int ret; int ret;
ret = ucsi_send_command(con->ucsi, ctrl, NULL, 0); ret = ucsi_send_command(con->ucsi, command, NULL, 0);
if (ret == -ETIMEDOUT) { if (ret == -ETIMEDOUT) {
struct ucsi_control c; u64 c;
/* PPM most likely stopped responding. Resetting everything. */ /* PPM most likely stopped responding. Resetting everything. */
mutex_lock(&con->ucsi->ppm_lock); mutex_lock(&con->ucsi->ppm_lock);
ucsi_reset_ppm(con->ucsi); ucsi_reset_ppm(con->ucsi);
mutex_unlock(&con->ucsi->ppm_lock); mutex_unlock(&con->ucsi->ppm_lock);
UCSI_CMD_SET_NTFY_ENABLE(c, UCSI_ENABLE_NTFY_ALL); c = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
ucsi_send_command(con->ucsi, &c, NULL, 0); ucsi_send_command(con->ucsi, c, NULL, 0);
ucsi_reset_connector(con, true); ucsi_reset_connector(con, true);
} }
...@@ -642,7 +649,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, struct ucsi_control *ctrl) ...@@ -642,7 +649,7 @@ static int ucsi_role_cmd(struct ucsi_connector *con, struct ucsi_control *ctrl)
static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role) static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
{ {
struct ucsi_connector *con = typec_get_drvdata(port); struct ucsi_connector *con = typec_get_drvdata(port);
struct ucsi_control ctrl; u64 command;
int ret = 0; int ret = 0;
mutex_lock(&con->lock); mutex_lock(&con->lock);
...@@ -658,8 +665,10 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role) ...@@ -658,8 +665,10 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
role == TYPEC_HOST)) role == TYPEC_HOST))
goto out_unlock; goto out_unlock;
UCSI_CMD_SET_UOR(ctrl, con, role); command = UCSI_SET_UOR | UCSI_CONNECTOR_NUMBER(con->num);
ret = ucsi_role_cmd(con, &ctrl); command |= UCSI_SET_UOR_ROLE(role);
command |= UCSI_SET_UOR_ACCEPT_ROLE_SWAPS;
ret = ucsi_role_cmd(con, command);
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
...@@ -676,7 +685,7 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role) ...@@ -676,7 +685,7 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
{ {
struct ucsi_connector *con = typec_get_drvdata(port); struct ucsi_connector *con = typec_get_drvdata(port);
struct ucsi_control ctrl; u64 command;
int ret = 0; int ret = 0;
mutex_lock(&con->lock); mutex_lock(&con->lock);
...@@ -689,8 +698,10 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) ...@@ -689,8 +698,10 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
if (con->status.pwr_dir == role) if (con->status.pwr_dir == role)
goto out_unlock; goto out_unlock;
UCSI_CMD_SET_PDR(ctrl, con, role); command = UCSI_SET_PDR | UCSI_CONNECTOR_NUMBER(con->num);
ret = ucsi_role_cmd(con, &ctrl); command |= UCSI_SET_PDR_ROLE(role);
command |= UCSI_SET_PDR_ACCEPT_ROLE_SWAPS;
ret = ucsi_role_cmd(con, command);
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
...@@ -733,7 +744,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index) ...@@ -733,7 +744,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
struct ucsi_connector *con = &ucsi->connector[index]; struct ucsi_connector *con = &ucsi->connector[index];
struct typec_capability *cap = &con->typec_cap; struct typec_capability *cap = &con->typec_cap;
enum typec_accessory *accessory = cap->accessory; enum typec_accessory *accessory = cap->accessory;
struct ucsi_control ctrl; u64 command;
int ret; int ret;
INIT_WORK(&con->work, ucsi_handle_connector_change); INIT_WORK(&con->work, ucsi_handle_connector_change);
...@@ -743,8 +754,9 @@ static int ucsi_register_port(struct ucsi *ucsi, int index) ...@@ -743,8 +754,9 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
con->ucsi = ucsi; con->ucsi = ucsi;
/* Get connector capability */ /* Get connector capability */
UCSI_CMD_GET_CONNECTOR_CAPABILITY(ctrl, con->num); command = UCSI_GET_CONNECTOR_CAPABILITY;
ret = ucsi_run_command(ucsi, &ctrl, &con->cap, sizeof(con->cap)); command |= UCSI_CONNECTOR_NUMBER(con->num);
ret = ucsi_run_command(ucsi, command, &con->cap, sizeof(con->cap));
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -787,8 +799,9 @@ static int ucsi_register_port(struct ucsi *ucsi, int index) ...@@ -787,8 +799,9 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
con->num); con->num);
/* Get the status */ /* Get the status */
UCSI_CMD_GET_CONNECTOR_STATUS(ctrl, con->num); command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
ret = ucsi_run_command(ucsi, &ctrl, &con->status, sizeof(con->status)); ret = ucsi_run_command(ucsi, command, &con->status,
sizeof(con->status));
if (ret < 0) { if (ret < 0) {
dev_err(ucsi->dev, "con%d: failed to get status\n", con->num); dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
return 0; return 0;
...@@ -836,7 +849,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index) ...@@ -836,7 +849,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
int ucsi_init(struct ucsi *ucsi) int ucsi_init(struct ucsi *ucsi)
{ {
struct ucsi_connector *con; struct ucsi_connector *con;
struct ucsi_control ctrl; u64 command;
int ret; int ret;
int i; int i;
...@@ -850,15 +863,15 @@ int ucsi_init(struct ucsi *ucsi) ...@@ -850,15 +863,15 @@ int ucsi_init(struct ucsi *ucsi)
} }
/* Enable basic notifications */ /* Enable basic notifications */
UCSI_CMD_SET_NTFY_ENABLE(ctrl, UCSI_ENABLE_NTFY_CMD_COMPLETE | command = UCSI_SET_NOTIFICATION_ENABLE;
UCSI_ENABLE_NTFY_ERROR); command |= UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
ret = ucsi_run_command(ucsi, &ctrl, NULL, 0); ret = ucsi_run_command(ucsi, command, NULL, 0);
if (ret < 0) if (ret < 0)
goto err_reset; goto err_reset;
/* Get PPM capabilities */ /* Get PPM capabilities */
UCSI_CMD_GET_CAPABILITY(ctrl); command = UCSI_GET_CAPABILITY;
ret = ucsi_run_command(ucsi, &ctrl, &ucsi->cap, sizeof(ucsi->cap)); ret = ucsi_run_command(ucsi, command, &ucsi->cap, sizeof(ucsi->cap));
if (ret < 0) if (ret < 0)
goto err_reset; goto err_reset;
...@@ -883,8 +896,8 @@ int ucsi_init(struct ucsi *ucsi) ...@@ -883,8 +896,8 @@ int ucsi_init(struct ucsi *ucsi)
} }
/* Enable all notifications */ /* Enable all notifications */
UCSI_CMD_SET_NTFY_ENABLE(ctrl, UCSI_ENABLE_NTFY_ALL); command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
ret = ucsi_run_command(ucsi, &ctrl, NULL, 0); ret = ucsi_run_command(ucsi, command, NULL, 0);
if (ret < 0) if (ret < 0)
goto err_unregister; goto err_unregister;
...@@ -1005,15 +1018,15 @@ EXPORT_SYMBOL_GPL(ucsi_register); ...@@ -1005,15 +1018,15 @@ EXPORT_SYMBOL_GPL(ucsi_register);
*/ */
void ucsi_unregister(struct ucsi *ucsi) void ucsi_unregister(struct ucsi *ucsi)
{ {
struct ucsi_control ctrl; u64 command;
int i; int i;
/* Make sure that we are not in the middle of driver initialization */ /* Make sure that we are not in the middle of driver initialization */
cancel_work_sync(&ucsi->work); cancel_work_sync(&ucsi->work);
/* Disable everything except command complete notification */ /* Disable everything except command complete notification */
UCSI_CMD_SET_NTFY_ENABLE(ctrl, UCSI_ENABLE_NTFY_CMD_COMPLETE) command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_CMD_COMPLETE;
ucsi_send_command(ucsi, &ctrl, NULL, 0); ucsi_send_command(ucsi, command, NULL, 0);
for (i = 0; i < ucsi->cap.num_connectors; i++) { for (i = 0; i < ucsi->cap.num_connectors; i++) {
cancel_work_sync(&ucsi->connector[i].work); cancel_work_sync(&ucsi->connector[i].work);
......
...@@ -60,178 +60,6 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num); ...@@ -60,178 +60,6 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Command Status and Connector Change Indication (CCI) data structure */
struct ucsi_cci {
u8:1; /* reserved */
u8 connector_change:7;
u8 data_length;
u16:9; /* reserved */
u16 not_supported:1;
u16 cancel_complete:1;
u16 reset_complete:1;
u16 busy:1;
u16 ack_complete:1;
u16 error:1;
u16 cmd_complete:1;
} __packed;
/* Default fields in CONTROL data structure */
struct ucsi_command {
u8 cmd;
u8 length;
u64 data:48;
} __packed;
/* ACK Command structure */
struct ucsi_ack_cmd {
u8 cmd;
u8 length;
u8 cci_ack:1;
u8 cmd_ack:1;
u8:6; /* reserved */
} __packed;
/* Connector Reset Command structure */
struct ucsi_con_rst {
u8 cmd;
u8 length;
u8 con_num:7;
u8 hard_reset:1;
} __packed;
/* Set USB Operation Mode Command structure */
struct ucsi_uor_cmd {
u8 cmd;
u8 length;
u16 con_num:7;
u16 role:3;
#define UCSI_UOR_ROLE_DFP BIT(0)
#define UCSI_UOR_ROLE_UFP BIT(1)
#define UCSI_UOR_ROLE_DRP BIT(2)
u16:6; /* reserved */
} __packed;
/* Get Alternate Modes Command structure */
struct ucsi_altmode_cmd {
u8 cmd;
u8 length;
u8 recipient;
#define UCSI_RECIPIENT_CON 0
#define UCSI_RECIPIENT_SOP 1
#define UCSI_RECIPIENT_SOP_P 2
#define UCSI_RECIPIENT_SOP_PP 3
u8 con_num;
u8 offset;
u8 num_altmodes;
} __packed;
struct ucsi_control {
union {
u64 raw_cmd;
struct ucsi_command cmd;
struct ucsi_uor_cmd uor;
struct ucsi_ack_cmd ack;
struct ucsi_con_rst con_rst;
struct ucsi_altmode_cmd alt;
};
};
#define __UCSI_CMD(_ctrl_, _cmd_) \
{ \
(_ctrl_).raw_cmd = 0; \
(_ctrl_).cmd.cmd = _cmd_; \
}
/* Helper for preparing ucsi_control for CONNECTOR_RESET command. */
#define UCSI_CMD_CONNECTOR_RESET(_ctrl_, _con_, _hard_) \
{ \
__UCSI_CMD(_ctrl_, UCSI_CONNECTOR_RESET) \
(_ctrl_).con_rst.con_num = (_con_)->num; \
(_ctrl_).con_rst.hard_reset = _hard_; \
}
/* Helper for preparing ucsi_control for ACK_CC_CI command. */
#define UCSI_CMD_ACK(_ctrl_, _ack_) \
{ \
__UCSI_CMD(_ctrl_, UCSI_ACK_CC_CI) \
(_ctrl_).ack.cci_ack = ((_ack_) == UCSI_ACK_EVENT); \
(_ctrl_).ack.cmd_ack = ((_ack_) == UCSI_ACK_CMD); \
}
/* Helper for preparing ucsi_control for SET_NOTIFY_ENABLE command. */
#define UCSI_CMD_SET_NTFY_ENABLE(_ctrl_, _ntfys_) \
{ \
__UCSI_CMD(_ctrl_, UCSI_SET_NOTIFICATION_ENABLE) \
(_ctrl_).cmd.data = _ntfys_; \
}
/* Helper for preparing ucsi_control for GET_CAPABILITY command. */
#define UCSI_CMD_GET_CAPABILITY(_ctrl_) \
{ \
__UCSI_CMD(_ctrl_, UCSI_GET_CAPABILITY) \
}
/* Helper for preparing ucsi_control for GET_CONNECTOR_CAPABILITY command. */
#define UCSI_CMD_GET_CONNECTOR_CAPABILITY(_ctrl_, _con_) \
{ \
__UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_CAPABILITY) \
(_ctrl_).cmd.data = _con_; \
}
/* Helper for preparing ucsi_control for GET_ALTERNATE_MODES command. */
#define UCSI_CMD_GET_ALTERNATE_MODES(_ctrl_, _r_, _con_num_, _o_, _num_)\
{ \
__UCSI_CMD((_ctrl_), UCSI_GET_ALTERNATE_MODES) \
_ctrl_.alt.recipient = (_r_); \
_ctrl_.alt.con_num = (_con_num_); \
_ctrl_.alt.offset = (_o_); \
_ctrl_.alt.num_altmodes = (_num_) - 1; \
}
/* Helper for preparing ucsi_control for GET_CAM_SUPPORTED command. */
#define UCSI_CMD_GET_CAM_SUPPORTED(_ctrl_, _con_) \
{ \
__UCSI_CMD((_ctrl_), UCSI_GET_CAM_SUPPORTED) \
_ctrl_.cmd.data = (_con_); \
}
/* Helper for preparing ucsi_control for GET_CAM_SUPPORTED command. */
#define UCSI_CMD_GET_CURRENT_CAM(_ctrl_, _con_) \
{ \
__UCSI_CMD((_ctrl_), UCSI_GET_CURRENT_CAM) \
_ctrl_.cmd.data = (_con_); \
}
/* Helper for preparing ucsi_control for GET_CONNECTOR_STATUS command. */
#define UCSI_CMD_GET_CONNECTOR_STATUS(_ctrl_, _con_) \
{ \
__UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_STATUS) \
(_ctrl_).cmd.data = _con_; \
}
#define __UCSI_ROLE(_ctrl_, _cmd_, _con_num_) \
{ \
__UCSI_CMD(_ctrl_, _cmd_) \
(_ctrl_).uor.con_num = _con_num_; \
(_ctrl_).uor.role = UCSI_UOR_ROLE_DRP; \
}
/* Helper for preparing ucsi_control for SET_UOR command. */
#define UCSI_CMD_SET_UOR(_ctrl_, _con_, _role_) \
{ \
__UCSI_ROLE(_ctrl_, UCSI_SET_UOR, (_con_)->num) \
(_ctrl_).uor.role |= (_role_) == TYPEC_HOST ? UCSI_UOR_ROLE_DFP : \
UCSI_UOR_ROLE_UFP; \
}
/* Helper for preparing ucsi_control for SET_PDR command. */
#define UCSI_CMD_SET_PDR(_ctrl_, _con_, _role_) \
{ \
__UCSI_ROLE(_ctrl_, UCSI_SET_PDR, (_con_)->num) \
(_ctrl_).uor.role |= (_role_) == TYPEC_SOURCE ? UCSI_UOR_ROLE_DFP : \
UCSI_UOR_ROLE_UFP; \
}
/* Commands */ /* Commands */
#define UCSI_PPM_RESET 0x01 #define UCSI_PPM_RESET 0x01
#define UCSI_CANCEL 0x02 #define UCSI_CANCEL 0x02
...@@ -253,28 +81,49 @@ struct ucsi_control { ...@@ -253,28 +81,49 @@ struct ucsi_control {
#define UCSI_GET_CONNECTOR_STATUS 0x12 #define UCSI_GET_CONNECTOR_STATUS 0x12
#define UCSI_GET_ERROR_STATUS 0x13 #define UCSI_GET_ERROR_STATUS 0x13
/* ACK_CC_CI commands */ #define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16)
#define UCSI_ACK_EVENT 1
#define UCSI_ACK_CMD 2 /* CONNECTOR_RESET command bits */
#define UCSI_CONNECTOR_RESET_HARD BIT(23) /* Deprecated in v1.1 */
/* Bits for ACK CC or CI */ /* ACK_CC_CI bits */
#define UCSI_ACK_CONNECTOR_CHANGE BIT(16) #define UCSI_ACK_CONNECTOR_CHANGE BIT(16)
#define UCSI_ACK_COMMAND_COMPLETE BIT(17) #define UCSI_ACK_COMMAND_COMPLETE BIT(17)
/* Bits for SET_NOTIFICATION_ENABLE command */ /* SET_NOTIFICATION_ENABLE command bits */
#define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(0) #define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(16)
#define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(1) #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(17)
#define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(2) #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(18)
#define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(5) #define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(19)
#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(6) #define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(20)
#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(7) #define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(21)
#define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(8) #define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(22)
#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(9) #define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(23)
#define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(11) #define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(24)
#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(12) #define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(25)
#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(14) #define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(26)
#define UCSI_ENABLE_NTFY_ERROR BIT(15) #define UCSI_ENABLE_NTFY_ERROR BIT(27)
#define UCSI_ENABLE_NTFY_ALL 0xdbe7 #define UCSI_ENABLE_NTFY_ALL 0xdbe70000
/* SET_UOR command bits */
#define UCSI_SET_UOR_ROLE(_r_) (((_r_) == TYPEC_HOST ? 1 : 2) << 23)
#define UCSI_SET_UOR_ACCEPT_ROLE_SWAPS BIT(25)
/* SET_PDF command bits */
#define UCSI_SET_PDR_ROLE(_r_) (((_r_) == TYPEC_SOURCE ? 1 : 2) << 23)
#define UCSI_SET_PDR_ACCEPT_ROLE_SWAPS BIT(25)
/* GET_ALTERNATE_MODES command bits */
#define UCSI_GET_ALTMODE_RECIPIENT(_r_) ((u64)(_r_) << 16)
#define UCSI_RECIPIENT_CON 0
#define UCSI_RECIPIENT_SOP 1
#define UCSI_RECIPIENT_SOP_P 2
#define UCSI_RECIPIENT_SOP_PP 3
#define UCSI_GET_ALTMODE_CONNECTOR_NUMBER(_r_) ((u64)(_r_) << 24)
#define UCSI_GET_ALTMODE_OFFSET(_r_) ((u64)(_r_) << 32)
#define UCSI_GET_ALTMODE_NUM_ALTMODES(_r_) ((u64)(_r_) << 40)
/* -------------------------------------------------------------------------- */
/* Error information returned by PPM in response to GET_ERROR_STATUS command. */ /* Error information returned by PPM in response to GET_ERROR_STATUS command. */
#define UCSI_ERROR_UNREGONIZED_CMD BIT(0) #define UCSI_ERROR_UNREGONIZED_CMD BIT(0)
...@@ -443,7 +292,7 @@ struct ucsi_connector { ...@@ -443,7 +292,7 @@ struct ucsi_connector {
struct ucsi_connector_capability cap; struct ucsi_connector_capability cap;
}; };
int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl, int ucsi_send_command(struct ucsi *ucsi, u64 command,
void *retval, size_t size); void *retval, size_t size);
void ucsi_altmode_update_active(struct ucsi_connector *con); void ucsi_altmode_update_active(struct ucsi_connector *con);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment