1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * OnSemi NB7VPQ904M Type-C driver 4 * 5 * Copyright (C) 2023 Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 6 */ 7 #include <linux/i2c.h> 8 #include <linux/mutex.h> 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/regmap.h> 12 #include <linux/bitfield.h> 13 #include <linux/of_graph.h> 14 #include <drm/drm_bridge.h> 15 #include <linux/usb/typec_dp.h> 16 #include <linux/usb/typec_mux.h> 17 #include <linux/usb/typec_retimer.h> 18 #include <linux/gpio/consumer.h> 19 #include <linux/regulator/consumer.h> 20 21 #define NB7_CHNA 0 22 #define NB7_CHNB 1 23 #define NB7_CHNC 2 24 #define NB7_CHND 3 25 #define NB7_IS_CHAN_AD(channel) (channel == NB7_CHNA || channel == NB7_CHND) 26 27 #define GEN_DEV_SET_REG 0x00 28 29 #define GEN_DEV_SET_CHIP_EN BIT(0) 30 #define GEN_DEV_SET_CHNA_EN BIT(4) 31 #define GEN_DEV_SET_CHNB_EN BIT(5) 32 #define GEN_DEV_SET_CHNC_EN BIT(6) 33 #define GEN_DEV_SET_CHND_EN BIT(7) 34 35 #define GEN_DEV_SET_OP_MODE_MASK GENMASK(3, 1) 36 37 #define GEN_DEV_SET_OP_MODE_DP_CC2 0 38 #define GEN_DEV_SET_OP_MODE_DP_CC1 1 39 #define GEN_DEV_SET_OP_MODE_DP_4LANE 2 40 #define GEN_DEV_SET_OP_MODE_USB 5 41 42 #define EQ_SETTING_REG_BASE 0x01 43 #define EQ_SETTING_REG(n) (EQ_SETTING_REG_BASE + (n) * 2) 44 #define EQ_SETTING_MASK GENMASK(3, 1) 45 46 #define OUTPUT_COMPRESSION_AND_POL_REG_BASE 0x02 47 #define OUTPUT_COMPRESSION_AND_POL_REG(n) (OUTPUT_COMPRESSION_AND_POL_REG_BASE + (n) * 2) 48 #define OUTPUT_COMPRESSION_MASK GENMASK(2, 1) 49 50 #define FLAT_GAIN_REG_BASE 0x18 51 #define FLAT_GAIN_REG(n) (FLAT_GAIN_REG_BASE + (n) * 2) 52 #define FLAT_GAIN_MASK GENMASK(1, 0) 53 54 #define LOSS_MATCH_REG_BASE 0x19 55 #define LOSS_MATCH_REG(n) (LOSS_MATCH_REG_BASE + (n) * 2) 56 #define LOSS_MATCH_MASK GENMASK(1, 0) 57 58 #define AUX_CC_REG 0x09 59 60 #define CHIP_VERSION_REG 0x17 61 62 struct nb7vpq904m { 63 struct i2c_client *client; 64 struct gpio_desc *enable_gpio; 65 struct regulator *vcc_supply; 66 struct regmap *regmap; 67 struct typec_switch_dev *sw; 68 struct typec_retimer *retimer; 69 70 bool swap_data_lanes; 71 struct typec_switch *typec_switch; 72 73 struct drm_bridge bridge; 74 75 struct mutex lock; /* protect non-concurrent retimer & switch */ 76 77 enum typec_orientation orientation; 78 unsigned long mode; 79 unsigned int svid; 80 }; 81 82 static void nb7vpq904m_set_channel(struct nb7vpq904m *nb7, unsigned int channel, bool dp) 83 { 84 u8 eq, out_comp, flat_gain, loss_match; 85 86 if (dp) { 87 eq = NB7_IS_CHAN_AD(channel) ? 0x6 : 0x4; 88 out_comp = 0x3; 89 flat_gain = NB7_IS_CHAN_AD(channel) ? 0x2 : 0x1; 90 loss_match = 0x3; 91 } else { 92 eq = 0x4; 93 out_comp = 0x3; 94 flat_gain = NB7_IS_CHAN_AD(channel) ? 0x3 : 0x1; 95 loss_match = NB7_IS_CHAN_AD(channel) ? 0x1 : 0x3; 96 } 97 98 regmap_update_bits(nb7->regmap, EQ_SETTING_REG(channel), 99 EQ_SETTING_MASK, FIELD_PREP(EQ_SETTING_MASK, eq)); 100 regmap_update_bits(nb7->regmap, OUTPUT_COMPRESSION_AND_POL_REG(channel), 101 OUTPUT_COMPRESSION_MASK, FIELD_PREP(OUTPUT_COMPRESSION_MASK, out_comp)); 102 regmap_update_bits(nb7->regmap, FLAT_GAIN_REG(channel), 103 FLAT_GAIN_MASK, FIELD_PREP(FLAT_GAIN_MASK, flat_gain)); 104 regmap_update_bits(nb7->regmap, LOSS_MATCH_REG(channel), 105 LOSS_MATCH_MASK, FIELD_PREP(LOSS_MATCH_MASK, loss_match)); 106 } 107 108 static int nb7vpq904m_set(struct nb7vpq904m *nb7) 109 { 110 bool reverse = (nb7->orientation == TYPEC_ORIENTATION_REVERSE); 111 112 switch (nb7->mode) { 113 case TYPEC_STATE_SAFE: 114 regmap_write(nb7->regmap, GEN_DEV_SET_REG, 115 GEN_DEV_SET_CHIP_EN | 116 GEN_DEV_SET_CHNA_EN | 117 GEN_DEV_SET_CHNB_EN | 118 GEN_DEV_SET_CHNC_EN | 119 GEN_DEV_SET_CHND_EN | 120 FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK, 121 GEN_DEV_SET_OP_MODE_USB)); 122 nb7vpq904m_set_channel(nb7, NB7_CHNA, false); 123 nb7vpq904m_set_channel(nb7, NB7_CHNB, false); 124 nb7vpq904m_set_channel(nb7, NB7_CHNC, false); 125 nb7vpq904m_set_channel(nb7, NB7_CHND, false); 126 regmap_write(nb7->regmap, AUX_CC_REG, 0x2); 127 128 return 0; 129 130 case TYPEC_STATE_USB: 131 /* 132 * Normal Orientation (CC1) 133 * A -> USB RX 134 * B -> USB TX 135 * C -> X 136 * D -> X 137 * Flipped Orientation (CC2) 138 * A -> X 139 * B -> X 140 * C -> USB TX 141 * D -> USB RX 142 * 143 * Reversed if data lanes are swapped 144 */ 145 if (reverse ^ nb7->swap_data_lanes) { 146 regmap_write(nb7->regmap, GEN_DEV_SET_REG, 147 GEN_DEV_SET_CHIP_EN | 148 GEN_DEV_SET_CHNA_EN | 149 GEN_DEV_SET_CHNB_EN | 150 FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK, 151 GEN_DEV_SET_OP_MODE_USB)); 152 nb7vpq904m_set_channel(nb7, NB7_CHNA, false); 153 nb7vpq904m_set_channel(nb7, NB7_CHNB, false); 154 } else { 155 regmap_write(nb7->regmap, GEN_DEV_SET_REG, 156 GEN_DEV_SET_CHIP_EN | 157 GEN_DEV_SET_CHNC_EN | 158 GEN_DEV_SET_CHND_EN | 159 FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK, 160 GEN_DEV_SET_OP_MODE_USB)); 161 nb7vpq904m_set_channel(nb7, NB7_CHNC, false); 162 nb7vpq904m_set_channel(nb7, NB7_CHND, false); 163 } 164 regmap_write(nb7->regmap, AUX_CC_REG, 0x2); 165 166 return 0; 167 168 default: 169 if (nb7->svid != USB_TYPEC_DP_SID) 170 return -EINVAL; 171 172 break; 173 } 174 175 /* DP Altmode Setup */ 176 177 regmap_write(nb7->regmap, AUX_CC_REG, reverse ? 0x1 : 0x0); 178 179 switch (nb7->mode) { 180 case TYPEC_DP_STATE_C: 181 case TYPEC_DP_STATE_E: 182 /* 183 * Normal Orientation (CC1) 184 * A -> DP3 185 * B -> DP2 186 * C -> DP1 187 * D -> DP0 188 * Flipped Orientation (CC2) 189 * A -> DP0 190 * B -> DP1 191 * C -> DP2 192 * D -> DP3 193 */ 194 regmap_write(nb7->regmap, GEN_DEV_SET_REG, 195 GEN_DEV_SET_CHIP_EN | 196 GEN_DEV_SET_CHNA_EN | 197 GEN_DEV_SET_CHNB_EN | 198 GEN_DEV_SET_CHNC_EN | 199 GEN_DEV_SET_CHND_EN | 200 FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK, 201 GEN_DEV_SET_OP_MODE_DP_4LANE)); 202 nb7vpq904m_set_channel(nb7, NB7_CHNA, true); 203 nb7vpq904m_set_channel(nb7, NB7_CHNB, true); 204 nb7vpq904m_set_channel(nb7, NB7_CHNC, true); 205 nb7vpq904m_set_channel(nb7, NB7_CHND, true); 206 break; 207 208 case TYPEC_DP_STATE_D: 209 case TYPEC_DP_STATE_F: 210 regmap_write(nb7->regmap, GEN_DEV_SET_REG, 211 GEN_DEV_SET_CHIP_EN | 212 GEN_DEV_SET_CHNA_EN | 213 GEN_DEV_SET_CHNB_EN | 214 GEN_DEV_SET_CHNC_EN | 215 GEN_DEV_SET_CHND_EN | 216 FIELD_PREP(GEN_DEV_SET_OP_MODE_MASK, 217 reverse ^ nb7->swap_data_lanes ? 218 GEN_DEV_SET_OP_MODE_DP_CC2 219 : GEN_DEV_SET_OP_MODE_DP_CC1)); 220 221 /* 222 * Normal Orientation (CC1) 223 * A -> USB RX 224 * B -> USB TX 225 * C -> DP1 226 * D -> DP0 227 * Flipped Orientation (CC2) 228 * A -> DP0 229 * B -> DP1 230 * C -> USB TX 231 * D -> USB RX 232 * 233 * Reversed if data lanes are swapped 234 */ 235 if (nb7->swap_data_lanes) { 236 nb7vpq904m_set_channel(nb7, NB7_CHNA, !reverse); 237 nb7vpq904m_set_channel(nb7, NB7_CHNB, !reverse); 238 nb7vpq904m_set_channel(nb7, NB7_CHNC, reverse); 239 nb7vpq904m_set_channel(nb7, NB7_CHND, reverse); 240 } else { 241 nb7vpq904m_set_channel(nb7, NB7_CHNA, reverse); 242 nb7vpq904m_set_channel(nb7, NB7_CHNB, reverse); 243 nb7vpq904m_set_channel(nb7, NB7_CHNC, !reverse); 244 nb7vpq904m_set_channel(nb7, NB7_CHND, !reverse); 245 } 246 break; 247 248 default: 249 return -EOPNOTSUPP; 250 } 251 252 return 0; 253 } 254 255 static int nb7vpq904m_sw_set(struct typec_switch_dev *sw, enum typec_orientation orientation) 256 { 257 struct nb7vpq904m *nb7 = typec_switch_get_drvdata(sw); 258 int ret; 259 260 ret = typec_switch_set(nb7->typec_switch, orientation); 261 if (ret) 262 return ret; 263 264 mutex_lock(&nb7->lock); 265 266 if (nb7->orientation != orientation) { 267 nb7->orientation = orientation; 268 269 ret = nb7vpq904m_set(nb7); 270 } 271 272 mutex_unlock(&nb7->lock); 273 274 return ret; 275 } 276 277 static int nb7vpq904m_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state) 278 { 279 struct nb7vpq904m *nb7 = typec_retimer_get_drvdata(retimer); 280 int ret = 0; 281 282 mutex_lock(&nb7->lock); 283 284 if (nb7->mode != state->mode) { 285 nb7->mode = state->mode; 286 287 if (state->alt) 288 nb7->svid = state->alt->svid; 289 else 290 nb7->svid = 0; // No SVID 291 292 ret = nb7vpq904m_set(nb7); 293 } 294 295 mutex_unlock(&nb7->lock); 296 297 return ret; 298 } 299 300 #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) 301 static int nb7vpq904m_bridge_attach(struct drm_bridge *bridge, 302 enum drm_bridge_attach_flags flags) 303 { 304 struct nb7vpq904m *nb7 = container_of(bridge, struct nb7vpq904m, bridge); 305 struct drm_bridge *next_bridge; 306 307 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) 308 return -EINVAL; 309 310 next_bridge = devm_drm_of_get_bridge(&nb7->client->dev, nb7->client->dev.of_node, 0, 0); 311 if (IS_ERR(next_bridge)) { 312 dev_err(&nb7->client->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); 313 return PTR_ERR(next_bridge); 314 } 315 316 return drm_bridge_attach(bridge->encoder, next_bridge, bridge, 317 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 318 } 319 320 static const struct drm_bridge_funcs nb7vpq904m_bridge_funcs = { 321 .attach = nb7vpq904m_bridge_attach, 322 }; 323 324 static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7) 325 { 326 nb7->bridge.funcs = &nb7vpq904m_bridge_funcs; 327 nb7->bridge.of_node = nb7->client->dev.of_node; 328 329 return devm_drm_bridge_add(&nb7->client->dev, &nb7->bridge); 330 } 331 #else 332 static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7) 333 { 334 return 0; 335 } 336 #endif 337 338 static const struct regmap_config nb7_regmap = { 339 .max_register = 0x1f, 340 .reg_bits = 8, 341 .val_bits = 8, 342 }; 343 344 enum { 345 NORMAL_LANE_MAPPING, 346 INVERT_LANE_MAPPING, 347 }; 348 349 #define DATA_LANES_COUNT 4 350 351 static const int supported_data_lane_mapping[][DATA_LANES_COUNT] = { 352 [NORMAL_LANE_MAPPING] = { 0, 1, 2, 3 }, 353 [INVERT_LANE_MAPPING] = { 3, 2, 1, 0 }, 354 }; 355 356 static int nb7vpq904m_parse_data_lanes_mapping(struct nb7vpq904m *nb7) 357 { 358 struct device_node *ep; 359 u32 data_lanes[4]; 360 int ret, i, j; 361 362 ep = of_graph_get_endpoint_by_regs(nb7->client->dev.of_node, 1, 0); 363 364 if (ep) { 365 ret = of_property_count_u32_elems(ep, "data-lanes"); 366 if (ret == -EINVAL) 367 /* Property isn't here, consider default mapping */ 368 goto out_done; 369 if (ret < 0) 370 goto out_error; 371 372 if (ret != DATA_LANES_COUNT) { 373 dev_err(&nb7->client->dev, "expected 4 data lanes\n"); 374 ret = -EINVAL; 375 goto out_error; 376 } 377 378 ret = of_property_read_u32_array(ep, "data-lanes", data_lanes, DATA_LANES_COUNT); 379 if (ret) 380 goto out_error; 381 382 for (i = 0; i < ARRAY_SIZE(supported_data_lane_mapping); i++) { 383 for (j = 0; j < DATA_LANES_COUNT; j++) { 384 if (data_lanes[j] != supported_data_lane_mapping[i][j]) 385 break; 386 } 387 388 if (j == DATA_LANES_COUNT) 389 break; 390 } 391 392 switch (i) { 393 case NORMAL_LANE_MAPPING: 394 break; 395 case INVERT_LANE_MAPPING: 396 nb7->swap_data_lanes = true; 397 dev_info(&nb7->client->dev, "using inverted data lanes mapping\n"); 398 break; 399 default: 400 dev_err(&nb7->client->dev, "invalid data lanes mapping\n"); 401 ret = -EINVAL; 402 goto out_error; 403 } 404 } 405 406 out_done: 407 ret = 0; 408 409 out_error: 410 of_node_put(ep); 411 412 return ret; 413 } 414 415 static int nb7vpq904m_probe(struct i2c_client *client) 416 { 417 struct device *dev = &client->dev; 418 struct typec_switch_desc sw_desc = { }; 419 struct typec_retimer_desc retimer_desc = { }; 420 struct nb7vpq904m *nb7; 421 int ret; 422 423 nb7 = devm_kzalloc(dev, sizeof(*nb7), GFP_KERNEL); 424 if (!nb7) 425 return -ENOMEM; 426 427 nb7->client = client; 428 429 nb7->regmap = devm_regmap_init_i2c(client, &nb7_regmap); 430 if (IS_ERR(nb7->regmap)) { 431 dev_err(&client->dev, "Failed to allocate register map\n"); 432 return PTR_ERR(nb7->regmap); 433 } 434 435 nb7->mode = TYPEC_STATE_SAFE; 436 nb7->orientation = TYPEC_ORIENTATION_NONE; 437 438 mutex_init(&nb7->lock); 439 440 nb7->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); 441 if (IS_ERR(nb7->enable_gpio)) 442 return dev_err_probe(dev, PTR_ERR(nb7->enable_gpio), 443 "unable to acquire enable gpio\n"); 444 445 nb7->vcc_supply = devm_regulator_get_optional(dev, "vcc"); 446 if (IS_ERR(nb7->vcc_supply)) 447 return PTR_ERR(nb7->vcc_supply); 448 449 nb7->typec_switch = fwnode_typec_switch_get(dev->fwnode); 450 if (IS_ERR(nb7->typec_switch)) 451 return dev_err_probe(dev, PTR_ERR(nb7->typec_switch), 452 "failed to acquire orientation-switch\n"); 453 454 ret = nb7vpq904m_parse_data_lanes_mapping(nb7); 455 if (ret) 456 return ret; 457 458 ret = regulator_enable(nb7->vcc_supply); 459 if (ret) 460 dev_warn(dev, "Failed to enable vcc: %d\n", ret); 461 462 gpiod_set_value(nb7->enable_gpio, 1); 463 464 ret = nb7vpq904m_register_bridge(nb7); 465 if (ret) 466 return ret; 467 468 sw_desc.drvdata = nb7; 469 sw_desc.fwnode = dev->fwnode; 470 sw_desc.set = nb7vpq904m_sw_set; 471 472 nb7->sw = typec_switch_register(dev, &sw_desc); 473 if (IS_ERR(nb7->sw)) 474 return dev_err_probe(dev, PTR_ERR(nb7->sw), 475 "Error registering typec switch\n"); 476 477 retimer_desc.drvdata = nb7; 478 retimer_desc.fwnode = dev->fwnode; 479 retimer_desc.set = nb7vpq904m_retimer_set; 480 481 nb7->retimer = typec_retimer_register(dev, &retimer_desc); 482 if (IS_ERR(nb7->retimer)) { 483 typec_switch_unregister(nb7->sw); 484 return dev_err_probe(dev, PTR_ERR(nb7->retimer), 485 "Error registering typec retimer\n"); 486 } 487 488 return 0; 489 } 490 491 static void nb7vpq904m_remove(struct i2c_client *client) 492 { 493 struct nb7vpq904m *nb7 = i2c_get_clientdata(client); 494 495 typec_retimer_unregister(nb7->retimer); 496 typec_switch_unregister(nb7->sw); 497 498 gpiod_set_value(nb7->enable_gpio, 0); 499 500 regulator_disable(nb7->vcc_supply); 501 } 502 503 static const struct i2c_device_id nb7vpq904m_table[] = { 504 { "nb7vpq904m" }, 505 { } 506 }; 507 MODULE_DEVICE_TABLE(i2c, nb7vpq904m_table); 508 509 static const struct of_device_id nb7vpq904m_of_table[] = { 510 { .compatible = "onnn,nb7vpq904m" }, 511 { } 512 }; 513 MODULE_DEVICE_TABLE(of, nb7vpq904m_of_table); 514 515 static struct i2c_driver nb7vpq904m_driver = { 516 .driver = { 517 .name = "nb7vpq904m", 518 .of_match_table = nb7vpq904m_of_table, 519 }, 520 .probe_new = nb7vpq904m_probe, 521 .remove = nb7vpq904m_remove, 522 .id_table = nb7vpq904m_table, 523 }; 524 525 module_i2c_driver(nb7vpq904m_driver); 526 527 MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>"); 528 MODULE_DESCRIPTION("OnSemi NB7VPQ904M Type-C driver"); 529 MODULE_LICENSE("GPL"); 530