max3421_detect_conn(struct usb_hcd *hcd)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	unsigned int jk, have_conn = 0;
	u32 old_port_status, chg;
	unsigned long flags;
	u8 hrsl, mode;

	hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);

	jk = ((((hrsl >> MAX3421_HRSL_JSTATUS_BIT) & 1) << 0) |
	      (((hrsl >> MAX3421_HRSL_KSTATUS_BIT) & 1) << 1));

	mode = max3421_hcd->mode;

	switch (jk) {
	case 0x0: /* SE0: disconnect */
		/*
		 * Turn off SOFKAENAB bit to avoid getting interrupt
		 * every milli-second:
		 */
		mode &= ~BIT(MAX3421_MODE_SOFKAENAB_BIT);
		break;

	case 0x1: /* J=0,K=1: low-speed (in full-speed or vice versa) */
	case 0x2: /* J=1,K=0: full-speed (in full-speed or vice versa) */
		if (jk == 0x2)
			/* need to switch to the other speed: */
			mode ^= BIT(MAX3421_MODE_LOWSPEED_BIT);
		/* turn on SOFKAENAB bit: */
		mode |= BIT(MAX3421_MODE_SOFKAENAB_BIT);
		have_conn = 1;
		break;

	case 0x3: /* illegal */
		break;
	}

	max3421_hcd->mode = mode;
	spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode);

	spin_lock_irqsave(&max3421_hcd->lock, flags);
	old_port_status = max3421_hcd->port_status;
	if (have_conn)
		max3421_hcd->port_status |=  USB_PORT_STAT_CONNECTION;
	else
		max3421_hcd->port_status &= ~USB_PORT_STAT_CONNECTION;
	if (mode & BIT(MAX3421_MODE_LOWSPEED_BIT))
		max3421_hcd->port_status |=  USB_PORT_STAT_LOW_SPEED;
	else
		max3421_hcd->port_status &= ~USB_PORT_STAT_LOW_SPEED;
	chg = (old_port_status ^ max3421_hcd->port_status);
	max3421_hcd->port_status |= chg << 16;
	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
}
max3421_detect_conn(struct usb_hcd *hcd)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	unsigned int jk, have_conn = 0;
	u32 old_port_status, chg;
	unsigned long flags;
	u8 hrsl, mode;

	hrsl = spi_rd8(hcd, MAX3421_REG_HRSL);

	jk = ((((hrsl >> MAX3421_HRSL_JSTATUS_BIT) & 1) << 0) |
	      (((hrsl >> MAX3421_HRSL_KSTATUS_BIT) & 1) << 1));

	mode = max3421_hcd->mode;

	switch (jk) {
	case 0x0:  
		 
		mode &= ~BIT(MAX3421_MODE_SOFKAENAB_BIT);
		break;

	case 0x1:  
	case 0x2:  
		if (jk == 0x2)
			 
			mode ^= BIT(MAX3421_MODE_LOWSPEED_BIT);
		 
		mode |= BIT(MAX3421_MODE_SOFKAENAB_BIT);
		have_conn = 1;
		break;

	case 0x3:  
		break;
	}

	max3421_hcd->mode = mode;
	spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode);

	spin_lock_irqsave(&max3421_hcd->lock, flags);
	old_port_status = max3421_hcd->port_status;
	if (have_conn)
		max3421_hcd->port_status |=  USB_PORT_STAT_CONNECTION;
	else
		max3421_hcd->port_status &= ~USB_PORT_STAT_CONNECTION;
	if (mode & BIT(MAX3421_MODE_LOWSPEED_BIT))
		max3421_hcd->port_status |=  USB_PORT_STAT_LOW_SPEED;
	else
		max3421_hcd->port_status &= ~USB_PORT_STAT_LOW_SPEED;
	chg = (old_port_status ^ max3421_hcd->port_status);
	max3421_hcd->port_status |= chg << 16;
	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
}