diff options
Diffstat (limited to 'drivers/usb/musb/tusb6010.c')
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 102 |
1 files changed, 77 insertions, 25 deletions
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 2daa779f1382..3a5ffd575438 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -126,6 +126,52 @@ static void tusb_wbus_quirk(struct musb *musb, int enabled) | |||
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
129 | static u32 tusb_fifo_offset(u8 epnum) | ||
130 | { | ||
131 | return 0x200 + (epnum * 0x20); | ||
132 | } | ||
133 | |||
134 | static u32 tusb_ep_offset(u8 epnum, u16 offset) | ||
135 | { | ||
136 | return 0x10 + offset; | ||
137 | } | ||
138 | |||
139 | /* TUSB mapping: "flat" plus ep0 special cases */ | ||
140 | static void tusb_ep_select(void __iomem *mbase, u8 epnum) | ||
141 | { | ||
142 | musb_writeb(mbase, MUSB_INDEX, epnum); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. | ||
147 | */ | ||
148 | static u8 tusb_readb(const void __iomem *addr, unsigned offset) | ||
149 | { | ||
150 | u16 tmp; | ||
151 | u8 val; | ||
152 | |||
153 | tmp = __raw_readw(addr + (offset & ~1)); | ||
154 | if (offset & 1) | ||
155 | val = (tmp >> 8); | ||
156 | else | ||
157 | val = tmp & 0xff; | ||
158 | |||
159 | return val; | ||
160 | } | ||
161 | |||
162 | static void tusb_writeb(void __iomem *addr, unsigned offset, u8 data) | ||
163 | { | ||
164 | u16 tmp; | ||
165 | |||
166 | tmp = __raw_readw(addr + (offset & ~1)); | ||
167 | if (offset & 1) | ||
168 | tmp = (data << 8) | (tmp & 0xff); | ||
169 | else | ||
170 | tmp = (tmp & 0xff00) | data; | ||
171 | |||
172 | __raw_writew(tmp, addr + (offset & ~1)); | ||
173 | } | ||
174 | |||
129 | /* | 175 | /* |
130 | * TUSB 6010 may use a parallel bus that doesn't support byte ops; | 176 | * TUSB 6010 may use a parallel bus that doesn't support byte ops; |
131 | * so both loading and unloading FIFOs need explicit byte counts. | 177 | * so both loading and unloading FIFOs need explicit byte counts. |
@@ -173,7 +219,7 @@ static inline void tusb_fifo_read_unaligned(void __iomem *fifo, | |||
173 | } | 219 | } |
174 | } | 220 | } |
175 | 221 | ||
176 | void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf) | 222 | static void tusb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf) |
177 | { | 223 | { |
178 | struct musb *musb = hw_ep->musb; | 224 | struct musb *musb = hw_ep->musb; |
179 | void __iomem *ep_conf = hw_ep->conf; | 225 | void __iomem *ep_conf = hw_ep->conf; |
@@ -223,7 +269,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf) | |||
223 | tusb_fifo_write_unaligned(fifo, buf, len); | 269 | tusb_fifo_write_unaligned(fifo, buf, len); |
224 | } | 270 | } |
225 | 271 | ||
226 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) | 272 | static void tusb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) |
227 | { | 273 | { |
228 | struct musb *musb = hw_ep->musb; | 274 | struct musb *musb = hw_ep->musb; |
229 | void __iomem *ep_conf = hw_ep->conf; | 275 | void __iomem *ep_conf = hw_ep->conf; |
@@ -415,13 +461,13 @@ static void musb_do_idle(unsigned long _musb) | |||
415 | 461 | ||
416 | spin_lock_irqsave(&musb->lock, flags); | 462 | spin_lock_irqsave(&musb->lock, flags); |
417 | 463 | ||
418 | switch (musb->xceiv->state) { | 464 | switch (musb->xceiv->otg->state) { |
419 | case OTG_STATE_A_WAIT_BCON: | 465 | case OTG_STATE_A_WAIT_BCON: |
420 | if ((musb->a_wait_bcon != 0) | 466 | if ((musb->a_wait_bcon != 0) |
421 | && (musb->idle_timeout == 0 | 467 | && (musb->idle_timeout == 0 |
422 | || time_after(jiffies, musb->idle_timeout))) { | 468 | || time_after(jiffies, musb->idle_timeout))) { |
423 | dev_dbg(musb->controller, "Nothing connected %s, turning off VBUS\n", | 469 | dev_dbg(musb->controller, "Nothing connected %s, turning off VBUS\n", |
424 | usb_otg_state_string(musb->xceiv->state)); | 470 | usb_otg_state_string(musb->xceiv->otg->state)); |
425 | } | 471 | } |
426 | /* FALLTHROUGH */ | 472 | /* FALLTHROUGH */ |
427 | case OTG_STATE_A_IDLE: | 473 | case OTG_STATE_A_IDLE: |
@@ -474,9 +520,9 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) | |||
474 | 520 | ||
475 | /* Never idle if active, or when VBUS timeout is not set as host */ | 521 | /* Never idle if active, or when VBUS timeout is not set as host */ |
476 | if (musb->is_active || ((musb->a_wait_bcon == 0) | 522 | if (musb->is_active || ((musb->a_wait_bcon == 0) |
477 | && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { | 523 | && (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON))) { |
478 | dev_dbg(musb->controller, "%s active, deleting timer\n", | 524 | dev_dbg(musb->controller, "%s active, deleting timer\n", |
479 | usb_otg_state_string(musb->xceiv->state)); | 525 | usb_otg_state_string(musb->xceiv->otg->state)); |
480 | del_timer(&musb_idle_timer); | 526 | del_timer(&musb_idle_timer); |
481 | last_timer = jiffies; | 527 | last_timer = jiffies; |
482 | return; | 528 | return; |
@@ -493,7 +539,7 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) | |||
493 | last_timer = timeout; | 539 | last_timer = timeout; |
494 | 540 | ||
495 | dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", | 541 | dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", |
496 | usb_otg_state_string(musb->xceiv->state), | 542 | usb_otg_state_string(musb->xceiv->otg->state), |
497 | (unsigned long)jiffies_to_msecs(timeout - jiffies)); | 543 | (unsigned long)jiffies_to_msecs(timeout - jiffies)); |
498 | mod_timer(&musb_idle_timer, timeout); | 544 | mod_timer(&musb_idle_timer, timeout); |
499 | } | 545 | } |
@@ -524,7 +570,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) | |||
524 | if (is_on) { | 570 | if (is_on) { |
525 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); | 571 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); |
526 | otg->default_a = 1; | 572 | otg->default_a = 1; |
527 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 573 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
528 | devctl |= MUSB_DEVCTL_SESSION; | 574 | devctl |= MUSB_DEVCTL_SESSION; |
529 | 575 | ||
530 | conf |= TUSB_DEV_CONF_USB_HOST_MODE; | 576 | conf |= TUSB_DEV_CONF_USB_HOST_MODE; |
@@ -537,16 +583,16 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) | |||
537 | /* If ID pin is grounded, we want to be a_idle */ | 583 | /* If ID pin is grounded, we want to be a_idle */ |
538 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); | 584 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); |
539 | if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { | 585 | if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { |
540 | switch (musb->xceiv->state) { | 586 | switch (musb->xceiv->otg->state) { |
541 | case OTG_STATE_A_WAIT_VRISE: | 587 | case OTG_STATE_A_WAIT_VRISE: |
542 | case OTG_STATE_A_WAIT_BCON: | 588 | case OTG_STATE_A_WAIT_BCON: |
543 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | 589 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; |
544 | break; | 590 | break; |
545 | case OTG_STATE_A_WAIT_VFALL: | 591 | case OTG_STATE_A_WAIT_VFALL: |
546 | musb->xceiv->state = OTG_STATE_A_IDLE; | 592 | musb->xceiv->otg->state = OTG_STATE_A_IDLE; |
547 | break; | 593 | break; |
548 | default: | 594 | default: |
549 | musb->xceiv->state = OTG_STATE_A_IDLE; | 595 | musb->xceiv->otg->state = OTG_STATE_A_IDLE; |
550 | } | 596 | } |
551 | musb->is_active = 0; | 597 | musb->is_active = 0; |
552 | otg->default_a = 1; | 598 | otg->default_a = 1; |
@@ -554,7 +600,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) | |||
554 | } else { | 600 | } else { |
555 | musb->is_active = 0; | 601 | musb->is_active = 0; |
556 | otg->default_a = 0; | 602 | otg->default_a = 0; |
557 | musb->xceiv->state = OTG_STATE_B_IDLE; | 603 | musb->xceiv->otg->state = OTG_STATE_B_IDLE; |
558 | MUSB_DEV_MODE(musb); | 604 | MUSB_DEV_MODE(musb); |
559 | } | 605 | } |
560 | 606 | ||
@@ -569,7 +615,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) | |||
569 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | 615 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
570 | 616 | ||
571 | dev_dbg(musb->controller, "VBUS %s, devctl %02x otg %3x conf %08x prcm %08x\n", | 617 | dev_dbg(musb->controller, "VBUS %s, devctl %02x otg %3x conf %08x prcm %08x\n", |
572 | usb_otg_state_string(musb->xceiv->state), | 618 | usb_otg_state_string(musb->xceiv->otg->state), |
573 | musb_readb(musb->mregs, MUSB_DEVCTL), | 619 | musb_readb(musb->mregs, MUSB_DEVCTL), |
574 | musb_readl(tbase, TUSB_DEV_OTG_STAT), | 620 | musb_readl(tbase, TUSB_DEV_OTG_STAT), |
575 | conf, prcm); | 621 | conf, prcm); |
@@ -668,23 +714,23 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
668 | 714 | ||
669 | if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { | 715 | if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { |
670 | dev_dbg(musb->controller, "Forcing disconnect (no interrupt)\n"); | 716 | dev_dbg(musb->controller, "Forcing disconnect (no interrupt)\n"); |
671 | if (musb->xceiv->state != OTG_STATE_B_IDLE) { | 717 | if (musb->xceiv->otg->state != OTG_STATE_B_IDLE) { |
672 | /* INTR_DISCONNECT can hide... */ | 718 | /* INTR_DISCONNECT can hide... */ |
673 | musb->xceiv->state = OTG_STATE_B_IDLE; | 719 | musb->xceiv->otg->state = OTG_STATE_B_IDLE; |
674 | musb->int_usb |= MUSB_INTR_DISCONNECT; | 720 | musb->int_usb |= MUSB_INTR_DISCONNECT; |
675 | } | 721 | } |
676 | musb->is_active = 0; | 722 | musb->is_active = 0; |
677 | } | 723 | } |
678 | dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", | 724 | dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", |
679 | usb_otg_state_string(musb->xceiv->state), otg_stat); | 725 | usb_otg_state_string(musb->xceiv->otg->state), otg_stat); |
680 | idle_timeout = jiffies + (1 * HZ); | 726 | idle_timeout = jiffies + (1 * HZ); |
681 | schedule_work(&musb->irq_work); | 727 | schedule_work(&musb->irq_work); |
682 | 728 | ||
683 | } else /* A-dev state machine */ { | 729 | } else /* A-dev state machine */ { |
684 | dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", | 730 | dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", |
685 | usb_otg_state_string(musb->xceiv->state), otg_stat); | 731 | usb_otg_state_string(musb->xceiv->otg->state), otg_stat); |
686 | 732 | ||
687 | switch (musb->xceiv->state) { | 733 | switch (musb->xceiv->otg->state) { |
688 | case OTG_STATE_A_IDLE: | 734 | case OTG_STATE_A_IDLE: |
689 | dev_dbg(musb->controller, "Got SRP, turning on VBUS\n"); | 735 | dev_dbg(musb->controller, "Got SRP, turning on VBUS\n"); |
690 | musb_platform_set_vbus(musb, 1); | 736 | musb_platform_set_vbus(musb, 1); |
@@ -731,9 +777,9 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
731 | u8 devctl; | 777 | u8 devctl; |
732 | 778 | ||
733 | dev_dbg(musb->controller, "%s timer, %03x\n", | 779 | dev_dbg(musb->controller, "%s timer, %03x\n", |
734 | usb_otg_state_string(musb->xceiv->state), otg_stat); | 780 | usb_otg_state_string(musb->xceiv->otg->state), otg_stat); |
735 | 781 | ||
736 | switch (musb->xceiv->state) { | 782 | switch (musb->xceiv->otg->state) { |
737 | case OTG_STATE_A_WAIT_VRISE: | 783 | case OTG_STATE_A_WAIT_VRISE: |
738 | /* VBUS has probably been valid for a while now, | 784 | /* VBUS has probably been valid for a while now, |
739 | * but may well have bounced out of range a bit | 785 | * but may well have bounced out of range a bit |
@@ -745,7 +791,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
745 | dev_dbg(musb->controller, "devctl %02x\n", devctl); | 791 | dev_dbg(musb->controller, "devctl %02x\n", devctl); |
746 | break; | 792 | break; |
747 | } | 793 | } |
748 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | 794 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; |
749 | musb->is_active = 0; | 795 | musb->is_active = 0; |
750 | idle_timeout = jiffies | 796 | idle_timeout = jiffies |
751 | + msecs_to_jiffies(musb->a_wait_bcon); | 797 | + msecs_to_jiffies(musb->a_wait_bcon); |
@@ -1135,9 +1181,17 @@ static int tusb_musb_exit(struct musb *musb) | |||
1135 | } | 1181 | } |
1136 | 1182 | ||
1137 | static const struct musb_platform_ops tusb_ops = { | 1183 | static const struct musb_platform_ops tusb_ops = { |
1184 | .quirks = MUSB_IN_TUSB, | ||
1138 | .init = tusb_musb_init, | 1185 | .init = tusb_musb_init, |
1139 | .exit = tusb_musb_exit, | 1186 | .exit = tusb_musb_exit, |
1140 | 1187 | ||
1188 | .ep_offset = tusb_ep_offset, | ||
1189 | .ep_select = tusb_ep_select, | ||
1190 | .fifo_offset = tusb_fifo_offset, | ||
1191 | .readb = tusb_readb, | ||
1192 | .writeb = tusb_writeb, | ||
1193 | .read_fifo = tusb_read_fifo, | ||
1194 | .write_fifo = tusb_write_fifo, | ||
1141 | .enable = tusb_musb_enable, | 1195 | .enable = tusb_musb_enable, |
1142 | .disable = tusb_musb_disable, | 1196 | .disable = tusb_musb_disable, |
1143 | 1197 | ||
@@ -1164,10 +1218,8 @@ static int tusb_probe(struct platform_device *pdev) | |||
1164 | int ret; | 1218 | int ret; |
1165 | 1219 | ||
1166 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | 1220 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
1167 | if (!glue) { | 1221 | if (!glue) |
1168 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
1169 | return -ENOMEM; | 1222 | return -ENOMEM; |
1170 | } | ||
1171 | 1223 | ||
1172 | glue->dev = &pdev->dev; | 1224 | glue->dev = &pdev->dev; |
1173 | 1225 | ||