rk3588s 定制版 USB adb , USB2.0与USB3.0 区别,adb 由typeC 转换到USB3.0(第二部分)

硬件资源: rk3588s 核心板+定制的地板

软件资源: 网盘上的 android12 源码

1 硬件上

客户只想使用 type c 接口中的 usb2.0 OTG 。在硬件上,甚至连 CC芯片都没有连接。

关于一些前置的知识。

1 USB2.0 与 USB3.0 的区别。

usb3.0 兼容2.0 不就是相当于 无脑 include 吗。

2 adb 如何转换到 USB3.0 的接口。

这个资源网上已经有人发了,是3399 的,但是我们有验证过,不知道真的假的,假设是正确的。

我就完全 粘贴过来,方便以后参考。

这里 他的 typec0 与 typec1 使用的都是 2lane 的usb3.0 ,不知道,座子是typec的还是USB3.0 的。

互换了 otg 与 host.

然后就 涉及到了, 修改源码,这些我就看不懂了。

直接粘贴过来。


diff --git a/kernel/include/linux/phy/phy.h b/kernel/include/linux/phy/phy.h

index a3965c3..c0daa66 100644

--- a/kernel/include/linux/phy/phy.h

+++ b/kernel/include/linux/phy/phy.h

@@ -36,6 +36,7 @@ enum phy_mode {

* @power_on: powering on the phy

* @power_off: powering off the phy

* @set_mode: set the mode of the phy

  • * @set_vbusdet: usb disconnect of the phy

* @reset: resetting the phy

* @cp_test: prepare for the phy compliance test

* @owner: the module owner containing the ops

@@ -46,6 +47,7 @@ struct phy_ops {

int (*power_on)(struct phy *phy);

int (*power_off)(struct phy *phy);

int (*set_mode)(struct phy *phy, enum phy_mode mode);

  • int (*set_vbusdet)(struct phy *phy, bool level);

int (*reset)(struct phy *phy);

int (*cp_test)(struct phy *phy);

struct module *owner;

@@ -133,6 +135,7 @@ int phy_exit(struct phy *phy);

int phy_power_on(struct phy *phy);

int phy_power_off(struct phy *phy);

int phy_set_mode(struct phy *phy, enum phy_mode mode);

+int phy_set_vbusdet(struct phy *phy, bool level);

int phy_reset(struct phy *phy);

int phy_cp_test(struct phy *phy);

static inline int phy_get_bus_width(struct phy *phy)

@@ -247,6 +250,13 @@ static inline int phy_set_mode(struct phy *phy, enum phy_mode mode)

return -ENOSYS;

}

+static inline int phy_set_vbusdet(struct phy *phy, bool level)

+{

  • if (!phy)

  • return 0;

  • return -ENOSYS;

+}

static inline int phy_reset(struct phy *phy)

{

if (!phy)


diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c

index 66fb407..1f11ae1 100644

--- a/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c

+++ b/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c

@@ -37,6 +37,8 @@

#include <linux/usb/of.h>

#include <linux/usb/otg.h>

#include <linux/wakelock.h>

+#include <linux/gpio.h>

+#include <linux/of_gpio.h>

#define BIT_WRITEABLE_SHIFT 16

#define SCHEDULE_DELAY (60 * HZ)

@@ -250,6 +252,7 @@ struct rockchip_usb2phy_port {

struct delayed_work chg_work;

struct delayed_work otg_sm_work;

struct delayed_work sm_work;

  • struct delayed_work peripheral_work;

struct regulator *vbus;

const struct rockchip_usb2phy_port_cfg *port_cfg;

struct notifier_block event_nb;

@@ -816,12 +819,37 @@ static int rockchip_usb2phy_set_mode(struct phy *phy, enum phy_mode mode)

return ret;

}

+static int rockchip_usb2phy_set_vbusdet(struct phy *phy, bool level)

+{

  • struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);

  • struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);

  • int ret = 0;

  • if (rport->port_id != USB2PHY_PORT_OTG)

  • return ret;

  • if (rphy->phy_cfg->reg == 0xe460) {

  • if (level)

  • {

  • ret = regmap_write(rphy->grf, 0x4518, GENMASK(20, 20) | 0x10);

  • }

  • else

  • {

  • ret = regmap_write(rphy->grf, 0x4518, GENMASK(20, 20) | 0x00);

  • }

  • }

  • return ret;

+}

static const struct phy_ops rockchip_usb2phy_ops = {

.init = rockchip_usb2phy_init,

.exit = rockchip_usb2phy_exit,

.power_on = rockchip_usb2phy_power_on,

.power_off = rockchip_usb2phy_power_off,

.set_mode = rockchip_usb2phy_set_mode,

  • .set_vbusdet = rockchip_usb2phy_set_vbusdet,

.owner = THIS_MODULE,

};

@@ -1530,13 +1558,24 @@ static int rockchip_otg_event(struct notifier_block *nb,

return NOTIFY_DONE;

}

+static void rockchip_usb2phy_peripheral_work(struct work_struct *work)

+{

  • struct rockchip_usb2phy_port *rport =

  • container_of(work, struct rockchip_usb2phy_port, peripheral_work.work);

  • struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);

  • extcon_set_state(rphy->edev, EXTCON_USB, true);

  • extcon_sync(rphy->edev, EXTCON_USB);

  • schedule_delayed_work(&rport->peripheral_work, 3 * HZ);

+}

static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,

struct rockchip_usb2phy_port *rport,

struct device_node *child_np)

{

int ret;

int iddig;

  • int gpio_vbus_5v;

rport->port_id = USB2PHY_PORT_OTG;

rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];

rport->state = OTG_STATE_UNDEFINED;

@@ -1584,6 +1623,32 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,

rport->vbus = NULL;

}

  • rport->vbus_always_on =

  • of_property_read_bool(child_np, "rockchip,vbus-always-on");

  • if (rport->vbus_always_on)

  • {

  • ret = of_get_named_gpio_flags(child_np, "vbus-5v-gpios", 0, NULL);

  • if (ret < 0) {

  • printk("%s() Can not read property vbus-5v-gpio\n", FUNCTION);

  • } else {

  • gpio_vbus_5v = ret;

  • ret = devm_gpio_request(rphy->dev, gpio_vbus_5v, "vbus-gpio");

  • if(ret < 0)

  • printk("%s() devm_gpio_request vbus-gpio request ERROR\n", FUNCTION);

  • ret = gpio_direction_output(gpio_vbus_5v,1);

  • if(ret < 0)

  • printk("%s() gpio_direction_output vbus-gpio set ERROR\n", FUNCTION);

  • }

  • INIT_DELAYED_WORK(&rport->peripheral_work, rockchip_usb2phy_peripheral_work);

  • schedule_delayed_work(&rport->peripheral_work, 3 * HZ);

  • goto out;

  • }

rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);

if (rport->mode == USB_DR_MODE_HOST ||

rport->mode == USB_DR_MODE_UNKNOWN) {

@@ -1600,9 +1665,6 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,

goto out;

}

  • if (rport->vbus_always_on)

  • goto out;

wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");

INIT_DELAYED_WORK(&rport->bypass_uart_work,

rockchip_usb_bypass_uart_work);


diff --git a/kernel/drivers/phy/phy-core.c b/kernel/drivers/phy/phy-core.c

index 0587933..8dd548b 100644

--- a/kernel/drivers/phy/phy-core.c

+++ b/kernel/drivers/phy/phy-core.c

@@ -387,6 +387,21 @@ int phy_cp_test(struct phy *phy)

}

EXPORT_SYMBOL_GPL(phy_cp_test);

+int phy_set_vbusdet(struct phy *phy, bool level)

+{

  • int ret;

  • if (!phy || !phy->ops->set_vbusdet)

  • return 0;

  • mutex_lock(&phy->mutex);

  • ret = phy->ops->set_vbusdet(phy, level);

  • mutex_unlock(&phy->mutex);

  • return ret;

+}

+EXPORT_SYMBOL_GPL(phy_set_vbusdet);

/**

* _of_phy_get() - lookup and obtain a reference to a phy by phandle

* @np: device_node for which to get the phy


diff --git a/kernel/drivers/usb/dwc3/dwc3-rockchip.c b/kernel/drivers/usb/dwc3/dwc3-rockchip.c

index 539b89a..7cf9675 100644

--- a/kernel/drivers/usb/dwc3/dwc3-rockchip.c

+++ b/kernel/drivers/usb/dwc3/dwc3-rockchip.c

@@ -24,6 +24,7 @@

#include <linux/dma-mapping.h>

#include <linux/clk.h>

#include <linux/clk-provider.h>

+#include <linux/debugfs.h>

#include <linux/of.h>

#include <linux/of_platform.h>

#include <linux/pm_runtime.h>

@@ -31,6 +32,7 @@

#include <linux/freezer.h>

#include <linux/iopoll.h>

#include <linux/reset.h>

+#include <linux/uaccess.h>

#include <linux/usb.h>

#include <linux/usb/hcd.h>

#include <linux/usb/ch9.h>

@@ -47,6 +49,7 @@

struct dwc3_rockchip {

int num_clocks;

bool connected;

  • bool disconnect;

bool skip_suspend;

bool suspended;

bool force_mode;

@@ -56,6 +59,7 @@ struct dwc3_rockchip {

struct device *dev;

struct clk **clks;

struct dwc3 *dwc;

  • struct dentry *root;

struct reset_control *otg_rst;

struct extcon_dev *edev;

struct usb_hcd *hcd;

@@ -96,6 +100,7 @@ static ssize_t dwc3_mode_store(struct device *device,

struct dwc3_rockchip *rockchip = dev_get_drvdata(device);

struct dwc3 *dwc = rockchip->dwc;

enum usb_dr_mode new_dr_mode;

  • //char buf[32];

if (!rockchip->original_dr_mode)

rockchip->original_dr_mode = dwc->dr_mode;

@@ -107,15 +112,21 @@ static ssize_t dwc3_mode_store(struct device *device,

if (!strncmp(buf, "0", 1) || !strncmp(buf, "otg", 3)) {

new_dr_mode = USB_DR_MODE_OTG;

  • phy_set_vbusdet(dwc->usb2_generic_phy, 0);

} else if (!strncmp(buf, "1", 1) || !strncmp(buf, "host", 4)) {

new_dr_mode = USB_DR_MODE_HOST;

  • phy_set_vbusdet(dwc->usb2_generic_phy, 0);

} else if (!strncmp(buf, "2", 1) || !strncmp(buf, "peripheral", 10)) {

new_dr_mode = USB_DR_MODE_PERIPHERAL;

  • phy_set_vbusdet(dwc->usb2_generic_phy, 1);

} else {

dev_info(rockchip->dev, "illegal dr_mode\n");

  • phy_set_vbusdet(dwc->usb2_generic_phy, 0);

return count;

}

  • msleep(200);

if (dwc->dr_mode == new_dr_mode) {

dev_info(rockchip->dev, "Same with current dr_mode\n");

return count;

@@ -378,6 +389,17 @@ static void dwc3_rockchip_otg_extcon_evt_work(struct work_struct *work)

mutex_lock(&rockchip->lock);

  • if (extcon_get_cable_state_(edev, EXTCON_USB)) {

  • if ((dwc->link_state == DWC3_LINK_STATE_U3) && !rockchip->disconnect) {

  • phy_set_vbusdet(dwc->usb2_generic_phy, 0);

  • msleep(3000);

  • phy_set_vbusdet(dwc->usb2_generic_phy, 1);

  • rockchip->disconnect = true;

  • } else if(dwc->link_state == DWC3_LINK_STATE_U0) {

  • rockchip->disconnect = false;

  • }

  • }

if (rockchip->force_mode ? dwc->dr_mode == USB_DR_MODE_PERIPHERAL :

extcon_get_cable_state_(edev, EXTCON_USB)) {

if (rockchip->connected)

@@ -624,6 +646,7 @@ out:

static int dwc3_rockchip_get_extcon_dev(struct dwc3_rockchip *rockchip)

{

  • //int ret;

struct device *dev = rockchip->dev;

struct extcon_dev *edev;

@@ -743,6 +766,7 @@ static int dwc3_rockchip_probe(struct platform_device *pdev)

struct device *dev = &pdev->dev;

struct device_node *np = dev->of_node, *child;

struct platform_device *child_pdev;

  • //struct usb_hcd *hcd = NULL;

unsigned int count;

int ret;


那么是不是说,我自己在3588s上, 我改过了 typec0 之后 还需要在 android 系统启动之后,再做些设置呢。

感觉很像,我改过 typec 0 之后, android得打印信息可能与这个有关。

3 adb 的时候,是主设备还是从设备。

是做为从设备。

4 adb 使用的是 usb3.0 还是usb2.0

这是不是说,在adb 的时候,既可以使用 3.0 , 也可以使用 2.0 ,是自动适应的。

2 软件上的修改。

我参考的是 3588的 地板的设计, 在3588上 USB3.0 有这种设计。

3588底板原理图如下:

3588 核心板的原理图如下。

我参考一下typeC0 的引脚。

然后来看一下 TYPEC 1 的引脚。

所以 我觉得 3588 在软件上应该也是 有相应的设置的。

题外话,这里看一个 关于 typec 与 dp的关系的配置。

3588 核心板上的这几个图说的很明白了。

我去参考一下。

对于 typec1 的配置,就有这些,因为在硬件上 把它作为一个 USB3.0+USB2.0 使用了。只是 HOSt。

但是 type c 0 的配置就有很多。

所以 在软件上 我只要 在3588S的设备数中 ,去掉 typec0 的CC芯片的配置+dwc3_0 中,配置成 HOSt模式,应该在客户的底板上也是可以接上 USB的。

接下来就是我对 3588s的设备数的配置。

编译 + 烧写,之后测试。

发现 接上 USB+鼠标都是正常的。

但是有一些不必要的打印信息:

这些个报错的原因难道说还要 在android 文件系统上做些适配吗?

当然这些报错是不影响使用的。

但是看着不好看。

目前还是可以进一步去调试的,目前 typeC 的usb2.0 作为主设备是没有问题了,但是能不能 作为一个OTG设备呢?

3 我自己的实际的测试。


问题: 我现在 发现 在 3588S的设备数中有一个 gpio 我控制不了。

最原始的状态。

但是实际测试 这个GPIO 是可以 用的。

总结: 也最是, 他们只配置了 gpio 子系统,没有配置 pinctrl 子系统,但是是可以用的。

我自己的问题:

如果我把 GPIO4_A5 ,换成 GPIO4_A7 的话,然后在设备数中 改了 gpio+pinctrl 的话,烧写+编译测量发现, 这个脚是没有点评的。

然后又把设备数改回去,发现一个现象。

就是,板卡只有 在插上 typec 的时候,这个脚才会有 到电平,如果不插 type c 的话, 这个脚 , 是没有高电平的。

这就是说, 这个脚 只有在检测到 插拔之后,才会由驱动 去配置 高低电平。

我知道 3588 usb3.0 是通过 typec 转换过来的, 我去对比一下 两者的设备树的区别。

电源节点是这样的。

typec 的节点是这样的。

cc芯片引用了, typec 的电源节点。

电源节点是这样的。

总结一下:  在3588 中, usb3.0 与typec 的电源节点是两个节点。并且是单独引用的。

再来看看 我的 3588S的设备数的逻辑。

可以看到也是 在CC芯片中 引用了这个电源节点,所以我之前一直配置的 gpio的配置会失效。

那么我需要在 phy 的配置中重新引入这个节点。

我的疑问: usb 适配器的驱动是如何控制 电源驱动的呢,按理说,调用了驱动就应该自动把gpio拉高的。,先不管这个问题。

资源 : 在瑞芯微的文档里 , 是有关于这个问题的说明的。

接下来我 继续去修改设备树。

首先就是去掉 关于 CC芯片的内容。

然后是 添加相关的内容。

首先是 GPIO的添加。

这里我先不改。

然后是 phy 节点的更改。

然后是关于 dwc节点的更改。

相关推荐
CCTV果冻爽2 天前
ADB ROOT开启流程
adb
WZF-Sang2 天前
【MySQL】数据类型【mysql当中各自经典的数据类型的学习和使用】
linux·数据库·sql·学习·mysql·adb
我命由我123452 天前
ADB 之 logcat 极简小抄(过滤日志、保存日志到文件)
android·运维·adb·android studio·安卓·运维开发·android-studio
不吃饭的猪2 天前
mysql一主2从部署
android·mysql·adb
lhxwished3 天前
MySQL
数据库·mysql·adb
CCTV果冻爽3 天前
USB开启ADB设置流程
adb
爱吃奶酪的松鼠丶4 天前
adb的安装和使用 以及安装Frida 16.0.10+雷电模拟器
adb
Mr-Apple5 天前
orangepi部署web环境
android·前端·adb
轩轶子5 天前
【MySQL-初级】mysql基础操作(账户、数据库、表的增删查改)
数据库·mysql·adb
安卓机器5 天前
玩机搞机-----如何简单的使用ADB指令来卸载和冻结系统应用 无需root权限 详细操作图示教程
adb·adb卸载·adb冻结