Skip to content

Commit

Permalink
Merge branch 'usb-otg' into sg-ns-ics
Browse files Browse the repository at this point in the history
  • Loading branch information
stevegaron committed Jan 25, 2012
2 parents 598eead + 9914c12 commit db73376
Show file tree
Hide file tree
Showing 57 changed files with 11,383 additions and 4 deletions.
83 changes: 83 additions & 0 deletions Documentation/usb/s3c-otg-host.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
This file is a collection of notes on using the USB OTG port of the Samsung Galaxy Tab in HOST mode.

1/17/12 - Zsolt Sz. Sztupak, mail@sztupy.hu, http://android.sztupy.hu

Kevin's patch to the kernel was great, but it had some problems, namely:
* it was based on an old Froyo (or Eclair?) branch of the kernel, which still had a lot of old code, and methods
that were deprecated in later kernel versions
* the actual client/host changing code was put inside the 30pin connector file, which only exists in the Galaxy
Tab based Kernels

The changes I've made are the following:
* port some of the deprecated code to kernel version 3.x
* change the otg detector/switcher code from the 30 pin connector module to the s3c otg gadget (client mode) module

There is still a lof code not ported from the old kernel branch as it uses a lot of ugly old samsung kernel code,
which are non existent in later kernel versions. These include interrupt, LDO and clock switchings, which might
be the case of some of the hangups.

8/24/11 - Kevin Hester, kevin@ridemission.com

I'm writing this document to capture both the software and hardware changes needed for this device in one place.
If you are a brave Android kernel hacker, please try these changes out and send pull requests to github with any
fixes you add. I have been unable to find a 'master' github site where hobbyists are maintaining a master Samsung
kernel and Android OS, if you have such a site feel free to include my fixes (though credit would be appreciated).
These fixes are provided 'as-is' and you could bust your device or do any number of bad things.

I'm going to post these notes on the xda forums, but for the latest code and documentation please see my github site.

History: The Samsung open source kernel files (from opensource.samsung.com) contained a USB host mode driver for the
S5PC110 chipset. These drivers were located in drivers/usb/host/s3c-otg. The driver contained a number of bugs which
I've fixed and it now seems to work reasonably well for USB serial ports, flash drives etc.

Hardware: To use USB host mode on your samsung tablet _external 5V DC seems to be required_. I have not found
turning any of the samsung LDOs on to make the unit provide USB power (if you find different, please let me know).

To wire up a USB host mode cable you'll need the following pinout (found on a web forum):
1 Gnd P
2 Gnd P
3 USB_DP_CON I/O
4 USB_DM_CON I/O
5 IF_CON_SENSE I
6 V_ACCESSORY_5.0V P
7 V_BUS_1 P
8 V_BUS_1 P
9 VOUT_CHARGER P (gives out 4v when checked with a multimeter)
10 VOUT_CHARGER P (gives out 4v when checked with a multimeter)
11 --- --
12 --- --
13 ACCESSORY_ID / USB_ID I
14 ACCESSORY_INT I
15 Gnd P
16 Gnd P
17 MHL_DP I/O
18 MHL_DM I/O
19 MHL_ID I
20 IF_RXD I
21 IF_TXD O
22 --- --
23 AP_TV_OUT O
24 REMOTE_SENSE I
25 --- --
26 --- --
27 EAR_L_CRADLE O
28 EAR_R_CRADLE O
29 3.5_INT_TEST I
30 Gnd P

Your cable will need to connect the following five pins:
1 Gnd
3 USB_DP
4 USB_DM
8 5V+ (at least 1A if you want to support high speed charging of the tablet)
13 Host mode (attach to ground to run tablet as a host, or leave disconnected to run tablet as a USB target)

A summary of my driver changes:
* Fix a nubmer of cases where TDs would be used after delete_td and the associated storage was freed (caused kernel
heap corruption)
* Allow a bit more time for some mystery Samsung LDO to power up before switching to host mode (caused failure in device detect)
* Wait for channel disabled interrupt when cancelling transactions (prevents a race condition with the ISR)
* Properly switch into USB host mode when a host mode cable is detected (see 30pin_con.c)
* Mark transfers as done when cancel_to_transfer_td is called (prevents rescheduling transactions we have freed)
* do not force is_need_to_insert_scheduler true in cancel_transfer, this caused list corruption in the ed list

45 changes: 43 additions & 2 deletions arch/arm/mach-s5pv210/mach-herring.c
Original file line number Diff line number Diff line change
Expand Up @@ -5473,6 +5473,9 @@ static struct platform_device *herring_devices[] __initdata = {
&herring_i2c11_device, /* optical sensor */
&herring_i2c12_device, /* magnetic sensor */
&herring_i2c14_device, /* nfc sensor */
#ifdef CONFIG_USB_S3C_OTG_HOST
&s3c_device_usb_otghcd,
#endif
#ifdef CONFIG_USB_GADGET
&s3c_device_usbgadget,
#endif
Expand Down Expand Up @@ -5947,10 +5950,10 @@ void otg_phy_init(void)
S3C_USBOTG_PHYCLK);
writel((readl(S3C_USBOTG_RSTCON) & ~(0x3<<1)) | (0x1<<0),
S3C_USBOTG_RSTCON);
msleep(1);
mdelay(1);
writel(readl(S3C_USBOTG_RSTCON) & ~(0x7<<0),
S3C_USBOTG_RSTCON);
msleep(1);
mdelay(1);

/* rising/falling time */
writel(readl(S3C_USBOTG_PHYTUNE) | (0x1<<20),
Expand Down Expand Up @@ -6009,6 +6012,44 @@ void usb_host_phy_off(void)
EXPORT_SYMBOL(usb_host_phy_off);
#endif

#ifdef CONFIG_USB_S3C_OTG_HOST

/* Initializes OTG Phy */
void otg_host_phy_init(void)
{
__raw_writel(__raw_readl(S5P_USB_PHY_CONTROL)
|(0x1<<0), S5P_USB_PHY_CONTROL); /*USB PHY0 Enable */
// from galaxy tab otg host:
// __raw_writel((__raw_readl(S3C_USBOTG_PHYPWR)
// &~(0x3<<3)&~(0x1<<0))|(0x1<<5), S3C_USBOTG_PHYPWR);
// from galaxy s2 otg host:
__raw_writel((__raw_readl(S3C_USBOTG_PHYPWR)
&~(0x7<<3)&~(0x1<<0)), S3C_USBOTG_PHYPWR);
__raw_writel((__raw_readl(S3C_USBOTG_PHYCLK)
&~(0x1<<4))|(0x7<<0), S3C_USBOTG_PHYCLK);

__raw_writel((__raw_readl(S3C_USBOTG_RSTCON)
&~(0x3<<1))|(0x1<<0), S3C_USBOTG_RSTCON);
mdelay(1);
__raw_writel((__raw_readl(S3C_USBOTG_RSTCON)
&~(0x7<<0)), S3C_USBOTG_RSTCON);
mdelay(1);

__raw_writel((__raw_readl(S3C_UDC_OTG_GUSBCFG)
|(0x3<<8)), S3C_UDC_OTG_GUSBCFG);

// smb136_set_otg_mode(1);

printk("otg_host_phy_int : USBPHYCTL=0x%x,PHYPWR=0x%x,PHYCLK=0x%x,USBCFG=0x%x\n",
readl(S5P_USB_PHY_CONTROL),
readl(S3C_USBOTG_PHYPWR),
readl(S3C_USBOTG_PHYCLK),
readl(S3C_UDC_OTG_GUSBCFG)
);
}
EXPORT_SYMBOL(otg_host_phy_init);
#endif

MACHINE_START(HERRING, "herring")
.boot_params = S5P_PA_SDRAM + 0x100,
.fixup = herring_fixup,
Expand Down
31 changes: 31 additions & 0 deletions arch/arm/plat-s5p/devs.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,37 @@
#include <mach/media.h>
#include <s3cfb.h>

#ifdef CONFIG_USB_S3C_OTG_HOST
/* USB Device (OTG hcd)*/
static struct resource s3c_usb_otghcd_resource[] = {
[0] = {
.start = S3C_PA_OTG,
.end = S3C_PA_OTG + S3C_SZ_OTG - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_OTG,
.end = IRQ_OTG,
.flags = IORESOURCE_IRQ,
}
};

static u64 s3c_device_usb_otghcd_dmamask = 0xffffffffUL;

struct platform_device s3c_device_usb_otghcd = {
.name = "s3c_otghcd",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_usb_otghcd_resource),
.resource = s3c_usb_otghcd_resource,
.dev = {
.dma_mask = &s3c_device_usb_otghcd_dmamask,
.coherent_dma_mask = 0xffffffffUL
}
};

EXPORT_SYMBOL(s3c_device_usb_otghcd);
#endif

/* RTC */
static struct resource s5p_rtc_resource[] = {
[0] = {
Expand Down
55 changes: 55 additions & 0 deletions arch/arm/plat-s5p/include/plat/s5p-otghost.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* linux/arch/arm/plat-s5p/include/plat/s5p-otghost.h
*
* Copyright 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Platform header file for Samsung OTG Host driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _PLAT_S5P_OTGHOST_H
#define _PLAT_S5P_OTGHOST_H __FILE__

#include <linux/wakelock.h>

/*#define CONFIG_USB_S3C_OTG_HOST_HANDLING_CLOCK*/
#define CONFIG_USB_S3C_OTG_HOST_DTGDRVVBUS

union port_flags_t {
/** raw register data */
u32 d32;
/** register bits */
struct {
unsigned port_connect_status_change:1;
unsigned port_connect_status:1;
unsigned port_reset_change:1;
unsigned port_enable_change:1;
unsigned port_suspend_change:1;
unsigned port_over_current_change:1;
unsigned reserved:26;
} b;
};

struct sec_otghost_data {
bool clk_usage;
void (*set_pwr_cb)(int on);
int host_notify;
int sec_whlist_table_num;
};

struct sec_otghost {
spinlock_t lock;

bool ch_halt;
union port_flags_t port_flag;
struct wake_lock wake_lock;

struct work_struct work;
struct workqueue_struct *wq;

struct sec_otghost_data *otg_data;
};

#endif /*_PLAT_S5P_OTGHOST_H */
3 changes: 3 additions & 0 deletions arch/arm/plat-samsung/include/plat/devs.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ extern struct platform_device s3c_device_android_usb;
extern struct platform_device s3c_device_usb_mass_storage;
extern struct platform_device s3c_device_rndis;
extern struct platform_device s3c_device_usb_hsotg;
#ifdef CONFIG_USB_S3C_OTG_HOST
extern struct platform_device s3c_device_usb_otghcd;
#endif

extern struct platform_device s5p_device_rotator;
extern struct platform_device s5p_device_tvout;
Expand Down
18 changes: 18 additions & 0 deletions drivers/misc/fsa9480.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@
#define INT_DETACH (1 << 1)
#define INT_ATTACH (1 << 0)

#ifdef CONFIG_USB_S3C_OTG_HOST
extern void set_otghost_mode(int mode);
#endif

struct fsa9480_usbsw {
struct i2c_client *client;
struct fsa9480_platform_data *pdata;
Expand Down Expand Up @@ -265,6 +269,16 @@ static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw)
dev_err(&client->dev,
"%s: err %d\n", __func__, ret);
}
#ifdef CONFIG_USB_S3C_OTG_HOST
// sztupy: handle automatic otg switching
if (val1 & DEV_USB_OTG) {
// otg cable detected
set_otghost_mode(2);
} else {
// client cable detected
set_otghost_mode(1);
}
#endif
/* UART */
} else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
if (pdata->uart_cb)
Expand Down Expand Up @@ -319,6 +333,10 @@ static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw)
usbsw->dev2 & DEV_T2_USB_MASK) {
if (pdata->usb_cb)
pdata->usb_cb(FSA9480_DETACHED);
#ifdef CONFIG_USB_S3C_OTG_HOST
// sztupy: also switch off otg host mode
set_otghost_mode(0);
#endif
/* UART */
} else if (usbsw->dev1 & DEV_T1_UART_MASK ||
usbsw->dev2 & DEV_T2_UART_MASK) {
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,6 @@ source "drivers/usb/gadget/Kconfig"

source "drivers/usb/otg/Kconfig"

source "drivers/usb/notify/Kconfig"

endif # USB_SUPPORT
3 changes: 3 additions & 0 deletions drivers/usb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ obj-$(CONFIG_USB) += core/
obj-$(CONFIG_USB_MON) += mon/

obj-$(CONFIG_PCI) += host/
obj-$(CONFIG_USB_S3C_OTG_HOST) += host/
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_ISP116X_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
Expand Down Expand Up @@ -51,3 +52,5 @@ obj-$(CONFIG_USB_MUSB_HDRC) += musb/
obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/
obj-$(CONFIG_USB_OTG_UTILS) += otg/
obj-$(CONFIG_USB_GADGET) += gadget/

obj-$(CONFIG_USB_HOST_NOTIFY) += notify/
4 changes: 4 additions & 0 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ static const u8 usb2_rh_dev_descriptor [18] = {

0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
#ifdef CONFIG_USB_S3C_OTG_HOST
0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ] */
#else
0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */
#endif
0x40, /* __u8 bMaxPacketSize0; 64 Bytes */

0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ config USB_S3C_HSUDC

config USB_GADGET_S3C_OTGD
boolean "S3C HS USB OTG Device"
depends on (ARCH_S5PV210) && !(USB_S3C_OTG_HOST)
depends on (ARCH_S5PV210)
help
Samsung's S3C64XX processors include high speed USB OTG2.0
controller. It has 15 configurable endpoints, as well as
Expand Down Expand Up @@ -652,7 +652,7 @@ comment "NOTE: S3C OTG device role enables the controller driver below"

config USB_S3C_OTGD
tristate "S3C high speed(2.0, dual-speed) USB OTG device"
depends on USB_GADGET && USB_GADGET_S3C_OTGD && !(USB_S3C_OTG_HOST)
depends on USB_GADGET && USB_GADGET_S3C_OTGD
default y
default USB_GADGET
select USB_GADGET_SELECTED
Expand Down
Loading

0 comments on commit db73376

Please sign in to comment.