1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * NXP PTN36502 Type-C driver 4 * 5 * Copyright (C) 2023 Luca Weiss <luca.weiss@fairphone.com> 6 * 7 * Based on NB7VPQ904M driver: 8 * Copyright (C) 2023 Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 9 */ 10 11 #include <drm/bridge/aux-bridge.h> 12 #include <linux/bitfield.h> 13 #include <linux/i2c.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/mutex.h> 17 #include <linux/of_graph.h> 18 #include <linux/regmap.h> 19 #include <linux/regulator/consumer.h> 20 #include <linux/usb/typec_dp.h> 21 #include <linux/usb/typec_mux.h> 22 #include <linux/usb/typec_retimer.h> 23 24 #define PTN36502_CHIP_ID_REG 0x00 25 #define PTN36502_CHIP_ID 0x02 26 27 #define PTN36502_CHIP_REVISION_REG 0x01 28 #define PTN36502_CHIP_REVISION_BASE_MASK GENMASK(7, 4) 29 #define PTN36502_CHIP_REVISION_METAL_MASK GENMASK(3, 0) 30 31 #define PTN36502_DP_LINK_CTRL_REG 0x06 32 #define PTN36502_DP_LINK_CTRL_LANES_MASK GENMASK(3, 2) 33 #define PTN36502_DP_LINK_CTRL_LANES_2 (2) 34 #define PTN36502_DP_LINK_CTRL_LANES_4 (3) 35 #define PTN36502_DP_LINK_CTRL_LINK_RATE_MASK GENMASK(1, 0) 36 #define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS (2) 37 38 /* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */ 39 #define PTN36502_DP_LANE_CTRL_REG(n) (0x07 + (n)) 40 #define PTN36502_DP_LANE_CTRL_RX_GAIN_MASK GENMASK(6, 4) 41 #define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB (2) 42 #define PTN36502_DP_LANE_CTRL_TX_SWING_MASK GENMASK(3, 2) 43 #define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD (2) 44 #define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_MASK GENMASK(1, 0) 45 #define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB (1) 46 47 #define PTN36502_MODE_CTRL1_REG 0x0b 48 #define PTN36502_MODE_CTRL1_PLUG_ORIENT_MASK GENMASK(5, 5) 49 #define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE (1) 50 #define PTN36502_MODE_CTRL1_AUX_CROSSBAR_MASK GENMASK(3, 3) 51 #define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON (1) 52 #define PTN36502_MODE_CTRL1_MODE_MASK GENMASK(2, 0) 53 #define PTN36502_MODE_CTRL1_MODE_OFF (0) 54 #define PTN36502_MODE_CTRL1_MODE_USB_ONLY (1) 55 #define PTN36502_MODE_CTRL1_MODE_USB_DP (2) 56 #define PTN36502_MODE_CTRL1_MODE_DP (3) 57 58 #define PTN36502_DEVICE_CTRL_REG 0x0d 59 #define PTN36502_DEVICE_CTRL_AUX_MONITORING_MASK GENMASK(7, 7) 60 #define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN (1) 61 62 struct ptn36502 { 63 struct i2c_client *client; 64 struct regulator *vdd18_supply; 65 struct regmap *regmap; 66 struct typec_switch_dev *sw; 67 struct typec_retimer *retimer; 68 69 struct typec_switch *typec_switch; 70 struct typec_mux *typec_mux; 71 72 struct mutex lock; /* protect non-concurrent retimer & switch */ 73 74 enum typec_orientation orientation; 75 unsigned long mode; 76 unsigned int svid; 77 }; 78 79 static int ptn36502_set(struct ptn36502 *ptn) 80 { 81 bool reverse = (ptn->orientation == TYPEC_ORIENTATION_REVERSE); 82 unsigned int ctrl1_val = 0; 83 unsigned int lane_ctrl_val = 0; 84 unsigned int link_ctrl_val = 0; 85 86 switch (ptn->mode) { 87 case TYPEC_STATE_SAFE: 88 /* Deep power saving state */ 89 regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG, 90 FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, 91 PTN36502_MODE_CTRL1_MODE_OFF)); 92 return 0; 93 94 case TYPEC_STATE_USB: 95 /* 96 * Normal Orientation (CC1) 97 * A -> USB RX 98 * B -> USB TX 99 * C -> X 100 * D -> X 101 * Flipped Orientation (CC2) 102 * A -> X 103 * B -> X 104 * C -> USB TX 105 * D -> USB RX 106 */ 107 108 /* USB 3.1 Gen 1 only */ 109 ctrl1_val = FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, 110 PTN36502_MODE_CTRL1_MODE_USB_ONLY); 111 if (reverse) 112 ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_PLUG_ORIENT_MASK, 113 PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE); 114 115 regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG, ctrl1_val); 116 return 0; 117 118 default: 119 if (ptn->svid != USB_TYPEC_DP_SID) 120 return -EINVAL; 121 122 break; 123 } 124 125 /* DP Altmode Setup */ 126 127 switch (ptn->mode) { 128 case TYPEC_DP_STATE_C: 129 case TYPEC_DP_STATE_E: 130 /* 131 * Normal Orientation (CC1) 132 * A -> DP3 133 * B -> DP2 134 * C -> DP1 135 * D -> DP0 136 * Flipped Orientation (CC2) 137 * A -> DP0 138 * B -> DP1 139 * C -> DP2 140 * D -> DP3 141 */ 142 143 /* 4-lane DP */ 144 ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, 145 PTN36502_MODE_CTRL1_MODE_DP); 146 link_ctrl_val |= FIELD_PREP(PTN36502_DP_LINK_CTRL_LANES_MASK, 147 PTN36502_DP_LINK_CTRL_LANES_4); 148 break; 149 150 case TYPEC_DP_STATE_D: 151 case TYPEC_DP_STATE_F: /* State F is deprecated */ 152 /* 153 * Normal Orientation (CC1) 154 * A -> USB RX 155 * B -> USB TX 156 * C -> DP1 157 * D -> DP0 158 * Flipped Orientation (CC2) 159 * A -> DP0 160 * B -> DP1 161 * C -> USB TX 162 * D -> USB RX 163 */ 164 165 /* USB 3.1 Gen 1 and 2-lane DP */ 166 ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, 167 PTN36502_MODE_CTRL1_MODE_USB_DP); 168 link_ctrl_val |= FIELD_PREP(PTN36502_DP_LINK_CTRL_LANES_MASK, 169 PTN36502_DP_LINK_CTRL_LANES_2); 170 break; 171 172 default: 173 return -EOPNOTSUPP; 174 } 175 176 /* Enable AUX monitoring */ 177 regmap_write(ptn->regmap, PTN36502_DEVICE_CTRL_REG, 178 FIELD_PREP(PTN36502_DEVICE_CTRL_AUX_MONITORING_MASK, 179 PTN36502_DEVICE_CTRL_AUX_MONITORING_EN)); 180 181 /* Enable AUX switch path */ 182 ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_AUX_CROSSBAR_MASK, 183 PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON); 184 if (reverse) 185 ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_PLUG_ORIENT_MASK, 186 PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE); 187 regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG, ctrl1_val); 188 189 /* DP Link rate: 5.4 Gbps (HBR2) */ 190 link_ctrl_val |= FIELD_PREP(PTN36502_DP_LINK_CTRL_LINK_RATE_MASK, 191 PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS); 192 regmap_write(ptn->regmap, PTN36502_DP_LINK_CTRL_REG, link_ctrl_val); 193 194 /* 195 * For all lanes: 196 * - Rx equivalization gain: 3 dB 197 * - TX output swing control: 800 mVppd 198 * - Pre-emphasis control: 3.5 dB 199 */ 200 lane_ctrl_val = FIELD_PREP(PTN36502_DP_LANE_CTRL_RX_GAIN_MASK, 201 PTN36502_DP_LANE_CTRL_RX_GAIN_3DB) | 202 FIELD_PREP(PTN36502_DP_LANE_CTRL_TX_SWING_MASK, 203 PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD) | 204 FIELD_PREP(PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_MASK, 205 PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB); 206 regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(0), lane_ctrl_val); 207 regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(1), lane_ctrl_val); 208 regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(2), lane_ctrl_val); 209 regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(3), lane_ctrl_val); 210 211 return 0; 212 } 213 214 static int ptn36502_sw_set(struct typec_switch_dev *sw, enum typec_orientation orientation) 215 { 216 struct ptn36502 *ptn = typec_switch_get_drvdata(sw); 217 int ret; 218 219 ret = typec_switch_set(ptn->typec_switch, orientation); 220 if (ret) 221 return ret; 222 223 mutex_lock(&ptn->lock); 224 225 if (ptn->orientation != orientation) { 226 ptn->orientation = orientation; 227 228 ret = ptn36502_set(ptn); 229 } 230 231 mutex_unlock(&ptn->lock); 232 233 return ret; 234 } 235 236 static int ptn36502_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state) 237 { 238 struct ptn36502 *ptn = typec_retimer_get_drvdata(retimer); 239 struct typec_mux_state mux_state; 240 int ret = 0; 241 242 mutex_lock(&ptn->lock); 243 244 if (ptn->mode != state->mode) { 245 ptn->mode = state->mode; 246 247 if (state->alt) 248 ptn->svid = state->alt->svid; 249 else 250 ptn->svid = 0; // No SVID 251 252 ret = ptn36502_set(ptn); 253 } 254 255 mutex_unlock(&ptn->lock); 256 257 if (ret) 258 return ret; 259 260 mux_state.alt = state->alt; 261 mux_state.data = state->data; 262 mux_state.mode = state->mode; 263 264 return typec_mux_set(ptn->typec_mux, &mux_state); 265 } 266 267 static int ptn36502_detect(struct ptn36502 *ptn) 268 { 269 struct device *dev = &ptn->client->dev; 270 unsigned int reg_val; 271 int ret; 272 273 ret = regmap_read(ptn->regmap, PTN36502_CHIP_ID_REG, 274 ®_val); 275 if (ret < 0) 276 return dev_err_probe(dev, ret, "Failed to read chip ID\n"); 277 278 if (reg_val != PTN36502_CHIP_ID) 279 return dev_err_probe(dev, -ENODEV, "Unexpected chip ID: %x\n", reg_val); 280 281 ret = regmap_read(ptn->regmap, PTN36502_CHIP_REVISION_REG, 282 ®_val); 283 if (ret < 0) 284 return dev_err_probe(dev, ret, "Failed to read chip revision\n"); 285 286 dev_dbg(dev, "Chip revision: base layer version %lx, metal layer version %lx\n", 287 FIELD_GET(PTN36502_CHIP_REVISION_BASE_MASK, reg_val), 288 FIELD_GET(PTN36502_CHIP_REVISION_METAL_MASK, reg_val)); 289 290 return 0; 291 } 292 293 static const struct regmap_config ptn36502_regmap = { 294 .max_register = 0x0d, 295 .reg_bits = 8, 296 .val_bits = 8, 297 }; 298 299 static int ptn36502_probe(struct i2c_client *client) 300 { 301 struct device *dev = &client->dev; 302 struct typec_switch_desc sw_desc = { }; 303 struct typec_retimer_desc retimer_desc = { }; 304 struct ptn36502 *ptn; 305 int ret; 306 307 ptn = devm_kzalloc(dev, sizeof(*ptn), GFP_KERNEL); 308 if (!ptn) 309 return -ENOMEM; 310 311 ptn->client = client; 312 313 ptn->regmap = devm_regmap_init_i2c(client, &ptn36502_regmap); 314 if (IS_ERR(ptn->regmap)) { 315 dev_err(&client->dev, "Failed to allocate register map\n"); 316 return PTR_ERR(ptn->regmap); 317 } 318 319 ptn->mode = TYPEC_STATE_SAFE; 320 ptn->orientation = TYPEC_ORIENTATION_NONE; 321 322 mutex_init(&ptn->lock); 323 324 ptn->vdd18_supply = devm_regulator_get_optional(dev, "vdd18"); 325 if (IS_ERR(ptn->vdd18_supply)) 326 return PTR_ERR(ptn->vdd18_supply); 327 328 ptn->typec_switch = fwnode_typec_switch_get(dev->fwnode); 329 if (IS_ERR(ptn->typec_switch)) 330 return dev_err_probe(dev, PTR_ERR(ptn->typec_switch), 331 "Failed to acquire orientation-switch\n"); 332 333 ptn->typec_mux = fwnode_typec_mux_get(dev->fwnode); 334 if (IS_ERR(ptn->typec_mux)) { 335 ret = dev_err_probe(dev, PTR_ERR(ptn->typec_mux), 336 "Failed to acquire mode-switch\n"); 337 goto err_switch_put; 338 } 339 340 ret = regulator_enable(ptn->vdd18_supply); 341 if (ret) { 342 ret = dev_err_probe(dev, ret, "Failed to enable vdd18\n"); 343 goto err_mux_put; 344 } 345 346 ret = ptn36502_detect(ptn); 347 if (ret) 348 goto err_disable_regulator; 349 350 ret = drm_aux_bridge_register(dev); 351 if (ret) 352 goto err_disable_regulator; 353 354 sw_desc.drvdata = ptn; 355 sw_desc.fwnode = dev->fwnode; 356 sw_desc.set = ptn36502_sw_set; 357 358 ptn->sw = typec_switch_register(dev, &sw_desc); 359 if (IS_ERR(ptn->sw)) { 360 ret = dev_err_probe(dev, PTR_ERR(ptn->sw), 361 "Failed to register typec switch\n"); 362 goto err_disable_regulator; 363 } 364 365 retimer_desc.drvdata = ptn; 366 retimer_desc.fwnode = dev->fwnode; 367 retimer_desc.set = ptn36502_retimer_set; 368 369 ptn->retimer = typec_retimer_register(dev, &retimer_desc); 370 if (IS_ERR(ptn->retimer)) { 371 ret = dev_err_probe(dev, PTR_ERR(ptn->retimer), 372 "Failed to register typec retimer\n"); 373 goto err_switch_unregister; 374 } 375 376 return 0; 377 378 err_switch_unregister: 379 typec_switch_unregister(ptn->sw); 380 381 err_disable_regulator: 382 regulator_disable(ptn->vdd18_supply); 383 384 err_mux_put: 385 typec_mux_put(ptn->typec_mux); 386 387 err_switch_put: 388 typec_switch_put(ptn->typec_switch); 389 390 return ret; 391 } 392 393 static void ptn36502_remove(struct i2c_client *client) 394 { 395 struct ptn36502 *ptn = i2c_get_clientdata(client); 396 397 typec_retimer_unregister(ptn->retimer); 398 typec_switch_unregister(ptn->sw); 399 400 regulator_disable(ptn->vdd18_supply); 401 402 typec_mux_put(ptn->typec_mux); 403 typec_switch_put(ptn->typec_switch); 404 } 405 406 static const struct i2c_device_id ptn36502_table[] = { 407 { "ptn36502" }, 408 { } 409 }; 410 MODULE_DEVICE_TABLE(i2c, ptn36502_table); 411 412 static const struct of_device_id ptn36502_of_table[] = { 413 { .compatible = "nxp,ptn36502" }, 414 { } 415 }; 416 MODULE_DEVICE_TABLE(of, ptn36502_of_table); 417 418 static struct i2c_driver ptn36502_driver = { 419 .driver = { 420 .name = "ptn36502", 421 .of_match_table = ptn36502_of_table, 422 }, 423 .probe = ptn36502_probe, 424 .remove = ptn36502_remove, 425 .id_table = ptn36502_table, 426 }; 427 module_i2c_driver(ptn36502_driver); 428 429 MODULE_AUTHOR("Luca Weiss <luca.weiss@fairphone.com>"); 430 MODULE_DESCRIPTION("NXP PTN36502 Type-C driver"); 431 MODULE_LICENSE("GPL"); 432