mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 15:43:35 -04:00
usb: typec: hd3ss3220: configure advertised power opmode based on fwnode property
The TI HD3SS3220 Type-C controller supports configuring its advertised power operation mode over I2C using the CURRENT_MODE_ADVERTISE field of the Connection Status Register. Configure this power mode based on the existing (optional) property "typec-power-opmode" of /schemas/connector/usb-connector.yaml Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Oliver Facklam <oliver.facklam@zuehlke.com> Link: https://lore.kernel.org/r/20241211-usb-typec-controller-enhancements-v3-1-e4bc1b6e1441@zuehlke.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
485ff98608
commit
14ba185d2f
@@ -16,10 +16,17 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define HD3SS3220_REG_CN_STAT 0x08
|
||||
#define HD3SS3220_REG_CN_STAT_CTRL 0x09
|
||||
#define HD3SS3220_REG_GEN_CTRL 0x0A
|
||||
#define HD3SS3220_REG_DEV_REV 0xA0
|
||||
|
||||
/* Register HD3SS3220_REG_CN_STAT */
|
||||
#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MASK (BIT(7) | BIT(6))
|
||||
#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_DEFAULT 0x00
|
||||
#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MID BIT(6)
|
||||
#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH BIT(7)
|
||||
|
||||
/* Register HD3SS3220_REG_CN_STAT_CTRL*/
|
||||
#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6))
|
||||
#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6)
|
||||
@@ -43,6 +50,31 @@ struct hd3ss3220 {
|
||||
bool poll;
|
||||
};
|
||||
|
||||
static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode)
|
||||
{
|
||||
int current_mode;
|
||||
|
||||
switch (power_opmode) {
|
||||
case TYPEC_PWR_MODE_USB:
|
||||
current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_DEFAULT;
|
||||
break;
|
||||
case TYPEC_PWR_MODE_1_5A:
|
||||
current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_MID;
|
||||
break;
|
||||
case TYPEC_PWR_MODE_3_0A:
|
||||
current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH;
|
||||
break;
|
||||
case TYPEC_PWR_MODE_PD: /* Power delivery not supported */
|
||||
default:
|
||||
dev_err(hd3ss3220->dev, "bad power operation mode: %d\n", power_opmode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT,
|
||||
HD3SS3220_REG_CN_STAT_CURRENT_MODE_MASK,
|
||||
current_mode);
|
||||
}
|
||||
|
||||
static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int src_pref)
|
||||
{
|
||||
return regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
|
||||
@@ -162,6 +194,23 @@ static irqreturn_t hd3ss3220_irq_handler(int irq, void *data)
|
||||
return hd3ss3220_irq(hd3ss3220);
|
||||
}
|
||||
|
||||
static int hd3ss3220_configure_power_opmode(struct hd3ss3220 *hd3ss3220,
|
||||
struct fwnode_handle *connector)
|
||||
{
|
||||
/*
|
||||
* Supported power operation mode can be configured through device tree
|
||||
*/
|
||||
const char *cap_str;
|
||||
int ret, power_opmode;
|
||||
|
||||
ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
power_opmode = typec_find_pwr_opmode(cap_str);
|
||||
return hd3ss3220_set_power_opmode(hd3ss3220, power_opmode);
|
||||
}
|
||||
|
||||
static const struct regmap_config config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@@ -223,6 +272,10 @@ static int hd3ss3220_probe(struct i2c_client *client)
|
||||
goto err_put_role;
|
||||
}
|
||||
|
||||
ret = hd3ss3220_configure_power_opmode(hd3ss3220, connector);
|
||||
if (ret < 0)
|
||||
goto err_unreg_port;
|
||||
|
||||
hd3ss3220_set_role(hd3ss3220);
|
||||
ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, &data);
|
||||
if (ret < 0)
|
||||
|
||||
Reference in New Issue
Block a user