typec CC脚检测中断
1 2 3 4 5 | [TYPEC_ATTACH_DETACH_IRQ] = { .name = "typec-attach-detach" , .handler = smblite_typec_attach_detach_irq_handler, .wake = true , }, |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | irqreturn_t smblite_typec_attach_detach_irq_handler( int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; u8 stat; bool attached = false ; int rc; /* IRQ not expected to be executed for uUSB, return */ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) return IRQ_HANDLED; smblite_lib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n" , irq_data->name); rc = smblite_lib_read(chg, TYPE_C_STATE_MACHINE_STATUS_REG, &stat); if (rc < 0) { smblite_lib_err(chg, "Couldn't read TYPE_C_STATE_MACHINE_STATUS_REG rc=%d\n" , rc); return IRQ_HANDLED; } attached = !!(stat & TYPEC_ATTACH_DETACH_STATE_BIT); if (attached) { rc = smblite_lib_read(chg, TYPE_C_MISC_STATUS_REG, &stat); if (rc < 0) { smblite_lib_err(chg, "Couldn't read TYPE_C_MISC_STATUS_REG rc=%d\n" , rc); return IRQ_HANDLED; } if (smblite_lib_get_prop_dfp_mode(chg) == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { chg->sink_src_mode = AUDIO_ACCESS_MODE; typec_ra_ra_insertion(chg); } else if (stat & SNK_SRC_MODE_BIT) { chg->sink_src_mode = SRC_MODE; typec_sink_insertion(chg); //mode的切换 } else { chg->sink_src_mode = SINK_MODE; typec_src_insertion(chg); //mode的切换 } rc = typec_partner_register(chg); if (rc < 0) smblite_lib_err(chg, "Couldn't to register partner rc =%d\n" , rc); } else { switch (chg->sink_src_mode) { case SRC_MODE: typec_sink_removal(chg); break ; case SINK_MODE: case AUDIO_ACCESS_MODE: typec_src_removal(chg); break ; case UNATTACHED_MODE: default : typec_mode_unattached(chg); break ; } if (!chg->pr_swap_in_progress) chg->sink_src_mode = UNATTACHED_MODE; /* * Restore DRP mode on type-C cable disconnect if role * swap is not in progress, to ensure forced sink or src * mode configuration is reset properly. */ if (chg->typec_port && !chg->pr_swap_in_progress) { /* * Schedule the work to differentiate actual removal * of cable and detach interrupt during role swap, * unregister the partner only during actual cable * removal. */ cancel_delayed_work(&chg->pr_swap_detach_work); vote(chg->awake_votable, DETACH_DETECT_VOTER, true , 0); schedule_delayed_work(&chg->pr_swap_detach_work, msecs_to_jiffies(TYPEC_DETACH_DETECT_DELAY_MS)); smblite_lib_force_dr_mode(chg, TYPEC_PORT_DRP); /* * To handle cable removal during role * swap failure. */ chg->typec_role_swap_failed = false ; } } rc = smblite_lib_masked_write(chg, USB_CMD_PULLDOWN_REG, EN_PULLDOWN_USB_IN_BIT, attached ? 0 : EN_PULLDOWN_USB_IN_BIT); if (rc < 0) smblite_lib_err(chg, "Couldn't configure pulldown on USB_IN rc=%d\n" , rc); power_supply_changed(chg->usb_psy); return IRQ_HANDLED; } |
- typec的otg功能,是当otg线插上时CC pin会被到下拉GND,触发typec-attach-detach然后就会切换成host mode,识别设备:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | static void smblite_lib_notify_usb_host( struct smb_charger *chg, bool enable) { int rc = 0; /* LDO mode doesn't support OTG */ if (chg->ldo_mode) return ; if (enable) { smblite_lib_dbg(chg, PR_OTG, "enabling VBUS in OTG mode\n" ); rc = smblite_lib_masked_write(chg, DCDC_CMD_OTG_REG, OTG_EN_BIT, OTG_EN_BIT); //typec打开otg功能,给设备供电 if (rc < 0) { smblite_lib_err(chg, "Couldn't enable VBUS in OTG mode rc=%d\n" , rc); return ; } rc = smblite_lib_masked_write(chg, DCDC_BST_VREG_SEL, VBOOST_MASK, VBOOST_5P00V); if (rc < 0) { smblite_lib_err(chg, "Couldn't write BST_VREG_SEL rc=%d\n" , rc); return ; } smblite_lib_notify_extcon_props(chg, EXTCON_USB_HOST); } else { smblite_lib_dbg(chg, PR_OTG, "disabling VBUS in OTG mode\n" ); rc = smblite_lib_masked_write(chg, DCDC_CMD_OTG_REG, OTG_EN_BIT, 0); if (rc < 0) { smblite_lib_err(chg, "Couldn't disable VBUS in OTG mode rc=%d\n" , rc); return ; } } extcon_set_state_sync(chg->extcon, EXTCON_USB_HOST, enable); //切换host模式 chg->otg_present = enable; } |
当插入typec线CCpin会被上拉到vbus时,切换成device模式:
1 2 3 4 5 6 7 | static void smblite_lib_notify_device_mode( struct smb_charger *chg, bool enable) { if (enable) smblite_lib_notify_extcon_props(chg, EXTCON_USB); extcon_set_state_sync(chg->extcon, EXTCON_USB, enable); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)