1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * serdes-i2c.c -- display i2c for different serdes chips 4 * 5 * Copyright (c) 2023 Rockchip Electronics Co. Ltd. 6 * 7 * Author: luowei <lw@rock-chips.com> 8 */ 9 10 #include "core.h" 11 12 static int dm_i2c_reg_write_u8(struct udevice *dev, u8 reg, u8 val) 13 { 14 int ret; 15 u8 buf[2]; 16 struct i2c_msg msg; 17 struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); 18 19 buf[0] = reg; 20 buf[1] = val; 21 msg.addr = chip->chip_addr; 22 msg.flags = 0; 23 msg.len = 2; 24 msg.buf = buf; 25 26 ret = dm_i2c_xfer(dev, &msg, 1); 27 if (ret) { 28 printf("dm i2c write failed: %d\n", ret); 29 return ret; 30 } 31 32 return 0; 33 } 34 35 static uint8_t dm_i2c_reg_read_u8(struct udevice *dev, u8 reg) 36 { 37 int ret; 38 u8 data; 39 struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); 40 struct i2c_msg msg[] = { 41 { 42 .addr = chip->chip_addr, 43 .flags = 0, 44 .buf = (u8 *)®, 45 .len = 1, 46 }, { 47 .addr = chip->chip_addr, 48 .flags = I2C_M_RD, 49 .buf = (u8 *)&data, 50 .len = 1, 51 } 52 }; 53 54 ret = dm_i2c_xfer(dev, msg, 2); 55 if (ret) { 56 printf("dm i2c read failed: %d\n", ret); 57 return ret; 58 } 59 60 return data; 61 } 62 63 static int dm_i2c_reg_clrset_u8(struct udevice *dev, 64 u8 offset, 65 u8 clr, u8 set) 66 { 67 u8 val; 68 69 val = dm_i2c_reg_read_u8(dev, offset); 70 if (val < 0) 71 return val; 72 73 val &= ~clr; 74 val |= set; 75 76 return dm_i2c_reg_write_u8(dev, offset, val); 77 } 78 79 /** 80 * serdes_reg_read: Read a single serdes register. 81 * 82 * @serdes: Device to read from. 83 * @reg: Register to read. 84 * @val: Date read from register. 85 */ 86 int serdes_reg_read(struct serdes *serdes, 87 unsigned int reg, unsigned int *val) 88 { 89 unsigned int value; 90 91 if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT) 92 value = dm_i2c_reg_read_u8(serdes->dev, reg); 93 else 94 value = dm_i2c_reg_read(serdes->dev, reg); 95 96 *val = value; 97 SERDES_DBG_I2C("%s %s %s Read Reg%04x %04x\n", 98 __func__, serdes->dev->name, 99 serdes->dev->name, reg, *val); 100 return 0; 101 } 102 EXPORT_SYMBOL_GPL(serdes_reg_read); 103 104 /** 105 * serdes_reg_write: Write a single serdes register. 106 * 107 * @serdes: Device to write to. 108 * @reg: Register to write to. 109 * @val: Value to write. 110 */ 111 int serdes_reg_write(struct serdes *serdes, unsigned int reg, 112 unsigned int val) 113 { 114 int ret = 0; 115 116 SERDES_DBG_I2C("%s %s Write Reg%04x %04x) type=%d\n", 117 __func__, serdes->dev->name, 118 reg, val, serdes->chip_data->reg_val_type); 119 if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT) { 120 ret = dm_i2c_reg_write_u8(serdes->dev, reg, val); 121 if (ret != 0) 122 return ret; 123 } else { 124 ret = dm_i2c_reg_write(serdes->dev, reg, val); 125 if (ret != 0) 126 return ret; 127 } 128 129 return ret; 130 } 131 EXPORT_SYMBOL_GPL(serdes_reg_write); 132 133 /** 134 * serdes_multi_reg_write: Write many serdes register. 135 * 136 * @serdes: Device to write to. 137 * @regs: Registers to write to. 138 * @num_regs: Number of registers to write. 139 */ 140 int serdes_multi_reg_write(struct serdes *serdes, 141 const struct reg_sequence *regs, 142 int num_regs) 143 { 144 int i, ret = 0; 145 146 SERDES_DBG_I2C("%s %s %s num=%d\n", __func__, serdes->dev->name, 147 serdes->chip_data->name, num_regs); 148 149 for (i = 0; i < num_regs; i++) { 150 ret = serdes_reg_write(serdes, regs[i].reg, regs[i].def); 151 SERDES_DBG_I2C("serdes %s Write Reg%04x %04x ret=%d\n", 152 serdes->chip_data->name, 153 regs[i].reg, regs[i].def, ret); 154 } 155 156 return ret; 157 } 158 EXPORT_SYMBOL_GPL(serdes_multi_reg_write); 159 160 /** 161 * serdes_set_bits: Set the value of a bitfield in a serdes register 162 * 163 * @serdes: Device to write to. 164 * @reg: Register to write to. 165 * @mask: Mask of bits to set. 166 * @val: Value to set (unshifted) 167 */ 168 int serdes_set_bits(struct serdes *serdes, unsigned int reg, 169 unsigned int mask, unsigned int val) 170 { 171 int ret = 0; 172 173 SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x) mask=%04x\n", 174 __func__, 175 serdes->dev->name, 176 serdes->dev->name, reg, val, mask); 177 178 if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT) 179 ret = dm_i2c_reg_clrset_u8(serdes->dev, reg, mask, val); 180 else 181 ret = dm_i2c_reg_clrset(serdes->dev, reg, mask, val); 182 183 return ret; 184 } 185 EXPORT_SYMBOL_GPL(serdes_set_bits); 186 187 int serdes_i2c_set_sequence(struct serdes *serdes) 188 { 189 int i, ret = 0; 190 unsigned int def = 0; 191 192 if (serdes->mcu_enable) { 193 printf("serdes %s i2c set sequence in MCU\n", 194 serdes->dev->name); 195 return 0; 196 } 197 198 for (i = 0; i < serdes->serdes_init_seq->reg_seq_cnt; i++) { 199 if (serdes->serdes_init_seq->reg_sequence[i].reg == 0xffff) { 200 SERDES_DBG_MFD("%s: delay 0x%04x us\n", __func__, 201 serdes->serdes_init_seq->reg_sequence[i].def); 202 udelay(serdes->serdes_init_seq->reg_sequence[i].def); 203 continue; 204 } 205 206 ret = serdes_reg_write(serdes, 207 serdes->serdes_init_seq->reg_sequence[i].reg, 208 serdes->serdes_init_seq->reg_sequence[i].def); 209 210 if (ret < 0) { 211 SERDES_DBG_MFD("failed to write reg %04x, ret %d\n", 212 serdes->serdes_init_seq->reg_sequence[i].reg, ret); 213 ret = serdes_reg_write(serdes, 214 serdes->serdes_init_seq->reg_sequence[i].reg, 215 serdes->serdes_init_seq->reg_sequence[i].def); 216 } 217 serdes_reg_read(serdes, serdes->serdes_init_seq->reg_sequence[i].reg, &def); 218 if ((def != serdes->serdes_init_seq->reg_sequence[i].def) || (ret < 0)) { 219 /*if read value != write value then write again*/ 220 printf("%s read %04x %04x != %04x\n", serdes->dev->name, 221 serdes->serdes_init_seq->reg_sequence[i].reg, 222 def, serdes->serdes_init_seq->reg_sequence[i].def); 223 ret = serdes_reg_write(serdes, 224 serdes->serdes_init_seq->reg_sequence[i].reg, 225 serdes->serdes_init_seq->reg_sequence[i].def); 226 } 227 } 228 229 /* workaround */ 230 if (serdes->chip_data->serdes_id == MAXIM_ID_MAX96752) { 231 ret = serdes_reg_write(serdes, 0x10, 0x21); 232 mdelay(10); 233 printf("%s reset oneshot max96752\n", serdes->dev->name); 234 } 235 236 SERDES_DBG_MFD("serdes %s sequence_init\n", serdes->dev->name); 237 238 return ret; 239 } 240 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence); 241 242 int serdes_parse_init_seq(struct udevice *dev, const u16 *data, 243 int length, struct serdes_init_seq *seq) 244 { 245 struct reg_sequence *reg_sequence; 246 u16 *buf, *d; 247 unsigned int i, cnt; 248 int ret; 249 250 if (!seq) 251 return -EINVAL; 252 253 buf = calloc(1, length); 254 if (!buf) 255 return -ENOMEM; 256 257 memcpy(buf, data, length); 258 259 d = buf; 260 cnt = length / 4; 261 seq->reg_seq_cnt = cnt; 262 263 seq->reg_sequence = calloc(cnt, sizeof(struct reg_sequence)); 264 if (!seq->reg_sequence) { 265 ret = -ENOMEM; 266 goto free_buf; 267 } 268 269 for (i = 0; i < cnt; i++) { 270 reg_sequence = &seq->reg_sequence[i]; 271 reg_sequence->reg = get_unaligned_be16(&d[0]); 272 reg_sequence->def = get_unaligned_be16(&d[1]); 273 d += 2; 274 } 275 276 return 0; 277 278 free_buf: 279 free(buf); 280 281 return ret; 282 } 283 EXPORT_SYMBOL_GPL(serdes_parse_init_seq); 284 285 int serdes_get_init_seq(struct serdes *serdes) 286 { 287 const void *data = NULL; 288 int len, err; 289 290 data = dev_read_prop(serdes->dev, "serdes-init-sequence", &len); 291 if (!data) { 292 printf("failed to get serdes-init-sequence\n"); 293 return -EINVAL; 294 } 295 296 serdes->serdes_init_seq = calloc(1, sizeof(*serdes->serdes_init_seq)); 297 if (!serdes->serdes_init_seq) 298 return -ENOMEM; 299 300 err = serdes_parse_init_seq(serdes->dev, 301 data, len, serdes->serdes_init_seq); 302 if (err) { 303 printf("failed to parse serdes-init-sequence\n"); 304 goto free_init_seq; 305 } 306 307 return 0; 308 309 free_init_seq: 310 free(serdes->serdes_init_seq); 311 312 return err; 313 } 314 EXPORT_SYMBOL_GPL(serdes_get_init_seq); 315 316 int serdes_gpio_register(struct udevice *dev) 317 { 318 bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); 319 struct uclass_driver *drv; 320 int ret = -ENODEV; 321 const char *name; 322 const char *status; 323 ofnode subnode; 324 struct udevice *subdev; 325 struct udevice *gpio_dev; 326 327 SERDES_DBG_MFD("%s node=%s\n", 328 __func__, ofnode_get_name(dev->node)); 329 330 /* Lookup GPIO driver */ 331 drv = lists_uclass_lookup(UCLASS_GPIO); 332 if (!drv) { 333 printf("Cannot find GPIO driver\n"); 334 return -ENOENT; 335 } 336 337 dev_for_each_subnode(subnode, dev) { 338 if (pre_reloc_only && 339 !ofnode_pre_reloc(subnode)) 340 continue; 341 342 name = ofnode_get_name(subnode); 343 if (!name) 344 continue; 345 346 if (strstr(name, "gpio")) { 347 status = ofnode_read_string(subnode, "status"); 348 if (status && strcmp(status, "okay") != 0) { 349 SERDES_DBG_MFD("%s node=%s status=%s, exit\n", 350 __func__, name, status); 351 return 0; 352 } 353 354 ret = device_bind_driver_to_node(dev, 355 "serdes-gpio", name, 356 subnode, &subdev); 357 if (ret) { 358 printf("Cannot find serdes gpio driver\n"); 359 return ret; 360 } 361 362 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, 363 subnode, 364 &gpio_dev); 365 if (ret) { 366 printf("%s failed to get gpio dev\n", __func__); 367 return ret; 368 } 369 370 SERDES_DBG_MFD("%s select %s gpio_dev=%s\n", 371 __func__, name, gpio_dev->name); 372 return 0; 373 } 374 } 375 376 return ret; 377 } 378 EXPORT_SYMBOL_GPL(serdes_gpio_register); 379 380 int serdes_pinctrl_register(struct udevice *dev) 381 { 382 bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); 383 struct uclass_driver *drv; 384 int ret = -ENODEV; 385 const char *name; 386 const char *status; 387 ofnode subnode; 388 struct udevice *subdev; 389 struct udevice *pinctrl_dev; 390 struct serdes *serdes = dev_get_priv(dev); 391 392 SERDES_DBG_MFD("%s node=%s\n", 393 __func__, ofnode_get_name(dev->node)); 394 395 /* Lookup PINCTRL driver */ 396 drv = lists_uclass_lookup(UCLASS_PINCTRL); 397 if (!drv) { 398 printf("Cannot find PINCTRL driver\n"); 399 return -ENOENT; 400 } 401 402 dev_for_each_subnode(subnode, dev) { 403 if (pre_reloc_only && 404 !ofnode_pre_reloc(subnode)) 405 continue; 406 407 name = ofnode_get_name(subnode); 408 if (!name) 409 continue; 410 411 if (strstr(name, "pinctrl")) { 412 status = ofnode_read_string(subnode, "status"); 413 if (status && strcmp(status, "okay") != 0) { 414 SERDES_DBG_MFD("%s node=%s status=%s, exit\n", 415 __func__, name, status); 416 return 0; 417 } 418 419 if (serdes->mcu_enable) { 420 printf("serdes %s iomux init in MCU\n", 421 serdes->dev->name); 422 return 0; 423 } 424 425 ret = device_bind_driver_to_node(dev, 426 "serdes-pinctrl", name, 427 subnode, &subdev); 428 if (ret) { 429 printf("Cannot find serdes pinctrl driver\n"); 430 return ret; 431 } 432 433 ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL, 434 subnode, 435 &pinctrl_dev); 436 if (ret) { 437 printf("%s failed to get pinctrl\n", __func__); 438 return ret; 439 } 440 441 SERDES_DBG_MFD("%s select %s pinctrl_dev=%s\n", 442 __func__, name, pinctrl_dev->name); 443 return 0; 444 } 445 } 446 447 return ret; 448 } 449 EXPORT_SYMBOL_GPL(serdes_pinctrl_register); 450 451 static int serdes_i2c_init(struct serdes *serdes) 452 { 453 int ret = 0; 454 int i = 0; 455 456 if (serdes->vpower_supply) 457 regulator_set_enable(serdes->vpower_supply, true); 458 459 if (dm_gpio_is_valid(&serdes->enable_gpio)) 460 dm_gpio_set_value(&serdes->enable_gpio, 1); 461 462 mdelay(5); 463 464 for (i = 0; i < 3; i++) { 465 ret = serdes_i2c_set_sequence(serdes); 466 if (!ret) 467 break; 468 mdelay(20); 469 } 470 471 SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name, 472 serdes->chip_data->name); 473 474 return ret; 475 } 476 477 static int serdes_i2c_probe(struct udevice *dev) 478 { 479 struct serdes *serdes = dev_get_priv(dev); 480 int ret; 481 482 ret = i2c_set_chip_offset_len(dev, 2); 483 if (ret) 484 return ret; 485 486 serdes->dev = dev; 487 serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev); 488 serdes->type = serdes->chip_data->serdes_type; 489 490 SERDES_DBG_MFD("serdes %s %s probe start\n", 491 serdes->dev->name, serdes->chip_data->name); 492 493 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, 494 "vpower-supply", 495 &serdes->vpower_supply); 496 if (ret && ret != -ENOENT) 497 SERDES_DBG_MFD("%s: Cannot get power supply: %d\n", 498 __func__, ret); 499 500 ret = gpio_request_by_name(dev, "enable-gpios", 0, 501 &serdes->enable_gpio, GPIOD_IS_OUT); 502 if (ret) 503 SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n", 504 __func__, ret); 505 506 ret = gpio_request_by_name(dev, "lock-gpios", 0, 507 &serdes->lock_gpio, 508 GPIOD_IS_IN); 509 if (ret) 510 SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n", 511 __func__, ret); 512 513 ret = gpio_request_by_name(dev, "err-gpios", 0, 514 &serdes->err_gpio, 515 GPIOD_IS_IN); 516 if (ret) 517 SERDES_DBG_MFD("%s: failed to err gpio: %d\n", 518 __func__, ret); 519 520 ret = serdes_get_init_seq(serdes); 521 if (ret) 522 return ret; 523 524 serdes_i2c_init(serdes); 525 526 printf("%s %s successful, version %s\n", 527 __func__, 528 serdes->dev->name, 529 SERDES_UBOOT_DISPLAY_VERSION); 530 531 return 0; 532 } 533 534 static const struct udevice_id serdes_of_match[] = { 535 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_NOVO_NCA9539) 536 { .compatible = "novo,nca9539", .data = (ulong)&serdes_nca9539_data }, 537 #endif 538 { } 539 }; 540 541 U_BOOT_DRIVER(serdes_misc) = { 542 .name = "serdes-misc", 543 .id = UCLASS_MISC, 544 .of_match = serdes_of_match, 545 .probe = serdes_i2c_probe, 546 .priv_auto_alloc_size = sizeof(struct serdes), 547 }; 548 549 int serdes_power_init(void) 550 { 551 struct udevice *dev; 552 int ret = 0; 553 554 ret = uclass_get_device_by_driver(UCLASS_MISC, 555 DM_GET_DRIVER(serdes_misc), 556 &dev); 557 if (ret) 558 printf("%s failed to get misc device ret=%d\n", __func__, ret); 559 560 return ret; 561 } 562