.. | .. |
---|
5 | 5 | |
---|
6 | 6 | #include <linux/delay.h> |
---|
7 | 7 | #include <linux/of_address.h> |
---|
| 8 | +#include <linux/of_platform.h> |
---|
8 | 9 | |
---|
9 | 10 | #include "sun8i_dw_hdmi.h" |
---|
10 | 11 | |
---|
.. | .. |
---|
13 | 14 | * it is set in BSP driver. |
---|
14 | 15 | */ |
---|
15 | 16 | #define I2C_ADDR 0x69 |
---|
| 17 | + |
---|
| 18 | +static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = { |
---|
| 19 | + { |
---|
| 20 | + 30666000, { |
---|
| 21 | + { 0x00b3, 0x0000 }, |
---|
| 22 | + { 0x2153, 0x0000 }, |
---|
| 23 | + { 0x40f3, 0x0000 }, |
---|
| 24 | + }, |
---|
| 25 | + }, { |
---|
| 26 | + 36800000, { |
---|
| 27 | + { 0x00b3, 0x0000 }, |
---|
| 28 | + { 0x2153, 0x0000 }, |
---|
| 29 | + { 0x40a2, 0x0001 }, |
---|
| 30 | + }, |
---|
| 31 | + }, { |
---|
| 32 | + 46000000, { |
---|
| 33 | + { 0x00b3, 0x0000 }, |
---|
| 34 | + { 0x2142, 0x0001 }, |
---|
| 35 | + { 0x40a2, 0x0001 }, |
---|
| 36 | + }, |
---|
| 37 | + }, { |
---|
| 38 | + 61333000, { |
---|
| 39 | + { 0x0072, 0x0001 }, |
---|
| 40 | + { 0x2142, 0x0001 }, |
---|
| 41 | + { 0x40a2, 0x0001 }, |
---|
| 42 | + }, |
---|
| 43 | + }, { |
---|
| 44 | + 73600000, { |
---|
| 45 | + { 0x0072, 0x0001 }, |
---|
| 46 | + { 0x2142, 0x0001 }, |
---|
| 47 | + { 0x4061, 0x0002 }, |
---|
| 48 | + }, |
---|
| 49 | + }, { |
---|
| 50 | + 92000000, { |
---|
| 51 | + { 0x0072, 0x0001 }, |
---|
| 52 | + { 0x2145, 0x0002 }, |
---|
| 53 | + { 0x4061, 0x0002 }, |
---|
| 54 | + }, |
---|
| 55 | + }, { |
---|
| 56 | + 122666000, { |
---|
| 57 | + { 0x0051, 0x0002 }, |
---|
| 58 | + { 0x2145, 0x0002 }, |
---|
| 59 | + { 0x4061, 0x0002 }, |
---|
| 60 | + }, |
---|
| 61 | + }, { |
---|
| 62 | + 147200000, { |
---|
| 63 | + { 0x0051, 0x0002 }, |
---|
| 64 | + { 0x2145, 0x0002 }, |
---|
| 65 | + { 0x4064, 0x0003 }, |
---|
| 66 | + }, |
---|
| 67 | + }, { |
---|
| 68 | + 184000000, { |
---|
| 69 | + { 0x0051, 0x0002 }, |
---|
| 70 | + { 0x214c, 0x0003 }, |
---|
| 71 | + { 0x4064, 0x0003 }, |
---|
| 72 | + }, |
---|
| 73 | + }, { |
---|
| 74 | + 226666000, { |
---|
| 75 | + { 0x0040, 0x0003 }, |
---|
| 76 | + { 0x214c, 0x0003 }, |
---|
| 77 | + { 0x4064, 0x0003 }, |
---|
| 78 | + }, |
---|
| 79 | + }, { |
---|
| 80 | + 272000000, { |
---|
| 81 | + { 0x0040, 0x0003 }, |
---|
| 82 | + { 0x214c, 0x0003 }, |
---|
| 83 | + { 0x5a64, 0x0003 }, |
---|
| 84 | + }, |
---|
| 85 | + }, { |
---|
| 86 | + 340000000, { |
---|
| 87 | + { 0x0040, 0x0003 }, |
---|
| 88 | + { 0x3b4c, 0x0003 }, |
---|
| 89 | + { 0x5a64, 0x0003 }, |
---|
| 90 | + }, |
---|
| 91 | + }, { |
---|
| 92 | + 594000000, { |
---|
| 93 | + { 0x1a40, 0x0003 }, |
---|
| 94 | + { 0x3b4c, 0x0003 }, |
---|
| 95 | + { 0x5a64, 0x0003 }, |
---|
| 96 | + }, |
---|
| 97 | + }, { |
---|
| 98 | + ~0UL, { |
---|
| 99 | + { 0x0000, 0x0000 }, |
---|
| 100 | + { 0x0000, 0x0000 }, |
---|
| 101 | + { 0x0000, 0x0000 }, |
---|
| 102 | + }, |
---|
| 103 | + } |
---|
| 104 | +}; |
---|
| 105 | + |
---|
| 106 | +static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = { |
---|
| 107 | + /* pixelclk bpp8 bpp10 bpp12 */ |
---|
| 108 | + { 27000000, { 0x0012, 0x0000, 0x0000 }, }, |
---|
| 109 | + { 74250000, { 0x0013, 0x001a, 0x001b }, }, |
---|
| 110 | + { 148500000, { 0x0019, 0x0033, 0x0034 }, }, |
---|
| 111 | + { 297000000, { 0x0019, 0x001b, 0x001b }, }, |
---|
| 112 | + { 594000000, { 0x0010, 0x001b, 0x001b }, }, |
---|
| 113 | + { ~0UL, { 0x0000, 0x0000, 0x0000 }, } |
---|
| 114 | +}; |
---|
| 115 | + |
---|
| 116 | +static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = { |
---|
| 117 | + /*pixelclk symbol term vlev*/ |
---|
| 118 | + { 27000000, 0x8009, 0x0007, 0x02b0 }, |
---|
| 119 | + { 74250000, 0x8009, 0x0006, 0x022d }, |
---|
| 120 | + { 148500000, 0x8029, 0x0006, 0x0270 }, |
---|
| 121 | + { 297000000, 0x8039, 0x0005, 0x01ab }, |
---|
| 122 | + { 594000000, 0x8029, 0x0000, 0x008a }, |
---|
| 123 | + { ~0UL, 0x0000, 0x0000, 0x0000} |
---|
| 124 | +}; |
---|
16 | 125 | |
---|
17 | 126 | static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi, |
---|
18 | 127 | struct sun8i_hdmi_phy *phy, |
---|
.. | .. |
---|
225 | 334 | } |
---|
226 | 335 | |
---|
227 | 336 | static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data, |
---|
228 | | - struct drm_display_mode *mode) |
---|
| 337 | + const struct drm_display_info *display, |
---|
| 338 | + const struct drm_display_mode *mode) |
---|
229 | 339 | { |
---|
230 | 340 | struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data; |
---|
231 | 341 | u32 val = 0; |
---|
.. | .. |
---|
280 | 390 | .setup_hpd = &dw_hdmi_phy_setup_hpd, |
---|
281 | 391 | }; |
---|
282 | 392 | |
---|
| 393 | +static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy) |
---|
| 394 | +{ |
---|
| 395 | + /* enable read access to HDMI controller */ |
---|
| 396 | + regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG, |
---|
| 397 | + SUN8I_HDMI_PHY_READ_EN_MAGIC); |
---|
| 398 | + |
---|
| 399 | + /* unscramble register offsets */ |
---|
| 400 | + regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG, |
---|
| 401 | + SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC); |
---|
| 402 | +} |
---|
| 403 | + |
---|
| 404 | +static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy) |
---|
| 405 | +{ |
---|
| 406 | + regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, |
---|
| 407 | + SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN, |
---|
| 408 | + SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN); |
---|
| 409 | + |
---|
| 410 | + regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, |
---|
| 411 | + 0xffff0000, 0x80c00000); |
---|
| 412 | +} |
---|
| 413 | + |
---|
283 | 414 | static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy) |
---|
284 | 415 | { |
---|
| 416 | + sun8i_hdmi_phy_unlock(phy); |
---|
| 417 | + |
---|
285 | 418 | regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG, |
---|
286 | 419 | SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK, |
---|
287 | 420 | SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK); |
---|
.. | .. |
---|
298 | 431 | static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy) |
---|
299 | 432 | { |
---|
300 | 433 | unsigned int val; |
---|
| 434 | + |
---|
| 435 | + sun8i_hdmi_phy_unlock(phy); |
---|
301 | 436 | |
---|
302 | 437 | regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, 0); |
---|
303 | 438 | regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, |
---|
.. | .. |
---|
371 | 506 | phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2; |
---|
372 | 507 | } |
---|
373 | 508 | |
---|
374 | | -void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) |
---|
| 509 | +int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) |
---|
375 | 510 | { |
---|
376 | | - /* enable read access to HDMI controller */ |
---|
377 | | - regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG, |
---|
378 | | - SUN8I_HDMI_PHY_READ_EN_MAGIC); |
---|
| 511 | + int ret; |
---|
379 | 512 | |
---|
380 | | - /* unscramble register offsets */ |
---|
381 | | - regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG, |
---|
382 | | - SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC); |
---|
| 513 | + ret = reset_control_deassert(phy->rst_phy); |
---|
| 514 | + if (ret) { |
---|
| 515 | + dev_err(phy->dev, "Cannot deassert phy reset control: %d\n", ret); |
---|
| 516 | + return ret; |
---|
| 517 | + } |
---|
| 518 | + |
---|
| 519 | + ret = clk_prepare_enable(phy->clk_bus); |
---|
| 520 | + if (ret) { |
---|
| 521 | + dev_err(phy->dev, "Cannot enable bus clock: %d\n", ret); |
---|
| 522 | + goto err_assert_rst_phy; |
---|
| 523 | + } |
---|
| 524 | + |
---|
| 525 | + ret = clk_prepare_enable(phy->clk_mod); |
---|
| 526 | + if (ret) { |
---|
| 527 | + dev_err(phy->dev, "Cannot enable mod clock: %d\n", ret); |
---|
| 528 | + goto err_disable_clk_bus; |
---|
| 529 | + } |
---|
| 530 | + |
---|
| 531 | + if (phy->variant->has_phy_clk) { |
---|
| 532 | + ret = sun8i_phy_clk_create(phy, phy->dev, |
---|
| 533 | + phy->variant->has_second_pll); |
---|
| 534 | + if (ret) { |
---|
| 535 | + dev_err(phy->dev, "Couldn't create the PHY clock\n"); |
---|
| 536 | + goto err_disable_clk_mod; |
---|
| 537 | + } |
---|
| 538 | + |
---|
| 539 | + clk_prepare_enable(phy->clk_phy); |
---|
| 540 | + } |
---|
383 | 541 | |
---|
384 | 542 | phy->variant->phy_init(phy); |
---|
| 543 | + |
---|
| 544 | + return 0; |
---|
| 545 | + |
---|
| 546 | +err_disable_clk_mod: |
---|
| 547 | + clk_disable_unprepare(phy->clk_mod); |
---|
| 548 | +err_disable_clk_bus: |
---|
| 549 | + clk_disable_unprepare(phy->clk_bus); |
---|
| 550 | +err_assert_rst_phy: |
---|
| 551 | + reset_control_assert(phy->rst_phy); |
---|
| 552 | + |
---|
| 553 | + return ret; |
---|
385 | 554 | } |
---|
386 | 555 | |
---|
387 | | -const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void) |
---|
| 556 | +void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy) |
---|
388 | 557 | { |
---|
389 | | - return &sun8i_hdmi_phy_ops; |
---|
| 558 | + clk_disable_unprepare(phy->clk_mod); |
---|
| 559 | + clk_disable_unprepare(phy->clk_bus); |
---|
| 560 | + clk_disable_unprepare(phy->clk_phy); |
---|
| 561 | + |
---|
| 562 | + reset_control_assert(phy->rst_phy); |
---|
390 | 563 | } |
---|
391 | 564 | |
---|
392 | | -static struct regmap_config sun8i_hdmi_phy_regmap_config = { |
---|
| 565 | +void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, |
---|
| 566 | + struct dw_hdmi_plat_data *plat_data) |
---|
| 567 | +{ |
---|
| 568 | + struct sun8i_hdmi_phy_variant *variant = phy->variant; |
---|
| 569 | + |
---|
| 570 | + if (variant->is_custom_phy) { |
---|
| 571 | + plat_data->phy_ops = &sun8i_hdmi_phy_ops; |
---|
| 572 | + plat_data->phy_name = "sun8i_dw_hdmi_phy"; |
---|
| 573 | + plat_data->phy_data = phy; |
---|
| 574 | + } else { |
---|
| 575 | + plat_data->mpll_cfg = variant->mpll_cfg; |
---|
| 576 | + plat_data->cur_ctr = variant->cur_ctr; |
---|
| 577 | + plat_data->phy_config = variant->phy_cfg; |
---|
| 578 | + } |
---|
| 579 | +} |
---|
| 580 | + |
---|
| 581 | +static const struct regmap_config sun8i_hdmi_phy_regmap_config = { |
---|
393 | 582 | .reg_bits = 32, |
---|
394 | 583 | .val_bits = 32, |
---|
395 | 584 | .reg_stride = 4, |
---|
.. | .. |
---|
397 | 586 | .name = "phy" |
---|
398 | 587 | }; |
---|
399 | 588 | |
---|
400 | | -static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = { |
---|
401 | | - .has_phy_clk = true, |
---|
402 | | - .phy_init = &sun8i_hdmi_phy_init_h3, |
---|
403 | | - .phy_disable = &sun8i_hdmi_phy_disable_h3, |
---|
404 | | - .phy_config = &sun8i_hdmi_phy_config_h3, |
---|
405 | | -}; |
---|
406 | | - |
---|
407 | 589 | static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = { |
---|
| 590 | + .is_custom_phy = true, |
---|
408 | 591 | .phy_init = &sun8i_hdmi_phy_init_a83t, |
---|
409 | 592 | .phy_disable = &sun8i_hdmi_phy_disable_a83t, |
---|
410 | 593 | .phy_config = &sun8i_hdmi_phy_config_a83t, |
---|
.. | .. |
---|
412 | 595 | |
---|
413 | 596 | static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = { |
---|
414 | 597 | .has_phy_clk = true, |
---|
| 598 | + .is_custom_phy = true, |
---|
415 | 599 | .phy_init = &sun8i_hdmi_phy_init_h3, |
---|
416 | 600 | .phy_disable = &sun8i_hdmi_phy_disable_h3, |
---|
417 | 601 | .phy_config = &sun8i_hdmi_phy_config_h3, |
---|
418 | 602 | }; |
---|
419 | 603 | |
---|
| 604 | +static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = { |
---|
| 605 | + .has_phy_clk = true, |
---|
| 606 | + .has_second_pll = true, |
---|
| 607 | + .is_custom_phy = true, |
---|
| 608 | + .phy_init = &sun8i_hdmi_phy_init_h3, |
---|
| 609 | + .phy_disable = &sun8i_hdmi_phy_disable_h3, |
---|
| 610 | + .phy_config = &sun8i_hdmi_phy_config_h3, |
---|
| 611 | +}; |
---|
| 612 | + |
---|
| 613 | +static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = { |
---|
| 614 | + .has_phy_clk = true, |
---|
| 615 | + .is_custom_phy = true, |
---|
| 616 | + .phy_init = &sun8i_hdmi_phy_init_h3, |
---|
| 617 | + .phy_disable = &sun8i_hdmi_phy_disable_h3, |
---|
| 618 | + .phy_config = &sun8i_hdmi_phy_config_h3, |
---|
| 619 | +}; |
---|
| 620 | + |
---|
| 621 | +static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = { |
---|
| 622 | + .cur_ctr = sun50i_h6_cur_ctr, |
---|
| 623 | + .mpll_cfg = sun50i_h6_mpll_cfg, |
---|
| 624 | + .phy_cfg = sun50i_h6_phy_config, |
---|
| 625 | + .phy_init = &sun50i_hdmi_phy_init_h6, |
---|
| 626 | +}; |
---|
| 627 | + |
---|
420 | 628 | static const struct of_device_id sun8i_hdmi_phy_of_table[] = { |
---|
421 | | - { |
---|
422 | | - .compatible = "allwinner,sun50i-a64-hdmi-phy", |
---|
423 | | - .data = &sun50i_a64_hdmi_phy, |
---|
424 | | - }, |
---|
425 | 629 | { |
---|
426 | 630 | .compatible = "allwinner,sun8i-a83t-hdmi-phy", |
---|
427 | 631 | .data = &sun8i_a83t_hdmi_phy, |
---|
.. | .. |
---|
430 | 634 | .compatible = "allwinner,sun8i-h3-hdmi-phy", |
---|
431 | 635 | .data = &sun8i_h3_hdmi_phy, |
---|
432 | 636 | }, |
---|
| 637 | + { |
---|
| 638 | + .compatible = "allwinner,sun8i-r40-hdmi-phy", |
---|
| 639 | + .data = &sun8i_r40_hdmi_phy, |
---|
| 640 | + }, |
---|
| 641 | + { |
---|
| 642 | + .compatible = "allwinner,sun50i-a64-hdmi-phy", |
---|
| 643 | + .data = &sun50i_a64_hdmi_phy, |
---|
| 644 | + }, |
---|
| 645 | + { |
---|
| 646 | + .compatible = "allwinner,sun50i-h6-hdmi-phy", |
---|
| 647 | + .data = &sun50i_h6_hdmi_phy, |
---|
| 648 | + }, |
---|
433 | 649 | { /* sentinel */ } |
---|
434 | 650 | }; |
---|
435 | 651 | |
---|
436 | | -int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) |
---|
| 652 | +int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node) |
---|
| 653 | +{ |
---|
| 654 | + struct platform_device *pdev = of_find_device_by_node(node); |
---|
| 655 | + struct sun8i_hdmi_phy *phy; |
---|
| 656 | + |
---|
| 657 | + if (!pdev) |
---|
| 658 | + return -EPROBE_DEFER; |
---|
| 659 | + |
---|
| 660 | + phy = platform_get_drvdata(pdev); |
---|
| 661 | + if (!phy) |
---|
| 662 | + return -EPROBE_DEFER; |
---|
| 663 | + |
---|
| 664 | + hdmi->phy = phy; |
---|
| 665 | + |
---|
| 666 | + put_device(&pdev->dev); |
---|
| 667 | + |
---|
| 668 | + return 0; |
---|
| 669 | +} |
---|
| 670 | + |
---|
| 671 | +static int sun8i_hdmi_phy_probe(struct platform_device *pdev) |
---|
437 | 672 | { |
---|
438 | 673 | const struct of_device_id *match; |
---|
439 | | - struct device *dev = hdmi->dev; |
---|
| 674 | + struct device *dev = &pdev->dev; |
---|
| 675 | + struct device_node *node = dev->of_node; |
---|
440 | 676 | struct sun8i_hdmi_phy *phy; |
---|
441 | 677 | struct resource res; |
---|
442 | 678 | void __iomem *regs; |
---|
.. | .. |
---|
453 | 689 | return -ENOMEM; |
---|
454 | 690 | |
---|
455 | 691 | phy->variant = (struct sun8i_hdmi_phy_variant *)match->data; |
---|
| 692 | + phy->dev = dev; |
---|
456 | 693 | |
---|
457 | 694 | ret = of_address_to_resource(node, 0, &res); |
---|
458 | 695 | if (ret) { |
---|
.. | .. |
---|
511 | 748 | goto err_put_clk_pll1; |
---|
512 | 749 | } |
---|
513 | 750 | |
---|
514 | | - ret = reset_control_deassert(phy->rst_phy); |
---|
515 | | - if (ret) { |
---|
516 | | - dev_err(dev, "Cannot deassert phy reset control: %d\n", ret); |
---|
517 | | - goto err_put_rst_phy; |
---|
518 | | - } |
---|
519 | | - |
---|
520 | | - ret = clk_prepare_enable(phy->clk_bus); |
---|
521 | | - if (ret) { |
---|
522 | | - dev_err(dev, "Cannot enable bus clock: %d\n", ret); |
---|
523 | | - goto err_deassert_rst_phy; |
---|
524 | | - } |
---|
525 | | - |
---|
526 | | - ret = clk_prepare_enable(phy->clk_mod); |
---|
527 | | - if (ret) { |
---|
528 | | - dev_err(dev, "Cannot enable mod clock: %d\n", ret); |
---|
529 | | - goto err_disable_clk_bus; |
---|
530 | | - } |
---|
531 | | - |
---|
532 | | - if (phy->variant->has_phy_clk) { |
---|
533 | | - ret = sun8i_phy_clk_create(phy, dev, |
---|
534 | | - phy->variant->has_second_pll); |
---|
535 | | - if (ret) { |
---|
536 | | - dev_err(dev, "Couldn't create the PHY clock\n"); |
---|
537 | | - goto err_disable_clk_mod; |
---|
538 | | - } |
---|
539 | | - |
---|
540 | | - clk_prepare_enable(phy->clk_phy); |
---|
541 | | - } |
---|
542 | | - |
---|
543 | | - hdmi->phy = phy; |
---|
| 751 | + platform_set_drvdata(pdev, phy); |
---|
544 | 752 | |
---|
545 | 753 | return 0; |
---|
546 | 754 | |
---|
547 | | -err_disable_clk_mod: |
---|
548 | | - clk_disable_unprepare(phy->clk_mod); |
---|
549 | | -err_disable_clk_bus: |
---|
550 | | - clk_disable_unprepare(phy->clk_bus); |
---|
551 | | -err_deassert_rst_phy: |
---|
552 | | - reset_control_assert(phy->rst_phy); |
---|
553 | | -err_put_rst_phy: |
---|
554 | | - reset_control_put(phy->rst_phy); |
---|
555 | 755 | err_put_clk_pll1: |
---|
556 | 756 | clk_put(phy->clk_pll1); |
---|
557 | 757 | err_put_clk_pll0: |
---|
.. | .. |
---|
564 | 764 | return ret; |
---|
565 | 765 | } |
---|
566 | 766 | |
---|
567 | | -void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi) |
---|
| 767 | +static int sun8i_hdmi_phy_remove(struct platform_device *pdev) |
---|
568 | 768 | { |
---|
569 | | - struct sun8i_hdmi_phy *phy = hdmi->phy; |
---|
570 | | - |
---|
571 | | - clk_disable_unprepare(phy->clk_mod); |
---|
572 | | - clk_disable_unprepare(phy->clk_bus); |
---|
573 | | - clk_disable_unprepare(phy->clk_phy); |
---|
574 | | - |
---|
575 | | - reset_control_assert(phy->rst_phy); |
---|
| 769 | + struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev); |
---|
576 | 770 | |
---|
577 | 771 | reset_control_put(phy->rst_phy); |
---|
578 | 772 | |
---|
.. | .. |
---|
580 | 774 | clk_put(phy->clk_pll1); |
---|
581 | 775 | clk_put(phy->clk_mod); |
---|
582 | 776 | clk_put(phy->clk_bus); |
---|
| 777 | + return 0; |
---|
583 | 778 | } |
---|
| 779 | + |
---|
| 780 | +struct platform_driver sun8i_hdmi_phy_driver = { |
---|
| 781 | + .probe = sun8i_hdmi_phy_probe, |
---|
| 782 | + .remove = sun8i_hdmi_phy_remove, |
---|
| 783 | + .driver = { |
---|
| 784 | + .name = "sun8i-hdmi-phy", |
---|
| 785 | + .of_match_table = sun8i_hdmi_phy_of_table, |
---|
| 786 | + }, |
---|
| 787 | +}; |
---|