aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-09-25 15:28:13 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-25 13:21:27 -0500
commit0e9a3ddc91882a19e255dceb18b712f57e3bb731 (patch)
tree00497818ebd8b4beea33c033ae2e2267afea3da2 /arch/arm/mach-davinci
parente5d3d252d5e06e846d767166e254831b711ee243 (diff)
davinci: DA830 EVM: OHCI platform code
On this board the OHCI port's power control and over-current signals from TPS2065 power switch are connected via GPIO1[15] and GPIO2[1] respectively, so we can implement the DA8xx OHCI glue layer's hooks for overriding the root hub port's power and over-current status bits. We also have to properly set up the clocking mode in the CFGCHIP2 register, so that internal 24 MHz reference clock is fed to the USB 2.0 (MUSB) PHY and its output is used to clock the USB 1.1 (OHCI) PHY... Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 20100370e2e6..9dc4813c8645 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/console.h> 15#include <linux/console.h>
16#include <linux/interrupt.h>
16#include <linux/gpio.h> 17#include <linux/gpio.h>
17#include <linux/i2c.h> 18#include <linux/i2c.h>
18#include <linux/i2c/pcf857x.h> 19#include <linux/i2c/pcf857x.h>
@@ -28,6 +29,7 @@
28#include <mach/gpio.h> 29#include <mach/gpio.h>
29#include <mach/da8xx.h> 30#include <mach/da8xx.h>
30#include <mach/asp.h> 31#include <mach/asp.h>
32#include <mach/usb.h>
31 33
32#define DA830_EVM_PHY_MASK 0x0 34#define DA830_EVM_PHY_MASK 0x0
33#define DA830_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ 35#define DA830_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */
@@ -84,6 +86,127 @@ static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
84 .bus_delay = 0, /* usec */ 86 .bus_delay = 0, /* usec */
85}; 87};
86 88
89/*
90 * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
91 */
92#define ON_BD_USB_DRV GPIO_TO_PIN(1, 15)
93#define ON_BD_USB_OVC GPIO_TO_PIN(2, 4)
94
95static const short da830_evm_usb11_pins[] = {
96 DA830_GPIO1_15, DA830_GPIO2_4,
97 -1
98};
99
100static da8xx_ocic_handler_t da830_evm_usb_ocic_handler;
101
102static int da830_evm_usb_set_power(unsigned port, int on)
103{
104 gpio_set_value(ON_BD_USB_DRV, on);
105 return 0;
106}
107
108static int da830_evm_usb_get_power(unsigned port)
109{
110 return gpio_get_value(ON_BD_USB_DRV);
111}
112
113static int da830_evm_usb_get_oci(unsigned port)
114{
115 return !gpio_get_value(ON_BD_USB_OVC);
116}
117
118static irqreturn_t da830_evm_usb_ocic_irq(int, void *);
119
120static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
121{
122 int irq = gpio_to_irq(ON_BD_USB_OVC);
123 int error = 0;
124
125 if (handler != NULL) {
126 da830_evm_usb_ocic_handler = handler;
127
128 error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
129 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
130 "OHCI over-current indicator", NULL);
131 if (error)
132 printk(KERN_ERR "%s: could not request IRQ to watch "
133 "over-current indicator changes\n", __func__);
134 } else
135 free_irq(irq, NULL);
136
137 return error;
138}
139
140static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
141 .set_power = da830_evm_usb_set_power,
142 .get_power = da830_evm_usb_get_power,
143 .get_oci = da830_evm_usb_get_oci,
144 .ocic_notify = da830_evm_usb_ocic_notify,
145
146 /* TPS2065 switch @ 5V */
147 .potpgt = (3 + 1) / 2, /* 3 ms max */
148};
149
150static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
151{
152 da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1);
153 return IRQ_HANDLED;
154}
155
156static __init void da830_evm_usb_init(void)
157{
158 u32 cfgchip2;
159 int ret;
160
161 /*
162 * Set up USB clock/mode in the CFGCHIP2 register.
163 * FYI: CFGCHIP2 is 0x0000ef00 initially.
164 */
165 cfgchip2 = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
166
167 /* USB2.0 PHY reference clock is 24 MHz */
168 cfgchip2 &= ~CFGCHIP2_REFFREQ;
169 cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
170
171 /*
172 * Select internal reference clock for USB 2.0 PHY
173 * and use it as a clock source for USB 1.1 PHY
174 * (this is the default setting anyway).
175 */
176 cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
177 cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX;
178
179 __raw_writel(cfgchip2, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
180
181 ret = da8xx_pinmux_setup(da830_evm_usb11_pins);
182 if (ret) {
183 pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
184 __func__, ret);
185 return;
186 }
187
188 ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
189 if (ret) {
190 printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
191 "power control: %d\n", __func__, ret);
192 return;
193 }
194 gpio_direction_output(ON_BD_USB_DRV, 0);
195
196 ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
197 if (ret) {
198 printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
199 "over-current indicator: %d\n", __func__, ret);
200 return;
201 }
202 gpio_direction_input(ON_BD_USB_OVC);
203
204 ret = da8xx_register_usb11(&da830_evm_usb11_pdata);
205 if (ret)
206 pr_warning("%s: USB 1.1 registration failed: %d\n",
207 __func__, ret);
208}
209
87static struct davinci_uart_config da830_evm_uart_config __initdata = { 210static struct davinci_uart_config da830_evm_uart_config __initdata = {
88 .enabled_uarts = 0x7, 211 .enabled_uarts = 0x7,
89}; 212};
@@ -186,6 +309,8 @@ static __init void da830_evm_init(void)
186 pr_warning("da830_evm_init: i2c0 registration failed: %d\n", 309 pr_warning("da830_evm_init: i2c0 registration failed: %d\n",
187 ret); 310 ret);
188 311
312 da830_evm_usb_init();
313
189 soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK; 314 soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK;
190 soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY; 315 soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY;
191 soc_info->emac_pdata->rmii_en = 1; 316 soc_info->emac_pdata->rmii_en = 1;