diff mbox series

[v2,2/3] extcon: usbc-tusb320: Add support for TUSB320L

Message ID W4cbBtSKsvNY8PoUe5j75MtKCqkxYop7f0WBuSsjnM@cp4-web-038.plabs.ch
State New
Headers show
Series None | expand

Commit Message

Yassine Oudjana July 27, 2021, 9:56 a.m. UTC
TUSB320L is a newer chip with additional features, and it has additional steps
in its mode changing sequence:
 - Disable CC state machine,
 - Write to mode register,
 - Wait for 5 ms,
 - Re-enable CC state machine.
It also has an additional register that a revision number can be read from.

Add support for the mode changing sequence, and read the revision number during
probe and print it as info.

Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
---
 drivers/extcon/extcon-usbc-tusb320.c | 61 +++++++++++++++++++++++++---
 1 file changed, 56 insertions(+), 5 deletions(-)

Comments

kernel test robot July 27, 2021, 2:16 p.m. UTC | #1
Hi Yassine,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on chanwoo-extcon/extcon-next]
[also build test WARNING on v5.14-rc3 next-20210726]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yassine-Oudjana/extcon-usbc-tusb320-Initial-TUSB320L-support/20210727-175921
base:   https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git extcon-next
config: riscv-randconfig-r035-20210727 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project c658b472f3e61e1818e1909bf02f3d65470018a5)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/db60f91ecc2dfa9cc22c6c6c5bfa89665b48cd2d
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yassine-Oudjana/extcon-usbc-tusb320-Initial-TUSB320L-support/20210727-175921
        git checkout db60f91ecc2dfa9cc22c6c6c5bfa89665b48cd2d
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/extcon/extcon-usbc-tusb320.c:244:15: warning: cast to smaller integer type 'enum tusb320_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
           priv->type = (enum tusb320_type)match_data;
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning generated.


vim +244 drivers/extcon/extcon-usbc-tusb320.c

   218	
   219	static int tusb320_extcon_probe(struct i2c_client *client,
   220					const struct i2c_device_id *id)
   221	{
   222		struct tusb320_priv *priv;
   223		const void *match_data;
   224		unsigned int revision;
   225		int ret;
   226	
   227		priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
   228		if (!priv)
   229			return -ENOMEM;
   230		priv->dev = &client->dev;
   231	
   232		priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config);
   233		if (IS_ERR(priv->regmap))
   234			return PTR_ERR(priv->regmap);
   235	
   236		ret = tusb320_check_signature(priv);
   237		if (ret)
   238			return ret;
   239	
   240		match_data = device_get_match_data(&client->dev);
   241		if (!match_data)
   242			return -EINVAL;
   243	
 > 244		priv->type = (enum tusb320_type)match_data;
   245	
   246		priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable);
   247		if (IS_ERR(priv->edev)) {
   248			dev_err(priv->dev, "failed to allocate extcon device\n");
   249			return PTR_ERR(priv->edev);
   250		}
   251	
   252		if(priv->type == TYPE_TUSB320L) {
   253			ret = regmap_read(priv->regmap, TUSB320L_REGA0_REVISION, &revision);
   254	
   255			if(ret)
   256				dev_warn(priv->dev,
   257					"failed to read revision register: %d\n", ret);
   258			else
   259				dev_info(priv->dev, "chip revision %d\n", revision);
   260		}
   261	
   262		ret = devm_extcon_dev_register(priv->dev, priv->edev);
   263		if (ret < 0) {
   264			dev_err(priv->dev, "failed to register extcon device\n");
   265			return ret;
   266		}
   267	
   268		/* Reset chip to its default state */
   269		ret = tusb320_reset(priv);
   270		if(ret)
   271			dev_warn(priv->dev, "failed to reset chip: %d\n", ret);
   272	
   273		extcon_set_property_capability(priv->edev, EXTCON_USB,
   274					       EXTCON_PROP_USB_TYPEC_POLARITY);
   275		extcon_set_property_capability(priv->edev, EXTCON_USB_HOST,
   276					       EXTCON_PROP_USB_TYPEC_POLARITY);
   277	
   278		/* update initial state */
   279		tusb320_irq_handler(client->irq, priv);
   280	
   281		ret = devm_request_threaded_irq(priv->dev, client->irq, NULL,
   282						tusb320_irq_handler,
   283						IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
   284						client->name, priv);
   285	
   286		return ret;
   287	}
   288	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
index c8d931abbf9f..994c661bb675 100644
--- a/drivers/extcon/extcon-usbc-tusb320.c
+++ b/drivers/extcon/extcon-usbc-tusb320.c
@@ -21,10 +21,13 @@ 
 #define TUSB320_REG9_INTERRUPT_STATUS		BIT(4)
 
 #define TUSB320_REGA				0xa
+#define TUSB320L_REGA_DISABLE_TERM		BIT(0)
 #define TUSB320_REGA_I2C_SOFT_RESET		BIT(3)
 #define TUSB320_REGA_MODE_SELECT_SHIFT		4
 #define TUSB320_REGA_MODE_SELECT_MASK		0x3
 
+#define TUSB320L_REGA0_REVISION			0xa0
+
 enum tusb320_attached_state {
 	TUSB320_ATTACHED_STATE_NONE,
 	TUSB320_ATTACHED_STATE_DFP,
@@ -39,9 +42,16 @@  enum tusb320_mode {
 	TUSB320_MODE_DRP,
 };
 
+enum tusb320_type {
+	TYPE_TUSB320,
+	TYPE_TUSB320L,
+};
+
+
 struct tusb320_priv {
 	struct device *dev;
 	struct regmap *regmap;
+	enum tusb320_type type;
 	struct extcon_dev *edev;
 
 	enum tusb320_attached_state state;
@@ -90,8 +100,19 @@  static int tusb320_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode)
 {
 	int ret;
 
-	/* Mode cannot be changed while cable is attached */
-	if(priv->state != TUSB320_ATTACHED_STATE_NONE)
+	if(priv->type == TYPE_TUSB320L) {
+		/* Disable CC state machine */
+		ret = regmap_write_bits(priv->regmap, TUSB320_REGA,
+			TUSB320L_REGA_DISABLE_TERM, 1);
+		if(ret) {
+			dev_err(priv->dev,
+				"failed to disable CC state machine: %d\n", ret);
+			return ret;
+		}
+	}
+
+	/* Mode cannot be changed on TUSB320 while cable is attached */
+	if(priv->type == TYPE_TUSB320 && priv->state != TUSB320_ATTACHED_STATE_NONE)
 		return -EBUSY;
 
 	/* Write mode */
@@ -100,10 +121,21 @@  static int tusb320_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode)
 		mode << TUSB320_REGA_MODE_SELECT_SHIFT);
 	if(ret) {
 		dev_err(priv->dev, "failed to write mode: %d\n", ret);
-		return ret;
+		goto err;
 	}
 
-	return 0;
+	msleep(5);
+err:
+	if(priv->type == TYPE_TUSB320L) {
+		/* Re-enable CC state machine */
+		ret = regmap_write_bits(priv->regmap, TUSB320_REGA,
+			TUSB320L_REGA_DISABLE_TERM, 0);
+		if(ret)
+			dev_err(priv->dev,
+				"failed to re-enable CC state machine: %d\n", ret);
+	}
+
+	return ret;
 }
 
 static int tusb320_reset(struct tusb320_priv *priv)
@@ -188,6 +220,8 @@  static int tusb320_extcon_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
 	struct tusb320_priv *priv;
+	const void *match_data;
+	unsigned int revision;
 	int ret;
 
 	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
@@ -203,12 +237,28 @@  static int tusb320_extcon_probe(struct i2c_client *client,
 	if (ret)
 		return ret;
 
+	match_data = device_get_match_data(&client->dev);
+	if (!match_data)
+		return -EINVAL;
+
+	priv->type = (enum tusb320_type)match_data;
+
 	priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable);
 	if (IS_ERR(priv->edev)) {
 		dev_err(priv->dev, "failed to allocate extcon device\n");
 		return PTR_ERR(priv->edev);
 	}
 
+	if(priv->type == TYPE_TUSB320L) {
+		ret = regmap_read(priv->regmap, TUSB320L_REGA0_REVISION, &revision);
+
+		if(ret)
+			dev_warn(priv->dev,
+				"failed to read revision register: %d\n", ret);
+		else
+			dev_info(priv->dev, "chip revision %d\n", revision);
+	}
+
 	ret = devm_extcon_dev_register(priv->dev, priv->edev);
 	if (ret < 0) {
 		dev_err(priv->dev, "failed to register extcon device\n");
@@ -237,7 +287,8 @@  static int tusb320_extcon_probe(struct i2c_client *client,
 }
 
 static const struct of_device_id tusb320_extcon_dt_match[] = {
-	{ .compatible = "ti,tusb320", },
+	{ .compatible = "ti,tusb320", .data = (void *)TYPE_TUSB320, },
+	{ .compatible = "ti,tusb320l", .data = (void *)TYPE_TUSB320L, },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);