static int dwc_otg_charger_hwdet(bool enable) { int retval; struct usb_phy *phy; struct dwc_otg2 *otg = dwc3_get_otg(); /* Just return if charger detection is not enabled */ if (!charger_detect_enable(otg)) return 0; phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!phy) return -ENODEV; if (enable) { retval = usb_phy_io_write(phy, PWCTRL_HWDETECT, TUSB1211_POWER_CONTROL_SET); if (retval) return retval; otg_dbg(otg, "set HWDETECT\n"); } else { retval = usb_phy_io_write(phy, PWCTRL_HWDETECT, TUSB1211_POWER_CONTROL_CLR); if (retval) return retval; otg_dbg(otg, "clear HWDETECT\n"); } usb_put_phy(phy); return 0; }
static void ci13xxx_msm_disconnect(void) { struct ci13xxx *udc = _udc; struct usb_phy *phy = udc->transceiver; if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP)) { u32 temp; usb_phy_io_write(phy, ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL, ULPI_CLR(ULPI_MISC_A)); /* Notify LINK of VBUS LOW */ temp = readl_relaxed(USB_USBCMD); temp &= ~USBCMD_SESS_VLD_CTRL; writel_relaxed(temp, USB_USBCMD); /* * Add memory barrier as it is must to complete * above USB PHY and Link register writes before * moving ahead with USB peripheral mode enumeration, * otherwise USB peripheral mode may not work. */ mb(); } }
static void ci13xxx_msm_connect(struct ci13xxx *ci) { struct usb_phy *phy = ci->transceiver; if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP)) { int temp; usb_phy_io_write(phy, ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL, ULPI_SET(ULPI_MISC_A)); temp = readl_relaxed(USB_GENCONFIG2); temp |= GENCFG2_SESS_VLD_CTRL_EN; writel_relaxed(temp, USB_GENCONFIG2); temp = readl_relaxed(USB_USBCMD); temp |= USBCMD_SESS_VLD_CTRL; writel_relaxed(temp, USB_USBCMD); /* * Add memory barrier as it is must to complete * above USB PHY and Link register writes before * moving ahead with USB peripheral mode enumeration, * otherwise USB peripheral mode may not work. */ mb(); } }
static int ulpi_check_integrity(struct usb_phy *phy) { int ret, i; unsigned int val = 0x55; for (i = 0; i < 2; i++) { ret = usb_phy_io_write(phy, val, ULPI_SCRATCH); if (ret < 0) return ret; ret = usb_phy_io_read(phy, ULPI_SCRATCH); if (ret < 0) return ret; if (ret != val) { pr_err("ULPI integrity check: failed!"); return -ENODEV; } val = val << 1; } pr_info("ULPI integrity check: passed.\n"); return 0; }
static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) { struct usb_phy *phy = otg->phy; unsigned int flags = usb_phy_io_read(phy, ULPI_IFC_CTRL); if (!host) { otg->host = NULL; return 0; } otg->host = host; flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE | ULPI_IFC_CTRL_3_PIN_SERIAL_MODE | ULPI_IFC_CTRL_CARKITMODE); if (phy->flags & ULPI_IC_6PIN_SERIAL) flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE; else if (phy->flags & ULPI_IC_3PIN_SERIAL) flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE; else if (phy->flags & ULPI_IC_CARKIT) flags |= ULPI_IFC_CTRL_CARKITMODE; return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); }
static void usb2phy_eye_optimization(struct dwc_otg2 *otg) { void __iomem *addr; struct usb_phy *phy; struct intel_dwc_otg_pdata *data; if (!otg || !otg->otg_data) return; data = (struct intel_dwc_otg_pdata *)otg->otg_data; phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!phy) return; if ((data->usb2_phy_type == USB2_PHY_ULPI) && !!data->ulpi_eye_calibration) usb_phy_io_write(phy, data->ulpi_eye_calibration, TUSB1211_VENDOR_SPECIFIC1_SET); else if ((data->usb2_phy_type == USB2_PHY_UTMI) && !!data->utmi_eye_calibration) { addr = ioremap_nocache(UTMI_PHY_USB2PERPORT, 4); if (!addr) { otg_info(otg, "UTMI phy register ioremap failed, use default setup!\n"); usb_put_phy(phy); return; } writel(data->utmi_eye_calibration, addr); iounmap(addr); } else otg_info(otg, "usb2 phy eye optimization fail, use default setup!\n"); usb_put_phy(phy); }
static void ci13xxx_msm_notify_event(struct ci13xxx *ci, unsigned event) { struct device *dev = ci->gadget.dev.parent; int val; switch (event) { case CI13XXX_CONTROLLER_RESET_EVENT: dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n"); writel(0, USB_AHBBURST); writel(0, USB_AHBMODE); break; case CI13XXX_CONTROLLER_STOPPED_EVENT: dev_dbg(dev, "CI13XXX_CONTROLLER_STOPPED_EVENT received\n"); /* * Put the transceiver in non-driving mode. Otherwise host * may not detect soft-disconnection. */ val = usb_phy_io_read(ci->transceiver, ULPI_FUNC_CTRL); val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; usb_phy_io_write(ci->transceiver, val, ULPI_FUNC_CTRL); break; default: dev_dbg(dev, "unknown ci13xxx event\n"); break; } }
static void ci13xxx_msm_connect(void) { struct ci13xxx *udc = _udc; struct usb_phy *phy = udc->transceiver; if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP)) { int temp; usb_phy_io_write(phy, ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL, ULPI_SET(ULPI_MISC_A)); temp = readl_relaxed(USB_GENCONFIG2); temp |= GENCFG2_SESS_VLD_CTRL_EN; writel_relaxed(temp, USB_GENCONFIG2); temp = readl_relaxed(USB_USBCMD); temp |= USBCMD_SESS_VLD_CTRL; writel_relaxed(temp, USB_USBCMD); /* */ mb(); } }
static void ci13xxx_msm_disconnect(struct ci13xxx *ci) { struct usb_phy *phy = ci->transceiver; if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP)) usb_phy_io_write(phy, ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL, ULPI_CLR(ULPI_MISC_A)); }
static int ulpi_set_vbus(struct usb_otg *otg, bool on) { struct usb_phy *phy = otg->phy; unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL); flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); if (on) { if (phy->flags & ULPI_OTG_DRVVBUS) flags |= ULPI_OTG_CTRL_DRVVBUS; if (phy->flags & ULPI_OTG_DRVVBUS_EXT) flags |= ULPI_OTG_CTRL_DRVVBUS_EXT; } return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); }
static int ulpi_set_ic_flags(struct usb_phy *phy) { unsigned int flags = 0; if (phy->flags & ULPI_IC_AUTORESUME) flags |= ULPI_IFC_CTRL_AUTORESUME; if (phy->flags & ULPI_IC_EXTVBUS_INDINV) flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS; if (phy->flags & ULPI_IC_IND_PASSTHRU) flags |= ULPI_IFC_CTRL_PASSTHRU; if (phy->flags & ULPI_IC_PROTECT_DIS) flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE; return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); }
static void usb2phy_eye_optimization(struct dwc_otg2 *otg) { struct intel_dwc_otg_pdata *data; struct usb_phy *phy; data = (struct intel_dwc_otg_pdata *)otg->otg_data; phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!phy) return; /* Modify VS1 for better quality in eye diagram */ if (data && data->ti_phy_vs1) usb_phy_io_write(phy, data->ti_phy_vs1, TUSB1211_VENDOR_SPECIFIC1_SET); usb_put_phy(phy); }
static int ulpi_set_fc_flags(struct usb_phy *phy) { unsigned int flags = 0; /* * ULPI Specification rev.1.1 default * for XcvrSelect is Full Speed. */ if (phy->flags & ULPI_FC_HS) flags |= ULPI_FUNC_CTRL_HIGH_SPEED; else if (phy->flags & ULPI_FC_LS) flags |= ULPI_FUNC_CTRL_LOW_SPEED; else if (phy->flags & ULPI_FC_FS4LS) flags |= ULPI_FUNC_CTRL_FS4LS; else flags |= ULPI_FUNC_CTRL_FULL_SPEED; if (phy->flags & ULPI_FC_TERMSEL) flags |= ULPI_FUNC_CTRL_TERMSELECT; /* * ULPI Specification rev.1.1 default * for OpMode is Normal Operation. */ if (phy->flags & ULPI_FC_OP_NODRV) flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; else if (phy->flags & ULPI_FC_OP_DIS_NRZI) flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI; else if (phy->flags & ULPI_FC_OP_NSYNC_NEOP) flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP; else flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL; /* * ULPI Specification rev.1.1 default * for SuspendM is Powered. */ flags |= ULPI_FUNC_CTRL_SUSPENDM; return usb_phy_io_write(phy, flags, ULPI_FUNC_CTRL); }
static void ci13xxx_msm_disconnect(void) { struct ci13xxx *udc = _udc; struct usb_phy *phy = udc->transceiver; if (phy && (phy->flags & ENABLE_DP_MANUAL_PULLUP)) { u32 temp; usb_phy_io_write(phy, ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL, ULPI_CLR(ULPI_MISC_A)); temp = readl_relaxed(USB_USBCMD); temp &= ~USBCMD_SESS_VLD_CTRL; writel_relaxed(temp, USB_USBCMD); mb(); } }
static int msm_phy_notify_disconnect(struct usb_phy *phy, enum usb_device_speed speed) { struct msm_otg *motg = container_of(phy, struct msm_otg, phy); int val; if (motg->manual_pullup) { val = ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL; usb_phy_io_write(phy, val, ULPI_CLR(ULPI_MISC_A)); } /* * Put the transceiver in non-driving mode. Otherwise host * may not detect soft-disconnection. */ val = ulpi_read(phy, ULPI_FUNC_CTRL); val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; ulpi_write(phy, val, ULPI_FUNC_CTRL); return 0; }
static int ulpi_set_otg_flags(struct usb_phy *phy) { unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN | ULPI_OTG_CTRL_DM_PULLDOWN; if (phy->flags & ULPI_OTG_ID_PULLUP) flags |= ULPI_OTG_CTRL_ID_PULLUP; /* * ULPI Specification rev.1.1 default * for Dp/DmPulldown is enabled. */ if (phy->flags & ULPI_OTG_DP_PULLDOWN_DIS) flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN; if (phy->flags & ULPI_OTG_DM_PULLDOWN_DIS) flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN; if (phy->flags & ULPI_OTG_EXTVBUSIND) flags |= ULPI_OTG_CTRL_EXTVBUSIND; return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); }
static int ehci_mxc_drv_probe(struct platform_device *pdev) { struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; int irq, ret; unsigned int flags; struct ehci_mxc_priv *priv; struct device *dev = &pdev->dev; struct ehci_hcd *ehci; dev_info(&pdev->dev, "initializing i.MX USB Controller\n"); if (!pdata) { dev_err(dev, "No platform data given, bailing out.\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev)); if (!hcd) return -ENOMEM; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; goto err_alloc; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "Found HC with no register addr. Check setup!\n"); ret = -ENODEV; goto err_get_resource; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(dev, "controller already in use\n"); ret = -EBUSY; goto err_request_mem; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(dev, "error mapping memory\n"); ret = -EFAULT; goto err_ioremap; } priv->usbclk = clk_get(dev, "usb"); if (IS_ERR(priv->usbclk)) { ret = PTR_ERR(priv->usbclk); goto err_clk; } clk_enable(priv->usbclk); if (!cpu_is_mx35() && !cpu_is_mx25()) { priv->ahbclk = clk_get(dev, "usb_ahb"); if (IS_ERR(priv->ahbclk)) { ret = PTR_ERR(priv->ahbclk); goto err_clk_ahb; } clk_enable(priv->ahbclk); } if (cpu_is_mx51() && (pdev->id == 0)) { priv->phy1clk = clk_get(dev, "usb_phy1"); if (IS_ERR(priv->phy1clk)) { ret = PTR_ERR(priv->phy1clk); goto err_clk_phy; } clk_enable(priv->phy1clk); } if (pdata->init) { ret = pdata->init(pdev); if (ret) { dev_err(dev, "platform init failed\n"); goto err_init; } mdelay(10); } ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); msleep(10); if (pdata->otg) { pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; ret = usb_phy_init(pdata->otg); if (ret) { dev_err(dev, "unable to init transceiver, probably missing\n"); ret = -ENODEV; goto err_add; } ret = otg_set_vbus(pdata->otg->otg, 1); if (ret) { dev_err(dev, "unable to enable vbus on transceiver\n"); goto err_add; } } priv->hcd = hcd; platform_set_drvdata(pdev, priv); ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto err_add; if (pdata->otg) { if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) { flags = usb_phy_io_read(pdata->otg, ULPI_OTG_CTRL); flags |= ULPI_OTG_CTRL_CHRGVBUS; ret = usb_phy_io_write(pdata->otg, flags, ULPI_OTG_CTRL); if (ret) { dev_err(dev, "unable to set CHRVBUS\n"); goto err_add; } } } return 0; err_add: if (pdata && pdata->exit) pdata->exit(pdev); err_init: if (priv->phy1clk) { clk_disable(priv->phy1clk); clk_put(priv->phy1clk); } err_clk_phy: if (priv->ahbclk) { clk_disable(priv->ahbclk); clk_put(priv->ahbclk); } err_clk_ahb: clk_disable(priv->usbclk); clk_put(priv->usbclk); err_clk: iounmap(hcd->regs); err_ioremap: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_request_mem: err_get_resource: kfree(priv); err_alloc: usb_put_hcd(hcd); return ret; }
static enum power_supply_charger_cable_type dwc3_intel_byt_get_charger_type(struct dwc_otg2 *otg) { struct usb_phy *phy; u8 val, vdat_det, chgd_serx_dm; unsigned long timeout, interval; enum power_supply_charger_cable_type type = POWER_SUPPLY_CHARGER_TYPE_NONE; /* No need to do charger detection if not enabled */ if (!charger_detect_enable(otg)) return POWER_SUPPLY_CHARGER_TYPE_USB_SDP; phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!phy) { otg_err(otg, "Get USB2 PHY failed\n"); return POWER_SUPPLY_CHARGER_TYPE_NONE; } /* PHY Enable: * Power on PHY */ enable_usb_phy(otg, true); /* Wait 10ms (~5ms before PHY de-asserts DIR, * XXus for initial Link reg sync-up).*/ msleep(20); /* DCD Enable: Change OPMODE to 01 (Non-driving), * TermSel to 0, & * XcvrSel to 01 (enable FS xcvr) */ usb_phy_io_write(phy, FUNCCTRL_OPMODE(1) | FUNCCTRL_XCVRSELECT(1), TUSB1211_FUNC_CTRL_SET); usb_phy_io_write(phy, FUNCCTRL_OPMODE(2) | FUNCCTRL_XCVRSELECT(2) | FUNCCTRL_TERMSELECT, TUSB1211_FUNC_CTRL_CLR); /*Enable SW control*/ usb_phy_io_write(phy, PWCTRL_SW_CONTROL, TUSB1211_POWER_CONTROL_SET); /* Enable IDPSRC */ usb_phy_io_write(phy, VS3_CHGD_IDP_SRC_EN, TUSB1211_VENDOR_SPECIFIC3_SET); /* Check DCD result, use same polling parameter */ timeout = jiffies + msecs_to_jiffies(DATACON_TIMEOUT); interval = DATACON_INTERVAL * 1000; /* us */ /* DCD Check: * Delay 66.5 ms. (Note: * TIDP_SRC_ON + TCHGD_SERX_DEB = * 347.8us + 66.1ms). */ usleep_range(66500, 67000); while (!time_after(jiffies, timeout)) { /* Read DP logic level. */ val = usb_phy_io_read(phy, TUSB1211_VENDOR_SPECIFIC4); if (val < 0) { otg_err(otg, "ULPI read error! try again\n"); continue; } if (!(val & VS4_CHGD_SERX_DP)) { otg_info(otg, "Data contact detected!\n"); break; } /* Polling interval */ usleep_range(interval, interval + 2000); } /* Disable DP pullup (Idp_src) */ usb_phy_io_write(phy, VS3_CHGD_IDP_SRC_EN, TUSB1211_VENDOR_SPECIFIC3_CLR); /* SE1 Det Enable: * Read DP/DM logic level. Note: use DEBUG * because VS4 isn’t enabled in this situation. */ val = usb_phy_io_read(phy, TUSB1211_DEBUG); if (val < 0) otg_err(otg, "ULPI read error!\n"); val &= DEBUG_LINESTATE; /* If '11': SE1 detected; goto 'Cleanup'. * Else: goto 'Pri Det Enable'. */ if (val == 3) { type = POWER_SUPPLY_CHARGER_TYPE_SE1; goto cleanup; } /* Pri Det Enable: * Enable VDPSRC. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_SET); /* Wait >106.1ms (40ms for BC * Tvdpsrc_on, 66.1ms for TI CHGD_SERX_DEB). */ msleep(107); /* Pri Det Check: * Check if DM > VDATREF. */ vdat_det = usb_phy_io_read(phy, TUSB1211_POWER_CONTROL); if (vdat_det < 0) otg_err(otg, "ULPI read error!\n"); vdat_det &= PWCTRL_VDAT_DET; /* Check if DM<VLGC */ chgd_serx_dm = usb_phy_io_read(phy, TUSB1211_VENDOR_SPECIFIC4); if (chgd_serx_dm < 0) otg_err(otg, "ULPI read error!\n"); chgd_serx_dm &= VS4_CHGD_SERX_DM; /* If VDAT_DET==0 || CHGD_SERX_DM==1: SDP detected * If VDAT_DET==1 && CHGD_SERX_DM==0: CDP/DCP */ if (vdat_det == 0 || chgd_serx_dm == 1) type = POWER_SUPPLY_CHARGER_TYPE_USB_SDP; /* Disable VDPSRC. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_CLR); /* If SDP, goto “Cleanup”. * Else, goto “Sec Det Enable” */ if (type == POWER_SUPPLY_CHARGER_TYPE_USB_SDP) goto cleanup; /* Sec Det Enable: * delay 1ms. */ usleep_range(1000, 1500); /* Swap DP & DM */ usb_phy_io_write(phy, VS1_DATAPOLARITY, TUSB1211_VENDOR_SPECIFIC1_CLR); /* Enable 'VDMSRC'. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_SET); /* Wait >73ms (40ms for BC Tvdmsrc_on, 33ms for TI TVDPSRC_DEB) */ msleep(80); /* Sec Det Check: * Check if DP>VDATREF. */ val = usb_phy_io_read(phy, TUSB1211_POWER_CONTROL); if (val < 0) otg_err(otg, "ULPI read error!\n"); val &= PWCTRL_VDAT_DET; /* If VDAT_DET==0: CDP detected. * If VDAT_DET==1: DCP detected. */ if (!val) type = POWER_SUPPLY_CHARGER_TYPE_USB_CDP; else type = POWER_SUPPLY_CHARGER_TYPE_USB_DCP; /* Disable VDMSRC. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_CLR); /* Swap DP & DM. */ usb_phy_io_write(phy, VS1_DATAPOLARITY, TUSB1211_VENDOR_SPECIFIC1_SET); cleanup: /* If DCP detected, assert VDPSRC. */ if (type == POWER_SUPPLY_CHARGER_TYPE_USB_DCP) usb_phy_io_write(phy, PWCTRL_SW_CONTROL | PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_SET); usb_put_phy(phy); switch (type) { case POWER_SUPPLY_CHARGER_TYPE_ACA_DOCK: case POWER_SUPPLY_CHARGER_TYPE_ACA_A: case POWER_SUPPLY_CHARGER_TYPE_ACA_B: case POWER_SUPPLY_CHARGER_TYPE_ACA_C: case POWER_SUPPLY_CHARGER_TYPE_USB_DCP: case POWER_SUPPLY_CHARGER_TYPE_USB_CDP: case POWER_SUPPLY_CHARGER_TYPE_SE1: dwc_otg_charger_hwdet(true); break; default: break; }; return type; }
static inline int isp1704_write(struct isp1704_charger *isp, u32 reg, u32 val) { return usb_phy_io_write(isp->phy, val, reg); }