aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/typec/fusb302/fusb302.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/typec/fusb302/fusb302.c')
-rw-r--r--drivers/usb/typec/fusb302/fusb302.c121
1 files changed, 35 insertions, 86 deletions
diff --git a/drivers/usb/typec/fusb302/fusb302.c b/drivers/usb/typec/fusb302/fusb302.c
index 703617129067..1e68da10bf17 100644
--- a/drivers/usb/typec/fusb302/fusb302.c
+++ b/drivers/usb/typec/fusb302/fusb302.c
@@ -18,7 +18,6 @@
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
-#include <linux/power_supply.h>
#include <linux/proc_fs.h>
#include <linux/regulator/consumer.h>
#include <linux/sched/clock.h>
@@ -99,11 +98,6 @@ struct fusb302_chip {
/* lock for sharing chip states */
struct mutex lock;
- /* psy + psy status */
- struct power_supply *psy;
- u32 current_limit;
- u32 supply_voltage;
-
/* chip status */
enum toggling_mode toggling_mode;
enum src_current_status src_current_status;
@@ -120,6 +114,7 @@ struct fusb302_chip {
enum typec_cc_polarity cc_polarity;
enum typec_cc_status cc1;
enum typec_cc_status cc2;
+ u32 snk_pdo[PDO_MAX_OBJECTS];
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
@@ -220,32 +215,28 @@ DEFINE_SHOW_ATTRIBUTE(fusb302_debug);
static struct dentry *rootdir;
-static int fusb302_debugfs_init(struct fusb302_chip *chip)
+static void fusb302_debugfs_init(struct fusb302_chip *chip)
{
mutex_init(&chip->logbuffer_lock);
- if (!rootdir) {
+ if (!rootdir)
rootdir = debugfs_create_dir("fusb302", NULL);
- if (!rootdir)
- return -ENOMEM;
- }
chip->dentry = debugfs_create_file(dev_name(chip->dev),
S_IFREG | 0444, rootdir,
chip, &fusb302_debug_fops);
-
- return 0;
}
static void fusb302_debugfs_exit(struct fusb302_chip *chip)
{
debugfs_remove(chip->dentry);
+ debugfs_remove(rootdir);
}
#else
static void fusb302_log(const struct fusb302_chip *chip,
const char *fmt, ...) { }
-static int fusb302_debugfs_init(const struct fusb302_chip *chip) { return 0; }
+static void fusb302_debugfs_init(const struct fusb302_chip *chip) { }
static void fusb302_debugfs_exit(const struct fusb302_chip *chip) { }
#endif
@@ -861,13 +852,11 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge)
chip->vbus_on = on;
fusb302_log(chip, "vbus := %s", on ? "On" : "Off");
}
- if (chip->charge_on == charge) {
+ if (chip->charge_on == charge)
fusb302_log(chip, "charge is already %s",
charge ? "On" : "Off");
- } else {
+ else
chip->charge_on = charge;
- power_supply_changed(chip->psy);
- }
done:
mutex_unlock(&chip->lock);
@@ -883,11 +872,6 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv)
fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)",
max_ma, mv);
- chip->supply_voltage = mv;
- chip->current_limit = max_ma;
-
- power_supply_changed(chip->psy);
-
return 0;
}
@@ -1212,11 +1196,6 @@ static const u32 snk_pdo[] = {
static const struct tcpc_config fusb302_tcpc_config = {
.src_pdo = src_pdo,
.nr_src_pdo = ARRAY_SIZE(src_pdo),
- .snk_pdo = snk_pdo,
- .nr_snk_pdo = ARRAY_SIZE(snk_pdo),
- .max_snk_mv = 5000,
- .max_snk_ma = 3000,
- .max_snk_mw = 15000,
.operating_snk_mw = 2500,
.type = TYPEC_PORT_DRP,
.data = TYPEC_PORT_DRD,
@@ -1686,43 +1665,6 @@ done:
return IRQ_HANDLED;
}
-static int fusb302_psy_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct fusb302_chip *chip = power_supply_get_drvdata(psy);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = chip->charge_on;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = chip->supply_voltage * 1000; /* mV -> µV */
- break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- val->intval = chip->current_limit * 1000; /* mA -> µA */
- break;
- default:
- return -ENODATA;
- }
-
- return 0;
-}
-
-static enum power_supply_property fusb302_psy_properties[] = {
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_MAX,
-};
-
-static const struct power_supply_desc fusb302_psy_desc = {
- .name = "fusb302-typec-source",
- .type = POWER_SUPPLY_TYPE_USB_TYPE_C,
- .properties = fusb302_psy_properties,
- .num_properties = ARRAY_SIZE(fusb302_psy_properties),
- .get_property = fusb302_psy_get_property,
-};
-
static int init_gpio(struct fusb302_chip *chip)
{
struct device_node *node;
@@ -1756,13 +1698,35 @@ static int init_gpio(struct fusb302_chip *chip)
return 0;
}
+static int fusb302_composite_snk_pdo_array(struct fusb302_chip *chip)
+{
+ struct device *dev = chip->dev;
+ u32 max_uv, max_ua;
+
+ chip->snk_pdo[0] = PDO_FIXED(5000, 400, PDO_FIXED_FLAGS);
+
+ /*
+ * As max_snk_ma/mv/mw is not needed for tcpc_config,
+ * those settings should be passed in via sink PDO, so
+ * "fcs, max-sink-*" properties will be deprecated, to
+ * perserve compatibility with existing users of them,
+ * we read those properties to convert them to be a var
+ * PDO.
+ */
+ if (device_property_read_u32(dev, "fcs,max-sink-microvolt", &max_uv) ||
+ device_property_read_u32(dev, "fcs,max-sink-microamp", &max_ua))
+ return 1;
+
+ chip->snk_pdo[1] = PDO_VAR(5000, max_uv / 1000, max_ua / 1000);
+ return 2;
+}
+
static int fusb302_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct fusb302_chip *chip;
struct i2c_adapter *adapter;
struct device *dev = &client->dev;
- struct power_supply_config cfg = {};
const char *name;
int ret = 0;
u32 v;
@@ -1784,18 +1748,13 @@ static int fusb302_probe(struct i2c_client *client,
chip->tcpc_dev.config = &chip->tcpc_config;
mutex_init(&chip->lock);
- if (!device_property_read_u32(dev, "fcs,max-sink-microvolt", &v))
- chip->tcpc_config.max_snk_mv = v / 1000;
-
- if (!device_property_read_u32(dev, "fcs,max-sink-microamp", &v))
- chip->tcpc_config.max_snk_ma = v / 1000;
-
- if (!device_property_read_u32(dev, "fcs,max-sink-microwatt", &v))
- chip->tcpc_config.max_snk_mw = v / 1000;
-
if (!device_property_read_u32(dev, "fcs,operating-sink-microwatt", &v))
chip->tcpc_config.operating_snk_mw = v / 1000;
+ /* Composite sink PDO */
+ chip->tcpc_config.nr_snk_pdo = fusb302_composite_snk_pdo_array(chip);
+ chip->tcpc_config.snk_pdo = chip->snk_pdo;
+
/*
* Devicetree platforms should get extcon via phandle (not yet
* supported). On ACPI platforms, we get the name from a device prop.
@@ -1809,17 +1768,7 @@ static int fusb302_probe(struct i2c_client *client,
return -EPROBE_DEFER;
}
- cfg.drv_data = chip;
- chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg);
- if (IS_ERR(chip->psy)) {
- ret = PTR_ERR(chip->psy);
- dev_err(chip->dev, "Error registering power-supply: %d\n", ret);
- return ret;
- }
-
- ret = fusb302_debugfs_init(chip);
- if (ret < 0)
- return ret;
+ fusb302_debugfs_init(chip);
chip->wq = create_singlethread_workqueue(dev_name(chip->dev));
if (!chip->wq) {