aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/typec
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/typec')
-rw-r--r--drivers/usb/typec/Kconfig1
-rw-r--r--drivers/usb/typec/class.c16
-rw-r--r--drivers/usb/typec/mux.c2
-rw-r--r--drivers/usb/typec/tcpm/fusb302.c101
-rw-r--r--drivers/usb/typec/tcpm/tcpm.c23
-rw-r--r--drivers/usb/typec/tcpm/wcove.c4
-rw-r--r--drivers/usb/typec/ucsi/ucsi_ccg.c13
7 files changed, 58 insertions, 102 deletions
diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
index 89d9193bd1cf..895e2418de53 100644
--- a/drivers/usb/typec/Kconfig
+++ b/drivers/usb/typec/Kconfig
@@ -53,6 +53,7 @@ source "drivers/usb/typec/ucsi/Kconfig"
config TYPEC_TPS6598X
tristate "TI TPS6598x USB Power Delivery controller driver"
depends on I2C
+ select REGMAP_I2C
help
Say Y or M here if your system has TI TPS65982 or TPS65983 USB Power
Delivery controller.
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index a18285a990a8..94a3eda62add 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -205,16 +205,6 @@ static void typec_altmode_put_partner(struct altmode *altmode)
put_device(&adev->dev);
}
-static int typec_port_fwnode_match(struct device *dev, const void *fwnode)
-{
- return dev_fwnode(dev) == fwnode;
-}
-
-static int typec_port_name_match(struct device *dev, const void *name)
-{
- return !strcmp((const char *)name, dev_name(dev));
-}
-
static void *typec_port_match(struct device_connection *con, int ep, void *data)
{
struct device *dev;
@@ -224,11 +214,9 @@ static void *typec_port_match(struct device_connection *con, int ep, void *data)
* we need to return ERR_PTR(-PROBE_DEFER) when there is no device.
*/
if (con->fwnode)
- return class_find_device(typec_class, NULL, con->fwnode,
- typec_port_fwnode_match);
+ return class_find_device_by_fwnode(typec_class, con->fwnode);
- dev = class_find_device(typec_class, NULL, con->endpoint[ep],
- typec_port_name_match);
+ dev = class_find_device_by_name(typec_class, con->endpoint[ep]);
return dev ? dev : ERR_PTR(-EPROBE_DEFER);
}
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 61b7bc58dd81..57907f26f681 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -215,7 +215,7 @@ static void *typec_mux_match(struct device_connection *con, int ep, void *data)
}
/* Alternate Mode muxes */
- nval = fwnode_property_read_u16_array(con->fwnode, "svid", NULL, 0);
+ nval = fwnode_property_count_u16(con->fwnode, "svid");
if (nval <= 0)
return NULL;
diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
index c524088246ee..ed8655c6af8c 100644
--- a/drivers/usb/typec/tcpm/fusb302.c
+++ b/drivers/usb/typec/tcpm/fusb302.c
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/usb.h>
#include <linux/usb/typec.h>
#include <linux/usb/tcpm.h>
#include <linux/usb/pd.h>
@@ -75,7 +76,6 @@ struct fusb302_chip {
struct i2c_client *i2c_client;
struct tcpm_port *tcpm_port;
struct tcpc_dev tcpc_dev;
- struct tcpc_config tcpc_config;
struct regulator *vbus;
@@ -207,23 +207,19 @@ static int fusb302_debug_show(struct seq_file *s, void *v)
}
DEFINE_SHOW_ATTRIBUTE(fusb302_debug);
-static struct dentry *rootdir;
-
static void fusb302_debugfs_init(struct fusb302_chip *chip)
{
- mutex_init(&chip->logbuffer_lock);
- if (!rootdir)
- rootdir = debugfs_create_dir("fusb302", NULL);
+ char name[NAME_MAX];
- chip->dentry = debugfs_create_file(dev_name(chip->dev),
- S_IFREG | 0444, rootdir,
+ mutex_init(&chip->logbuffer_lock);
+ snprintf(name, NAME_MAX, "fusb302-%s", dev_name(chip->dev));
+ chip->dentry = debugfs_create_file(name, S_IFREG | 0444, usb_debug_root,
chip, &fusb302_debug_fops);
}
static void fusb302_debugfs_exit(struct fusb302_chip *chip)
{
debugfs_remove(chip->dentry);
- debugfs_remove(rootdir);
}
#else
@@ -1110,23 +1106,6 @@ done:
mutex_unlock(&chip->lock);
}
-#define PDO_FIXED_FLAGS \
- (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM)
-
-static const u32 src_pdo[] = {
- PDO_FIXED(5000, 400, PDO_FIXED_FLAGS),
-};
-
-static const struct tcpc_config fusb302_tcpc_config = {
- .src_pdo = src_pdo,
- .nr_src_pdo = ARRAY_SIZE(src_pdo),
- .operating_snk_mw = 2500,
- .type = TYPEC_PORT_DRP,
- .data = TYPEC_PORT_DRD,
- .default_role = TYPEC_SINK,
- .alt_modes = NULL,
-};
-
static void init_tcpc_dev(struct tcpc_dev *fusb302_tcpc_dev)
{
fusb302_tcpc_dev->init = tcpm_init;
@@ -1670,27 +1649,36 @@ 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;
+#define PDO_FIXED_FLAGS \
+ (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM)
- chip->snk_pdo[0] = PDO_FIXED(5000, 400, PDO_FIXED_FLAGS);
+static const u32 src_pdo[] = {
+ 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;
+static const u32 snk_pdo[] = {
+ PDO_FIXED(5000, 400, PDO_FIXED_FLAGS)
+};
+
+static const struct property_entry port_props[] = {
+ PROPERTY_ENTRY_STRING("data-role", "dual"),
+ PROPERTY_ENTRY_STRING("power-role", "dual"),
+ PROPERTY_ENTRY_STRING("try-power-role", "sink"),
+ PROPERTY_ENTRY_U32_ARRAY("source-pdos", src_pdo),
+ PROPERTY_ENTRY_U32_ARRAY("sink-pdos", snk_pdo),
+ PROPERTY_ENTRY_U32("op-sink-microwatt", 2500),
+ { }
+};
- chip->snk_pdo[1] = PDO_VAR(5000, max_uv / 1000, max_ua / 1000);
- return 2;
+static struct fwnode_handle *fusb302_fwnode_get(struct device *dev)
+{
+ struct fwnode_handle *fwnode;
+
+ fwnode = device_get_named_child_node(dev, "connector");
+ if (!fwnode)
+ fwnode = fwnode_create_software_node(port_props, NULL);
+
+ return fwnode;
}
static int fusb302_probe(struct i2c_client *client,
@@ -1701,7 +1689,6 @@ static int fusb302_probe(struct i2c_client *client,
struct device *dev = &client->dev;
const char *name;
int ret = 0;
- u32 v;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
dev_err(&client->dev,
@@ -1714,20 +1701,8 @@ static int fusb302_probe(struct i2c_client *client,
chip->i2c_client = client;
chip->dev = &client->dev;
- chip->tcpc_config = fusb302_tcpc_config;
- chip->tcpc_dev.config = &chip->tcpc_config;
mutex_init(&chip->lock);
- chip->tcpc_dev.fwnode =
- device_get_named_child_node(dev, "connector");
-
- 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.
@@ -1753,6 +1728,7 @@ static int fusb302_probe(struct i2c_client *client,
INIT_WORK(&chip->irq_work, fusb302_irq_work);
INIT_DELAYED_WORK(&chip->bc_lvl_handler, fusb302_bc_lvl_handler_work);
init_tcpc_dev(&chip->tcpc_dev);
+ fusb302_debugfs_init(chip);
if (client->irq) {
chip->gpio_int_n_irq = client->irq;
@@ -1762,8 +1738,15 @@ static int fusb302_probe(struct i2c_client *client,
goto destroy_workqueue;
}
+ chip->tcpc_dev.fwnode = fusb302_fwnode_get(dev);
+ if (IS_ERR(chip->tcpc_dev.fwnode)) {
+ ret = PTR_ERR(chip->tcpc_dev.fwnode);
+ goto destroy_workqueue;
+ }
+
chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev);
if (IS_ERR(chip->tcpm_port)) {
+ fwnode_handle_put(chip->tcpc_dev.fwnode);
ret = PTR_ERR(chip->tcpm_port);
if (ret != -EPROBE_DEFER)
dev_err(dev, "cannot register tcpm port, ret=%d", ret);
@@ -1778,14 +1761,15 @@ static int fusb302_probe(struct i2c_client *client,
goto tcpm_unregister_port;
}
enable_irq_wake(chip->gpio_int_n_irq);
- fusb302_debugfs_init(chip);
i2c_set_clientdata(client, chip);
return ret;
tcpm_unregister_port:
tcpm_unregister_port(chip->tcpm_port);
+ fwnode_handle_put(chip->tcpc_dev.fwnode);
destroy_workqueue:
+ fusb302_debugfs_exit(chip);
destroy_workqueue(chip->wq);
return ret;
@@ -1800,6 +1784,7 @@ static int fusb302_remove(struct i2c_client *client)
cancel_work_sync(&chip->irq_work);
cancel_delayed_work_sync(&chip->bc_lvl_handler);
tcpm_unregister_port(chip->tcpm_port);
+ fwnode_handle_put(chip->tcpc_dev.fwnode);
destroy_workqueue(chip->wq);
fusb302_debugfs_exit(chip);
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index bcfdb55fd198..96562744101c 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -19,6 +19,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/usb.h>
#include <linux/usb/pd.h>
#include <linux/usb/pd_ado.h>
#include <linux/usb/pd_bdo.h>
@@ -571,17 +572,13 @@ static int tcpm_debug_show(struct seq_file *s, void *v)
}
DEFINE_SHOW_ATTRIBUTE(tcpm_debug);
-static struct dentry *rootdir;
-
static void tcpm_debugfs_init(struct tcpm_port *port)
{
- mutex_init(&port->logbuffer_lock);
- /* /sys/kernel/debug/tcpm/usbcX */
- if (!rootdir)
- rootdir = debugfs_create_dir("tcpm", NULL);
+ char name[NAME_MAX];
- port->dentry = debugfs_create_file(dev_name(port->dev),
- S_IFREG | 0444, rootdir,
+ mutex_init(&port->logbuffer_lock);
+ snprintf(name, NAME_MAX, "tcpm-%s", dev_name(port->dev));
+ port->dentry = debugfs_create_file(name, S_IFREG | 0444, usb_debug_root,
port, &tcpm_debug_fops);
}
@@ -597,10 +594,6 @@ static void tcpm_debugfs_exit(struct tcpm_port *port)
mutex_unlock(&port->logbuffer_lock);
debugfs_remove(port->dentry);
- if (list_empty(&rootdir->d_subdirs)) {
- debugfs_remove(rootdir);
- rootdir = NULL;
- }
}
#else
@@ -4434,8 +4427,7 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
goto sink;
/* Get source pdos */
- ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
- NULL, 0);
+ ret = fwnode_property_count_u32(fwnode, "source-pdos");
if (ret <= 0)
return -EINVAL;
@@ -4459,8 +4451,7 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
return -EINVAL;
sink:
/* Get sink pdos */
- ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
- NULL, 0);
+ ret = fwnode_property_count_u32(fwnode, "sink-pdos");
if (ret <= 0)
return -EINVAL;
diff --git a/drivers/usb/typec/tcpm/wcove.c b/drivers/usb/typec/tcpm/wcove.c
index 6b317c150bdd..edc271da14f4 100644
--- a/drivers/usb/typec/tcpm/wcove.c
+++ b/drivers/usb/typec/tcpm/wcove.c
@@ -617,10 +617,8 @@ static int wcove_typec_probe(struct platform_device *pdev)
wcove->regmap = pmic->regmap;
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+ if (irq < 0)
return irq;
- }
irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq);
if (irq < 0)
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 8e9f8fba55af..907e20e1a71e 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -1104,14 +1104,11 @@ static ssize_t do_flash_store(struct device *dev,
static DEVICE_ATTR_WO(do_flash);
-static struct attribute *ucsi_ccg_sysfs_attrs[] = {
+static struct attribute *ucsi_ccg_attrs[] = {
&dev_attr_do_flash.attr,
NULL,
};
-
-static struct attribute_group ucsi_ccg_attr_group = {
- .attrs = ucsi_ccg_sysfs_attrs,
-};
+ATTRIBUTE_GROUPS(ucsi_ccg);
static int ucsi_ccg_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -1189,10 +1186,6 @@ static int ucsi_ccg_probe(struct i2c_client *client,
i2c_set_clientdata(client, uc);
- status = sysfs_create_group(&uc->dev->kobj, &ucsi_ccg_attr_group);
- if (status)
- dev_err(uc->dev, "cannot create sysfs group: %d\n", status);
-
pm_runtime_set_active(uc->dev);
pm_runtime_enable(uc->dev);
pm_runtime_idle(uc->dev);
@@ -1209,7 +1202,6 @@ static int ucsi_ccg_remove(struct i2c_client *client)
ucsi_unregister_ppm(uc->ucsi);
pm_runtime_disable(uc->dev);
free_irq(uc->irq, uc);
- sysfs_remove_group(&uc->dev->kobj, &ucsi_ccg_attr_group);
return 0;
}
@@ -1270,6 +1262,7 @@ static struct i2c_driver ucsi_ccg_driver = {
.driver = {
.name = "ucsi_ccg",
.pm = &ucsi_ccg_pm,
+ .dev_groups = ucsi_ccg_groups,
},
.probe = ucsi_ccg_probe,
.remove = ucsi_ccg_remove,