Exemplo n.º 1
0
static int sleep_until_event(struct dwc_otg2 *otg,
			u32 otg_mask, u32 user_mask,
			u32 *otg_events, u32 *user_events,
			int timeout)
{
	int rc = 0;

	pm_runtime_mark_last_busy(otg->dev);
	pm_runtime_put_autosuspend(otg->dev);
	/* Wait until it occurs, or timeout, or interrupt. */
	if (timeout) {
		otg_dbg(otg, "Waiting for event (timeout=%d)...\n", timeout);
		rc = sleep_main_thread_until_condition_timeout(otg,
				check_event(otg, otg_mask,
				user_mask, otg_events, user_events), timeout);
	} else {
		otg_dbg(otg, "Waiting for event (no timeout)...\n");
		rc = sleep_main_thread_until_condition(otg,
				check_event(otg, otg_mask,
					user_mask, otg_events, user_events));
	}
	pm_runtime_get_sync(otg->dev);

	/* Disable the events */
	otg_write(otg, OEVTEN, 0);
	otg_write(otg, ADPEVTEN, 0);

	otg_dbg(otg, "Woke up rc=%d\n", rc);

	return rc;
}
static ssize_t store_vbus_evt(struct device *_dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	unsigned long flags;
	struct dwc_otg2	*otg = dwc3_get_otg();

	if (count != 2) {
		otg_err(otg, "return EINVAL\n");
		return -EINVAL;
	}

	if (count > 0 && buf[count-1] == '\n')
		((char *) buf)[count-1] = 0;

	switch (buf[0]) {
	case '1':
		otg_dbg(otg, "Change the VBUS to High\n");
		otg->otg_events |= OEVT_B_DEV_SES_VLD_DET_EVNT;
		spin_lock_irqsave(&otg->lock, flags);
		dwc3_wakeup_otg_thread(otg);
		spin_unlock_irqrestore(&otg->lock, flags);
		return count;
	case '0':
		otg_dbg(otg, "Change the VBUS to Low\n");
		otg->otg_events |= OEVT_A_DEV_SESS_END_DET_EVNT;
		spin_lock_irqsave(&otg->lock, flags);
		dwc3_wakeup_otg_thread(otg);
		spin_unlock_irqrestore(&otg->lock, flags);
		return count;
	default:
		return -EINVAL;
	}

	return count;
}
Exemplo n.º 3
0
static int check_event(struct dwc_otg2 *otg,
		u32 otg_mask,
		u32 user_mask,
		u32 *otg_events,
		u32 *user_events)
{
	get_and_clear_events(otg, otg_mask, user_mask,
			otg_events, user_events);

	otg_dbg(otg, "Event occurred:");

	if (otg_events && (*otg_events & otg_mask)) {
		otg_dbg(otg, "otg_events=0x%x, otg_mask=0x%x",
				*otg_events, otg_mask);
		return 1;
	}

	if (user_events && (*user_events & user_mask)) {
		otg_dbg(otg, "user_events=0x%x, user_mask=0x%x",
				*user_events, user_mask);
		return 1;
	}

	return 0;
}
Exemplo n.º 4
0
static int do_b_peripheral(struct dwc_otg2 *otg)
{
	int rc = 0;
	u32 otg_mask, user_mask, otg_events, user_events;

	otg_mask = 0;
	user_mask = 0;
	otg_events = 0;
	user_events = 0;

	otg_mask = OEVT_A_DEV_SESS_END_DET_EVNT;
	user_mask = USER_ID_A_CHANGE_EVENT;

	rc = sleep_until_event(otg,
			otg_mask, user_mask,
			&otg_events, &user_events, 0);
	if (rc < 0)
		return DWC_STATE_EXIT;

	if (otg_events & OEVT_A_DEV_SESS_END_DET_EVNT) {
		otg_dbg(otg, "OEVT_A_DEV_SESS_END_DET_EVNT\n");
		dwc_otg_notify_charger_type(otg,
				POWER_SUPPLY_CHARGER_EVENT_DISCONNECT);
		return DWC_STATE_B_IDLE;
	}

	if (user_events & USER_ID_A_CHANGE_EVENT) {
		otg_dbg(otg, "USER_ID_A_CHANGE_EVENT\n");
		otg->user_events |= USER_ID_A_CHANGE_EVENT;
		return DWC_STATE_B_IDLE;
	}

	return DWC_STATE_INVALID;
}
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;
}
Exemplo n.º 6
0
int dwc3_intel_platform_init(struct dwc_otg2 *otg)
{
	int retval;
	struct intel_dwc_otg_pdata *data;

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;

	/* Init a_bus_drop callback */
	otg->usb2_phy.a_bus_drop = dwc_a_bus_drop;
	otg->usb2_phy.vbus_state = VBUS_ENABLED;
	/* Get usb2 phy type */
	otg->usb2_phy.intf = data->usb2_phy_type;

	/* Turn off VUSBPHY if it haven't used by USB2 PHY.
	 * Otherwise, it will consume ~2.6mA(on VSYS) on MOFD.
	 */
	if (!data->using_vusbphy) {
		retval = control_usb_phy_power(PMIC_VLDOCNT, false);
		if (retval)
			otg_err(otg, "Fail to turn off VUSBPHY\n");
	} else if (!is_utmi_phy(otg)) {
		/* If the current USB2 PHY low power controlled by VUSBPHY. Then
		 * we need to de-assert USBRST pin to make USB2 PHY always stay
		 * in active state.
		 */
		retval = control_usb_phy_power(PMIC_USBPHYCTRL, true);
		if (retval)
			otg_err(otg, "Fail to de-assert USBRST#\n");
	} else {
		/* If we are using utmi phy, and through VUSBPHY to do power
		 * control. Then we need to assert USBRST# for external ULPI phy
		 * to ask it under inactive state saving power.
		 */
		retval = control_usb_phy_power(PMIC_USBPHYCTRL, false);
		if (retval)
			otg_err(otg, "Fail to de-assert USBRST#\n");
	}

	/* Don't let phy go to suspend mode, which
	 * will cause FS/LS devices enum failed in host mode.
	 */
	set_sus_phy(otg, 0);

	retval = device_create_file(otg->dev, &dev_attr_otg_id);
	if (retval < 0) {
		otg_dbg(otg,
			"Can't register sysfs attribute: %d\n", retval);
		return -ENOMEM;
	}

	otg_dbg(otg, "\n");
	otg_write(otg, OEVTEN, 0);
	otg_write(otg, OCTL, 0);

	dwc3_switch_mode(otg, GCTL_PRT_CAP_DIR_OTG);

	return 0;
}
Exemplo n.º 7
0
/*Internal function of isr */
static void process_port_intr(struct usb_hcd *hcd)
{
	hprt_t	hprt; /* by ss1, clear_hprt; */
	struct sec_otghost *otghost = hcd_to_sec_otghost(hcd);

	hprt.d32 = read_reg_32(HPRT);

	otg_dbg(OTG_DBG_ISR, "Port Interrupt() : HPRT = 0x%x\n", hprt.d32);

	if (hprt.b.prtconndet) {
		otg_dbg(true, "detect connection");

		otghost->port_flag.b.port_connect_status_change = 1;

		if (hprt.b.prtconnsts)
			otghost->port_flag.b.port_connect_status = 1;

		/* wake_lock(&otghost->wake_lock); */
	}


	if (hprt.b.prtenchng) {
		otg_dbg(true, "port enable/disable changed\n");
		otghost->port_flag.b.port_enable_change = 1;

		// kevinh - it seems the hw implicitly disables the interface on unplug, so mark that we are unplugged
		if(!hprt.b.prtconnsts) {
		  otghost->port_flag.b.port_connect_status_change = 1;
		  otghost->port_flag.b.port_connect_status = 0;
		}
	}

	if (hprt.b.prtovrcurrchng) {
		otg_dbg(true, "over current condition is changed\n");

		if (hprt.b.prtovrcurract) {
			otg_dbg(true, "port_over_current_change = 1\n");
			otghost->port_flag.b.port_over_current_change = 1;

		} else {
			otghost->port_flag.b.port_over_current_change = 0;
		}
		/* defer otg power control into a kernel thread */
		queue_work(otghost->wq, &otghost->work);
	}

	hprt.b.prtena = 0; /* prtena를 writeclear시키면 안됨. */
	/* hprt.b.prtpwr = 0; */
	hprt.b.prtrst = 0;
	hprt.b.prtconnsts = 0;

	write_reg_32(HPRT, hprt.d32);
}
Exemplo n.º 8
0
static enum dwc_otg_state do_charging(struct dwc_otg2 *otg)
{
	int ret;
	u32 otg_events = 0;
	u32 user_events = 0;
	u32 otg_mask = 0;
	u32 user_mask = 0;

	otg_mask = OEVT_A_DEV_SESS_END_DET_EVNT;

	if (dwc3_otg_pdata->do_charging)
		dwc3_otg_pdata->do_charging(otg);

	ret = sleep_until_event(otg, otg_mask,
			user_mask, &otg_events,
			&user_events, 0);
	if (ret < 0)
		return DWC_STATE_EXIT;

	if (otg_events & OEVT_A_DEV_SESS_END_DET_EVNT) {
		otg_dbg(otg, "OEVT_A_DEV_SESS_END_DET_EVNT\n");
		dwc_otg_notify_charger_type(otg,
				POWER_SUPPLY_CHARGER_EVENT_DISCONNECT);
		return DWC_STATE_B_IDLE;
	}

	return DWC_STATE_INVALID;
}
Exemplo n.º 9
0
static int insert_ed_to_ready_q(struct ed *insert_ed, bool is_first)
{
	otg_dbg(OTG_DBG_SCHEDULE_ED, "ed_id %d, td_id %d, %d\n",
			insert_ed->ed_id, insert_ed->num_td, is_first);

	if (insert_ed->ed_desc.endpoint_type == BULK_TRANSFER ||
		insert_ed->ed_desc.endpoint_type == CONTROL_TRANSFER) {

		if (is_first) {
			otg_list_push_next(&insert_ed->readyq_list,
					&nonperiodic_trans_ready_q.entity_list);
		} else {
			otg_list_push_prev(&insert_ed->readyq_list,
					&nonperiodic_trans_ready_q.entity_list);
		}
		nonperiodic_trans_ready_q.entity_num++;

	} else {
		if (is_first) {
			otg_list_push_next(&insert_ed->readyq_list,
					&periodic_trans_ready_q.entity_list);
		} else {
			otg_list_push_prev(&insert_ed->readyq_list,
					&periodic_trans_ready_q.entity_list);
		}
		periodic_trans_ready_q.entity_num++;
	}
	return USB_ERR_SUCCESS;
}
Exemplo n.º 10
0
static void start_main_thread(struct dwc_otg2 *otg)
{
	enum dwc3_otg_mode mode = dwc3_otg_pdata->mode;
	bool children_ready = false;

	mutex_lock(&lock);

	if ((mode == DWC3_DEVICE_ONLY) &&
			otg->otg.gadget)
		children_ready = true;

	if ((mode == DWC3_HOST_ONLY) &&
			otg->otg.host)
		children_ready = true;

	if ((mode == DWC3_DRD) &&
			otg->otg.host && otg->otg.gadget)
		children_ready = true;

	if (!otg->main_thread && children_ready) {
		otg_dbg(otg, "Starting OTG main thread\n");
		otg->main_thread = kthread_create(otg_main_thread, otg, "otg");
		wake_up_process(otg->main_thread);
	}
	mutex_unlock(&lock);
}
Exemplo n.º 11
0
/**
 * int reset_and_enable_port(const u8 port)
 * 
 * @brief Reset port and make enable status the specific port
 * 
 * @param [IN] port : port number
 * 
 * @return USB_ERR_SUCCESS : If success \n
 *         USB_ERR_FAIL : If call fail \n
 *
 * @remark 
 * 
 */
int reset_and_enable_port(const u8 port)
{
	hprt_t hprt;
	u32 count = 0;
	u32 max_error_count = 1000;
	
	mdelay(50);
	hprt.d32 = read_reg_32(HPRT);

	if(!hprt.b.prtena)
	{
		hprt.b.prtrst = 1; 	// drive reset
		write_reg_32(HPRT, hprt.d32);
		mdelay(80);

		hprt.b.prtrst = 0;
		write_reg_32(HPRT, hprt.d32);
		mdelay(60);
	
		do
		{
			hprt.d32 = read_reg_32(HPRT);
			udelay(10);
			
			if(count > max_error_count)
			{
				otg_dbg(OTG_DBG_ROOTHUB,"Port Reset Fail : HPRT : 0x%x\n",(u16)read_reg_32(HPRT));
				return USB_ERR_FAIL;
			}
			count++;
		}while(!hprt.b.prtena);
	}

	return USB_ERR_SUCCESS;
}
Exemplo n.º 12
0
static enum dwc_otg_state do_wait_vbus_fall(struct dwc_otg2 *otg)
{
	int ret;

	u32 otg_events = 0;
	u32 user_events = 0;
	u32 otg_mask = 0;
	u32 user_mask = 0;

	otg_mask = OEVT_A_DEV_SESS_END_DET_EVNT;

	ret = sleep_until_event(otg, otg_mask,
			user_mask, &otg_events,
			&user_events, VBUS_TIMEOUT);
	if (ret < 0)
		return DWC_STATE_EXIT;

	if (otg_events & OEVT_A_DEV_SESS_END_DET_EVNT) {
		otg_dbg(otg, "OEVT_A_DEV_SESS_END_DET_EVNT\n");
		if (otg->charging_cap.chrg_type ==
				POWER_SUPPLY_CHARGER_TYPE_ACA_DOCK)
			dwc_otg_notify_charger_type(otg,
				POWER_SUPPLY_CHARGER_EVENT_DISCONNECT);
		return DWC_STATE_B_IDLE;
	}

	/* timeout*/
	if (!ret) {
		otg_err(otg, "Haven't get VBus drop event! Maybe something wrong\n");
		return DWC_STATE_B_IDLE;
	}

	return DWC_STATE_INVALID;
}
static int dwc3_intel_byt_handle_notification(struct notifier_block *nb,
		unsigned long event, void *data)
{
	struct dwc_otg2 *otg = dwc3_get_otg();
	int state, val;
	unsigned long flags;

	if (!otg)
		return NOTIFY_BAD;

	val = *(int *)data;

	spin_lock_irqsave(&otg->lock, flags);
	switch (event) {
	case USB_EVENT_VBUS:
		if (val) {
			otg->otg_events |= OEVT_B_DEV_SES_VLD_DET_EVNT;
			otg->otg_events &= ~OEVT_A_DEV_SESS_END_DET_EVNT;
		} else {
			otg->otg_events |= OEVT_A_DEV_SESS_END_DET_EVNT;
			otg->otg_events &= ~OEVT_B_DEV_SES_VLD_DET_EVNT;
		}
		state = NOTIFY_OK;
		break;
	default:
		otg_dbg(otg, "DWC OTG Notify unknow notify message\n");
		state = NOTIFY_DONE;
	}
	dwc3_wakeup_otg_thread(otg);
	spin_unlock_irqrestore(&otg->lock, flags);

	return state;

}
Exemplo n.º 14
0
static enum dwc_otg_state do_wait_vbus_raise(struct dwc_otg2 *otg)
{
	int ret;
	u32 otg_events = 0;
	u32 user_events = 0;
	u32 otg_mask = 0;
	u32 user_mask = 0;

	otg_mask = OEVT_B_DEV_SES_VLD_DET_EVNT;

	ret = sleep_until_event(otg, otg_mask,
			user_mask, &otg_events,
			&user_events, VBUS_TIMEOUT);
	if (ret < 0)
		return DWC_STATE_EXIT;

	if (otg_events & OEVT_B_DEV_SES_VLD_DET_EVNT) {
		otg_dbg(otg, "OEVT_B_SES_VLD_EVT\n");
		return DWC_STATE_CHARGER_DETECTION;
	}

	/* timeout*/
	if (!ret)
		return DWC_STATE_A_HOST;

	return DWC_STATE_B_IDLE;
}
static int dwc3_check_gpio_id(struct dwc_otg2 *otg2)
{
	struct dwc_otg2 *otg = dwc3_get_otg();
	struct intel_dwc_otg_pdata *data;
	int id = 0;
	int next = 0;
	int count = 0;
	unsigned long timeout;

	otg_dbg(otg, "start check gpio id\n");

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;

	/* Polling ID GPIO PIN value for SW debounce as HW debouce chip
	 * is not connected on BYT CR board */
	if (data && data->gpio_id) {
		id = gpio_get_value(data->gpio_id);

		/* If get 20 of the same value in a row by GPIO read,
		 * then end SW debouce and return the ID value.
		 * the total length of debouce time is 80ms~100ms for
		 * 20 times GPIO read on BYT CR, which is longer than
		 * normal debounce time done by HW chip.
		 * Also set 200ms timeout value to avoid impact from
		 * pin unstable cases */
		timeout = jiffies + msecs_to_jiffies(200);
		while ((count < 20) && (!time_after(jiffies, timeout))) {
			next = gpio_get_value(data->gpio_id);
			otg_dbg(otg, "id value pin %d = %d\n",
				data->gpio_id, next);
			if (next < 0)
				return -EINVAL;
			else if (id == next)
				count++;
			else {
				id = next;
				count = 0;
			}
		}
		if (count >= 20) {
			otg_dbg(otg, "id debounce done = %d\n", id);
			return id;
		}
	}

	return -ENODEV;
}
Exemplo n.º 16
0
/* Caller must hold otg->lock */
void dwc3_wakeup_otg_thread(struct dwc_otg2 *otg)
{
	if (!otg->main_thread)
		return;

	otg_dbg(otg, "\n");
	/* Tell the main thread that something has happened */
	otg->main_wakeup_needed = 1;
	wake_up_interruptible(&otg->main_wq);
}
Exemplo n.º 17
0
static void stop_main_thread(struct dwc_otg2 *otg)
{
	mutex_lock(&lock);
	if (otg->main_thread) {
		otg_dbg(otg, "Stopping OTG main thread\n");
		otg->state = DWC_STATE_EXIT;
		dwc3_wakeup_otg_thread(otg);
	}
	mutex_unlock(&lock);
}
static ssize_t store_otg_id(struct device *_dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	unsigned long flags;
	struct dwc_otg2 *otg = dwc3_get_otg();

	if (!otg)
		return 0;
	if (count != 2) {
		otg_err(otg, "return EINVAL\n");
		return -EINVAL;
	}

	if (count > 0 && buf[count-1] == '\n')
		((char *) buf)[count-1] = 0;

	switch (buf[0]) {
	case 'a':
	case 'A':
		otg_dbg(otg, "Change ID to A\n");
		otg->user_events |= USER_ID_A_CHANGE_EVENT;
		spin_lock_irqsave(&otg->lock, flags);
		dwc3_wakeup_otg_thread(otg);
		otg_id = 0;
		spin_unlock_irqrestore(&otg->lock, flags);
		return count;
	case 'b':
	case 'B':
		otg_dbg(otg, "Change ID to B\n");
		otg->user_events |= USER_ID_B_CHANGE_EVENT;
		spin_lock_irqsave(&otg->lock, flags);
		dwc3_wakeup_otg_thread(otg);
		otg_id = 1;
		spin_unlock_irqrestore(&otg->lock, flags);
		return count;
	default:
		otg_err(otg, "Just support change ID to A!\n");
		return -EINVAL;
	}

	return count;
}
Exemplo n.º 19
0
/**
 * int get_otg_port_status(const u8 port, char* status)
 * 
 * @brief Get port change bitmap information 
 * 
 * @param [IN] port : port number
 *	   [OUT] status : buffer to store bitmap information
 * 
 * @returnUSB_ERR_SUCCESS : If success \n
 *         USB_ERR_FAIL : If call fail \n
 *
 * @remark 
 * 
 */
__inline__ int get_otg_port_status(const u8 port, char *status)
{
	//return root_hub_feature(port, GetPortStatus, NULL, status);

	status[port] = 0;
	status[port] |= (port_flag.b.port_connect_status_change ||
		    	port_flag.b.port_reset_change ||
		    	port_flag.b.port_enable_change ||
		    	port_flag.b.port_suspend_change ||
		    	port_flag.b.port_over_current_change) << 1;

	if (status[port]) {
		otg_dbg(OTG_DBG_ROOTHUB, " Root port status changed\n");
		otg_dbg(OTG_DBG_ROOTHUB, "  port_connect_status_change: %d\n",
			    port_flag.b.port_connect_status_change);
		otg_dbg(OTG_DBG_ROOTHUB, "  port_reset_change: %d\n",
			    port_flag.b.port_reset_change);
		otg_dbg(OTG_DBG_ROOTHUB,  "  port_enable_change: %d\n",
			    port_flag.b.port_enable_change);
		otg_dbg(OTG_DBG_ROOTHUB, "  port_suspend_change: %d\n",
			    port_flag.b.port_suspend_change);
		otg_dbg(OTG_DBG_ROOTHUB, "  port_over_current_change: %d\n",
			    port_flag.b.port_over_current_change);
	}

	return (status[port] !=0);
}
Exemplo n.º 20
0
static int sleep_main_thread_timeout(struct dwc_otg2 *otg, int msecs)
{
	signed long jiffies;
	int rc = msecs;

	if (otg->state == DWC_STATE_EXIT) {
		otg_dbg(otg, "Main thread exiting\n");
		rc = -EINTR;
		goto done;
	}

	if (signal_pending(current)) {
		otg_dbg(otg, "Main thread signal pending\n");
		rc = -EINTR;
		goto done;
	}
	if (otg->main_wakeup_needed) {
		otg_dbg(otg, "Main thread wakeup needed\n");
		rc = msecs;
		goto done;
	}

	jiffies = msecs_to_jiffies(msecs);
	rc = wait_event_freezable_timeout(otg->main_wq,
					otg->main_wakeup_needed,
					jiffies);

	if (otg->state == DWC_STATE_EXIT) {
		otg_dbg(otg, "Main thread exiting\n");
		rc = -EINTR;
		goto done;
	}

	if (rc > 0)
		rc = jiffies_to_msecs(rc);

done:
	otg->main_wakeup_needed = 0;
	return rc;
}
int dwc3_intel_byt_after_stop_peripheral(struct dwc_otg2 *otg)
{
	struct intel_dwc_otg_pdata *data;

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;
	if (!data)
		return -EINVAL;

	otg_dbg(otg, "cancel discon work\n");
	__cancel_delayed_work(&data->suspend_discon_work);

	return 0;
}
Exemplo n.º 22
0
static int dwc_otg2_set_host(struct usb_otg *x, struct usb_bus *host)
{
    struct dwc_otg2 *otg;

    if (!x) {
        otg_dbg(otg, "otg is NULL!\n");
        return -ENODEV;
    }

    otg = xceiv_to_dwc_otg2(x);
    otg_dbg(otg, "\n");

    if (!host) {
        otg->otg.host = NULL;
        stop_main_thread(otg);
        return -ENODEV;
    }

    otg->otg.host = host;
    start_main_thread(otg);
    return 0;
}
static void dwc_otg_suspend_discon_work(struct work_struct *work)
{
	struct dwc_otg2 *otg = dwc3_get_otg();
	unsigned long flags;

	otg_dbg(otg, "start suspend_disconn work\n");

	spin_lock_irqsave(&otg->lock, flags);
	otg->otg_events |= OEVT_A_DEV_SESS_END_DET_EVNT;
	otg->otg_events &= ~OEVT_B_DEV_SES_VLD_DET_EVNT;
	dwc3_wakeup_otg_thread(otg);
	spin_unlock_irqrestore(&otg->lock, flags);
}
Exemplo n.º 24
0
/**
 * static int __init s3c6410_otg_module_init(void)
 * 
 * @brief module_init function
 * 
 * @return it returns result of platform_driver_register
 * @remark 
 * This function is called when the s3c6410_otg_driver is installed with the
 * insmod command. It registers the s3c6410_otg_driver structure with the
 * appropriate bus driver. This will cause the s3c6410_otg_driver_probe function
 * to be called. In addition, the bus driver will automatically expose
 * attributes defined for the device and driver in the special sysfs file
 * system.
 */
static int __init s3c6410_otg_module_init(void) 
{ 
	int	ret_val = 0;
	
	otg_dbg(OTG_DBG_OTGHCDI_DRIVER, "s3c_otg_module_init \n");		

	ret_val = platform_driver_register(&s3c6410_otg_driver);
	if (ret_val < 0) 
	{		
		otg_err(OTG_DBG_OTGHCDI_DRIVER, "platform_driver_register \n");		
	}
	return ret_val;    
} 
static void oci_set_global_interrupt(bool set)
{
    gahbcfg_t ahbcfg;

    otg_dbg(OTG_DBG_OCI, "oci_set_global_interrupt\n");

    ahbcfg.d32 = 0;
    ahbcfg.b.glblintrmsk = 1;

    if (set)
        update_reg_32(GAHBCFG, ahbcfg.d32);
    else
        clear_reg_32(GAHBCFG, ahbcfg.d32);
}
Exemplo n.º 26
0
/**
 * int bus_resume(void)
 * 
 * @brief Make resume status when this platform support PM Mode
 * 
 * @param None
 * 
 * @return USB_ERR_SUCCESS : If success \n
 *         USB_ERR_FAIL : If call fail \n
 *
 * @remark 
 * 
 */
int bus_resume(void)
{
	/*
	hprt_t	hprt;
	pcgcctl_t	pcgcctl;
	hprt.d32 = 0;
	pcgcctl.d32 = 0;

	pcgcctl.b.stoppclk = 1;
	clear_reg_32(PCGCCTL,pcgcctl.d32);
	udelay(1);

	pcgcctl.b.pwrclmp = 1;
	clear_reg_32(PCGCCTL,pcgcctl.d32);
	udelay(1);

	pcgcctl.b.rstpdwnmodule = 1;
	clear_reg_32(PCGCCTL,pcgcctl.d32);
	udelay(1);

	hprt.b.prtres = 1;
	update_reg_32(HPRT, hprt.d32);
	mdelay(20);

	clear_reg_32(HPRT, hprt.d32);
	*/
	otg_dbg(OTG_DBG_OTGHCDI_HCD, "bus_resume()...... \n");
	if(oci_init() == USB_ERR_SUCCESS)
	{
		if(oci_start() == USB_ERR_SUCCESS)
		{
			otg_dbg(OTG_DBG_OTGHCDI_HCD, "OTG Init Success...... \n");
			return USB_ERR_SUCCESS;
		}
	}
	return USB_ERR_FAIL;
}
Exemplo n.º 27
0
static void	init_transfer_ready_q(void)
{
	otg_dbg(OTG_DBG_SCHEDULE, "start init_transfer_ready_q\n");

	otg_list_init(&periodic_trans_ready_q.entity_list);
	periodic_trans_ready_q.is_periodic = true;
	periodic_trans_ready_q.entity_num = 0;
	periodic_trans_ready_q.total_alloc_chnum = 0;
	periodic_trans_ready_q.total_perio_bus_bandwidth = 0;

	otg_list_init(&nonperiodic_trans_ready_q.entity_list);
	nonperiodic_trans_ready_q.is_periodic = false;
	nonperiodic_trans_ready_q.entity_num = 0;
	nonperiodic_trans_ready_q.total_alloc_chnum = 0;
	nonperiodic_trans_ready_q.total_perio_bus_bandwidth = 0;
}
Exemplo n.º 28
0
static int stop_host(struct dwc_otg2 *otg)
{
	int ret = -1;
	struct usb_hcd *hcd = NULL;

	otg_dbg(otg, "\n");

	hcd = container_of(otg->otg.host, struct usb_hcd, self);
	if (otg->otg.host)
		ret = otg->stop_host(hcd);

	if (dwc3_otg_pdata->after_stop_host)
		ret = dwc3_otg_pdata->after_stop_host(otg);

	return ret;
}
Exemplo n.º 29
0
static int remove_ed_from_ready_q(struct ed	*remove_ed)
{
	otg_dbg(OTG_DBG_SCHEDULE_ED, "ed_id %d, td_id %d\n",
			remove_ed->ed_id, remove_ed->num_td);

	otg_list_pop(&remove_ed->readyq_list);

	if (remove_ed->ed_desc.endpoint_type == BULK_TRANSFER ||
		remove_ed->ed_desc.endpoint_type == CONTROL_TRANSFER) {

		nonperiodic_trans_ready_q.entity_num--;

	} else
		periodic_trans_ready_q.entity_num--;

	return USB_ERR_SUCCESS;
}
Exemplo n.º 30
0
static int s5pc110_stop_otg(void)
{
	struct sec_otghost *otghost = NULL;
	struct sec_otghost_data *otgdata = NULL;

	pr_info("+++++ OTG STOP\n");

	otg_dbg(OTG_DBG_OTGHCDI_DRIVER, "s5pc110_stop_otg\n");

	otghost = hcd_to_sec_otghost(g_pUsbHcd);

#ifdef CONFIG_USB_HOST_NOTIFY
	host_notify_dev_unregister(&g_pUsbHcd->ndev);
#endif

	otg_hcd_deinit_modules(otghost);

	destroy_workqueue(otghost->wq);

	wake_unlock(&otghost->wake_lock);
	wake_lock_destroy(&otghost->wake_lock);

	usb_remove_hcd(g_pUsbHcd);

#if 1
	if (g_pUDCBase == S3C_VA_HSOTG) {
		pr_info("otg release_mem_region\n");
		release_mem_region(g_pUsbHcd->rsrc_start, g_pUsbHcd->rsrc_len);
	}
#endif

	usb_put_hcd(g_pUsbHcd);

	otgdata = otghost->otg_data;
	if (otgdata && otgdata->phy_exit && otgdata->pdev) {
		pr_info("otg phy_off\n");
		otgdata->phy_exit(0);
	}

	return 0;
}