Blame view

arch/arm/mach-s3c2410/usb-simtec.c 2.81 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /* linux/arch/arm/mach-s3c2410/usb-simtec.c
   *
e02f86645   Ben Dooks   ARM: S3C: Update ...
3
   * Copyright 2004-2005 Simtec Electronics
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
   *   Ben Dooks <ben@simtec.co.uk>
   *
   * http://www.simtec.co.uk/products/EB2410ITX/
   *
   * Simtec BAST and Thorcom VR1000 USB port support functions
   *
   * 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
  */
  
  #define DEBUG
  
  #include <linux/kernel.h>
  #include <linux/types.h>
  #include <linux/interrupt.h>
  #include <linux/list.h>
ec976d6eb   Ben Dooks   [ARM] S3C24XX: GP...
21
  #include <linux/gpio.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
  #include <linux/timer.h>
  #include <linux/init.h>
  #include <linux/device.h>
fced80c73   Russell King   [ARM] Convert asm...
25
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
  
  #include <asm/mach/arch.h>
  #include <asm/mach/map.h>
  #include <asm/mach/irq.h>
a09e64fbc   Russell King   [ARM] Move includ...
30
31
  #include <mach/bast-map.h>
  #include <mach/bast-irq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32

a09e64fbc   Russell King   [ARM] Move includ...
33
  #include <mach/hardware.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  #include <asm/irq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

49121aa14   Ben Dooks   USB: S3C: Move us...
36
  #include <plat/usb-control.h>
a2b7ba9ca   Ben Dooks   [ARM] S3C24XX: Mo...
37
  #include <plat/devs.h>
49121aa14   Ben Dooks   USB: S3C: Move us...
38

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
  #include "usb-simtec.h"
  
  /* control power and monitor over-current events on various Simtec
   * designed boards.
  */
484ae6bd9   Ben Dooks   [PATCH] ARM: 2849...
44
  static unsigned int power_state[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
48
49
  static void
  usb_simtec_powercontrol(int port, int to)
  {
  	pr_debug("usb_simtec_powercontrol(%d,%d)
  ", port, to);
484ae6bd9   Ben Dooks   [PATCH] ARM: 2849...
50
51
52
  	power_state[port] = to;
  
  	if (power_state[0] && power_state[1])
7a05a2cbd   Ben Dooks   [ARM] S3C24XX: GP...
53
  		gpio_set_value(S3C2410_GPB(4), 0);
484ae6bd9   Ben Dooks   [PATCH] ARM: 2849...
54
  	else
7a05a2cbd   Ben Dooks   [ARM] S3C24XX: GP...
55
  		gpio_set_value(S3C2410_GPB(4), 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  }
  
  static irqreturn_t
0cd61b68c   Linus Torvalds   Initial blind fix...
59
  usb_simtec_ocirq(int irq, void *pw)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  {
2a7057e30   Jeff Garzik   [ARM] Remove poin...
61
  	struct s3c2410_hcd_info *info = pw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62

7a05a2cbd   Ben Dooks   [ARM] S3C24XX: GP...
63
  	if (gpio_get_value(S3C2410_GPG(10)) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
  		pr_debug("usb_simtec: over-current irq (oc detected)
  ");
484ae6bd9   Ben Dooks   [PATCH] ARM: 2849...
66
  		s3c2410_usb_report_oc(info, 3);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
  	} else {
  		pr_debug("usb_simtec: over-current irq (oc cleared)
  ");
484ae6bd9   Ben Dooks   [PATCH] ARM: 2849...
70
  		s3c2410_usb_report_oc(info, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
77
78
79
80
  	}
  
  	return IRQ_HANDLED;
  }
  
  static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
  {
  	int ret;
  
  	if (on) {
9ded96f24   Russell King   [PATCH] IRQ type ...
81
  		ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
52e405eaa   Thomas Gleixner   [PATCH] ARM: fixu...
82
83
  				  IRQF_DISABLED | IRQF_TRIGGER_RISING |
  				   IRQF_TRIGGER_FALLING,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
88
  				  "USB Over-current", info);
  		if (ret != 0) {
  			printk(KERN_ERR "failed to request usb oc irq
  ");
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
91
92
  	} else {
  		free_irq(IRQ_USBOC, info);
  	}
  }
f12675204   Ben Dooks   ARM: SAMSUNG: Add...
93
  static struct s3c2410_hcd_info usb_simtec_info __initdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  	.port[0]	= {
  		.flags	= S3C_HCDFLG_USED
  	},
  	.port[1]	= {
  		.flags	= S3C_HCDFLG_USED
  	},
  
  	.power_control	= usb_simtec_powercontrol,
  	.enable_oc	= usb_simtec_enableoc,
  };
  
  
  int usb_simtec_init(void)
  {
7a05a2cbd   Ben Dooks   [ARM] S3C24XX: GP...
108
  	int ret;
50f430e3a   Ben Dooks   ARM: S3C: Fix Sim...
109
110
  	printk("USB Power Control, Copyright 2004 Simtec Electronics
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111

7a05a2cbd   Ben Dooks   [ARM] S3C24XX: GP...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  	ret = gpio_request(S3C2410_GPB(4), "USB power control");
  	if (ret < 0) {
  		pr_err("%s: failed to get GPB4
  ", __func__);
  		return ret;
  	}
  
  	ret = gpio_request(S3C2410_GPG(10), "USB overcurrent");
  	if (ret < 0) {
  		pr_err("%s: failed to get GPG10
  ", __func__);
  		gpio_free(S3C2410_GPB(4));
  		return ret;
  	}
  
  	/* turn power on */
  	gpio_direction_output(S3C2410_GPB(4), 1);
  	gpio_direction_input(S3C2410_GPG(10));
f12675204   Ben Dooks   ARM: SAMSUNG: Add...
130
  	s3c_ohci_set_platdata(&usb_simtec_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
132
  	return 0;
  }