0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/i2c.h>
0009 #include <linux/module.h>
0010 #include <linux/regmap.h>
0011 #include <linux/regulator/consumer.h>
0012 #include <linux/usb/typec.h>
0013
0014 #define WUSB3801_REG_DEVICE_ID 0x01
0015 #define WUSB3801_REG_CTRL0 0x02
0016 #define WUSB3801_REG_INT 0x03
0017 #define WUSB3801_REG_STAT 0x04
0018 #define WUSB3801_REG_CTRL1 0x05
0019 #define WUSB3801_REG_TEST00 0x06
0020 #define WUSB3801_REG_TEST01 0x07
0021 #define WUSB3801_REG_TEST02 0x08
0022 #define WUSB3801_REG_TEST03 0x09
0023 #define WUSB3801_REG_TEST04 0x0a
0024 #define WUSB3801_REG_TEST05 0x0b
0025 #define WUSB3801_REG_TEST06 0x0c
0026 #define WUSB3801_REG_TEST07 0x0d
0027 #define WUSB3801_REG_TEST08 0x0e
0028 #define WUSB3801_REG_TEST09 0x0f
0029 #define WUSB3801_REG_TEST0A 0x10
0030 #define WUSB3801_REG_TEST0B 0x11
0031 #define WUSB3801_REG_TEST0C 0x12
0032 #define WUSB3801_REG_TEST0D 0x13
0033 #define WUSB3801_REG_TEST0E 0x14
0034 #define WUSB3801_REG_TEST0F 0x15
0035 #define WUSB3801_REG_TEST10 0x16
0036 #define WUSB3801_REG_TEST11 0x17
0037 #define WUSB3801_REG_TEST12 0x18
0038
0039 #define WUSB3801_DEVICE_ID_VERSION_ID GENMASK(7, 3)
0040 #define WUSB3801_DEVICE_ID_VENDOR_ID GENMASK(2, 0)
0041
0042 #define WUSB3801_CTRL0_DIS_ACC_SUPPORT BIT(7)
0043 #define WUSB3801_CTRL0_TRY GENMASK(6, 5)
0044 #define WUSB3801_CTRL0_TRY_NONE (0x0 << 5)
0045 #define WUSB3801_CTRL0_TRY_SNK (0x1 << 5)
0046 #define WUSB3801_CTRL0_TRY_SRC (0x2 << 5)
0047 #define WUSB3801_CTRL0_CURRENT GENMASK(4, 3)
0048 #define WUSB3801_CTRL0_CURRENT_DEFAULT (0x0 << 3)
0049 #define WUSB3801_CTRL0_CURRENT_1_5A (0x1 << 3)
0050 #define WUSB3801_CTRL0_CURRENT_3_0A (0x2 << 3)
0051 #define WUSB3801_CTRL0_ROLE GENMASK(2, 1)
0052 #define WUSB3801_CTRL0_ROLE_SNK (0x0 << 1)
0053 #define WUSB3801_CTRL0_ROLE_SRC (0x1 << 1)
0054 #define WUSB3801_CTRL0_ROLE_DRP (0x2 << 1)
0055 #define WUSB3801_CTRL0_INT_MASK BIT(0)
0056
0057 #define WUSB3801_INT_ATTACHED BIT(0)
0058 #define WUSB3801_INT_DETACHED BIT(1)
0059
0060 #define WUSB3801_STAT_VBUS_DETECTED BIT(7)
0061 #define WUSB3801_STAT_CURRENT GENMASK(6, 5)
0062 #define WUSB3801_STAT_CURRENT_STANDBY (0x0 << 5)
0063 #define WUSB3801_STAT_CURRENT_DEFAULT (0x1 << 5)
0064 #define WUSB3801_STAT_CURRENT_1_5A (0x2 << 5)
0065 #define WUSB3801_STAT_CURRENT_3_0A (0x3 << 5)
0066 #define WUSB3801_STAT_PARTNER GENMASK(4, 2)
0067 #define WUSB3801_STAT_PARTNER_STANDBY (0x0 << 2)
0068 #define WUSB3801_STAT_PARTNER_SNK (0x1 << 2)
0069 #define WUSB3801_STAT_PARTNER_SRC (0x2 << 2)
0070 #define WUSB3801_STAT_PARTNER_AUDIO (0x3 << 2)
0071 #define WUSB3801_STAT_PARTNER_DEBUG (0x4 << 2)
0072 #define WUSB3801_STAT_ORIENTATION GENMASK(1, 0)
0073 #define WUSB3801_STAT_ORIENTATION_NONE (0x0 << 0)
0074 #define WUSB3801_STAT_ORIENTATION_CC1 (0x1 << 0)
0075 #define WUSB3801_STAT_ORIENTATION_CC2 (0x2 << 0)
0076 #define WUSB3801_STAT_ORIENTATION_BOTH (0x3 << 0)
0077
0078 #define WUSB3801_CTRL1_SM_RESET BIT(0)
0079
0080 #define WUSB3801_TEST01_VENDOR_SUB_ID (BIT(8) | BIT(6))
0081
0082 #define WUSB3801_TEST02_FORCE_ERR_RCY BIT(8)
0083
0084 #define WUSB3801_TEST0A_WAIT_VBUS BIT(5)
0085
0086 struct wusb3801 {
0087 struct typec_capability cap;
0088 struct device *dev;
0089 struct typec_partner *partner;
0090 struct typec_port *port;
0091 struct regmap *regmap;
0092 struct regulator *vbus_supply;
0093 unsigned int partner_type;
0094 enum typec_port_type port_type;
0095 enum typec_pwr_opmode pwr_opmode;
0096 bool vbus_on;
0097 };
0098
0099 static enum typec_role wusb3801_get_default_role(struct wusb3801 *wusb3801)
0100 {
0101 switch (wusb3801->port_type) {
0102 case TYPEC_PORT_SRC:
0103 return TYPEC_SOURCE;
0104 case TYPEC_PORT_SNK:
0105 return TYPEC_SINK;
0106 case TYPEC_PORT_DRP:
0107 default:
0108 if (wusb3801->cap.prefer_role == TYPEC_SOURCE)
0109 return TYPEC_SOURCE;
0110 return TYPEC_SINK;
0111 }
0112 }
0113
0114 static int wusb3801_map_port_type(enum typec_port_type type)
0115 {
0116 switch (type) {
0117 case TYPEC_PORT_SRC:
0118 return WUSB3801_CTRL0_ROLE_SRC;
0119 case TYPEC_PORT_SNK:
0120 return WUSB3801_CTRL0_ROLE_SNK;
0121 case TYPEC_PORT_DRP:
0122 default:
0123 return WUSB3801_CTRL0_ROLE_DRP;
0124 }
0125 }
0126
0127 static int wusb3801_map_pwr_opmode(enum typec_pwr_opmode mode)
0128 {
0129 switch (mode) {
0130 case TYPEC_PWR_MODE_USB:
0131 default:
0132 return WUSB3801_CTRL0_CURRENT_DEFAULT;
0133 case TYPEC_PWR_MODE_1_5A:
0134 return WUSB3801_CTRL0_CURRENT_1_5A;
0135 case TYPEC_PWR_MODE_3_0A:
0136 return WUSB3801_CTRL0_CURRENT_3_0A;
0137 }
0138 }
0139
0140 static unsigned int wusb3801_map_try_role(int role)
0141 {
0142 switch (role) {
0143 case TYPEC_NO_PREFERRED_ROLE:
0144 default:
0145 return WUSB3801_CTRL0_TRY_NONE;
0146 case TYPEC_SINK:
0147 return WUSB3801_CTRL0_TRY_SNK;
0148 case TYPEC_SOURCE:
0149 return WUSB3801_CTRL0_TRY_SRC;
0150 }
0151 }
0152
0153 static enum typec_orientation wusb3801_unmap_orientation(unsigned int status)
0154 {
0155 switch (status & WUSB3801_STAT_ORIENTATION) {
0156 case WUSB3801_STAT_ORIENTATION_NONE:
0157 case WUSB3801_STAT_ORIENTATION_BOTH:
0158 default:
0159 return TYPEC_ORIENTATION_NONE;
0160 case WUSB3801_STAT_ORIENTATION_CC1:
0161 return TYPEC_ORIENTATION_NORMAL;
0162 case WUSB3801_STAT_ORIENTATION_CC2:
0163 return TYPEC_ORIENTATION_REVERSE;
0164 }
0165 }
0166
0167 static enum typec_pwr_opmode wusb3801_unmap_pwr_opmode(unsigned int status)
0168 {
0169 switch (status & WUSB3801_STAT_CURRENT) {
0170 case WUSB3801_STAT_CURRENT_STANDBY:
0171 case WUSB3801_STAT_CURRENT_DEFAULT:
0172 default:
0173 return TYPEC_PWR_MODE_USB;
0174 case WUSB3801_STAT_CURRENT_1_5A:
0175 return TYPEC_PWR_MODE_1_5A;
0176 case WUSB3801_STAT_CURRENT_3_0A:
0177 return TYPEC_PWR_MODE_3_0A;
0178 }
0179 }
0180
0181 static int wusb3801_try_role(struct typec_port *port, int role)
0182 {
0183 struct wusb3801 *wusb3801 = typec_get_drvdata(port);
0184
0185 return regmap_update_bits(wusb3801->regmap, WUSB3801_REG_CTRL0,
0186 WUSB3801_CTRL0_TRY,
0187 wusb3801_map_try_role(role));
0188 }
0189
0190 static int wusb3801_port_type_set(struct typec_port *port,
0191 enum typec_port_type type)
0192 {
0193 struct wusb3801 *wusb3801 = typec_get_drvdata(port);
0194 int ret;
0195
0196 ret = regmap_update_bits(wusb3801->regmap, WUSB3801_REG_CTRL0,
0197 WUSB3801_CTRL0_ROLE,
0198 wusb3801_map_port_type(type));
0199 if (ret)
0200 return ret;
0201
0202 wusb3801->port_type = type;
0203
0204 return 0;
0205 }
0206
0207 static const struct typec_operations wusb3801_typec_ops = {
0208 .try_role = wusb3801_try_role,
0209 .port_type_set = wusb3801_port_type_set,
0210 };
0211
0212 static int wusb3801_hw_init(struct wusb3801 *wusb3801)
0213 {
0214 return regmap_write(wusb3801->regmap, WUSB3801_REG_CTRL0,
0215 wusb3801_map_try_role(wusb3801->cap.prefer_role) |
0216 wusb3801_map_pwr_opmode(wusb3801->pwr_opmode) |
0217 wusb3801_map_port_type(wusb3801->port_type));
0218 }
0219
0220 static void wusb3801_hw_update(struct wusb3801 *wusb3801)
0221 {
0222 struct typec_port *port = wusb3801->port;
0223 struct device *dev = wusb3801->dev;
0224 unsigned int partner_type, status;
0225 int ret;
0226
0227 ret = regmap_read(wusb3801->regmap, WUSB3801_REG_STAT, &status);
0228 if (ret) {
0229 dev_warn(dev, "Failed to read port status: %d\n", ret);
0230 status = 0;
0231 }
0232 dev_dbg(dev, "status = 0x%02x\n", status);
0233
0234 partner_type = status & WUSB3801_STAT_PARTNER;
0235
0236 if (partner_type == WUSB3801_STAT_PARTNER_SNK) {
0237 if (!wusb3801->vbus_on) {
0238 ret = regulator_enable(wusb3801->vbus_supply);
0239 if (ret)
0240 dev_warn(dev, "Failed to enable VBUS: %d\n", ret);
0241 wusb3801->vbus_on = true;
0242 }
0243 } else {
0244 if (wusb3801->vbus_on) {
0245 regulator_disable(wusb3801->vbus_supply);
0246 wusb3801->vbus_on = false;
0247 }
0248 }
0249
0250 if (partner_type != wusb3801->partner_type) {
0251 struct typec_partner_desc desc = {};
0252 enum typec_data_role data_role;
0253 enum typec_role pwr_role = wusb3801_get_default_role(wusb3801);
0254
0255 switch (partner_type) {
0256 case WUSB3801_STAT_PARTNER_STANDBY:
0257 break;
0258 case WUSB3801_STAT_PARTNER_SNK:
0259 pwr_role = TYPEC_SOURCE;
0260 break;
0261 case WUSB3801_STAT_PARTNER_SRC:
0262 pwr_role = TYPEC_SINK;
0263 break;
0264 case WUSB3801_STAT_PARTNER_AUDIO:
0265 desc.accessory = TYPEC_ACCESSORY_AUDIO;
0266 break;
0267 case WUSB3801_STAT_PARTNER_DEBUG:
0268 desc.accessory = TYPEC_ACCESSORY_DEBUG;
0269 break;
0270 }
0271
0272 if (wusb3801->partner) {
0273 typec_unregister_partner(wusb3801->partner);
0274 wusb3801->partner = NULL;
0275 }
0276
0277 if (partner_type != WUSB3801_STAT_PARTNER_STANDBY) {
0278 wusb3801->partner = typec_register_partner(port, &desc);
0279 if (IS_ERR(wusb3801->partner))
0280 dev_err(dev, "Failed to register partner: %ld\n",
0281 PTR_ERR(wusb3801->partner));
0282 }
0283
0284 data_role = pwr_role == TYPEC_SOURCE ? TYPEC_HOST : TYPEC_DEVICE;
0285 typec_set_data_role(port, data_role);
0286 typec_set_pwr_role(port, pwr_role);
0287 typec_set_vconn_role(port, pwr_role);
0288 }
0289
0290 typec_set_pwr_opmode(wusb3801->port,
0291 partner_type == WUSB3801_STAT_PARTNER_SRC
0292 ? wusb3801_unmap_pwr_opmode(status)
0293 : wusb3801->pwr_opmode);
0294 typec_set_orientation(wusb3801->port,
0295 wusb3801_unmap_orientation(status));
0296
0297 wusb3801->partner_type = partner_type;
0298 }
0299
0300 static irqreturn_t wusb3801_irq(int irq, void *data)
0301 {
0302 struct wusb3801 *wusb3801 = data;
0303 unsigned int dummy;
0304
0305
0306
0307
0308
0309 regmap_read(wusb3801->regmap, WUSB3801_REG_INT, &dummy);
0310
0311 wusb3801_hw_update(wusb3801);
0312
0313 return IRQ_HANDLED;
0314 }
0315
0316 static const struct regmap_config config = {
0317 .reg_bits = 8,
0318 .val_bits = 8,
0319 .max_register = WUSB3801_REG_TEST12,
0320 };
0321
0322 static int wusb3801_probe(struct i2c_client *client)
0323 {
0324 struct device *dev = &client->dev;
0325 struct fwnode_handle *connector;
0326 struct wusb3801 *wusb3801;
0327 const char *cap_str;
0328 int ret;
0329
0330 wusb3801 = devm_kzalloc(dev, sizeof(*wusb3801), GFP_KERNEL);
0331 if (!wusb3801)
0332 return -ENOMEM;
0333
0334 i2c_set_clientdata(client, wusb3801);
0335
0336 wusb3801->dev = dev;
0337
0338 wusb3801->regmap = devm_regmap_init_i2c(client, &config);
0339 if (IS_ERR(wusb3801->regmap))
0340 return PTR_ERR(wusb3801->regmap);
0341
0342 wusb3801->vbus_supply = devm_regulator_get(dev, "vbus");
0343 if (IS_ERR(wusb3801->vbus_supply))
0344 return PTR_ERR(wusb3801->vbus_supply);
0345
0346 connector = device_get_named_child_node(dev, "connector");
0347 if (!connector)
0348 return -ENODEV;
0349
0350 ret = typec_get_fw_cap(&wusb3801->cap, connector);
0351 if (ret)
0352 goto err_put_connector;
0353 wusb3801->port_type = wusb3801->cap.type;
0354
0355 ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
0356 if (ret)
0357 goto err_put_connector;
0358
0359 ret = typec_find_pwr_opmode(cap_str);
0360 if (ret < 0 || ret == TYPEC_PWR_MODE_PD)
0361 goto err_put_connector;
0362 wusb3801->pwr_opmode = ret;
0363
0364
0365 ret = wusb3801_hw_init(wusb3801);
0366 if (ret)
0367 return ret;
0368
0369 wusb3801->cap.revision = USB_TYPEC_REV_1_2;
0370 wusb3801->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO;
0371 wusb3801->cap.accessory[1] = TYPEC_ACCESSORY_DEBUG;
0372 wusb3801->cap.orientation_aware = true;
0373 wusb3801->cap.driver_data = wusb3801;
0374 wusb3801->cap.ops = &wusb3801_typec_ops;
0375
0376 wusb3801->port = typec_register_port(dev, &wusb3801->cap);
0377 if (IS_ERR(wusb3801->port)) {
0378 ret = PTR_ERR(wusb3801->port);
0379 goto err_put_connector;
0380 }
0381
0382
0383 wusb3801_hw_update(wusb3801);
0384
0385 ret = request_threaded_irq(client->irq, NULL, wusb3801_irq,
0386 IRQF_ONESHOT, dev_name(dev), wusb3801);
0387 if (ret)
0388 goto err_unregister_port;
0389
0390 fwnode_handle_put(connector);
0391
0392 return 0;
0393
0394 err_unregister_port:
0395 typec_unregister_port(wusb3801->port);
0396 err_put_connector:
0397 fwnode_handle_put(connector);
0398
0399 return ret;
0400 }
0401
0402 static int wusb3801_remove(struct i2c_client *client)
0403 {
0404 struct wusb3801 *wusb3801 = i2c_get_clientdata(client);
0405
0406 free_irq(client->irq, wusb3801);
0407
0408 if (wusb3801->partner)
0409 typec_unregister_partner(wusb3801->partner);
0410 typec_unregister_port(wusb3801->port);
0411
0412 if (wusb3801->vbus_on)
0413 regulator_disable(wusb3801->vbus_supply);
0414
0415 return 0;
0416 }
0417
0418 static const struct of_device_id wusb3801_of_match[] = {
0419 { .compatible = "willsemi,wusb3801" },
0420 {}
0421 };
0422 MODULE_DEVICE_TABLE(of, wusb3801_of_match);
0423
0424 static struct i2c_driver wusb3801_driver = {
0425 .probe_new = wusb3801_probe,
0426 .remove = wusb3801_remove,
0427 .driver = {
0428 .name = "wusb3801",
0429 .of_match_table = wusb3801_of_match,
0430 },
0431 };
0432
0433 module_i2c_driver(wusb3801_driver);
0434
0435 MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
0436 MODULE_DESCRIPTION("Willsemi WUSB3801 Type-C port controller driver");
0437 MODULE_LICENSE("GPL");