/*!ecm_fd_set_interface * * @brief called to indicate set interface request was received * @param function_instance * @param wIndex * @param altsetting * @return int */ int ecm_fd_set_interface (struct usbd_function_instance *function_instance, int wIndex, int altsetting) { struct usb_network_private *npd = function_instance->privdata; TRACE_MSG2(NTT, "SET INTERFACE[%02x] altsetting: %02x", wIndex, altsetting); npd->altsetting = altsetting; TRACE_MSG3(NTT, "ipaddr: %08x flags: %04x altsetting: %02x", npd->ip_addr, npd->flags, npd->altsetting); return (altsetting ? net_fd_start : net_fd_stop) (function_instance); }
/*! ecm_fd_set_configuration * @brief - called to indicate set configuration request was received * @param function_instance * @param configuration * @return int */ int ecm_fd_set_configuration (struct usbd_function_instance *function_instance, int configuration) { struct usb_network_private *npd = function_instance->privdata; //struct usbd_interface_instance *interface_instance = (struct usbd_interface_instance *)function_instance; //net_check_mesg(mesg_configured); if (npd->eem_os_buffer) net_os_dealloc_buffer(function_instance, npd->eem_os_data, npd->eem_os_buffer); npd->eem_os_data = npd->eem_os_buffer = NULL; //npd->flags |= NETWORK_CONFIGURED; npd->altsetting = 0; TRACE_MSG3(NTT, "CONFIGURED: %d ipaddr: %08x flags: %04x", configuration, npd->ip_addr, npd->flags); return 0; }
void mxc_hrt_callback (unsigned long arg) { TRACE_MSG1(OCD, "checking active: %d", mxc_hr_active); RETURN_UNLESS(mxc_hr_active); mxc_hr_active = FALSE; TRACE_MSG1(OCD, "resetting active: %d", mxc_hr_active); if (mxc_hr_usec_set >= 1000000) { //if requested period is in the range of 1 sec hr_timer.expires = jiffies + ((mxc_hr_usec_set/1000000)*mxc_hr_jiffy_per_sec); hr_timer.arch_cycle_expires = get_arch_cycles(jiffies); hr_timer.function = mxc_hrt_callback; } else { hr_timer.expires = jiffies; hr_timer.arch_cycle_expires = get_arch_cycles(jiffies); if (mxc_hr_usec_set < 100) { TRACE_MSG1(OCD, "usec: %d set to minimum 100", mxc_hr_usec_set); mxc_hr_usec_set = 100; } hr_timer.arch_cycle_expires += nsec_to_arch_cycle(mxc_hr_usec_set * 1000); //hr_timer.arch_cycle_expires += nsec_to_arch_cycle(100 * 1000 * 1000); while (hr_timer.arch_cycle_expires >= arch_cycles_per_jiffy) { hr_timer.expires++; hr_timer.arch_cycle_expires -= arch_cycles_per_jiffy; } } //end of else TRACE_MSG3 (OCD, "usec: %d expires: %8u arch_cycle_expires: %8u", mxc_hr_usec_set, hr_timer.expires, hr_timer.arch_cycle_expires); otg_event(ocd_instance->otg, TMOUT, OCD, "TMOUT"); // add_timer(&hr_timer); }
/*! * mxc_pmic_usbi_handler() - event handler * * * */ void pmic_usbi_handler(void) { TRACE_MSG0(REMOVE_TCD, "--"); pmic_otg_wakeup(); #if 0 #if 1 t_sensor_bits sense_bits; if (pmic_get_sensors(&sense_bits)) { printk(KERN_INFO "%s: pmic_get_sensors() failed\n", __FUNCTION__); return; } TRACE_MSG3(REMOVE_TCD, "MC13783 EVENT: 4V4S: %d 2V0S: %d 0V8S: %d", sense_bits.sense_usb4v4s, sense_bits.sense_usb2v0s, sense_bits.sense_usb0v8s); otg_event(tcd_instance->otg, (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) | (sense_bits. sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) | (sense_bits.sense_usb0v8s ? B_SESS_END : B_SESS_END_), REMOVE_TCD, "MC13783 USBI"); #else otg_event(tcd_instance->otg, (pmic_check_sense(sense_usb4v4s) ? VBUS_VLD : VBUS_VLD_) | (pmic_check_sense(sense_usb4v4s) ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) | (pmic_check_sense(sense_usb0v8s) ? B_SESS_END : B_SESS_END_), REMOVE_TCD, "MC13783 USBI"); #endif #endif }
/*! mc13783_bh * */ void mc13783_bh(void *arg) { TRACE_MSG0(TCD, "--"); global_flag = global_flag_array[start_flag]; if (global_flag & PUDP_FLAG_SET){ //set DP pullup //mc13783_convity_set_speed_mode (FALSE); //set high speed //mc13783_convity_set_pull_down_switch(PD_PU, TRUE); //variable 1.5K pull-up switch in power_ic_periph_set_usb_pull_up(TRUE); } if (global_flag & PUDP_FLAG_RESET){ //reset DP pullup //mc13783_convity_set_speed_mode (FALSE); //set high speed //mc13783_convity_set_pull_down_switch(PD_PU, FALSE); //variable 1.5K pull-up switch off power_ic_periph_set_usb_pull_up(FALSE); // Turn off the USB pullup } if (global_flag & PUDM_FLAG_SET){ //set DM pullup //mc13783_convity_set_speed_mode (TRUE); //set low speed //mc13783_convity_set_pull_down_switch(PD_PU, TRUE); //variable 1.5K pull-up switch in power_ic_periph_set_usb_pull_up(TRUE); } if (global_flag & PUDM_FLAG_RESET){ //reset DM pullup //mc13783_convity_set_speed_mode (TRUE); //set low speed //mc13783_convity_set_pull_down_switch(PD_PU, FALSE); //variable 1.5K pull-up switch off power_ic_periph_set_usb_pull_up(FALSE); // Turn off the USB pullup } if (global_flag & UPD_FLAG_SET){ //set DP pulldown power_ic_set_reg_bit(POWER_IC_REG_ATLAS_USB_0, BIT_UDPPD, TRUE); //mc13783_convity_set_pull_down_switch(PD_UPD_15, TRUE); //DP pull down switch is on } if (global_flag & UPD_FLAG_RESET){ //reset DP pulldown power_ic_set_reg_bit(POWER_IC_REG_ATLAS_USB_0, BIT_UDPPD, FALSE); //mc13783_convity_set_pull_down_switch(PD_UPD_15, FALSE); //DP pull down switch is off } if (global_flag & UDM_FLAG_SET){ //set DM pulldown power_ic_set_reg_bit(POWER_IC_REG_ATLAS_USB_0, BIT_UDMPD, TRUE); //mc13783_convity_set_pull_down_switch(PD_UDM_15, TRUE); //DP pull down switch is on } if (global_flag & UDM_FLAG_RESET){ //reset DM pulldown power_ic_set_reg_bit(POWER_IC_REG_ATLAS_USB_0, BIT_UDMPD, FALSE); //mc13783_convity_set_pull_down_switch(PD_UDM_15, FALSE); //DP pull down switch is off } /* Used for OTG if (global_flag & DRV_VBUS_SET){ //enable vbus voltage // mc13783_convity_set_output (FALSE, FALSE); //disable VUSB mc13783_convity_set_output (TRUE, TRUE); //enable VBUS } if (global_flag & DRV_VBUS_RESET){ //disable vbus voltage // mc13783_convity_set_output (FALSE, FALSE); //disable VUSB mc13783_convity_set_output (TRUE, FALSE); //disable VBUS } if (global_flag & CHRG_VBUS_SET){ //enable vbus #ifndef VBUS_TIMER mc13783_convity_set_output (TRUE, TRUE); //enable VBUS #else mc13783_convity_set_vbus_reg (3); //set VBUS on for 30 ms #endif } if (global_flag & CHRG_VBUS_RESET){ //disable vbus mc13783_convity_set_output (TRUE, FALSE); //disable VBUS } if (global_flag & DISCHRG_VBUS_SET){ //discharge vbus mc13783_convity_set_output (TRUE, FALSE); //disable VBUS mc13783_convity_set_vusb_voltage (TRUE); //set the VUSB voltage to 3.3 mc13783_convity_set_output (FALSE, TRUE); //enable VUSB } if (global_flag & DISCHRG_VBUS_RESET){ //discharge vbus disable mc13783_convity_set_output (TRUE, FALSE); //disable VBUS mc13783_convity_set_output (FALSE, TRUE); //enable VUSB // mc13783convity_set_output (FALSE, FALSE); //disable VUSB } */ TRACE_MSG3 (TCD, "gloabl flag %d start_flag %d end_flag %d", global_flag, start_flag, end_flag); global_flag = 0; global_flag_array[start_flag] = 0; if (start_flag ++ > 15) start_flag = 0; if (start_flag != end_flag) SCHEDULE_WORK(mc13783_work_bh); }
/*! * generic_cf_register() * */ void generic_cf_register(struct generic_config *config, char *match) { char *cp, *sp, *lp; int i; char **interface_list = NULL; int interfaces = 0; //printk(KERN_INFO"%s: Driver: \"%s\" idVendor: %04x idProduct: %04x interface_names: \"%s\" match: \"%s\"\n", // __FUNCTION__, // config->composite_driver.driver.name, MODPARM(idVendor), MODPARM(idProduct), config->interface_names, // match ? match : ""); TRACE_MSG5(GENERIC, "Driver: \"%s\" idVendor: %04x idProduct: %04x interface_names: \"%s\" match: \"%s\"", config->composite_driver.driver.name, MODPARM(idVendor), MODPARM(idProduct), config->interface_names, match ? match : ""); RETURN_IF (match && strlen(match) && strcmp(match, config->composite_driver.driver.name)); //printk(KERN_INFO"%s: MATCHED\n", __FUNCTION__); /* decompose interface names to construct interface_list */ RETURN_UNLESS (config->interface_names && strlen(config->interface_names)); /* count interface names and allocate _interface_names array */ for (cp = sp = config->interface_names, interfaces = 0; cp && *cp; ) { for (; *cp && *cp == ':'; cp++); // skip white space sp = cp; // save start of token for (; *cp && *cp != ':'; cp++); // find end of token BREAK_IF (sp == cp); if (*cp) cp++; interfaces++; } THROW_UNLESS(interfaces, error); TRACE_MSG1(GENERIC, "interfaces: %d", interfaces); THROW_UNLESS((interface_list = (char **) CKMALLOC (sizeof (char *) * (interfaces + 1), GFP_KERNEL)), error); for (cp = sp = config->interface_names, interfaces = 0; cp && *cp; interfaces++) { for (; *cp && *cp == ':'; cp++); // skip white space sp = cp; // save start of token for (; *cp && *cp != ':'; cp++); // find end of token BREAK_IF (sp == cp); lp = cp; if (*cp) cp++; *lp = '\0'; lp = CKMALLOC(strlen(sp), GFP_KERNEL); strcpy(lp, sp); interface_list[interfaces] = lp; TRACE_MSG3(GENERIC, "INTERFACE[%2d] %x \"%s\"", interfaces, interface_list[interfaces], interface_list[interfaces]); } config->composite_driver.device_description = &config->device_description; config->composite_driver.configuration_description = &config->configuration_description; config->composite_driver.driver.fops = &generic_function_ops; config->interface_list = interface_list; THROW_IF (usbd_register_composite_function ( &config->composite_driver, config->composite_driver.driver.name, config->class_name, config->interface_list, NULL), error); config->registered++; TRACE_MSG0(GENERIC, "REGISTER FINISHED"); CATCH(error) { otg_trace_invalidate_tag(GENERIC); } }
/*! net_fd_recv_urb_mdlm * @brief callback to process a received URB * * @param urb - pointer to received urb * @param rc - dummy parameter * @return non-zero for failure. */ int net_fd_recv_urb_mdlm(struct usbd_urb *urb, int rc) { struct usbd_function_instance *function_instance = urb->function_instance; struct usb_network_private *npd = function_instance->privdata; void *os_data = NULL; void *os_buffer = NULL; int crc_bad = 0; int trim = 0; int len; u32 crc; u32 temmp; len = urb->actual_length; trim = 0; //TRACE_MSG2(NTT, "status: %d actual_length: %d", urb->status, urb->actual_length); //RETURN_EINVAL_IF (urb->status == USBD_URB_OK); os_data = urb->function_privdata; //TRACE_MSG2(NTT, "os_data: %x os_buffer: %x", os_data, os_buffer); #if defined(CONFIG_OTG_NETWORK_BLAN_PADAFTER) { /* This version simply checks for a correct CRC along the * entire packet. Some UDC's have trouble with some packet * sizes, this allows us to add pad bytes after the CRC. */ u8 *src = urb->buffer; int copied; // XXX this should work, but the MIPS optimizer seems to get it wrong.... //copied = (len < urb->wMaxPacketSize) ? 0 : ((len / urb->wMaxPacketSize) - 1) * urb->wMaxPacketSize; if (len < urb->wMaxPacketSize*2) copied = 0; else { int pkts = ((len - urb->wMaxPacketSize) / urb->wMaxPacketSize); copied = (pkts - 1) * urb->wMaxPacketSize; } len -= copied; crc = CRC32_INIT; for (; copied-- > 0 ; crc = COMPUTE_FCS (crc, *os_buffer++ = *src++)); for (; (len-- > 0) && (CRC32_GOOD != crc); crc = COMPUTE_FCS (crc, *os_buffer++ = *src++)); trim = len + 4; if (CRC32_GOOD != crc) { TRACE_MSG1(NTT,"AAA frame: %03x", urb->framenum); THROW_IF(npd->seen_crc, crc_error); } else npd->seen_crc = 1; } //#else /* defined(CONFIG_OTG_NETWORK_BLAN_PADAFTER) */ #elif defined(CONFIG_OTG_NETWORK_BLAN_CRC) || defined(CONFIG_OTG_NETWORK_SAFE_CRC) /* * The CRC can be sent in two ways when the size of the transfer * ends up being a multiple of the packetsize: * * | * <data> <CRC><CRC><CRC><CRC>|<???> case 1 * <data> <NUL><CRC><CRC><CRC>|<CRC> case 2 * <data> <NUL><CRC><CRC><CRC><CRC>| case 3 * <data> <NUL><CRC><CRC><CRC>|<CRC> | case 4 * | * * This complicates CRC checking, there are four scenarios: * * 1. length is 1 more than multiple of packetsize with a trailing byte * 2. length is 1 more than multiple of packetsize * 3. length is multiple of packetsize * 4. none of the above * * Finally, even though we always compute CRC, we do not actually throw * things away until and unless we have previously seen a good CRC. * This allows backwards compatibility with hosts that do not support * adding a CRC to the frame. * */ // test if 1 more than packetsize multiple if (1 == (len % urb->wMaxPacketSize)) { u8 *cp = urb->buffer + len - 1 - 4; // copy and CRC up to the packetsize boundary crc = crc32_nocopy(urb->buffer, len - 1, CRC32_INIT); if (TRACE_VERBOSE) TRACE_MSG7(NTT,"A CRC nocopy: %08x %08x len: %d CRC: %02x %02x %02x %02x", CRC32_GOOD, crc, len, cp[0], cp[1], cp[2], cp[3]); // if the CRC is good then this is case 1 if (CRC32_GOOD != crc) { crc = crc32_nocopy(urb->buffer + len - 1, 1, crc); if (CRC32_GOOD != crc) { //crc_errors[len%64]++; TRACE_MSG3(NTT,"A CRC error %08x %08x %03x", CRC32_GOOD, crc, urb->framenum); printk(KERN_INFO"%s: A CRC\n", __FUNCTION__); npd->seen_crc_error = 1; THROW_IF(npd->seen_crc, crc_error); } else npd->seen_crc = 1; } else npd->seen_crc = 1; } else { u8 *cp = urb->buffer + len - 4; crc = crc32_nocopy(urb->buffer, len, CRC32_INIT); if (TRACE_VERBOSE) TRACE_MSG7(NTT,"B CRC nocopy: %08x %08x len: %d CRC: %02x %02x %02x %02x", CRC32_GOOD, crc, len, cp[0], cp[1], cp[2], cp[3]); if (CRC32_GOOD != crc) { //crc_errors[len%64]++; TRACE_MSG3(NTT,"B CRC error %08x %08x %03x", CRC32_GOOD, crc, urb->framenum); if (TRACE_VERBOSE) { TRACE_MSG2(NTT, "status: %d actual_length: %d", urb->status, urb->actual_length); TRACE_NRECV(NTT, 32, urb->buffer); TRACE_MSG0(NTT, "--"); TRACE_RECV(NTT, urb->actual_length, urb->buffer); } printk(KERN_INFO"%s: B CRC\n", __FUNCTION__); npd->seen_crc_error = 1; THROW_IF(npd->seen_crc, crc_error); } else npd->seen_crc = 1; // XXX shorten by 4 bytes? } // trim IFF we are paying attention to crc if (npd->seen_crc) trim = 4; #endif /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/ if (net_fd_recv_buffer(function_instance, urb->buffer, len, os_data, crc_bad, trim)) { TRACE_MSG0(NTT, "FAILED"); net_os_dealloc_buffer(function_instance, os_data, os_buffer); } // catch a simple error, just increment missed error and general error CATCH(error) { //TRACE_MSG4(NTT,"CATCH(error) urb: %p status: %d len: %d function: %p", // urb, urb->status, urb->actual_length, function_instance); // catch a CRC error CATCH(crc_error) { crc_bad = 1; npd->seen_crc_error = 1; } } return 0; }
/*! net_fd_start_xmit_mdlm * @brief - start sending a buffer * * @param function_instance - function instance pointer * @param buffer * @param len * @param data * * @return: 0 if all OK * -EINVAL, -EUNATCH, -ENOMEM * rc from usbd_start_in_urb() if that fails (is != 0, may be one of err values above) * Note: -ECOMM is interpreted by calling routine as signal to leave IF stopped. */ int net_fd_start_xmit_mdlm (struct usbd_function_instance *function_instance, u8 *buffer, int len, void *data) { struct usb_network_private *npd = function_instance->privdata; struct usbd_urb *urb = NULL; int rc; u32 crc; #ifndef CONFIG_OTG_NETWORK_DOUBLE_IN int xmit_index = 0; int endpoint_index = BULK_IN_A; #else /* CONFIG_OTG_NETWORK_DOUBLE_IN */ int xmit_index = (otg_atomic_read(&npd->xmit_urbs_started[0]) <= otg_atomic_read(&npd->xmit_urbs_started[1])) ? 0 : 1; int endpoint_index = (xmit_index) ? BULK_IN_B : BULK_IN_A; #endif /* CONFIG_OTG_NETWORK_DOUBLE_IN */ int in_pkt_sz = usbd_endpoint_wMaxPacketSize(function_instance, xmit_index, usbd_high_speed(function_instance)); if (TRACE_VERBOSE) TRACE_MSG8(NTT,"npd: %p flags: %04x len: %d endpoint_index: %d " "xmit_index: %d xmit_started: %d %d in_pkt_sz: %d", npd, npd->flags, len, endpoint_index, xmit_index, otg_atomic_read(&npd->xmit_urbs_started[0]), otg_atomic_read(&npd->xmit_urbs_started[1]), in_pkt_sz); #if defined(CONFIG_OTG_NETWORK_BLAN_CRC) || defined(CONFIG_OTG_NETWORK_SAFE_CRC) /* allocate urb 5 bytes larger than required */ if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + 4 + in_pkt_sz, net_fd_urb_sent_bulk ))) { u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance)); TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa); return -ENOMEM; } urb->actual_length = len; /* copy and crc len bytes */ crc = crc32_copy(urb->buffer, buffer, len, CRC32_INIT); if ((urb->actual_length % in_pkt_sz) == (in_pkt_sz - 4)) { /* no longer in Kconfig - change undef to define to active padbyte */ #undef CONFIG_OTG_NETWORK_PADBYTE #ifdef CONFIG_OTG_NETWORK_PADBYTE // add a pad byte if required to ensure a short packet, usbdnet driver // will correctly handle pad byte before or after CRC, but the MCCI driver // wants it before the CRC. crc = crc32_pad(urb->buffer + urb->actual_length, 1, crc); urb->actual_length++; #else /* CONFIG_OTG_NETWORK_PADBYTE */ urb->flags |= USBD_URB_SENDZLP; TRACE_MSG2(NTT,"setting ZLP: urb: %p flags: %x", urb, urb->flags); #endif /* CONFIG_OTG_NETWORK_PADBYTE */ } crc = ~crc; urb->buffer[urb->actual_length++] = crc & 0xff; urb->buffer[urb->actual_length++] = (crc >> 8) & 0xff; urb->buffer[urb->actual_length++] = (crc >> 16) & 0xff; urb->buffer[urb->actual_length++] = (crc >> 24) & 0xff; #if defined(CONFIG_OTG_NETWORK_BLAN_FERMAT) if (npd->fermat) fermat_encode(urb->buffer, urb->actual_length); #endif #else /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/ /* allocate urb with no buffer */ #ifdef CONFIG_OTG_NETWORK_XMIT_OS if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, 0, net_fd_urb_sent_bulk ))) { u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance)); TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa); return -ENOMEM; } urb->actual_length = len; urb->buffer = buffer; #else /* CONFIG_OTG_NETWORK_XMIT_OS */ if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + 4 + in_pkt_sz, net_fd_urb_sent_bulk ))) { u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance)); TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa); printk(KERN_ERR"%s: urb alloc failed len: %d endpoint: %02x\n", __FUNCTION__, len, epa); return -ENOMEM; } urb->actual_length = len; memcpy (urb->buffer, buffer, len); #endif /* CONFIG_OTG_NETWORK_XMIT_OS */ urb->flags |= ((urb->actual_length % in_pkt_sz) == 0) ? USBD_URB_SENDZLP : 0; #endif /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/ if (TRACE_VERBOSE) TRACE_MSG3(NTT,"urb: %p buf: %p priv: %p", urb, data, urb->function_privdata); urb->function_privdata = data; otg_atomic_add(urb->actual_length, &npd->queued_bytes); otg_atomic_inc(&npd->xmit_urbs_started[xmit_index]); if ((rc = usbd_start_in_urb (urb))) { TRACE_MSG1(NTT,"FAILED: %d", rc); printk(KERN_ERR"%s: FAILED: %d\n", __FUNCTION__, rc); urb->function_privdata = NULL; otg_atomic_sub(urb->actual_length, &npd->queued_bytes); otg_atomic_dec(&npd->xmit_urbs_started[xmit_index]); usbd_free_urb (urb); return rc; } return 0; }
/*! pmic_bh- work task bottom handler * @param data - otg_instance type pointer * */ void pmic_bh(void *data) { struct otg_instance *otg = (struct otg_instance *) data; do { // printk(KERN_INFO"%s: AAAA\n", __FUNCTION__); TRACE_MSG0(REMOVE_TCD, "--"); global_flag = global_flag_array[start_flag]; if (global_flag & PUDP_FLAG_SET) { //set DP pullup pmic_convity_usb_set_speed(pmic_handle, USB_FULL_SPEED); pmic_convity_usb_otg_set_config(pmic_handle, USB_PU); } if (global_flag & PUDP_FLAG_RESET) { //reset DP pullup pmic_convity_usb_set_speed(pmic_handle, USB_FULL_SPEED); pmic_convity_usb_otg_clear_config(pmic_handle, USB_PU); } if (global_flag & PUDM_FLAG_SET) { //set DM pullup pmic_convity_usb_set_speed(pmic_handle, USB_LOW_SPEED); pmic_convity_usb_otg_set_config(pmic_handle, USB_PU); } if (global_flag & PUDM_FLAG_RESET) { //reset DM pullup pmic_convity_usb_set_speed(pmic_handle, USB_LOW_SPEED); pmic_convity_usb_otg_clear_config(pmic_handle, USB_PU); } if (global_flag & UPD_FLAG_SET) { //set DP pulldown pmic_convity_usb_otg_set_config(pmic_handle, USB_UDP_PD); //DP pull down switch is on } if (global_flag & UPD_FLAG_RESET) { //reset DP pulldown pmic_convity_usb_otg_clear_config(pmic_handle, USB_UDP_PD); //DP pull down switch is off } if (global_flag & UDM_FLAG_SET) { //set DM pulldown pmic_convity_usb_otg_set_config(pmic_handle, USB_UDM_PD); //DP pull down switch is on } if (global_flag & UDM_FLAG_RESET) { //reset DM pulldown pmic_convity_usb_otg_clear_config(pmic_handle, USB_UDM_PD); //DP pull down switch is off } if (global_flag & DRV_VBUS_SET) { //enable vbus voltage pmic_convity_set_output(pmic_handle, TRUE, TRUE); //enable VBUS } if (global_flag & DRV_VBUS_RESET) { //disable vbus voltage pmic_convity_set_output(pmic_handle, TRUE, FALSE); //disable VBUS } if (global_flag & CHRG_VBUS_SET) { //enable vbus pmic_convity_usb_otg_set_config(pmic_handle, USB_VBUS_CURRENT_LIMIT_LOW_30MS); } if (global_flag & CHRG_VBUS_RESET) { //disable vbus pmic_convity_set_output(pmic_handle, TRUE, FALSE); //disable VBUS } if (global_flag & DISCHRG_VBUS_SET) { //discharge vbus pmic_convity_set_output(pmic_handle, TRUE, FALSE); //disable VBUS pmic_convity_usb_otg_clear_config(pmic_handle, USB_VBUS_PULLDOWN); pmic_convity_usb_set_power_source(pmic_handle, USB_POWER_INTERNAL, USB_POWER_3V3); pmic_convity_set_output(pmic_handle, FALSE, TRUE); //enable VUSB } if (global_flag & DISCHRG_VBUS_RESET) { //discharge vbus disable pmic_convity_set_output(pmic_handle, TRUE, FALSE); //disable VBUS pmic_convity_usb_otg_set_config(pmic_handle, USB_VBUS_PULLDOWN); pmic_convity_set_output(pmic_handle, FALSE, TRUE); //enable VUSB } #if 1 TRACE_MSG3(REMOVE_TCD, "gloabl flag %d start_flag %d end_flag %d", global_flag, start_flag, end_flag); #endif #if 0 printk(KERN_INFO "%d %d %d %d %d %d %d %d\n", (global_flag & PU_FLAG_SET), (global_flag & PU_FLAG_RESET), (global_flag & UPD_FLAG_SET), (global_flag & UPD_FLAG_RESET), (global_flag & UDM_FLAG_SET), (global_flag & UDM_FLAG_RESET), (global_flag & VBUSPDENB_RESET), (global_flag & VBUSREGEN_RESET)); #endif global_flag = 0; global_flag_array[start_flag] = 0; if (start_flag++ > 15) start_flag = 0; //if (start_flag != end_flag) // SCHEDULE_WORK(pmic_work_bh); // printk(KERN_INFO"%s: BBBB start: %d end: %d\n", __FUNCTION__, start_flag, end_flag); } while (start_flag != end_flag); // printk(KERN_INFO"%s: CCCC\n", __FUNCTION__); }