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