[TYPEC_ATTACH_DETACH_IRQ] = { .name = "typec-attach-detach", .handler = smblite_typec_attach_detach_irq_handler, .wake = true, },
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; }
标签:lib,chg,CC,typec,中断,mode,rc,smblite From: https://www.cnblogs.com/yuanqiangfei/p/17535599.html