0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/i2c.h>
0010 #include <linux/usb/role.h>
0011 #include <linux/irqreturn.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/regmap.h>
0014 #include <linux/slab.h>
0015 #include <linux/usb/typec.h>
0016 #include <linux/delay.h>
0017
0018 #define HD3SS3220_REG_CN_STAT_CTRL 0x09
0019 #define HD3SS3220_REG_GEN_CTRL 0x0A
0020 #define HD3SS3220_REG_DEV_REV 0xA0
0021
0022
0023 #define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6))
0024 #define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6)
0025 #define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7)
0026 #define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | BIT(6))
0027 #define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4)
0028
0029
0030 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1))
0031 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00
0032 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1)
0033 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1))
0034
0035 struct hd3ss3220 {
0036 struct device *dev;
0037 struct regmap *regmap;
0038 struct usb_role_switch *role_sw;
0039 struct typec_port *port;
0040 };
0041
0042 static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int src_pref)
0043 {
0044 return regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
0045 HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK,
0046 src_pref);
0047 }
0048
0049 static enum usb_role hd3ss3220_get_attached_state(struct hd3ss3220 *hd3ss3220)
0050 {
0051 unsigned int reg_val;
0052 enum usb_role attached_state;
0053 int ret;
0054
0055 ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL,
0056 ®_val);
0057 if (ret < 0)
0058 return ret;
0059
0060 switch (reg_val & HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK) {
0061 case HD3SS3220_REG_CN_STAT_CTRL_AS_DFP:
0062 attached_state = USB_ROLE_HOST;
0063 break;
0064 case HD3SS3220_REG_CN_STAT_CTRL_AS_UFP:
0065 attached_state = USB_ROLE_DEVICE;
0066 break;
0067 default:
0068 attached_state = USB_ROLE_NONE;
0069 break;
0070 }
0071
0072 return attached_state;
0073 }
0074
0075 static int hd3ss3220_dr_set(struct typec_port *port, enum typec_data_role role)
0076 {
0077 struct hd3ss3220 *hd3ss3220 = typec_get_drvdata(port);
0078 enum usb_role role_val;
0079 int pref, ret = 0;
0080
0081 if (role == TYPEC_HOST) {
0082 role_val = USB_ROLE_HOST;
0083 pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC;
0084 } else {
0085 role_val = USB_ROLE_DEVICE;
0086 pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK;
0087 }
0088
0089 ret = hd3ss3220_set_source_pref(hd3ss3220, pref);
0090 usleep_range(10, 100);
0091
0092 usb_role_switch_set_role(hd3ss3220->role_sw, role_val);
0093 typec_set_data_role(hd3ss3220->port, role);
0094
0095 return ret;
0096 }
0097
0098 static const struct typec_operations hd3ss3220_ops = {
0099 .dr_set = hd3ss3220_dr_set
0100 };
0101
0102 static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220)
0103 {
0104 enum usb_role role_state = hd3ss3220_get_attached_state(hd3ss3220);
0105
0106 usb_role_switch_set_role(hd3ss3220->role_sw, role_state);
0107 if (role_state == USB_ROLE_NONE)
0108 hd3ss3220_set_source_pref(hd3ss3220,
0109 HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT);
0110
0111 switch (role_state) {
0112 case USB_ROLE_HOST:
0113 typec_set_data_role(hd3ss3220->port, TYPEC_HOST);
0114 break;
0115 case USB_ROLE_DEVICE:
0116 typec_set_data_role(hd3ss3220->port, TYPEC_DEVICE);
0117 break;
0118 default:
0119 break;
0120 }
0121 }
0122
0123 static irqreturn_t hd3ss3220_irq(struct hd3ss3220 *hd3ss3220)
0124 {
0125 int err;
0126
0127 hd3ss3220_set_role(hd3ss3220);
0128 err = regmap_write_bits(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL,
0129 HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS,
0130 HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
0131 if (err < 0)
0132 return IRQ_NONE;
0133
0134 return IRQ_HANDLED;
0135 }
0136
0137 static irqreturn_t hd3ss3220_irq_handler(int irq, void *data)
0138 {
0139 struct i2c_client *client = to_i2c_client(data);
0140 struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client);
0141
0142 return hd3ss3220_irq(hd3ss3220);
0143 }
0144
0145 static const struct regmap_config config = {
0146 .reg_bits = 8,
0147 .val_bits = 8,
0148 .max_register = 0x0A,
0149 };
0150
0151 static int hd3ss3220_probe(struct i2c_client *client,
0152 const struct i2c_device_id *id)
0153 {
0154 struct typec_capability typec_cap = { };
0155 struct hd3ss3220 *hd3ss3220;
0156 struct fwnode_handle *connector, *ep;
0157 int ret;
0158 unsigned int data;
0159
0160 hd3ss3220 = devm_kzalloc(&client->dev, sizeof(struct hd3ss3220),
0161 GFP_KERNEL);
0162 if (!hd3ss3220)
0163 return -ENOMEM;
0164
0165 i2c_set_clientdata(client, hd3ss3220);
0166
0167 hd3ss3220->dev = &client->dev;
0168 hd3ss3220->regmap = devm_regmap_init_i2c(client, &config);
0169 if (IS_ERR(hd3ss3220->regmap))
0170 return PTR_ERR(hd3ss3220->regmap);
0171
0172 hd3ss3220_set_source_pref(hd3ss3220,
0173 HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT);
0174
0175 connector = device_get_named_child_node(hd3ss3220->dev, "connector");
0176 if (connector) {
0177 hd3ss3220->role_sw = fwnode_usb_role_switch_get(connector);
0178 } else {
0179 ep = fwnode_graph_get_next_endpoint(dev_fwnode(hd3ss3220->dev), NULL);
0180 if (!ep)
0181 return -ENODEV;
0182 connector = fwnode_graph_get_remote_port_parent(ep);
0183 fwnode_handle_put(ep);
0184 if (!connector)
0185 return -ENODEV;
0186 hd3ss3220->role_sw = usb_role_switch_get(hd3ss3220->dev);
0187 }
0188
0189 if (IS_ERR(hd3ss3220->role_sw)) {
0190 ret = PTR_ERR(hd3ss3220->role_sw);
0191 goto err_put_fwnode;
0192 }
0193
0194 typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
0195 typec_cap.driver_data = hd3ss3220;
0196 typec_cap.type = TYPEC_PORT_DRP;
0197 typec_cap.data = TYPEC_PORT_DRD;
0198 typec_cap.ops = &hd3ss3220_ops;
0199 typec_cap.fwnode = connector;
0200
0201 hd3ss3220->port = typec_register_port(&client->dev, &typec_cap);
0202 if (IS_ERR(hd3ss3220->port)) {
0203 ret = PTR_ERR(hd3ss3220->port);
0204 goto err_put_role;
0205 }
0206
0207 hd3ss3220_set_role(hd3ss3220);
0208 ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, &data);
0209 if (ret < 0)
0210 goto err_unreg_port;
0211
0212 if (data & HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS) {
0213 ret = regmap_write(hd3ss3220->regmap,
0214 HD3SS3220_REG_CN_STAT_CTRL,
0215 data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
0216 if (ret < 0)
0217 goto err_unreg_port;
0218 }
0219
0220 if (client->irq > 0) {
0221 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
0222 hd3ss3220_irq_handler,
0223 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0224 "hd3ss3220", &client->dev);
0225 if (ret)
0226 goto err_unreg_port;
0227 }
0228
0229 ret = i2c_smbus_read_byte_data(client, HD3SS3220_REG_DEV_REV);
0230 if (ret < 0)
0231 goto err_unreg_port;
0232
0233 fwnode_handle_put(connector);
0234
0235 dev_info(&client->dev, "probed revision=0x%x\n", ret);
0236
0237 return 0;
0238 err_unreg_port:
0239 typec_unregister_port(hd3ss3220->port);
0240 err_put_role:
0241 usb_role_switch_put(hd3ss3220->role_sw);
0242 err_put_fwnode:
0243 fwnode_handle_put(connector);
0244
0245 return ret;
0246 }
0247
0248 static int hd3ss3220_remove(struct i2c_client *client)
0249 {
0250 struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client);
0251
0252 typec_unregister_port(hd3ss3220->port);
0253 usb_role_switch_put(hd3ss3220->role_sw);
0254
0255 return 0;
0256 }
0257
0258 static const struct of_device_id dev_ids[] = {
0259 { .compatible = "ti,hd3ss3220"},
0260 {}
0261 };
0262 MODULE_DEVICE_TABLE(of, dev_ids);
0263
0264 static struct i2c_driver hd3ss3220_driver = {
0265 .driver = {
0266 .name = "hd3ss3220",
0267 .of_match_table = of_match_ptr(dev_ids),
0268 },
0269 .probe = hd3ss3220_probe,
0270 .remove = hd3ss3220_remove,
0271 };
0272
0273 module_i2c_driver(hd3ss3220_driver);
0274
0275 MODULE_AUTHOR("Biju Das <biju.das@bp.renesas.com>");
0276 MODULE_DESCRIPTION("TI HD3SS3220 DRP Port Controller Driver");
0277 MODULE_LICENSE("GPL");