提前说明一下有哪些“坑”。

1、PM8953 GPIO_8的TZ权限

2、PM8953 GPIO_8寄存器的写入保护

3、去掉高通默认的ID检测

4、增加dwc3的ID检测

5、增加TYPE-C的ID PIN控制

设备树配置:

&tlmm {
usb_id_default: usb_id_default {
mux {
pins = "gpio1";
function = "gpio";
}; config {
pins = "gpio1";
drive-strength = <2>;
bias-pull-up;
};
};
}; &pm8953_typec {
qcom,ssmux-gpio = <&tlmm 139 GPIO_ACTIVE_LOW>;
qcom,id-gpio = <&pm8953_gpios 8 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&typec_ssmux_config>;
status = "ok";
}; &usb3 {
vbus_dwc3-supply = <&usb_otg_switch>;
otg,id_det_pin = <&tlmm 1 0x0>;
extcon = <&usb_detect>;
pinctrl-names = "default";
pinctrl-0 = <&usb_id_default>;
}; &usb_otg_switch {
gpio = <&tlmm 3 0>;
}; &soc {
usb_detect: usb_detect {
compatible = "qcom,gpio-usbdetect";
interrupt-parent = <&spmi_bus>;
interrupts = <0x0 0xc6 0x0>;
interrupt-names = "vbus_det_irq";
qcom,vbus-det-gpio = <&pm8953_gpios 7 0x00>;
pinctrl-names = "default";
pinctrl-0 = <&pm8953_gpio7_default>;
};
};

修改PM8953 GPIO8 TZ权限

index e1d339e..dda5a23 100755
--- a/TZ.BF.4.0.5/trustzone_images/core/systemdrivers/pmic/config/msm8953_pm8950/src/pm_spmi_config.c
+++ b/TZ.BF.4.0.5/trustzone_images/core/systemdrivers/pmic/config/msm8953_pm8950/src/pm_spmi_config.c
@@ -167,7 +167,7 @@ SpmiCfg_ChannelCfg pm_spmi_pheriph_cfg [] = {0x0, 0xFE, 0, PM_RPM_OWNER, PM_RPM_OWNER}, /* TRIM */
- {0x0, 0xC7, 0, PM_WCONNECT_OWNER, SPMI_OPEN_OWNER}, /* GPIO8 */
+ {0x0, 0xC7, 0, PM_APPS_HLOS_OWNER, SPMI_OPEN_OWNER}, /* GPIO8 */
{0x0, 0xC6, 0, PM_APPS_HLOS_OWNER, SPMI_OPEN_OWNER}, /* GPIO7 */
{0x0, 0xC5, 0, PM_WCONNECT_OWNER, SPMI_OPEN_OWNER}, /* GPIO6 */
{0x0, 0xC4, 0, PM_WCONNECT_OWNER, SPMI_OPEN_OWNER}, /* GPIO5 */

  

去除PM8953 GPIO_8寄存器的写入保护

index 0f0b7ba..f7946e0 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -451,6 +451,7 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
dev_err(&pa->spmic->dev,
"error: impermissible write to peripheral sid:%d addr:0x%x\n",
sid, addr);
+ if (!(0xc740 == (addr & 0xc740))) // skip PM8953 GPIO_8 Register protect check
return -ENODEV;
}

  

去掉高通默认的ID检测

diff --git a/drivers/platform/msm/gpio-usbdetect.c b/drivers/platform/msm/gpio-usbdetect.c
index 6730d4a..d2cbdea 100644
--- a/drivers/platform/msm/gpio-usbdetect.c
+++ b/drivers/platform/msm/gpio-usbdetect.c
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/extcon.h>
#include <linux/regulator/consumer.h>
+#include <linux/delay.h> struct gpio_usbdetect {
struct platform_device *pdev;
@@ -45,66 +46,21 @@ static irqreturn_t gpio_usbdetect_vbus_irq(int irq, void *data)
struct gpio_usbdetect *usb = data;
union extcon_property_value val; - usb->vbus_state = gpio_get_value(usb->gpio);
+ usb->vbus_state = !!gpio_get_value(usb->gpio);
+
if (usb->vbus_state) {
- dev_dbg(&usb->pdev->dev, "setting vbus notification\n");
+ dev_err(&usb->pdev->dev, "xcz setting vbus notification\n");
val.intval = true;
- extcon_set_property(usb->extcon_dev, EXTCON_USB,
- EXTCON_PROP_USB_SS, val);
+
extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB, 1);
} else {
- dev_dbg(&usb->pdev->dev, "setting vbus removed notification\n");
+ dev_err(&usb->pdev->dev, "xcz setting vbus removed notification\n");
extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB, 0);
} return IRQ_HANDLED;
} -static irqreturn_t gpio_usbdetect_id_irq(int irq, void *data)
-{
- struct gpio_usbdetect *usb = data;
- int ret;
-
- ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL,
- &usb->id_state);
- if (ret < 0) {
- dev_err(&usb->pdev->dev, "unable to read ID IRQ LINE\n");
- return IRQ_HANDLED;
- }
-
- return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t gpio_usbdetect_id_irq_thread(int irq, void *data)
-{
- struct gpio_usbdetect *usb = data;
- bool curr_id_state;
- static int prev_id_state = -EINVAL;
- union extcon_property_value val;
-
- curr_id_state = usb->id_state;
- if (curr_id_state == prev_id_state) {
- dev_dbg(&usb->pdev->dev, "no change in ID state\n");
- return IRQ_HANDLED;
- }
-
- if (curr_id_state) {
- dev_dbg(&usb->pdev->dev, "stopping usb host\n");
- extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB_HOST, 0);
- enable_irq(usb->vbus_det_irq);
- } else {
- dev_dbg(&usb->pdev->dev, "starting usb HOST\n");
- disable_irq(usb->vbus_det_irq);
- val.intval = true;
- extcon_set_property(usb->extcon_dev, EXTCON_USB_HOST,
- EXTCON_PROP_USB_SS, val);
- extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB_HOST, 1);
- }
-
- prev_id_state = curr_id_state;
- return IRQ_HANDLED;
-}
-
static const u32 gpio_usb_extcon_exclusive[] = {0x3, 0}; static int gpio_usbdetect_probe(struct platform_device *pdev)
@@ -164,8 +120,6 @@ static int gpio_usbdetect_probe(struct platform_device *pdev)
"qcom,vbus-det-gpio", 0);
if (usb->gpio < 0) {
dev_err(&pdev->dev, "Failed to get gpio: %d\n", usb->gpio);
- rc = usb->gpio;
- goto error;
} rc = gpio_request(usb->gpio, "vbus-det-gpio");
@@ -174,7 +128,7 @@ static int gpio_usbdetect_probe(struct platform_device *pdev)
goto error;
} - usb->vbus_det_irq = gpio_to_irq(usb->gpio);
+ usb->vbus_det_irq = gpio_to_irq(usb->gpio);//0xc6;//= gpio_to_irq(usb->gpio);
if (usb->vbus_det_irq < 0) {
dev_err(&pdev->dev, "get vbus_det_irq failed\n");
rc = usb->vbus_det_irq;
@@ -191,35 +145,11 @@ static int gpio_usbdetect_probe(struct platform_device *pdev)
goto error;
} - usb->id_det_irq = platform_get_irq_byname(pdev, "pmic_id_irq");
- if (usb->id_det_irq < 0) {
- dev_err(&pdev->dev, "get id_det_irq failed\n");
- rc = usb->id_det_irq;
- goto error;
- }
-
- rc = devm_request_threaded_irq(&pdev->dev, usb->id_det_irq,
- gpio_usbdetect_id_irq,
- gpio_usbdetect_id_irq_thread,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT, "id_det_irq", usb);
- if (rc) {
- dev_err(&pdev->dev, "request for id_det_irq failed: %d\n", rc);
- goto error;
- }
+ usb->id_det_irq = platform_get_irq_byname(pdev, "vbus_det_irq"); enable_irq_wake(usb->vbus_det_irq);
- enable_irq_wake(usb->id_det_irq);
dev_set_drvdata(&pdev->dev, usb); - if (usb->id_det_irq) {
- gpio_usbdetect_id_irq(usb->id_det_irq, usb);
- if (!usb->id_state) {
- gpio_usbdetect_id_irq_thread(usb->id_det_irq, usb);
- return 0;
- }
- }
-
/* Read and report initial VBUS state */
gpio_usbdetect_vbus_irq(usb->vbus_det_irq, usb);

  

增加dwc3的ID检测

diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index f549047..cc54672 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -55,6 +55,8 @@
#include "debug.h"
#include "xhci.h" +#define DEBUG
+
#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */ /* time out to wait for USB cable status notification (in ms)*/
@@ -235,6 +237,8 @@ struct dwc3_msm {
bool use_pdc_interrupts;
enum dwc3_id_state id_state;
unsigned long lpm_flags;
+ int id_det_pin;
+ int id_det_irq;
#define MDWC3_SS_PHY_SUSPEND BIT(0)
#define MDWC3_ASYNC_IRQ_WAKE_CAPABILITY BIT(1)
#define MDWC3_POWER_COLLAPSE BIT(2)
@@ -290,7 +294,7 @@ struct dwc3_msm { #define DSTS_CONNECTSPD_SS 0x4 -
+static int dwc3_msm_id_notifier(struct notifier_block *nb, unsigned long event, void *ptr);
static void dwc3_pwr_event_handler(struct dwc3_msm *mdwc);
static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA);
static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
@@ -1860,13 +1864,8 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
reg |= DWC3_GCTL_CORESOFTRESET;
dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); - /*
- * If the core could not recover after MAX_ERROR_RECOVERY_TRIES,
- * skip the restart USB work and keep the core in softreset
- * state.
- */
- if (dwc->retries_on_error < MAX_ERROR_RECOVERY_TRIES)
- schedule_work(&mdwc->restart_usb_work);
+ /* restart USB which performs full reset and reconnect */
+ schedule_work(&mdwc->restart_usb_work);
break;
case DWC3_CONTROLLER_RESET_EVENT:
dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESET_EVENT received\n");
@@ -2828,6 +2827,17 @@ static irqreturn_t msm_dwc3_pwr_irq(int irq, void *data)
return IRQ_HANDLED;
} +// add 2020-02-24
+static irqreturn_t id_det_irq_handle(int irq, void *data)
+{
+ struct dwc3_msm *mdwc = data;
+
+ dwc3_msm_id_notifier(&mdwc->id_nb, gpio_get_value(mdwc->id_det_pin) ? 0 : 1, mdwc->extcon_id);
+
+ return IRQ_HANDLED;
+}
+// add 2020-02-24 end
+
static int dwc3_cpu_notifier_cb(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
@@ -2953,7 +2963,7 @@ static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc)
return 0;
} -static int dwc3_msm_id_notifier(struct notifier_block *nb,
+static int dwc3_msm_id_notifier(struct notifier_block *nb, //xcz
unsigned long event, void *ptr)
{
struct dwc3_msm *mdwc = container_of(nb, struct dwc3_msm, id_nb);
@@ -3005,7 +3015,10 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
struct dwc3_msm *mdwc = container_of(nb, struct dwc3_msm, vbus_nb);
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); - dev_dbg(mdwc->dev, "vbus:%ld event received\n", event);
+ dev_err(mdwc->dev, "vbus:%ld event received\n", event);
+
+ printk("xcz haha ===== vbus:%ld event received\n", event);
+ if (mdwc->vbus_active == event)
return NOTIFY_DONE;
@@ -3442,6 +3455,30 @@ static int dwc3_msm_probe(struct platform_device *pdev)
}
} + // add 2020-02-24
+ mdwc->id_det_pin = of_get_named_gpio(pdev->dev.of_node, "otg,id_det_pin", 0);
+ if (mdwc->id_det_pin > 0) {
+ ret = gpio_request(mdwc->id_det_pin, "id_det_pin");
+ if(0 != ret) {
+ dev_err(&pdev->dev, "xcz Otg id_det_pin request %d failed.\n", mdwc->id_det_pin);
+ }
+
+ mdwc->id_det_irq = gpio_to_irq(mdwc->id_det_pin);
+ dev_err(&pdev->dev, "xcz Otg id_det_pin: %d, irq: %d\n",
+ mdwc->id_det_pin, mdwc->id_det_irq);
+
+ ret = devm_request_irq(&pdev->dev,
+ mdwc->id_det_irq,
+ id_det_irq_handle,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "id_det_irq",
+ mdwc);
+ } else {
+ dev_err(&pdev->dev, "xcz Otg id_det_pin NUll\n");
+ }
+ // add 2020-02-24 end
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcsr_base");
if (!res) {
dev_dbg(&pdev->dev, "missing TCSR memory resource\n");
@@ -3701,7 +3738,8 @@ static int dwc3_msm_probe(struct platform_device *pdev)
if (pval.intval > 0)
dev_info(mdwc->dev, "charger detection in progress\n");
}
-
+ if(mdwc->id_det_pin > 0)
+ id_det_irq_handle(mdwc->id_det_irq, mdwc);
device_create_file(&pdev->dev, &dev_attr_mode);
device_create_file(&pdev->dev, &dev_attr_speed);
device_create_file(&pdev->dev, &dev_attr_usb_compliance_mode);

  

增加TYPE-C的ID PIN控制

diff --git a/drivers/power/supply/qcom/qpnp-typec.c b/drivers/power/supply/qcom/qpnp-typec.c
index 12aa16b..20f1a71 100644
--- a/drivers/power/supply/qcom/qpnp-typec.c
+++ b/drivers/power/supply/qcom/qpnp-typec.c
@@ -113,6 +113,7 @@ struct qpnp_typec_chip {
int ssmux_gpio;
enum of_gpio_flags gpio_flag;
int typec_state;
+ int id_gpio; /* Dual role support */
bool role_reversal_supported;
@@ -280,6 +281,15 @@ static int qpnp_typec_configure_ssmux(struct qpnp_typec_chip *chip,
return rc;
}
}
+
+ if (chip->id_gpio) {
+ rc = gpio_direction_input(chip->id_gpio);
+ if (rc) {
+ pr_err("failed to configure usb id gpio rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
break;
case CC_1:
case CC_2:
@@ -526,6 +536,8 @@ static irqreturn_t dfp_detect_handler(int irq, void *_chip)
pr_debug("UFP status reg = 0x%x DFP status reg = 0x%x\n",
reg[0], reg[1]); + // pull down USB ID pin to start host
+ gpio_direction_output(chip->id_gpio, 0);
out:
mutex_unlock(&chip->typec_lock);
return IRQ_HANDLED;
@@ -545,6 +557,8 @@ static irqreturn_t dfp_detach_handler(int irq, void *_chip) mutex_unlock(&chip->typec_lock); + // pull up USB ID pin to start device
+ gpio_direction_output(chip->id_gpio, 1);
return IRQ_HANDLED;
} @@ -589,6 +603,27 @@ static int qpnp_typec_parse_dt(struct qpnp_typec_chip *chip)
}
} + /* USB ID configuration gpio */
+ if (of_find_property(node, "qcom,id-gpio", NULL)) {
+ chip->id_gpio = of_get_named_gpio(node,
+ "qcom,id-gpio", 0);
+ if (!gpio_is_valid(chip->id_gpio)) {
+ if (chip->id_gpio != -EPROBE_DEFER)
+ pr_err("failed to get usb id config gpio=%d\n",
+ chip->id_gpio);
+ return chip->id_gpio;
+ }
+
+ rc = devm_gpio_request(chip->dev, chip->id_gpio,
+ "typec_usb_id_gpio");
+ if (rc) {
+ pr_err("failed to request usb id gpio rc=%d\n", rc);
+ chip->id_gpio = 0;
+ } else {
+ gpio_direction_input(chip->id_gpio);
+ }
+ }
+
/* SS-Mux regulator */
if (of_find_property(node, "ss-mux-supply", NULL)) {
chip->ss_mux_vreg = devm_regulator_get(chip->dev, "ss-mux");

  

MSM8953/SDM450 去PMI的USB3.0 TYPE-C Micro USB OTG功能适配的更多相关文章

  1. USB3.0驱动与2.0有什么区别

    安装好usb3.0驱动就可以驱动usb 3.0设备,能够适应于大部份主板,帮助用户解决usb3.0和电脑无法正常通讯的问题,并支持winxp,win7和win8系统,是目前网络上最好用的usb3.0万 ...

  2. 硕盟SM-T54(TYPE C转HDMI+VGA+USB3.0+PD3.0)

    硕盟SM-T54是一款TYPE C转HDMI+VGA+USB3.0+PD3.0四口扩展坞,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显示器.电视机或其他显示设备. ...

  3. 硕盟SM-T54| TYPE C转HDMI+VGA+USB3.0+PD3.0四合一多功能扩展坞

    硕盟SM-T54是一款 TYPE C转HDMI+VGA+USB3.0+PD3.0四合一多功能扩展坞,支持四口同时使用,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显 ...

  4. 硕盟 TYPE C转HDMI+VGA+USB3.0+PD3.0四口扩展坞

    硕盟SM-T54是一款USB-C 四合一多功能扩展坞,支持四口同时使用,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显示器.电视机或其他显示设备.产品可以接入硬盘. ...

  5. 硕盟SM-A44|USB3.0转RJ45千兆网口转换器(TYPE A USB3.0 TO RJ45)

    硕盟SM-A44是一款USB3.0转RJ45千兆网口转换器.,转换USB端口到以太网端口.它让你投入低成本就可以轻松拥有千兆以太网.可将网络连接到台式机,笔记本电脑等等设备.硕盟 USB千兆网卡采用嵌 ...

  6. 硕盟USB3.0 转RJ45千兆网卡 TYPE A USB3.0 TO RJ45

    硕盟SM-A44是一款USB3.0转RJ45千兆网口转换器.这是一种高性能和低开销的解决方案.转换USB端口到10 / 100/ 1000M以太网端口可以让您的笔记本,台式机电脑能够通过USB接口连接 ...

  7. AC6102开发板USB3.0测试和使用说明

    AC6102开发板USB3.0测试和使用说明 概述 AC6102上集成了一颗Cypress 推出的高性能USB3.0传输芯片CYUSB3014,Cypress称之为EZ-USBFX3.该芯片性能强劲, ...

  8. 关于在win7内集成usb3.0驱动。

    mac air 装了win7但是折腾良久还是无法升级,只能是重新安装. 很蛋疼.bootcamp 老是找不到驱动.只能是手动分区后U盘引导安装. 驱动的下载,直接在Os x 下用bootcamp 下载 ...

  9. VirtualBox虚拟机中启用usb3.0却无法显示u盘的解决方法

    主机系统为win7 64位,由于工作需要,安装了Virtualbox 5.18虚拟机,virtaulbox中安装了win7 32系统.以为下启用usb 3.0的步骤: 1.宿主机要支持 usb 3.0 ...

  10. USB3.0及NVME SSD安装WIN7X64

    USB3.0及NVME SSD安装WIN7X64https://tieba.baidu.com/p/4822034273?pn=1所有的人都是菜鸟过来的,不过有些人懂得自己动手找到答案:有些人则是懒得 ...

随机推荐

  1. 【磐维数据库】Oracle(透明网关)访问磐维数据库(PanWeiDB)

    磐维数据库(PanWeiDB)是由中国移动基于中国本土开源数据库openGauss打造的自研数据库产品,主要面向ICT基础设施.它具有高性能.高可靠性.高安全性和高兼容性的特点,能够支持集中式.分布式 ...

  2. 买了个mini主机当服务器

    虽然有苹果的电脑,但是在装一些软件的时候,从想着能不能有一个小型的服务器,免得各种设置什么帮我强各种别的导致Mac出现各种的异常,整体上的话去看了一些小的主机,看过苹果的MV迷你Mac,但是发现是太贵 ...

  3. 根据字符串,获取实体属性上的annotation,如:createTime” 找到对应实体属性中的 TableField(value = "create_time", fill = FieldFill.INSERT)

    根据字符串,获取实体属性上的annotation,如:createTime" 找到对应实体属性中的 TableField(value = "create_time", f ...

  4. mysql弱密码爆破

    mySQL弱密码  靶场:/vulhub/mysql/CVE-2012-2122  启动: docker-compose up -d 扫描端口 nmap -Sv -Pn -T4 靶机ip  看到在33 ...

  5. Windows通过修改注册表设置系统默认浏览器

    前段时间有个程序要求获取系统的默认浏览器,baidu.Google了好久,后又结合procmon.exe跟踪浏览器打开web页面的注册表操作信息,找到了最终的位置,这里做一个总结.亲测win10多个浏 ...

  6. gal game 杂谈——《GINKA》

    gal game 杂谈--<GINKA> 剧情梳理 Ps:女主分为小学阶段和高中阶段,这里称小学阶段为小时候的女主,高中阶段为大女主,分离出来爱的为GINKA(长相是小时候的女主). 1. ...

  7. MindSpore-2.4版本中的一些新特性

    技术背景 在前面的一篇博客中我们介绍了MindSpore-2.4-gpu的安装和其中可能出现的一些问题.这里我们在安装完成之后,可以尝试使用一些MindSpore新版本的特性.那么在安装之后,如果是使 ...

  8. 【朝花夕拾】蓝牙&WiFi常识篇

    一.蓝牙常识点 1.常见英文缩写 缩写 英文全称 释义 BLE Bluetooth Low Energy 低功耗蓝牙 BR Basic Rate 基本速率,一般说的经典蓝牙就是指BR/EDR EDR ...

  9. asp.net 简单日志收集

    做开发的都知道,完整的日志记录对问题的解决,回溯是多么的重要,多么的不可缺少. 那么我们怎么记录完整的日志? 今天,我们来说一说问题:从哪里开始记录呢?在哪里保存呢? IHttpModule,这个大家 ...

  10. vue 创建一个项目

    1.npm init -y 2.vue create 名称  3.manuall select features   [手动配置v2,v3] 4.选版本 5 6 启动:npm run serve