| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Allwinner sun4i USB phy driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Based on code from |
|---|
| 7 | 8 | * Allwinner Technology Co., Ltd. <www.allwinnertech.com> |
|---|
| 8 | 9 | * |
|---|
| 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 |
|---|
| 10 | 11 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
|---|
| 11 | 12 | * 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. |
|---|
| 22 | 13 | */ |
|---|
| 23 | 14 | |
|---|
| 24 | 15 | #include <linux/clk.h> |
|---|
| 25 | 16 | #include <linux/delay.h> |
|---|
| 26 | 17 | #include <linux/err.h> |
|---|
| 27 | 18 | #include <linux/extcon-provider.h> |
|---|
| 19 | +#include <linux/gpio/consumer.h> |
|---|
| 28 | 20 | #include <linux/io.h> |
|---|
| 29 | 21 | #include <linux/interrupt.h> |
|---|
| 30 | 22 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 115 | 107 | sun8i_r40_phy, |
|---|
| 116 | 108 | sun8i_v3s_phy, |
|---|
| 117 | 109 | sun50i_a64_phy, |
|---|
| 110 | + sun50i_h6_phy, |
|---|
| 118 | 111 | }; |
|---|
| 119 | 112 | |
|---|
| 120 | 113 | struct sun4i_usb_phy_cfg { |
|---|
| .. | .. |
|---|
| 295 | 288 | return ret; |
|---|
| 296 | 289 | } |
|---|
| 297 | 290 | |
|---|
| 298 | | - if (data->cfg->type == sun8i_a83t_phy) { |
|---|
| 291 | + if (data->cfg->type == sun8i_a83t_phy || |
|---|
| 292 | + data->cfg->type == sun50i_h6_phy) { |
|---|
| 299 | 293 | if (phy->index == 0) { |
|---|
| 300 | 294 | val = readl(data->base + data->cfg->phyctl_offset); |
|---|
| 301 | 295 | val |= PHY_CTL_VBUSVLDEXT; |
|---|
| .. | .. |
|---|
| 344 | 338 | struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); |
|---|
| 345 | 339 | |
|---|
| 346 | 340 | 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) { |
|---|
| 348 | 343 | void __iomem *phyctl = data->base + |
|---|
| 349 | 344 | data->cfg->phyctl_offset; |
|---|
| 350 | 345 | |
|---|
| .. | .. |
|---|
| 475 | 470 | return 0; |
|---|
| 476 | 471 | } |
|---|
| 477 | 472 | |
|---|
| 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) |
|---|
| 479 | 475 | { |
|---|
| 480 | 476 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); |
|---|
| 481 | 477 | struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); |
|---|
| .. | .. |
|---|
| 967 | 963 | .phy0_dual_route = true, |
|---|
| 968 | 964 | }; |
|---|
| 969 | 965 | |
|---|
| 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 | + |
|---|
| 970 | 977 | static const struct of_device_id sun4i_usb_phy_of_match[] = { |
|---|
| 971 | 978 | { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, |
|---|
| 972 | 979 | { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, |
|---|
| .. | .. |
|---|
| 980 | 987 | { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg }, |
|---|
| 981 | 988 | { .compatible = "allwinner,sun50i-a64-usb-phy", |
|---|
| 982 | 989 | .data = &sun50i_a64_cfg}, |
|---|
| 990 | + { .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg }, |
|---|
| 983 | 991 | { }, |
|---|
| 984 | 992 | }; |
|---|
| 985 | 993 | MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); |
|---|