aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c167
1 files changed, 100 insertions, 67 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index ca9041634c04..84793a0ee506 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -128,8 +128,6 @@ struct s3c_hsotg_ep {
128 char name[10]; 128 char name[10];
129}; 129};
130 130
131#define S3C_HSOTG_EPS (8+1) /* limit to 9 for the moment */
132
133/** 131/**
134 * struct s3c_hsotg - driver state. 132 * struct s3c_hsotg - driver state.
135 * @dev: The parent device supplied to the probe function 133 * @dev: The parent device supplied to the probe function
@@ -140,6 +138,7 @@ struct s3c_hsotg_ep {
140 * @irq: The IRQ number we are using 138 * @irq: The IRQ number we are using
141 * @supplies: Definition of USB power supplies 139 * @supplies: Definition of USB power supplies
142 * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. 140 * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos.
141 * @num_of_eps: Number of available EPs (excluding EP0)
143 * @debug_root: root directrory for debugfs. 142 * @debug_root: root directrory for debugfs.
144 * @debug_file: main status file for debugfs. 143 * @debug_file: main status file for debugfs.
145 * @debug_fifo: FIFO status file for debugfs. 144 * @debug_fifo: FIFO status file for debugfs.
@@ -164,6 +163,7 @@ struct s3c_hsotg {
164 struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; 163 struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)];
165 164
166 unsigned int dedicated_fifos:1; 165 unsigned int dedicated_fifos:1;
166 unsigned char num_of_eps;
167 167
168 struct dentry *debug_root; 168 struct dentry *debug_root;
169 struct dentry *debug_file; 169 struct dentry *debug_file;
@@ -177,7 +177,7 @@ struct s3c_hsotg {
177 struct usb_gadget gadget; 177 struct usb_gadget gadget;
178 unsigned int setup; 178 unsigned int setup;
179 unsigned long last_rst; 179 unsigned long last_rst;
180 struct s3c_hsotg_ep eps[]; 180 struct s3c_hsotg_ep *eps;
181}; 181};
182 182
183/** 183/**
@@ -952,7 +952,7 @@ static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg,
952 if (windex >= 0x100) 952 if (windex >= 0x100)
953 return NULL; 953 return NULL;
954 954
955 if (idx > S3C_HSOTG_EPS) 955 if (idx > hsotg->num_of_eps)
956 return NULL; 956 return NULL;
957 957
958 if (idx && ep->dir_in != dir) 958 if (idx && ep->dir_in != dir)
@@ -2036,7 +2036,7 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg)
2036 if (ep0_mps) { 2036 if (ep0_mps) {
2037 int i; 2037 int i;
2038 s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps); 2038 s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps);
2039 for (i = 1; i < S3C_HSOTG_EPS; i++) 2039 for (i = 1; i < hsotg->num_of_eps; i++)
2040 s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps); 2040 s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps);
2041 } 2041 }
2042 2042
@@ -2099,7 +2099,7 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg)
2099{ 2099{
2100 unsigned ep; 2100 unsigned ep;
2101 2101
2102 for (ep = 0; ep < S3C_HSOTG_EPS; ep++) 2102 for (ep = 0; ep < hsotg->num_of_eps; ep++)
2103 kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); 2103 kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true);
2104 2104
2105 call_gadget(hsotg, disconnect); 2105 call_gadget(hsotg, disconnect);
@@ -2117,7 +2117,7 @@ static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic)
2117 2117
2118 /* look through for any more data to transmit */ 2118 /* look through for any more data to transmit */
2119 2119
2120 for (epno = 0; epno < S3C_HSOTG_EPS; epno++) { 2120 for (epno = 0; epno < hsotg->num_of_eps; epno++) {
2121 ep = &hsotg->eps[epno]; 2121 ep = &hsotg->eps[epno];
2122 2122
2123 if (!ep->dir_in) 2123 if (!ep->dir_in)
@@ -2783,6 +2783,45 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
2783 hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); 2783 hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
2784} 2784}
2785 2785
2786static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
2787{
2788 /* unmask subset of endpoint interrupts */
2789
2790 writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk |
2791 S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk,
2792 hsotg->regs + S3C_DIEPMSK);
2793
2794 writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk |
2795 S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk,
2796 hsotg->regs + S3C_DOEPMSK);
2797
2798 writel(0, hsotg->regs + S3C_DAINTMSK);
2799
2800 /* Be in disconnected state until gadget is registered */
2801 __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
2802
2803 if (0) {
2804 /* post global nak until we're ready */
2805 writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak,
2806 hsotg->regs + S3C_DCTL);
2807 }
2808
2809 /* setup fifos */
2810
2811 dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
2812 readl(hsotg->regs + S3C_GRXFSIZ),
2813 readl(hsotg->regs + S3C_GNPTXFSIZ));
2814
2815 s3c_hsotg_init_fifo(hsotg);
2816
2817 /* set the PLL on, remove the HNP/SRP and set the PHY */
2818 writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | (0x5 << 10),
2819 hsotg->regs + S3C_GUSBCFG);
2820
2821 writel(using_dma(hsotg) ? S3C_GAHBCFG_DMAEn : 0x0,
2822 hsotg->regs + S3C_GAHBCFG);
2823}
2824
2786static int s3c_hsotg_start(struct usb_gadget_driver *driver, 2825static int s3c_hsotg_start(struct usb_gadget_driver *driver,
2787 int (*bind)(struct usb_gadget *)) 2826 int (*bind)(struct usb_gadget *))
2788{ 2827{
@@ -2853,7 +2892,7 @@ static int s3c_hsotg_stop(struct usb_gadget_driver *driver)
2853 return -EINVAL; 2892 return -EINVAL;
2854 2893
2855 /* all endpoints should be shutdown */ 2894 /* all endpoints should be shutdown */
2856 for (ep = 0; ep < S3C_HSOTG_EPS; ep++) 2895 for (ep = 0; ep < hsotg->num_of_eps; ep++)
2857 s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); 2896 s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
2858 2897
2859 call_gadget(hsotg, disconnect); 2898 call_gadget(hsotg, disconnect);
@@ -2944,53 +2983,28 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg,
2944 } 2983 }
2945} 2984}
2946 2985
2947static void s3c_hsotg_init(struct s3c_hsotg *hsotg) 2986/**
2987 * s3c_hsotg_hw_cfg - read HW configuration registers
2988 * @param: The device state
2989 *
2990 * Read the USB core HW configuration registers
2991 */
2992static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg)
2948{ 2993{
2949 u32 cfg4; 2994 u32 cfg2, cfg4;
2950 2995 /* check hardware configuration */
2951 /* unmask subset of endpoint interrupts */
2952
2953 writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk |
2954 S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk,
2955 hsotg->regs + S3C_DIEPMSK);
2956
2957 writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk |
2958 S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk,
2959 hsotg->regs + S3C_DOEPMSK);
2960
2961 writel(0, hsotg->regs + S3C_DAINTMSK);
2962
2963 /* Be in disconnected state until gadget is registered */
2964 __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
2965
2966 if (0) {
2967 /* post global nak until we're ready */
2968 writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak,
2969 hsotg->regs + S3C_DCTL);
2970 }
2971
2972 /* setup fifos */
2973
2974 dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
2975 readl(hsotg->regs + S3C_GRXFSIZ),
2976 readl(hsotg->regs + S3C_GNPTXFSIZ));
2977
2978 s3c_hsotg_init_fifo(hsotg);
2979
2980 /* set the PLL on, remove the HNP/SRP and set the PHY */
2981 writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | (0x5 << 10),
2982 hsotg->regs + S3C_GUSBCFG);
2983 2996
2984 writel(using_dma(hsotg) ? S3C_GAHBCFG_DMAEn : 0x0, 2997 cfg2 = readl(hsotg->regs + 0x48);
2985 hsotg->regs + S3C_GAHBCFG); 2998 hsotg->num_of_eps = (cfg2 >> 10) & 0xF;
2986 2999
2987 /* check hardware configuration */ 3000 dev_info(hsotg->dev, "EPs:%d\n", hsotg->num_of_eps);
2988 3001
2989 cfg4 = readl(hsotg->regs + 0x50); 3002 cfg4 = readl(hsotg->regs + 0x50);
2990 hsotg->dedicated_fifos = (cfg4 >> 25) & 1; 3003 hsotg->dedicated_fifos = (cfg4 >> 25) & 1;
2991 3004
2992 dev_info(hsotg->dev, "%s fifos\n", 3005 dev_info(hsotg->dev, "%s fifos\n",
2993 hsotg->dedicated_fifos ? "dedicated" : "shared"); 3006 hsotg->dedicated_fifos ? "dedicated" : "shared");
3007
2994} 3008}
2995 3009
2996static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) 3010static void s3c_hsotg_dump(struct s3c_hsotg *hsotg)
@@ -3284,7 +3298,7 @@ static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
3284 3298
3285 /* create one file for each endpoint */ 3299 /* create one file for each endpoint */
3286 3300
3287 for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) { 3301 for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
3288 struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; 3302 struct s3c_hsotg_ep *ep = &hsotg->eps[epidx];
3289 3303
3290 ep->debugfs = debugfs_create_file(ep->name, 0444, 3304 ep->debugfs = debugfs_create_file(ep->name, 0444,
@@ -3306,7 +3320,7 @@ static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
3306{ 3320{
3307 unsigned epidx; 3321 unsigned epidx;
3308 3322
3309 for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) { 3323 for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
3310 struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; 3324 struct s3c_hsotg_ep *ep = &hsotg->eps[epidx];
3311 debugfs_remove(ep->debugfs); 3325 debugfs_remove(ep->debugfs);
3312 } 3326 }
@@ -3320,6 +3334,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3320{ 3334{
3321 struct s3c_hsotg_plat *plat = pdev->dev.platform_data; 3335 struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
3322 struct device *dev = &pdev->dev; 3336 struct device *dev = &pdev->dev;
3337 struct s3c_hsotg_ep *eps;
3323 struct s3c_hsotg *hsotg; 3338 struct s3c_hsotg *hsotg;
3324 struct resource *res; 3339 struct resource *res;
3325 int epnum; 3340 int epnum;
@@ -3332,9 +3347,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3332 return -EINVAL; 3347 return -EINVAL;
3333 } 3348 }
3334 3349
3335 hsotg = kzalloc(sizeof(struct s3c_hsotg) + 3350 hsotg = kzalloc(sizeof(struct s3c_hsotg), GFP_KERNEL);
3336 sizeof(struct s3c_hsotg_ep) * S3C_HSOTG_EPS,
3337 GFP_KERNEL);
3338 if (!hsotg) { 3351 if (!hsotg) {
3339 dev_err(dev, "cannot get memory\n"); 3352 dev_err(dev, "cannot get memory\n");
3340 return -ENOMEM; 3353 return -ENOMEM;
@@ -3401,20 +3414,6 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3401 hsotg->gadget.dev.parent = dev; 3414 hsotg->gadget.dev.parent = dev;
3402 hsotg->gadget.dev.dma_mask = dev->dma_mask; 3415 hsotg->gadget.dev.dma_mask = dev->dma_mask;
3403 3416
3404 /* setup endpoint information */
3405
3406 INIT_LIST_HEAD(&hsotg->gadget.ep_list);
3407 hsotg->gadget.ep0 = &hsotg->eps[0].ep;
3408
3409 /* allocate EP0 request */
3410
3411 hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps[0].ep,
3412 GFP_KERNEL);
3413 if (!hsotg->ctrl_req) {
3414 dev_err(dev, "failed to allocate ctrl req\n");
3415 goto err_regs;
3416 }
3417
3418 /* reset the system */ 3417 /* reset the system */
3419 3418
3420 clk_enable(hsotg->clk); 3419 clk_enable(hsotg->clk);
@@ -3444,14 +3443,45 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3444 3443
3445 s3c_hsotg_corereset(hsotg); 3444 s3c_hsotg_corereset(hsotg);
3446 s3c_hsotg_init(hsotg); 3445 s3c_hsotg_init(hsotg);
3446 s3c_hsotg_hw_cfg(hsotg);
3447
3448 /* hsotg->num_of_eps holds number of EPs other than ep0 */
3449
3450 if (hsotg->num_of_eps == 0) {
3451 dev_err(dev, "wrong number of EPs (zero)\n");
3452 goto err_supplies;
3453 }
3454
3455 eps = kcalloc(hsotg->num_of_eps + 1, sizeof(struct s3c_hsotg_ep),
3456 GFP_KERNEL);
3457 if (!eps) {
3458 dev_err(dev, "cannot get memory\n");
3459 goto err_supplies;
3460 }
3461
3462 hsotg->eps = eps;
3463
3464 /* setup endpoint information */
3465
3466 INIT_LIST_HEAD(&hsotg->gadget.ep_list);
3467 hsotg->gadget.ep0 = &hsotg->eps[0].ep;
3468
3469 /* allocate EP0 request */
3470
3471 hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps[0].ep,
3472 GFP_KERNEL);
3473 if (!hsotg->ctrl_req) {
3474 dev_err(dev, "failed to allocate ctrl req\n");
3475 goto err_ep_mem;
3476 }
3447 3477
3448 /* initialise the endpoints now the core has been initialised */ 3478 /* initialise the endpoints now the core has been initialised */
3449 for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++) 3479 for (epnum = 0; epnum < hsotg->num_of_eps; epnum++)
3450 s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum); 3480 s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum);
3451 3481
3452 ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget); 3482 ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
3453 if (ret) 3483 if (ret)
3454 goto err_supplies; 3484 goto err_ep_mem;
3455 3485
3456 s3c_hsotg_create_debug(hsotg); 3486 s3c_hsotg_create_debug(hsotg);
3457 3487
@@ -3460,6 +3490,9 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
3460 our_hsotg = hsotg; 3490 our_hsotg = hsotg;
3461 return 0; 3491 return 0;
3462 3492
3493 err_ep_mem:
3494 kfree(eps);
3495
3463err_supplies: 3496err_supplies:
3464 s3c_hsotg_phy_disable(hsotg); 3497 s3c_hsotg_phy_disable(hsotg);
3465 3498