Commit 5944bd9a25291560405e5d86612a75a6791acf23
Committed by
Philipp Tomsich
1 parent
0dd1fc09bb
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
rockchip: i2c: enable i2c controller for rk3066 and rk3188
rk3066 and rk3188 has two I2C controller implementations. Current I2C driver wan't work with legacy implementation. Switching between controllers is performed using a bit inside GFR_SOC_CON1 register. The bit setting is performed by pinctrl driver. The patch ask pinctrl to do settings. Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com> Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> [fix warnings by including the rk3228 variant in the compatible-list]: Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Showing 1 changed file with 89 additions and 5 deletions Side-by-side Diff
drivers/i2c/rk_i2c.c
... | ... | @@ -31,6 +31,18 @@ |
31 | 31 | unsigned int speed; |
32 | 32 | }; |
33 | 33 | |
34 | +enum { | |
35 | + RK_I2C_LEGACY, | |
36 | + RK_I2C_NEW, | |
37 | +}; | |
38 | + | |
39 | +/** | |
40 | + * @controller_type: i2c controller type | |
41 | + */ | |
42 | +struct rk_i2c_soc_data { | |
43 | + int controller_type; | |
44 | +}; | |
45 | + | |
34 | 46 | static inline void rk_i2c_get_div(int div, int *divh, int *divl) |
35 | 47 | { |
36 | 48 | *divl = div / 2; |
37 | 49 | |
... | ... | @@ -378,9 +390,38 @@ |
378 | 390 | static int rockchip_i2c_probe(struct udevice *bus) |
379 | 391 | { |
380 | 392 | struct rk_i2c *priv = dev_get_priv(bus); |
393 | + struct rk_i2c_soc_data *soc_data; | |
394 | + struct udevice *pinctrl; | |
395 | + int bus_nr; | |
396 | + int ret; | |
381 | 397 | |
382 | 398 | priv->regs = dev_read_addr_ptr(bus); |
383 | 399 | |
400 | + soc_data = (struct rk_i2c_soc_data*)dev_get_driver_data(bus); | |
401 | + | |
402 | + if (soc_data->controller_type == RK_I2C_LEGACY) { | |
403 | + ret = dev_read_alias_seq(bus, &bus_nr); | |
404 | + if (ret < 0) { | |
405 | + debug("%s: Could not get alias for %s: %d\n", | |
406 | + __func__, bus->name, ret); | |
407 | + return ret; | |
408 | + } | |
409 | + | |
410 | + ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); | |
411 | + if (ret) { | |
412 | + debug("%s: Cannot find pinctrl device\n", __func__); | |
413 | + return ret; | |
414 | + } | |
415 | + | |
416 | + /* pinctrl will switch I2C to new type */ | |
417 | + ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_I2C0 + bus_nr); | |
418 | + if (ret) { | |
419 | + debug("%s: Failed to switch I2C to new type %s: %d\n", | |
420 | + __func__, bus->name, ret); | |
421 | + return ret; | |
422 | + } | |
423 | + } | |
424 | + | |
384 | 425 | return 0; |
385 | 426 | } |
386 | 427 | |
387 | 428 | |
... | ... | @@ -389,12 +430,55 @@ |
389 | 430 | .set_bus_speed = rockchip_i2c_set_bus_speed, |
390 | 431 | }; |
391 | 432 | |
433 | +static const struct rk_i2c_soc_data rk3066_soc_data = { | |
434 | + .controller_type = RK_I2C_LEGACY, | |
435 | +}; | |
436 | + | |
437 | +static const struct rk_i2c_soc_data rk3188_soc_data = { | |
438 | + .controller_type = RK_I2C_LEGACY, | |
439 | +}; | |
440 | + | |
441 | +static const struct rk_i2c_soc_data rk3228_soc_data = { | |
442 | + .controller_type = RK_I2C_NEW, | |
443 | +}; | |
444 | + | |
445 | +static const struct rk_i2c_soc_data rk3288_soc_data = { | |
446 | + .controller_type = RK_I2C_NEW, | |
447 | +}; | |
448 | + | |
449 | +static const struct rk_i2c_soc_data rk3328_soc_data = { | |
450 | + .controller_type = RK_I2C_NEW, | |
451 | +}; | |
452 | + | |
453 | +static const struct rk_i2c_soc_data rk3399_soc_data = { | |
454 | + .controller_type = RK_I2C_NEW, | |
455 | +}; | |
456 | + | |
392 | 457 | static const struct udevice_id rockchip_i2c_ids[] = { |
393 | - { .compatible = "rockchip,rk3066-i2c" }, | |
394 | - { .compatible = "rockchip,rk3188-i2c" }, | |
395 | - { .compatible = "rockchip,rk3288-i2c" }, | |
396 | - { .compatible = "rockchip,rk3328-i2c" }, | |
397 | - { .compatible = "rockchip,rk3399-i2c" }, | |
458 | + { | |
459 | + .compatible = "rockchip,rk3066-i2c", | |
460 | + .data = (ulong)&rk3066_soc_data, | |
461 | + }, | |
462 | + { | |
463 | + .compatible = "rockchip,rk3188-i2c", | |
464 | + .data = (ulong)&rk3188_soc_data, | |
465 | + }, | |
466 | + { | |
467 | + .compatible = "rockchip,rk3228-i2c", | |
468 | + .data = (ulong)&rk3228_soc_data, | |
469 | + }, | |
470 | + { | |
471 | + .compatible = "rockchip,rk3288-i2c", | |
472 | + .data = (ulong)&rk3288_soc_data, | |
473 | + }, | |
474 | + { | |
475 | + .compatible = "rockchip,rk3328-i2c", | |
476 | + .data = (ulong)&rk3328_soc_data, | |
477 | + }, | |
478 | + { | |
479 | + .compatible = "rockchip,rk3399-i2c", | |
480 | + .data = (ulong)&rk3399_soc_data, | |
481 | + }, | |
398 | 482 | { } |
399 | 483 | }; |
400 | 484 |