mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 08:07:32 -04:00
usb:pd: Add get/select PDO api
-usbpd_get_pd_info: get all PDO info from PD SOURCE, and save them to usbpd_pdo_info struct -usbpd_select_pdo: provide API to easy select the specific PDO, in order to program its voltage and current. Change-Id: I6663c04a9479b852449fa80e9e5c396ddfbc9e57 Signed-off-by: mahj8 <mahj8@lenovo.com> Reviewed-on: https://gerrit.mot.com/1943692 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Lu Chai <chailu1@motorola.com> Reviewed-by: Huosheng Liao <liaohs@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
5f87bbb9ec
commit
d1b029fe40
2 changed files with 153 additions and 0 deletions
|
|
@ -4343,6 +4343,139 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(usbpd_select_pdo_match);
|
||||
|
||||
int usbpd_get_pdo_info(struct usbpd *pd, struct usbpd_pdo_info *pdo_info, int length)
|
||||
{
|
||||
int pdo = 0;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if (!pd || !pdo_info)
|
||||
return -EINVAL;
|
||||
|
||||
if (length > PD_MAX_PDO_NUM) {
|
||||
usbpd_err(&pd->dev,
|
||||
"the members of the struct pd_info[] array must be less than %d, "
|
||||
"err length %d\n", PD_MAX_PDO_NUM, length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&pd->swap_lock);
|
||||
|
||||
if (pd->current_pr == PR_SRC) {
|
||||
usbpd_err(&pd->dev, "select_pdo:not support in source mode\n");
|
||||
ret = -ENOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
usbpd_err(&pd->dev, "select pdo info ,pd->current_state %d\n", pd->current_state);
|
||||
|
||||
if (!is_sink_tx_ok(pd))
|
||||
usbpd_err(&pd->dev, "select pdo info , !is_sink_tx_ok\n");
|
||||
|
||||
/* Only allowed if we are already in explicit sink contract */
|
||||
if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
|
||||
usbpd_err(&pd->dev, "select_pdo_info: Cannot select new PDO yet\n");
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
pdo = pd->received_pdos[i];
|
||||
if (pdo == 0)
|
||||
break;
|
||||
|
||||
pdo_info[i].pdo_pos = i + 1;
|
||||
pdo_info[i].type = PD_SRC_PDO_TYPE(pdo);
|
||||
if (pdo_info[i].type == PD_SRC_PDO_TYPE_FIXED) {
|
||||
pdo_info[i].ua = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10;
|
||||
pdo_info[i].uv_max = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50 * 1000;
|
||||
pdo_info[i].uv_min = PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50 * 1000;
|
||||
|
||||
printk(KERN_INFO "pdo %d, Fixed supply\n"
|
||||
"Voltage:%d (uV)\n"
|
||||
"Max Current:%d (uA)\n",
|
||||
pdo_info[i].pdo_pos,
|
||||
pdo_info[i].uv_max,
|
||||
pdo_info[i].ua);
|
||||
|
||||
} else if (pdo_info[i].type == PD_SRC_PDO_TYPE_AUGMENTED) {
|
||||
pdo_info[i].uv_max = PD_APDO_MAX_VOLT(pdo) * 100000;
|
||||
pdo_info[i].uv_min = PD_APDO_MIN_VOLT(pdo) * 100000;
|
||||
pdo_info[i].ua = PD_APDO_MAX_CURR(pdo) * 50000;
|
||||
|
||||
printk(KERN_INFO "pdo %d, Programmable Power supply\n"
|
||||
"Voltage:%d (uV)\n"
|
||||
"Max Current:%d (uA)\n",
|
||||
pdo_info[i].pdo_pos,
|
||||
pdo_info[i].uv_max,
|
||||
pdo_info[i].ua);
|
||||
|
||||
} else
|
||||
usbpd_err(&pd->dev, "Only get Fixed or Programmable PDOs supported\n");
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&pd->swap_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(usbpd_get_pdo_info);
|
||||
|
||||
int usbpd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!pd)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pd->swap_lock);
|
||||
|
||||
if (pd->current_pr == PR_SRC) {
|
||||
usbpd_err(&pd->dev, "select_pdo:not support in source mode\n");
|
||||
ret = -ENOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Only allowed if we are already in explicit sink contract */
|
||||
if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
|
||||
usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n");
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pdo_pos < 1 || pdo_pos > 7) {
|
||||
usbpd_err(&pd->dev, "select_pdo: invalid PDO:%d\n", pdo_pos);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = pd_select_pdo(pd, pdo_pos, uv, ua);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
reinit_completion(&pd->is_ready);
|
||||
pd->send_request = true;
|
||||
kick_sm(pd, 0);
|
||||
|
||||
/* wait for operation to complete */
|
||||
if (!wait_for_completion_timeout(&pd->is_ready,
|
||||
msecs_to_jiffies(1000))) {
|
||||
usbpd_err(&pd->dev, "select_pdo: request timed out\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* determine if request was accepted/rejected */
|
||||
if (pd->selected_pdo != pd->requested_pdo ||
|
||||
pd->current_voltage != pd->requested_voltage) {
|
||||
usbpd_err(&pd->dev, "select_pdo: request rejected\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
out:
|
||||
pd->send_request = false;
|
||||
mutex_unlock(&pd->swap_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(usbpd_select_pdo);
|
||||
|
||||
static ssize_t select_pdo_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ enum usbpd_svdm_cmd_type {
|
|||
#define USBPD_SVDM_EXIT_MODE 0x5
|
||||
#define USBPD_SVDM_ATTENTION 0x6
|
||||
|
||||
#define PD_MAX_PDO_NUM 7
|
||||
|
||||
/*
|
||||
* Implemented by client
|
||||
*/
|
||||
|
|
@ -65,6 +67,14 @@ struct usbpd_svid_handler {
|
|||
bool discovered;
|
||||
};
|
||||
|
||||
struct usbpd_pdo_info {
|
||||
int pdo_pos;
|
||||
int uv_max;
|
||||
int uv_min;
|
||||
int ua;
|
||||
int type;
|
||||
};
|
||||
|
||||
enum plug_orientation {
|
||||
ORIENTATION_NONE,
|
||||
ORIENTATION_CC1,
|
||||
|
|
@ -104,6 +114,16 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
|
|||
*/
|
||||
int usbpd_select_pdo_match(struct usbpd *pd);
|
||||
|
||||
/*
|
||||
* support that directly set pdo which is need in Source Mode.
|
||||
*/
|
||||
int usbpd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua);
|
||||
|
||||
/*
|
||||
* Transmit all effective pdo info.
|
||||
*/
|
||||
int usbpd_get_pdo_info(struct usbpd *pd, struct usbpd_pdo_info *pdo_info, int length);
|
||||
|
||||
/*
|
||||
* Get current status of CC pin orientation.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue