usb-simtec.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* linux/arch/arm/mach-s3c2410/usb-simtec.c
  2. *
  3. * Copyright (c) 2004 Simtec Electronics
  4. * Ben Dooks <ben@simtec.co.uk>
  5. *
  6. * http://www.simtec.co.uk/products/EB2410ITX/
  7. *
  8. * Simtec BAST and Thorcom VR1000 USB port support functions
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. *
  14. * Modifications:
  15. * 14-Sep-2004 BJD Created
  16. * 18-Oct-2004 BJD Cleanups, and added code to report OC cleared
  17. */
  18. #define DEBUG
  19. #include <linux/kernel.h>
  20. #include <linux/types.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/list.h>
  23. #include <linux/timer.h>
  24. #include <linux/init.h>
  25. #include <linux/device.h>
  26. #include <asm/mach/arch.h>
  27. #include <asm/mach/map.h>
  28. #include <asm/mach/irq.h>
  29. #include <asm/arch/bast-map.h>
  30. #include <asm/arch/bast-irq.h>
  31. #include <asm/arch/usb-control.h>
  32. #include <asm/arch/regs-gpio.h>
  33. #include <asm/hardware.h>
  34. #include <asm/io.h>
  35. #include <asm/irq.h>
  36. #include <asm/mach-types.h>
  37. #include "devs.h"
  38. #include "usb-simtec.h"
  39. /* control power and monitor over-current events on various Simtec
  40. * designed boards.
  41. */
  42. static void
  43. usb_simtec_powercontrol(int port, int to)
  44. {
  45. pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
  46. if (port == 1)
  47. s3c2410_gpio_setpin(S3C2410_GPB4, to ? 0:1);
  48. }
  49. static irqreturn_t
  50. usb_simtec_ocirq(int irq, void *pw, struct pt_regs *regs)
  51. {
  52. struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw;
  53. if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) {
  54. pr_debug("usb_simtec: over-current irq (oc detected)\n");
  55. s3c2410_report_oc(info, 3);
  56. } else {
  57. pr_debug("usb_simtec: over-current irq (oc cleared)\n");
  58. s3c2410_report_oc(info, 0);
  59. }
  60. return IRQ_HANDLED;
  61. }
  62. static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
  63. {
  64. int ret;
  65. if (on) {
  66. ret = request_irq(IRQ_USBOC, usb_simtec_ocirq, SA_INTERRUPT,
  67. "USB Over-current", info);
  68. if (ret != 0) {
  69. printk(KERN_ERR "failed to request usb oc irq\n");
  70. }
  71. set_irq_type(IRQ_USBOC, IRQT_BOTHEDGE);
  72. } else {
  73. free_irq(IRQ_USBOC, info);
  74. }
  75. }
  76. static struct s3c2410_hcd_info usb_simtec_info = {
  77. .port[0] = {
  78. .flags = S3C_HCDFLG_USED
  79. },
  80. .port[1] = {
  81. .flags = S3C_HCDFLG_USED
  82. },
  83. .power_control = usb_simtec_powercontrol,
  84. .enable_oc = usb_simtec_enableoc,
  85. };
  86. int usb_simtec_init(void)
  87. {
  88. printk("USB Power Control, (c) 2004 Simtec Electronics\n");
  89. s3c_device_usb.dev.platform_data = &usb_simtec_info;
  90. s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
  91. s3c2410_gpio_setpin(S3C2410_GPB4, 1);
  92. return 0;
  93. }