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", serdes->dev->name); 194 return 0; 195 } 196 197 for (i = 0; i < serdes->serdes_init_seq->reg_seq_cnt; i++) { 198 if (serdes->serdes_init_seq->reg_sequence[i].reg == 0xffff) { 199 SERDES_DBG_MFD("%s: delay 0x%04x us\n", __func__, 200 serdes->serdes_init_seq->reg_sequence[i].def); 201 udelay(serdes->serdes_init_seq->reg_sequence[i].def); 202 continue; 203 } 204 205 ret = serdes_reg_write(serdes, 206 serdes->serdes_init_seq->reg_sequence[i].reg, 207 serdes->serdes_init_seq->reg_sequence[i].def); 208 209 if (ret < 0) { 210 SERDES_DBG_MFD("failed to write reg %04x, ret %d\n", 211 serdes->serdes_init_seq->reg_sequence[i].reg, ret); 212 ret = serdes_reg_write(serdes, 213 serdes->serdes_init_seq->reg_sequence[i].reg, 214 serdes->serdes_init_seq->reg_sequence[i].def); 215 } 216 serdes_reg_read(serdes, serdes->serdes_init_seq->reg_sequence[i].reg, &def); 217 if ((def != serdes->serdes_init_seq->reg_sequence[i].def) || (ret < 0)) { 218 /*if read value != write value then write again*/ 219 printf("%s read %04x %04x != %04x\n", serdes->dev->name, 220 serdes->serdes_init_seq->reg_sequence[i].reg, 221 def, serdes->serdes_init_seq->reg_sequence[i].def); 222 ret = serdes_reg_write(serdes, 223 serdes->serdes_init_seq->reg_sequence[i].reg, 224 serdes->serdes_init_seq->reg_sequence[i].def); 225 } 226 } 227 228 /* workaround */ 229 if (serdes->chip_data->serdes_id == MAXIM_ID_MAX96752) { 230 ret = serdes_reg_write(serdes, 0x10, 0x21); 231 mdelay(10); 232 printf("%s reset oneshot max96752\n", serdes->dev->name); 233 } 234 235 SERDES_DBG_MFD("serdes %s sequence_init\n", serdes->dev->name); 236 237 return ret; 238 } 239 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence); 240 241 int serdes_parse_init_seq(struct udevice *dev, const u16 *data, 242 int length, struct serdes_init_seq *seq) 243 { 244 struct reg_sequence *reg_sequence; 245 u16 *buf, *d; 246 unsigned int i, cnt; 247 int ret; 248 249 if (!seq) 250 return -EINVAL; 251 252 buf = calloc(1, length); 253 if (!buf) 254 return -ENOMEM; 255 256 memcpy(buf, data, length); 257 258 d = buf; 259 cnt = length / 4; 260 seq->reg_seq_cnt = cnt; 261 262 seq->reg_sequence = calloc(cnt, sizeof(struct reg_sequence)); 263 if (!seq->reg_sequence) { 264 ret = -ENOMEM; 265 goto free_buf; 266 } 267 268 for (i = 0; i < cnt; i++) { 269 reg_sequence = &seq->reg_sequence[i]; 270 reg_sequence->reg = get_unaligned_be16(&d[0]); 271 reg_sequence->def = get_unaligned_be16(&d[1]); 272 d += 2; 273 } 274 275 return 0; 276 277 free_buf: 278 free(buf); 279 280 return ret; 281 } 282 EXPORT_SYMBOL_GPL(serdes_parse_init_seq); 283 284 int serdes_get_init_seq(struct serdes *serdes) 285 { 286 const void *data = NULL; 287 int len, err; 288 289 data = dev_read_prop(serdes->dev, "serdes-init-sequence", &len); 290 if (!data) { 291 printf("failed to get serdes-init-sequence\n"); 292 return -EINVAL; 293 } 294 295 serdes->serdes_init_seq = calloc(1, sizeof(*serdes->serdes_init_seq)); 296 if (!serdes->serdes_init_seq) 297 return -ENOMEM; 298 299 err = serdes_parse_init_seq(serdes->dev, 300 data, len, serdes->serdes_init_seq); 301 if (err) { 302 printf("failed to parse serdes-init-sequence\n"); 303 goto free_init_seq; 304 } 305 306 return 0; 307 308 free_init_seq: 309 free(serdes->serdes_init_seq); 310 311 return err; 312 } 313 EXPORT_SYMBOL_GPL(serdes_get_init_seq); 314 315 int serdes_gpio_register(struct udevice *dev, 316 struct serdes *serdes) 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 ofnode subnode; 323 struct udevice *subdev; 324 struct udevice *gpio_dev; 325 326 SERDES_DBG_MFD("%s node=%s\n", 327 __func__, ofnode_get_name(dev->node)); 328 329 /* Lookup GPIO driver */ 330 drv = lists_uclass_lookup(UCLASS_GPIO); 331 if (!drv) { 332 printf("Cannot find GPIO driver\n"); 333 return -ENOENT; 334 } 335 336 dev_for_each_subnode(subnode, dev) { 337 if (pre_reloc_only && 338 !ofnode_pre_reloc(subnode)) 339 continue; 340 341 name = ofnode_get_name(subnode); 342 if (!name) 343 continue; 344 345 if (strstr(name, "gpio")) { 346 ret = device_bind_driver_to_node(dev, 347 "serdes-gpio", name, 348 subnode, &subdev); 349 if (ret) 350 return ret; 351 352 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, 353 subnode, 354 &gpio_dev); 355 if (ret) { 356 printf("%s failed to get gpio dev\n", __func__); 357 return ret; 358 } 359 360 SERDES_DBG_MFD("%s select %s gpio_dev=%s\n", 361 __func__, name, gpio_dev->name); 362 return 0; 363 } 364 } 365 366 return ret; 367 } 368 EXPORT_SYMBOL_GPL(serdes_gpio_register); 369 370 int serdes_pinctrl_register(struct udevice *dev, 371 struct serdes *serdes) 372 { 373 bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); 374 struct uclass_driver *drv; 375 int ret = -ENODEV; 376 const char *name; 377 ofnode subnode; 378 struct udevice *subdev; 379 struct udevice *pinctrl_dev; 380 381 SERDES_DBG_MFD("%s node=%s\n", 382 __func__, ofnode_get_name(dev->node)); 383 384 /* Lookup PINCTRL driver */ 385 drv = lists_uclass_lookup(UCLASS_PINCTRL); 386 if (!drv) { 387 printf("Cannot find PINCTRL driver\n"); 388 return -ENOENT; 389 } 390 391 dev_for_each_subnode(subnode, dev) { 392 if (pre_reloc_only && 393 !ofnode_pre_reloc(subnode)) 394 continue; 395 396 name = ofnode_get_name(subnode); 397 if (!name) 398 continue; 399 400 if (strstr(name, "pinctrl")) { 401 ret = device_bind_driver_to_node(dev, 402 "serdes-pinctrl", name, 403 subnode, &subdev); 404 if (ret) 405 return ret; 406 407 ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL, 408 subnode, 409 &pinctrl_dev); 410 if (ret) { 411 printf("%s failed to get pinctrl\n", __func__); 412 return ret; 413 } 414 415 SERDES_DBG_MFD("%s select %s pinctrl_dev=%s\n", 416 __func__, name, pinctrl_dev->name); 417 return 0; 418 } 419 } 420 421 return ret; 422 } 423 EXPORT_SYMBOL_GPL(serdes_pinctrl_register); 424 425 static int serdes_i2c_init(struct serdes *serdes) 426 { 427 int ret = 0; 428 int i = 0; 429 430 if (serdes->vpower_supply) 431 regulator_set_enable(serdes->vpower_supply, true); 432 433 if (dm_gpio_is_valid(&serdes->enable_gpio)) 434 dm_gpio_set_value(&serdes->enable_gpio, 1); 435 436 mdelay(5); 437 438 for (i = 0; i < 3; i++) { 439 ret = serdes_i2c_set_sequence(serdes); 440 if (!ret) 441 break; 442 mdelay(20); 443 } 444 445 SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name, 446 serdes->chip_data->name); 447 448 return ret; 449 } 450 451 static int serdes_i2c_probe(struct udevice *dev) 452 { 453 struct serdes *serdes = dev_get_priv(dev); 454 int ret; 455 456 ret = i2c_set_chip_offset_len(dev, 2); 457 if (ret) 458 return ret; 459 460 serdes->dev = dev; 461 serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev); 462 serdes->type = serdes->chip_data->serdes_type; 463 464 SERDES_DBG_MFD("serdes %s %s probe start\n", 465 serdes->dev->name, serdes->chip_data->name); 466 467 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, 468 "vpower-supply", 469 &serdes->vpower_supply); 470 if (ret && ret != -ENOENT) 471 SERDES_DBG_MFD("%s: Cannot get power supply: %d\n", 472 __func__, ret); 473 474 ret = gpio_request_by_name(dev, "enable-gpios", 0, 475 &serdes->enable_gpio, GPIOD_IS_OUT); 476 if (ret) 477 SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n", 478 __func__, ret); 479 480 ret = gpio_request_by_name(dev, "lock-gpios", 0, 481 &serdes->lock_gpio, 482 GPIOD_IS_IN); 483 if (ret) 484 SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n", 485 __func__, ret); 486 487 ret = gpio_request_by_name(dev, "err-gpios", 0, 488 &serdes->err_gpio, 489 GPIOD_IS_IN); 490 if (ret) 491 SERDES_DBG_MFD("%s: failed to err gpio: %d\n", 492 __func__, ret); 493 494 ret = serdes_get_init_seq(serdes); 495 if (ret) 496 return ret; 497 498 serdes_i2c_init(serdes); 499 500 printf("%s %s successful, version %s\n", 501 __func__, 502 serdes->dev->name, 503 SERDES_UBOOT_DISPLAY_VERSION); 504 505 return 0; 506 } 507 508 static const struct udevice_id serdes_of_match[] = { 509 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_NOVO_NCA9539) 510 { .compatible = "novo,nca9539", .data = (ulong)&serdes_nca9539_data }, 511 #endif 512 { } 513 }; 514 515 U_BOOT_DRIVER(serdes_misc) = { 516 .name = "serdes-misc", 517 .id = UCLASS_MISC, 518 .of_match = serdes_of_match, 519 .probe = serdes_i2c_probe, 520 .priv_auto_alloc_size = sizeof(struct serdes), 521 }; 522 523 int serdes_power_init(void) 524 { 525 struct udevice *dev; 526 int ret = 0; 527 528 ret = uclass_get_device_by_driver(UCLASS_MISC, 529 DM_GET_DRIVER(serdes_misc), 530 &dev); 531 if (ret) 532 printf("%s failed to get misc device ret=%d\n", __func__, ret); 533 534 return ret; 535 } 536