diff options
author | Li Jun <jun.li@nxp.com> | 2017-07-28 16:12:42 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 58521c9ecdb3683bf71e8c939ad315e860bdc6bf (patch) | |
tree | f778e86ff5bd2a24581da074deefbe4c71136413 /drivers/staging | |
parent | 090a31a4e2a7e0643ec48cf1c2b0f68204d3105a (diff) |
MLK-16013-28 staging: typec: tcpci: Populate config from dt
Instead of static config, use dt to pass basic PD config for
below settings:
- Source pdo list
- Sink pdo list
- Max sink voltage
- Max sink current
- Sink operating power
- TypeC port type
- TypeC port preferred role
Reviewed-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/typec/tcpci.c | 89 | ||||
-rw-r--r-- | drivers/staging/typec/tcpm.h | 6 |
2 files changed, 90 insertions, 5 deletions
diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c index 7f947a4de2fb..6c2cdd294a36 100644 --- a/drivers/staging/typec/tcpci.c +++ b/drivers/staging/typec/tcpci.c @@ -588,14 +588,99 @@ const struct tcpc_config tcpci_tcpc_config = { .default_role = TYPEC_SINK, }; +/* Populate struct tcpc_config from ACPI/device-tree */ static int tcpci_parse_config(struct tcpci *tcpci) { + struct tcpc_config *tcfg; + int ret = 0; + tcpci->controls_vbus = true; /* XXX */ - /* TODO: Populate struct tcpc_config from ACPI/device-tree */ - tcpci->tcpc.config = &tcpci_tcpc_config; + /* Alloc tcpc_config struct */ + tcpci->tcpc.config = devm_kzalloc(tcpci->dev, sizeof(*tcfg), + GFP_KERNEL); + if (!tcpci->tcpc.config) + return -ENOMEM; + + tcfg = tcpci->tcpc.config; + + /* Get the port-type */ + tcfg->type = typec_get_port_type(tcpci->dev); + if (tcfg->type == TYPEC_PORT_TYPE_UNKNOWN) { + dev_err(tcpci->dev, "typec port type is NOT correct!\n"); + return -EINVAL; + } + + /* Get the default-role */ + tcfg->default_role = typec_get_power_role(tcpci->dev); + if (tcfg->default_role == TYPEC_ROLE_UNKNOWN) { + dev_err(tcpci->dev, "typec power role is NOT correct!\n"); + return -EINVAL; + } + + /* Check source pdo array size */ + tcfg->nr_src_pdo = device_property_read_u32_array(tcpci->dev, + "src-pdos", NULL, 0); + if (tcfg->nr_src_pdo <= 0 && (tcfg->type == TYPEC_PORT_DRP || + tcfg->type == TYPEC_PORT_DFP)) { + dev_err(tcpci->dev, "typec source pdo is missing!\n"); + return -EINVAL; + } + + /* Alloc src_pdo based on the array size */ + tcfg->src_pdo = devm_kzalloc(tcpci->dev, + sizeof(*tcfg->src_pdo) * tcfg->nr_src_pdo, GFP_KERNEL); + if (!tcfg->src_pdo) + return -ENOMEM; + + /* Read out source pdo array */ + ret = device_property_read_u32_array(tcpci->dev, "src-pdos", + tcfg->src_pdo, tcfg->nr_src_pdo); + if (ret) { + dev_err(tcpci->dev, "Failed to read src pdo!\n"); + return -EINVAL; + } + + /* Check the num of snk pdo */ + tcfg->nr_snk_pdo = device_property_read_u32_array(tcpci->dev, + "snk-pdos", NULL, 0); + if (tcfg->nr_snk_pdo <= 0 && (tcfg->type == TYPEC_PORT_DRP || + tcfg->type == TYPEC_PORT_UFP)) { + dev_err(tcpci->dev, "typec sink pdo is missing!\n"); + return -EINVAL; + } + + /* alloc snk_pdo based on the array size */ + tcfg->snk_pdo = devm_kzalloc(tcpci->dev, + sizeof(*tcfg->snk_pdo) * tcfg->nr_snk_pdo, GFP_KERNEL); + if (!tcfg->snk_pdo) + return -ENOMEM; + + /* Read out sink pdo array */ + ret = device_property_read_u32_array(tcpci->dev, "snk-pdos", + tcfg->snk_pdo, tcfg->nr_snk_pdo); + if (ret) { + dev_err(tcpci->dev, "Failed to read snk pdo!\n"); + return -EINVAL; + } + + /* Get the max-snk-mv max-snk-ma op-snk-mw */ + if (device_property_read_u32(tcpci->dev, "max-snk-mv", + &tcfg->max_snk_mv) || + device_property_read_u32(tcpci->dev, "max-snk-ma", + &tcfg->max_snk_ma) || + device_property_read_u32(tcpci->dev, "op-snk-mw", + &tcfg->operating_snk_mw)) + goto snk_setting_wrong; return 0; + +snk_setting_wrong: + if (tcfg->type == TYPEC_PORT_DRP || + tcfg->type == TYPEC_PORT_UFP) + dev_err(tcpci->dev, "Failed to read snk setting!\n"); + + return ret; } static int tcpci_ss_mux_control_init(struct tcpci *tcpci) diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h index e0502093cb6e..59b939933692 100644 --- a/drivers/staging/typec/tcpm.h +++ b/drivers/staging/typec/tcpm.h @@ -57,10 +57,10 @@ enum tcpm_transmit_type { }; struct tcpc_config { - const u32 *src_pdo; + u32 *src_pdo; unsigned int nr_src_pdo; - const u32 *snk_pdo; + u32 *snk_pdo; unsigned int nr_snk_pdo; unsigned int max_snk_mv; @@ -104,7 +104,7 @@ struct tcpc_mux_dev { }; struct tcpc_dev { - const struct tcpc_config *config; + struct tcpc_config *config; int (*init)(struct tcpc_dev *dev); int (*get_vbus)(struct tcpc_dev *dev); |