summaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2015-12-11 10:32:17 -0500
committerKishon Vijay Abraham I <kishon@ti.com>2015-12-20 04:51:38 -0500
commit68dbc2ce77bbe18a0475a497f4d6adde7c5d0b0c (patch)
treecdc1800f333aac977c805d7dde94358287efba3e /drivers/phy
parent75f072f9eab72e10a45886d84a9a762b1c65071d (diff)
phy-sun4i-usb: Use of_match_node to get model specific config data
Use of_match_node instead of calling of_device_is_compatible a ton of times to get model specific config data. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-sun4i-usb.c121
1 files changed, 79 insertions, 42 deletions
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index b12964b70625..35b1fa3b71fe 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -32,6 +32,7 @@
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/of_address.h> 34#include <linux/of_address.h>
35#include <linux/of_device.h>
35#include <linux/of_gpio.h> 36#include <linux/of_gpio.h>
36#include <linux/phy/phy.h> 37#include <linux/phy/phy.h>
37#include <linux/phy/phy-sun4i-usb.h> 38#include <linux/phy/phy-sun4i-usb.h>
@@ -88,12 +89,23 @@
88#define DEBOUNCE_TIME msecs_to_jiffies(50) 89#define DEBOUNCE_TIME msecs_to_jiffies(50)
89#define POLL_TIME msecs_to_jiffies(250) 90#define POLL_TIME msecs_to_jiffies(250)
90 91
92enum sun4i_usb_phy_type {
93 sun4i_a10_phy,
94 sun8i_a33_phy,
95};
96
97struct sun4i_usb_phy_cfg {
98 int num_phys;
99 enum sun4i_usb_phy_type type;
100 u32 disc_thresh;
101 u8 phyctl_offset;
102 bool dedicated_clocks;
103};
104
91struct sun4i_usb_phy_data { 105struct sun4i_usb_phy_data {
92 void __iomem *base; 106 void __iomem *base;
107 const struct sun4i_usb_phy_cfg *cfg;
93 struct mutex mutex; 108 struct mutex mutex;
94 int num_phys;
95 u32 disc_thresh;
96 bool has_a33_phyctl;
97 struct sun4i_usb_phy { 109 struct sun4i_usb_phy {
98 struct phy *phy; 110 struct phy *phy;
99 void __iomem *pmu; 111 void __iomem *pmu;
@@ -159,17 +171,14 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
159{ 171{
160 struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); 172 struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
161 u32 temp, usbc_bit = BIT(phy->index * 2); 173 u32 temp, usbc_bit = BIT(phy->index * 2);
162 void *phyctl; 174 void *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
163 int i; 175 int i;
164 176
165 mutex_lock(&phy_data->mutex); 177 mutex_lock(&phy_data->mutex);
166 178
167 if (phy_data->has_a33_phyctl) { 179 if (phy_data->cfg->type == sun8i_a33_phy) {
168 phyctl = phy_data->base + REG_PHYCTL_A33;
169 /* A33 needs us to set phyctl to 0 explicitly */ 180 /* A33 needs us to set phyctl to 0 explicitly */
170 writel(0, phyctl); 181 writel(0, phyctl);
171 } else {
172 phyctl = phy_data->base + REG_PHYCTL_A10;
173 } 182 }
174 183
175 for (i = 0; i < len; i++) { 184 for (i = 0; i < len; i++) {
@@ -249,7 +258,8 @@ static int sun4i_usb_phy_init(struct phy *_phy)
249 sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); 258 sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
250 259
251 /* Disconnect threshold adjustment */ 260 /* Disconnect threshold adjustment */
252 sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); 261 sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
262 data->cfg->disc_thresh, 2);
253 263
254 sun4i_usb_phy_passby(phy, 1); 264 sun4i_usb_phy_passby(phy, 1);
255 265
@@ -476,7 +486,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev,
476{ 486{
477 struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); 487 struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
478 488
479 if (args->args[0] >= data->num_phys) 489 if (args->args[0] >= data->cfg->num_phys)
480 return ERR_PTR(-ENODEV); 490 return ERR_PTR(-ENODEV);
481 491
482 return data->phys[args->args[0]].phy; 492 return data->phys[args->args[0]].phy;
@@ -511,7 +521,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
511 struct device *dev = &pdev->dev; 521 struct device *dev = &pdev->dev;
512 struct device_node *np = dev->of_node; 522 struct device_node *np = dev->of_node;
513 struct phy_provider *phy_provider; 523 struct phy_provider *phy_provider;
514 bool dedicated_clocks;
515 struct resource *res; 524 struct resource *res;
516 int i, ret; 525 int i, ret;
517 526
@@ -522,29 +531,9 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
522 mutex_init(&data->mutex); 531 mutex_init(&data->mutex);
523 INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan); 532 INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
524 dev_set_drvdata(dev, data); 533 dev_set_drvdata(dev, data);
525 534 data->cfg = of_device_get_match_data(dev);
526 if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || 535 if (!data->cfg)
527 of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || 536 return -EINVAL;
528 of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
529 data->num_phys = 2;
530 else
531 data->num_phys = 3;
532
533 if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") ||
534 of_device_is_compatible(np, "allwinner,sun7i-a20-usb-phy"))
535 data->disc_thresh = 2;
536 else
537 data->disc_thresh = 3;
538
539 if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy") ||
540 of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") ||
541 of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
542 dedicated_clocks = true;
543 else
544 dedicated_clocks = false;
545
546 if (of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
547 data->has_a33_phyctl = true;
548 537
549 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); 538 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl");
550 data->base = devm_ioremap_resource(dev, res); 539 data->base = devm_ioremap_resource(dev, res);
@@ -590,7 +579,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
590 } 579 }
591 } 580 }
592 581
593 for (i = 0; i < data->num_phys; i++) { 582 for (i = 0; i < data->cfg->num_phys; i++) {
594 struct sun4i_usb_phy *phy = data->phys + i; 583 struct sun4i_usb_phy *phy = data->phys + i;
595 char name[16]; 584 char name[16];
596 585
@@ -602,7 +591,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
602 phy->vbus = NULL; 591 phy->vbus = NULL;
603 } 592 }
604 593
605 if (dedicated_clocks) 594 if (data->cfg->dedicated_clocks)
606 snprintf(name, sizeof(name), "usb%d_phy", i); 595 snprintf(name, sizeof(name), "usb%d_phy", i);
607 else 596 else
608 strlcpy(name, "usb_phy", sizeof(name)); 597 strlcpy(name, "usb_phy", sizeof(name));
@@ -689,13 +678,61 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
689 return 0; 678 return 0;
690} 679}
691 680
681static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
682 .num_phys = 3,
683 .type = sun4i_a10_phy,
684 .disc_thresh = 3,
685 .phyctl_offset = REG_PHYCTL_A10,
686 .dedicated_clocks = false,
687};
688
689static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
690 .num_phys = 2,
691 .type = sun4i_a10_phy,
692 .disc_thresh = 2,
693 .phyctl_offset = REG_PHYCTL_A10,
694 .dedicated_clocks = false,
695};
696
697static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
698 .num_phys = 3,
699 .type = sun4i_a10_phy,
700 .disc_thresh = 3,
701 .phyctl_offset = REG_PHYCTL_A10,
702 .dedicated_clocks = true,
703};
704
705static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
706 .num_phys = 3,
707 .type = sun4i_a10_phy,
708 .disc_thresh = 2,
709 .phyctl_offset = REG_PHYCTL_A10,
710 .dedicated_clocks = false,
711};
712
713static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
714 .num_phys = 2,
715 .type = sun4i_a10_phy,
716 .disc_thresh = 3,
717 .phyctl_offset = REG_PHYCTL_A10,
718 .dedicated_clocks = true,
719};
720
721static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
722 .num_phys = 2,
723 .type = sun8i_a33_phy,
724 .disc_thresh = 3,
725 .phyctl_offset = REG_PHYCTL_A33,
726 .dedicated_clocks = true,
727};
728
692static const struct of_device_id sun4i_usb_phy_of_match[] = { 729static const struct of_device_id sun4i_usb_phy_of_match[] = {
693 { .compatible = "allwinner,sun4i-a10-usb-phy" }, 730 { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
694 { .compatible = "allwinner,sun5i-a13-usb-phy" }, 731 { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
695 { .compatible = "allwinner,sun6i-a31-usb-phy" }, 732 { .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg },
696 { .compatible = "allwinner,sun7i-a20-usb-phy" }, 733 { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg },
697 { .compatible = "allwinner,sun8i-a23-usb-phy" }, 734 { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg },
698 { .compatible = "allwinner,sun8i-a33-usb-phy" }, 735 { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg },
699 { }, 736 { },
700}; 737};
701MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); 738MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);