hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/phy/allwinner/phy-sun4i-usb.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Allwinner sun4i USB phy driver
34 *
....@@ -6,25 +7,16 @@
67 * Based on code from
78 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
89 *
9
- * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
10
+ * Modelled after: Samsung S5P/Exynos SoC series MIPI CSIS/DSIM DPHY driver
1011 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
1112 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
12
- *
13
- * This program is free software; you can redistribute it and/or modify
14
- * it under the terms of the GNU General Public License as published by
15
- * the Free Software Foundation; either version 2 of the License, or
16
- * (at your option) any later version.
17
- *
18
- * This program is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- * GNU General Public License for more details.
2213 */
2314
2415 #include <linux/clk.h>
2516 #include <linux/delay.h>
2617 #include <linux/err.h>
2718 #include <linux/extcon-provider.h>
19
+#include <linux/gpio/consumer.h>
2820 #include <linux/io.h>
2921 #include <linux/interrupt.h>
3022 #include <linux/kernel.h>
....@@ -115,6 +107,7 @@
115107 sun8i_r40_phy,
116108 sun8i_v3s_phy,
117109 sun50i_a64_phy,
110
+ sun50i_h6_phy,
118111 };
119112
120113 struct sun4i_usb_phy_cfg {
....@@ -295,7 +288,8 @@
295288 return ret;
296289 }
297290
298
- if (data->cfg->type == sun8i_a83t_phy) {
291
+ if (data->cfg->type == sun8i_a83t_phy ||
292
+ data->cfg->type == sun50i_h6_phy) {
299293 if (phy->index == 0) {
300294 val = readl(data->base + data->cfg->phyctl_offset);
301295 val |= PHY_CTL_VBUSVLDEXT;
....@@ -344,7 +338,8 @@
344338 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
345339
346340 if (phy->index == 0) {
347
- if (data->cfg->type == sun8i_a83t_phy) {
341
+ if (data->cfg->type == sun8i_a83t_phy ||
342
+ data->cfg->type == sun50i_h6_phy) {
348343 void __iomem *phyctl = data->base +
349344 data->cfg->phyctl_offset;
350345
....@@ -475,7 +470,8 @@
475470 return 0;
476471 }
477472
478
-static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode)
473
+static int sun4i_usb_phy_set_mode(struct phy *_phy,
474
+ enum phy_mode mode, int submode)
479475 {
480476 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
481477 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
....@@ -967,6 +963,17 @@
967963 .phy0_dual_route = true,
968964 };
969965
966
+static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
967
+ .num_phys = 4,
968
+ .type = sun50i_h6_phy,
969
+ .disc_thresh = 3,
970
+ .phyctl_offset = REG_PHYCTL_A33,
971
+ .dedicated_clocks = true,
972
+ .enable_pmu_unk1 = true,
973
+ .phy0_dual_route = true,
974
+ .missing_phys = BIT(1) | BIT(2),
975
+};
976
+
970977 static const struct of_device_id sun4i_usb_phy_of_match[] = {
971978 { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
972979 { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
....@@ -980,6 +987,7 @@
980987 { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg },
981988 { .compatible = "allwinner,sun50i-a64-usb-phy",
982989 .data = &sun50i_a64_cfg},
990
+ { .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg },
983991 { },
984992 };
985993 MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);