adm5120-hcd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. /*
  2. * HCD driver for ADM5120 SoC
  3. *
  4. * Copyright (C) 2005 Jeroen Vreeken ([email protected])
  5. *
  6. * Based on the ADMtek 2.4 driver
  7. * (C) Copyright 2003 Junius Chen <[email protected]>
  8. * Which again was based on the ohci and uhci drivers.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/delay.h>
  12. #include <linux/debugfs.h>
  13. #include <linux/seq_file.h>
  14. #include <linux/errno.h>
  15. #include <linux/init.h>
  16. #include <linux/list.h>
  17. #include <linux/usb.h>
  18. #include <linux/platform_device.h>
  19. #include <asm/io.h>
  20. #include <asm/irq.h>
  21. #include <asm/system.h>
  22. #include <asm/byteorder.h>
  23. #include <asm/mach-adm5120/adm5120_info.h>
  24. #include "../core/hcd.h"
  25. MODULE_DESCRIPTION("ADM5120 USB Host Controller Driver");
  26. MODULE_LICENSE("GPL");
  27. MODULE_AUTHOR("Jeroen Vreeken ([email protected])");
  28. #define ADMHCD_REG_CONTROL 0x00
  29. #define ADMHCD_REG_INTSTATUS 0x04
  30. #define ADMHCD_REG_INTENABLE 0x08
  31. #define ADMHCD_REG_HOSTCONTROL 0x10
  32. #define ADMHCD_REG_FMINTERVAL 0x18
  33. #define ADMHCD_REG_FMNUMBER 0x1c
  34. #define ADMHCD_REG_LSTHRESH 0x70
  35. #define ADMHCD_REG_RHDESCR 0x74
  36. #define ADMHCD_REG_PORTSTATUS0 0x78
  37. #define ADMHCD_REG_PORTSTATUS1 0x7c
  38. #define ADMHCD_REG_HOSTHEAD 0x80
  39. #define ADMHCD_NUMPORTS 2
  40. #define ADMHCD_HOST_EN 0x00000001 /* Host enable */
  41. #define ADMHCD_SW_INTREQ 0x00000002 /* request software int */
  42. #define ADMHCD_SW_RESET 0x00000008 /* Reset */
  43. #define ADMHCD_INT_TD 0x00100000 /* TD completed */
  44. #define ADMHCD_INT_SW 0x20000000 /* software interrupt */
  45. #define ADMHCD_INT_FATAL 0x40000000 /* Fatal interrupt */
  46. #define ADMHCD_INT_ACT 0x80000000 /* Interrupt active */
  47. #define ADMHCD_STATE_RST 0x00000000 /* bus state reset */
  48. #define ADMHCD_STATE_RES 0x00000001 /* bus state resume */
  49. #define ADMHCD_STATE_OP 0x00000002 /* bus state operational */
  50. #define ADMHCD_STATE_SUS 0x00000003 /* bus state suspended */
  51. #define ADMHCD_DMA_EN 0x00000004 /* enable dma engine */
  52. #define ADMHCD_NPS 0x00000020 /* No Power Switch */
  53. #define ADMHCD_LPSC 0x04000000 /* Local power switch change */
  54. #define ADMHCD_CCS 0x00000001 /* current connect status */
  55. #define ADMHCD_PES 0x00000002 /* port enable status */
  56. #define ADMHCD_PSS 0x00000004 /* port suspend status */
  57. #define ADMHCD_POCI 0x00000008 /* port overcurrent indicator */
  58. #define ADMHCD_PRS 0x00000010 /* port reset status */
  59. #define ADMHCD_PPS 0x00000100 /* port power status */
  60. #define ADMHCD_LSDA 0x00000200 /* low speed device attached */
  61. #define ADMHCD_CSC 0x00010000 /* connect status change */
  62. #define ADMHCD_PESC 0x00020000 /* enable status change */
  63. #define ADMHCD_PSSC 0x00040000 /* suspend status change */
  64. #define ADMHCD_OCIC 0x00080000 /* overcurrent change*/
  65. #define ADMHCD_PRSC 0x00100000 /* reset status change */
  66. struct admhcd_ed {
  67. /* Don't change first four, they used for DMA */
  68. u32 control;
  69. struct admhcd_td *tail;
  70. struct admhcd_td *head;
  71. struct admhcd_ed *next;
  72. /* the rest is for the driver only: */
  73. struct admhcd_td *cur;
  74. struct usb_host_endpoint *ep;
  75. struct urb *urb;
  76. struct admhcd_ed *real;
  77. } __attribute__ ((packed));
  78. #define ADMHCD_ED_EPSHIFT 7 /* Shift for endpoint number */
  79. #define ADMHCD_ED_INT 0x00000800 /* Is this an int endpoint */
  80. #define ADMHCD_ED_SPEED 0x00002000 /* Is it a high speed dev? */
  81. #define ADMHCD_ED_SKIP 0x00004000 /* Skip this ED */
  82. #define ADMHCD_ED_FORMAT 0x00008000 /* Is this an isoc endpoint */
  83. #define ADMHCD_ED_MAXSHIFT 16 /* Shift for max packet size */
  84. struct admhcd_td {
  85. /* Don't change first four, they are used for DMA */
  86. u32 control;
  87. u32 buffer;
  88. u32 buflen;
  89. struct admhcd_td *next;
  90. /* the rest is for the driver only: */
  91. struct urb *urb;
  92. struct admhcd_td *real;
  93. } __attribute__ ((packed));
  94. #define ADMHCD_TD_OWN 0x80000000
  95. #define ADMHCD_TD_TOGGLE 0x00000000
  96. #define ADMHCD_TD_DATA0 0x01000000
  97. #define ADMHCD_TD_DATA1 0x01800000
  98. #define ADMHCD_TD_OUT 0x00200000
  99. #define ADMHCD_TD_IN 0x00400000
  100. #define ADMHCD_TD_SETUP 0x00000000
  101. #define ADMHCD_TD_ISO 0x00010000
  102. #define ADMHCD_TD_R 0x00040000
  103. #define ADMHCD_TD_INTEN 0x00010000
  104. static int admhcd_td_err[16] = {
  105. 0, /* No */
  106. -EREMOTEIO, /* CRC */
  107. -EREMOTEIO, /* bit stuff */
  108. -EREMOTEIO, /* data toggle */
  109. -EPIPE, /* stall */
  110. -ETIMEDOUT, /* timeout */
  111. -EPROTO, /* pid err */
  112. -EPROTO, /* unexpected pid */
  113. -EREMOTEIO, /* data overrun */
  114. -EREMOTEIO, /* data underrun */
  115. -ETIMEDOUT, /* 1010 */
  116. -ETIMEDOUT, /* 1011 */
  117. -EREMOTEIO, /* buffer overrun */
  118. -EREMOTEIO, /* buffer underrun */
  119. -ETIMEDOUT, /* 1110 */
  120. -ETIMEDOUT, /* 1111 */
  121. };
  122. #define ADMHCD_TD_ERRMASK 0x38000000
  123. #define ADMHCD_TD_ERRSHIFT 27
  124. #define TD(td) ((struct admhcd_td *)(((u32)(td)) & ~0xf))
  125. #define ED(ed) ((struct admhcd_ed *)(((u32)(ed)) & ~0xf))
  126. struct admhcd {
  127. spinlock_t lock;
  128. void __iomem *addr_reg;
  129. void __iomem *data_reg;
  130. /* Root hub registers */
  131. u32 rhdesca;
  132. u32 rhdescb;
  133. u32 rhstatus;
  134. u32 rhport[2];
  135. /* async schedule: control, bulk */
  136. struct list_head async;
  137. u32 base;
  138. u32 dma_en;
  139. unsigned long flags;
  140. };
  141. static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd)
  142. {
  143. return (struct admhcd *)(hcd->hcd_priv);
  144. }
  145. static inline struct usb_hcd *admhcd_to_hcd(struct admhcd *admhcd)
  146. {
  147. return container_of((void *)admhcd, struct usb_hcd, hcd_priv);
  148. }
  149. static char hcd_name[] = "adm5120-hcd";
  150. static u32 admhcd_reg_get(struct admhcd *ahcd, int reg)
  151. {
  152. return *(volatile u32 *)KSEG1ADDR(ahcd->base+reg);
  153. }
  154. static void admhcd_reg_set(struct admhcd *ahcd, int reg, u32 val)
  155. {
  156. *(volatile u32 *)KSEG1ADDR(ahcd->base+reg) = val;
  157. }
  158. static void admhcd_lock(struct admhcd *ahcd)
  159. {
  160. spin_lock_irqsave(&ahcd->lock, ahcd->flags);
  161. ahcd->dma_en = admhcd_reg_get(ahcd, ADMHCD_REG_HOSTCONTROL) &
  162. ADMHCD_DMA_EN;
  163. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
  164. }
  165. static void admhcd_unlock(struct admhcd *ahcd)
  166. {
  167. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL,
  168. ADMHCD_STATE_OP | ahcd->dma_en);
  169. spin_unlock_irqrestore(&ahcd->lock, ahcd->flags);
  170. }
  171. static struct admhcd_td *admhcd_td_alloc(struct admhcd_ed *ed, struct urb *urb)
  172. {
  173. struct admhcd_td *tdn, *td;
  174. tdn = kmalloc(sizeof(struct admhcd_td), GFP_ATOMIC);
  175. if (!tdn)
  176. return NULL;
  177. tdn->real = tdn;
  178. tdn = (struct admhcd_td *)KSEG1ADDR(tdn);
  179. memset(tdn, 0, sizeof(struct admhcd_td));
  180. if (ed->cur == NULL) {
  181. ed->cur = tdn;
  182. ed->head = tdn;
  183. ed->tail = tdn;
  184. td = tdn;
  185. } else {
  186. /* Supply back the old tail and link in new td as tail */
  187. td = TD(ed->tail);
  188. TD(ed->tail)->next = tdn;
  189. ed->tail = tdn;
  190. }
  191. td->urb = urb;
  192. return td;
  193. }
  194. static void admhcd_td_free(struct admhcd_ed *ed, struct urb *urb)
  195. {
  196. struct admhcd_td *td, **tdp;
  197. if (urb == NULL)
  198. ed->control |= ADMHCD_ED_SKIP;
  199. tdp = &ed->cur;
  200. td = ed->cur;
  201. do {
  202. if (td->urb == urb)
  203. break;
  204. tdp = &td->next;
  205. td = TD(td->next);
  206. } while (td);
  207. while (td && td->urb == urb) {
  208. *tdp = TD(td->next);
  209. kfree(td->real);
  210. td = *tdp;
  211. }
  212. }
  213. /* Find an endpoint's descriptor, if needed allocate a new one and link it
  214. in the DMA chain
  215. */
  216. static struct admhcd_ed *admhcd_get_ed(struct admhcd *ahcd,
  217. struct usb_host_endpoint *ep, struct urb *urb)
  218. {
  219. struct admhcd_ed *hosthead;
  220. struct admhcd_ed *found = NULL, *ed = NULL;
  221. unsigned int pipe = urb->pipe;
  222. admhcd_lock(ahcd);
  223. hosthead = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD);
  224. if (hosthead) {
  225. for (ed = hosthead;; ed = ED(ed->next)) {
  226. if (ed->ep == ep) {
  227. found = ed;
  228. break;
  229. }
  230. if (ED(ed->next) == hosthead)
  231. break;
  232. }
  233. }
  234. if (!found) {
  235. found = kmalloc(sizeof(struct admhcd_ed), GFP_ATOMIC);
  236. if (!found)
  237. goto out;
  238. memset(found, 0, sizeof(struct admhcd_ed));
  239. found->real = found;
  240. found->ep = ep;
  241. found = (struct admhcd_ed *)KSEG1ADDR(found);
  242. found->control = usb_pipedevice(pipe) |
  243. (usb_pipeendpoint(pipe) << ADMHCD_ED_EPSHIFT) |
  244. (usb_pipeint(pipe) ? ADMHCD_ED_INT : 0) |
  245. (urb->dev->speed == USB_SPEED_FULL ? ADMHCD_ED_SPEED : 0) |
  246. (usb_pipeisoc(pipe) ? ADMHCD_ED_FORMAT : 0) |
  247. (usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)) << ADMHCD_ED_MAXSHIFT);
  248. /* Alloc first dummy td */
  249. admhcd_td_alloc(found, NULL);
  250. if (hosthead) {
  251. found->next = hosthead;
  252. ed->next = found;
  253. } else {
  254. found->next = found;
  255. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, (u32)found);
  256. }
  257. }
  258. out:
  259. admhcd_unlock(ahcd);
  260. return found;
  261. }
  262. static struct admhcd_td *admhcd_td_fill(u32 control, struct admhcd_td *td,
  263. dma_addr_t data, int len)
  264. {
  265. td->buffer = data;
  266. td->buflen = len;
  267. td->control = control;
  268. return TD(td->next);
  269. }
  270. static void admhcd_ed_start(struct admhcd *ahcd, struct admhcd_ed *ed)
  271. {
  272. struct admhcd_td *td = ed->cur;
  273. if (ed->urb)
  274. return;
  275. if (td->urb) {
  276. ed->urb = td->urb;
  277. while (1) {
  278. td->control |= ADMHCD_TD_OWN;
  279. if (TD(td->next)->urb != td->urb) {
  280. td->buflen |= ADMHCD_TD_INTEN;
  281. break;
  282. }
  283. td = TD(td->next);
  284. }
  285. }
  286. ed->head = TD(ed->head);
  287. ahcd->dma_en |= ADMHCD_DMA_EN;
  288. }
  289. static irqreturn_t adm5120hcd_irq(struct usb_hcd *hcd)
  290. {
  291. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  292. u32 intstatus;
  293. intstatus = admhcd_reg_get(ahcd, ADMHCD_REG_INTSTATUS);
  294. if (intstatus & ADMHCD_INT_FATAL) {
  295. admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_FATAL);
  296. //
  297. }
  298. if (intstatus & ADMHCD_INT_SW) {
  299. admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_SW);
  300. //
  301. }
  302. if (intstatus & ADMHCD_INT_TD) {
  303. struct admhcd_ed *ed, *head;
  304. admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_TD);
  305. head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD);
  306. ed = head;
  307. if (ed) do {
  308. /* Is it a finished TD? */
  309. if (ed->urb && !(ed->cur->control & ADMHCD_TD_OWN)) {
  310. struct admhcd_td *td;
  311. int error;
  312. td = ed->cur;
  313. error = (td->control & ADMHCD_TD_ERRMASK) >>
  314. ADMHCD_TD_ERRSHIFT;
  315. ed->urb->status = admhcd_td_err[error];
  316. admhcd_td_free(ed, ed->urb);
  317. // Calculate real length!!!
  318. ed->urb->actual_length = ed->urb->transfer_buffer_length;
  319. ed->urb->hcpriv = NULL;
  320. usb_hcd_giveback_urb(hcd, ed->urb);
  321. ed->urb = NULL;
  322. }
  323. admhcd_ed_start(ahcd, ed);
  324. ed = ED(ed->next);
  325. } while (ed != head);
  326. }
  327. return IRQ_HANDLED;
  328. }
  329. static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
  330. struct urb *urb, gfp_t mem_flags)
  331. {
  332. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  333. struct admhcd_ed *ed;
  334. struct admhcd_td *td;
  335. int size = 0, i, zero = 0, ret = 0;
  336. unsigned int pipe = urb->pipe, toggle = 0;
  337. dma_addr_t data = (dma_addr_t)urb->transfer_buffer;
  338. int data_len = urb->transfer_buffer_length;
  339. ed = admhcd_get_ed(ahcd, ep, urb);
  340. if (!ed)
  341. return -ENOMEM;
  342. switch(usb_pipetype(pipe)) {
  343. case PIPE_CONTROL:
  344. size = 2;
  345. case PIPE_INTERRUPT:
  346. case PIPE_BULK:
  347. default:
  348. size += urb->transfer_buffer_length / 4096;
  349. if (urb->transfer_buffer_length % 4096)
  350. size++;
  351. if (size == 0)
  352. size++;
  353. else if (urb->transfer_flags & URB_ZERO_PACKET &&
  354. !(urb->transfer_buffer_length %
  355. usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)))) {
  356. size++;
  357. zero = 1;
  358. }
  359. break;
  360. case PIPE_ISOCHRONOUS:
  361. size = urb->number_of_packets;
  362. break;
  363. }
  364. admhcd_lock(ahcd);
  365. /* Remember the first td */
  366. td = admhcd_td_alloc(ed, urb);
  367. if (!td) {
  368. ret = -ENOMEM;
  369. goto out;
  370. }
  371. /* Allocate additionall tds first */
  372. for (i = 1; i < size; i++) {
  373. if (admhcd_td_alloc(ed, urb) == NULL) {
  374. admhcd_td_free(ed, urb);
  375. ret = -ENOMEM;
  376. goto out;
  377. }
  378. }
  379. if (usb_gettoggle(urb->dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)))
  380. toggle = ADMHCD_TD_TOGGLE;
  381. else {
  382. toggle = ADMHCD_TD_DATA0;
  383. usb_settoggle(urb->dev, usb_pipeendpoint(pipe),
  384. usb_pipeout(pipe), 1);
  385. }
  386. switch(usb_pipetype(pipe)) {
  387. case PIPE_CONTROL:
  388. td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0,
  389. td, (dma_addr_t)urb->setup_packet, 8);
  390. while (data_len > 0) {
  391. td = admhcd_td_fill(ADMHCD_TD_DATA1
  392. | ADMHCD_TD_R |
  393. (usb_pipeout(pipe) ?
  394. ADMHCD_TD_OUT : ADMHCD_TD_IN), td,
  395. data, data_len % 4097);
  396. data_len -= 4096;
  397. }
  398. admhcd_td_fill(ADMHCD_TD_DATA1 | (usb_pipeout(pipe) ?
  399. ADMHCD_TD_IN : ADMHCD_TD_OUT), td,
  400. data, 0);
  401. break;
  402. case PIPE_INTERRUPT:
  403. case PIPE_BULK:
  404. //info ok for interrupt?
  405. i = 0;
  406. while(data_len > 4096) {
  407. td = admhcd_td_fill((usb_pipeout(pipe) ?
  408. ADMHCD_TD_OUT :
  409. ADMHCD_TD_IN | ADMHCD_TD_R) |
  410. (i ? ADMHCD_TD_TOGGLE : toggle), td,
  411. data, 4096);
  412. data += 4096;
  413. data_len -= 4096;
  414. i++;
  415. }
  416. td = admhcd_td_fill((usb_pipeout(pipe) ?
  417. ADMHCD_TD_OUT : ADMHCD_TD_IN) |
  418. (i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len);
  419. i++;
  420. if (zero)
  421. admhcd_td_fill((usb_pipeout(pipe) ?
  422. ADMHCD_TD_OUT : ADMHCD_TD_IN) |
  423. (i ? ADMHCD_TD_TOGGLE : toggle), td, 0, 0);
  424. break;
  425. case PIPE_ISOCHRONOUS:
  426. for (i = 0; i < urb->number_of_packets; i++) {
  427. td = admhcd_td_fill(ADMHCD_TD_ISO |
  428. ((urb->start_frame + i) & 0xffff), td,
  429. data + urb->iso_frame_desc[i].offset,
  430. urb->iso_frame_desc[i].length);
  431. }
  432. break;
  433. }
  434. urb->hcpriv = ed;
  435. admhcd_ed_start(ahcd, ed);
  436. out:
  437. admhcd_unlock(ahcd);
  438. return ret;
  439. }
  440. static int admhcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
  441. {
  442. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  443. struct admhcd_ed *ed;
  444. admhcd_lock(ahcd);
  445. ed = urb->hcpriv;
  446. if (ed && ed->urb != urb)
  447. admhcd_td_free(ed, urb);
  448. admhcd_unlock(ahcd);
  449. return 0;
  450. }
  451. static void admhcd_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
  452. {
  453. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  454. struct admhcd_ed *ed, *edt, *head;
  455. admhcd_lock(ahcd);
  456. head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD);
  457. if (!head)
  458. goto out;
  459. for (ed = head; ED(ed->next) != head; ed = ED(ed->next))
  460. if (ed->ep == ep)
  461. break;
  462. if (ed->ep != ep)
  463. goto out;
  464. while (ed->cur)
  465. admhcd_td_free(ed, ed->cur->urb);
  466. if (head == ed) {
  467. if (ED(ed->next) == ed) {
  468. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, 0);
  469. ahcd->dma_en = 0;
  470. goto out_free;
  471. }
  472. head = ED(ed->next);
  473. for (edt = head; ED(edt->next) != head; edt = ED(edt->next));
  474. edt->next = ED(ed->next);
  475. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, (u32)ed->next);
  476. goto out_free;
  477. }
  478. for (edt = head; edt->next != ed; edt = edt->next);
  479. edt->next = ed->next;
  480. out_free:
  481. kfree(ed->real);
  482. out:
  483. admhcd_unlock(ahcd);
  484. }
  485. static int admhcd_get_frame_number(struct usb_hcd *hcd)
  486. {
  487. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  488. return admhcd_reg_get(ahcd, ADMHCD_REG_FMNUMBER) & 0x0000ffff;
  489. }
  490. static int admhcd_hub_status_data(struct usb_hcd *hcd, char *buf)
  491. {
  492. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  493. int port;
  494. *buf = 0;
  495. for (port = 0; port < ADMHCD_NUMPORTS; port++) {
  496. if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4) &
  497. (ADMHCD_CSC | ADMHCD_PESC | ADMHCD_PSSC | ADMHCD_OCIC |
  498. ADMHCD_PRSC))
  499. *buf |= (1 << (port + 1));
  500. }
  501. return !!*buf;
  502. }
  503. static __u8 root_hub_hub_des[] = {
  504. 0x09, /* __u8 bLength; */
  505. 0x29, /* __u8 bDescriptorType; Hub-descriptor */
  506. 0x02, /* __u8 bNbrPorts; */
  507. 0x0a, 0x00, /* __u16 wHubCharacteristics; */
  508. 0x01, /* __u8 bPwrOn2pwrGood; 2ms */
  509. 0x00, /* __u8 bHubContrCurrent; 0mA */
  510. 0x00, /* __u8 DeviceRemovable; */
  511. 0xff, /* __u8 PortPwrCtrlMask; */
  512. };
  513. static int admhcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
  514. u16 wIndex, char *buf, u16 wLength)
  515. {
  516. struct admhcd *ahcd = hcd_to_admhcd(hcd);
  517. int retval = 0, len;
  518. unsigned int port = wIndex -1;
  519. switch (typeReq) {
  520. case GetHubStatus:
  521. *(__le32 *)buf = cpu_to_le32(0);
  522. break;
  523. case GetPortStatus:
  524. if (port >= ADMHCD_NUMPORTS)
  525. goto err;
  526. *(__le32 *)buf = cpu_to_le32(
  527. admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4));
  528. break;
  529. case SetHubFeature: /* We don't implement these */
  530. case ClearHubFeature:
  531. switch (wValue) {
  532. case C_HUB_OVER_CURRENT:
  533. case C_HUB_LOCAL_POWER:
  534. break;
  535. default:
  536. goto err;
  537. }
  538. case SetPortFeature:
  539. if (port >= ADMHCD_NUMPORTS)
  540. goto err;
  541. switch (wValue) {
  542. case USB_PORT_FEAT_SUSPEND:
  543. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  544. ADMHCD_PSS);
  545. break;
  546. case USB_PORT_FEAT_RESET:
  547. if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4)
  548. & ADMHCD_CCS) {
  549. admhcd_reg_set(ahcd,
  550. ADMHCD_REG_PORTSTATUS0 + port*4,
  551. ADMHCD_PRS | ADMHCD_CSC);
  552. mdelay(50);
  553. admhcd_reg_set(ahcd,
  554. ADMHCD_REG_PORTSTATUS0 + port*4,
  555. ADMHCD_PES | ADMHCD_CSC);
  556. }
  557. break;
  558. case USB_PORT_FEAT_POWER:
  559. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  560. ADMHCD_PPS);
  561. break;
  562. default:
  563. goto err;
  564. }
  565. break;
  566. case ClearPortFeature:
  567. if (port >= ADMHCD_NUMPORTS)
  568. goto err;
  569. switch (wValue) {
  570. case USB_PORT_FEAT_ENABLE:
  571. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  572. ADMHCD_CCS);
  573. break;
  574. case USB_PORT_FEAT_C_ENABLE:
  575. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  576. ADMHCD_PESC);
  577. break;
  578. case USB_PORT_FEAT_SUSPEND:
  579. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  580. ADMHCD_POCI);
  581. break;
  582. case USB_PORT_FEAT_C_SUSPEND:
  583. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  584. ADMHCD_PSSC);
  585. case USB_PORT_FEAT_POWER:
  586. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  587. ADMHCD_LSDA);
  588. break;
  589. case USB_PORT_FEAT_C_CONNECTION:
  590. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  591. ADMHCD_CSC);
  592. break;
  593. case USB_PORT_FEAT_C_OVER_CURRENT:
  594. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  595. ADMHCD_OCIC);
  596. break;
  597. case USB_PORT_FEAT_C_RESET:
  598. admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4,
  599. ADMHCD_PRSC);
  600. break;
  601. default:
  602. goto err;
  603. }
  604. break;
  605. case GetHubDescriptor:
  606. len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
  607. memcpy(buf, root_hub_hub_des, len);
  608. break;
  609. default:
  610. err:
  611. retval = -EPIPE;
  612. }
  613. return retval;
  614. }
  615. static struct hc_driver adm5120_hc_driver = {
  616. .description = hcd_name,
  617. .product_desc = "ADM5120 HCD",
  618. .hcd_priv_size = sizeof(struct admhcd),
  619. .irq = adm5120hcd_irq,
  620. .flags = HCD_USB11,
  621. .urb_enqueue = admhcd_urb_enqueue,
  622. .urb_dequeue = admhcd_urb_dequeue,
  623. .endpoint_disable = admhcd_endpoint_disable,
  624. .get_frame_number = admhcd_get_frame_number,
  625. .hub_status_data = admhcd_hub_status_data,
  626. .hub_control = admhcd_hub_control,
  627. };
  628. #define resource_len(r) (((r)->end - (r)->start) + 1)
  629. static int __init adm5120hcd_probe(struct platform_device *pdev)
  630. {
  631. struct usb_hcd *hcd;
  632. struct admhcd *ahcd;
  633. struct resource *addr, *data;
  634. void __iomem *addr_reg;
  635. void __iomem *data_reg;
  636. int err = 0, irq;
  637. if (pdev->num_resources < 3) {
  638. err = -ENODEV;
  639. goto out;
  640. }
  641. if (pdev->dev.dma_mask) {
  642. printk(KERN_DEBUG "no we won't dma\n");
  643. return -EINVAL;
  644. }
  645. irq = platform_get_irq(pdev, 0);
  646. data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  647. addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  648. if (!addr || !data || irq < 0) {
  649. err = -ENODEV;
  650. goto out;
  651. }
  652. if (!request_mem_region(addr->start, 2, hcd_name)) {
  653. err = -EBUSY;
  654. goto out;
  655. }
  656. addr_reg = ioremap(addr->start, resource_len(addr));
  657. if (addr_reg == NULL) {
  658. err = -ENOMEM;
  659. goto out_mem;
  660. }
  661. if (!request_mem_region(data->start, 2, hcd_name)) {
  662. err = -EBUSY;
  663. goto out_unmap;
  664. }
  665. data_reg = ioremap(data->start, resource_len(data));
  666. if (data_reg == NULL) {
  667. err = -ENOMEM;
  668. goto out_mem;
  669. }
  670. hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id);
  671. if (!hcd)
  672. goto out_mem;
  673. hcd->rsrc_start = addr->start;
  674. ahcd = hcd_to_admhcd(hcd);
  675. spin_lock_init(&ahcd->lock);
  676. INIT_LIST_HEAD(&ahcd->async);
  677. ahcd->data_reg = data_reg;
  678. ahcd->addr_reg = addr_reg;
  679. hcd->product_desc = "ADM5120 HCD";
  680. /* Initialise the HCD registers */
  681. admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
  682. mdelay(10);
  683. admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET);
  684. while (admhcd_reg_get(ahcd, ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET)
  685. mdelay(1);
  686. admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_HOST_EN);
  687. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, 0x00000000);
  688. admhcd_reg_set(ahcd, ADMHCD_REG_FMINTERVAL, 0x20002edf);
  689. admhcd_reg_set(ahcd, ADMHCD_REG_LSTHRESH, 0x628);
  690. admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE,
  691. ADMHCD_INT_ACT | ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD);
  692. admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS,
  693. ADMHCD_INT_ACT | ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD);
  694. admhcd_reg_set(ahcd, ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC);
  695. admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
  696. err = usb_add_hcd(hcd, irq, IRQF_DISABLED);
  697. if (err)
  698. goto out_dev;
  699. return 0;
  700. out_dev:
  701. usb_put_hcd(hcd);
  702. out_unmap:
  703. iounmap(addr_reg);
  704. out_mem:
  705. release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start);
  706. out:
  707. return err;
  708. }
  709. static int __init_or_module adm5120hcd_remove(struct platform_device *pdev)
  710. {
  711. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  712. struct admhcd *ahcd;
  713. if (!hcd)
  714. return 0;
  715. ahcd = hcd_to_admhcd(hcd);
  716. usb_remove_hcd(hcd);
  717. usb_put_hcd(hcd);
  718. return 0;
  719. }
  720. static struct platform_driver adm5120hcd_driver = {
  721. .probe = adm5120hcd_probe,
  722. .remove = adm5120hcd_remove,
  723. .driver = {
  724. .name = "adm5120-hcd",
  725. .owner = THIS_MODULE,
  726. },
  727. };
  728. static int __init adm5120hcd_init(void)
  729. {
  730. if (usb_disabled())
  731. return -ENODEV;
  732. if (!adm5120_board.has_usb)
  733. return -ENODEV;
  734. return platform_driver_register(&adm5120hcd_driver);
  735. }
  736. static void __exit adm5120hcd_exit(void)
  737. {
  738. platform_driver_unregister(&adm5120hcd_driver);
  739. }
  740. module_init(adm5120hcd_init);
  741. module_exit(adm5120hcd_exit);