aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-10-07 14:08:32 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-07 14:08:32 -0400
commitcc513ac0f29473de365664c4fba9cf033c1f2324 (patch)
tree27ee53310699caa0e5cac80d519c0ec04120f8ca /drivers
parent1543966a079fc7065849ae43ca4dd767c188ad55 (diff)
parent19ec95df2c4ec2d28919f267c4d17178f8fe9d9c (diff)
Merge branch 'viper-for-rmk' of git://www.misterjones.org/linux-2.6-arm
Merge branch 'pxa-viper' into pxa-machines Conflicts: arch/arm/mach-pxa/Makefile drivers/pcmcia/Kconfig drivers/pcmcia/Makefile
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/smc91x.c9
-rw-r--r--drivers/net/smc91x.h13
-rw-r--r--drivers/pcmcia/Kconfig3
-rw-r--r--drivers/pcmcia/Makefile2
-rw-r--r--drivers/pcmcia/pxa2xx_base.c44
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c179
6 files changed, 215 insertions, 35 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 24768c10cadb..e332a518efe8 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1520,7 +1520,9 @@ smc_open(struct net_device *dev)
1520 /* Setup the default Register Modes */ 1520 /* Setup the default Register Modes */
1521 lp->tcr_cur_mode = TCR_DEFAULT; 1521 lp->tcr_cur_mode = TCR_DEFAULT;
1522 lp->rcr_cur_mode = RCR_DEFAULT; 1522 lp->rcr_cur_mode = RCR_DEFAULT;
1523 lp->rpc_cur_mode = RPC_DEFAULT; 1523 lp->rpc_cur_mode = RPC_DEFAULT |
1524 lp->cfg.leda << RPC_LSXA_SHFT |
1525 lp->cfg.ledb << RPC_LSXB_SHFT;
1524 1526
1525 /* 1527 /*
1526 * If we are not using a MII interface, we need to 1528 * If we are not using a MII interface, we need to
@@ -2157,6 +2159,11 @@ static int smc_drv_probe(struct platform_device *pdev)
2157 lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0; 2159 lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0;
2158 } 2160 }
2159 2161
2162 if (!lp->cfg.leda && !lp->cfg.ledb) {
2163 lp->cfg.leda = RPC_LSA_DEFAULT;
2164 lp->cfg.ledb = RPC_LSB_DEFAULT;
2165 }
2166
2160 ndev->dma = (unsigned char)-1; 2167 ndev->dma = (unsigned char)-1;
2161 2168
2162 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); 2169 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 997e7f1d5c6e..160873f0a817 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -43,7 +43,8 @@
43#if defined(CONFIG_ARCH_LUBBOCK) ||\ 43#if defined(CONFIG_ARCH_LUBBOCK) ||\
44 defined(CONFIG_MACH_MAINSTONE) ||\ 44 defined(CONFIG_MACH_MAINSTONE) ||\
45 defined(CONFIG_MACH_ZYLONITE) ||\ 45 defined(CONFIG_MACH_ZYLONITE) ||\
46 defined(CONFIG_MACH_LITTLETON) 46 defined(CONFIG_MACH_LITTLETON) ||\
47 defined(CONFIG_ARCH_VIPER)
47 48
48#include <asm/mach-types.h> 49#include <asm/mach-types.h>
49 50
@@ -778,14 +779,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
778#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode 779#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode
779#define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb 780#define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb
780#define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb 781#define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb
781#define RPC_LED_100_10 (0x00) // LED = 100Mbps OR's with 10Mbps link detect
782#define RPC_LED_RES (0x01) // LED = Reserved
783#define RPC_LED_10 (0x02) // LED = 10Mbps link detect
784#define RPC_LED_FD (0x03) // LED = Full Duplex Mode
785#define RPC_LED_TX_RX (0x04) // LED = TX or RX packet occurred
786#define RPC_LED_100 (0x05) // LED = 100Mbps link dectect
787#define RPC_LED_TX (0x06) // LED = TX packet occurred
788#define RPC_LED_RX (0x07) // LED = RX packet occurred
789 782
790#ifndef RPC_LSA_DEFAULT 783#ifndef RPC_LSA_DEFAULT
791#define RPC_LSA_DEFAULT RPC_LED_100 784#define RPC_LSA_DEFAULT RPC_LED_100
@@ -794,7 +787,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
794#define RPC_LSB_DEFAULT RPC_LED_FD 787#define RPC_LSB_DEFAULT RPC_LED_FD
795#endif 788#endif
796 789
797#define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) 790#define RPC_DEFAULT (RPC_ANEG | RPC_SPEED | RPC_DPLX)
798 791
799 792
800/* Bank 0 0x0C is reserved */ 793/* Bank 0 0x0C is reserved */
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 40417d3fe50d..f57eeae3830a 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -220,7 +220,8 @@ config PCMCIA_PXA2XX
220 tristate "PXA2xx support" 220 tristate "PXA2xx support"
221 depends on ARM && ARCH_PXA && PCMCIA 221 depends on ARM && ARCH_PXA && PCMCIA
222 depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ 222 depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
223 || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA) 223 || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
224 || ARCH_VIPER)
224 help 225 help
225 Say Y here to include support for the PXA2xx PCMCIA controller 226 Say Y here to include support for the PXA2xx PCMCIA controller
226 227
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 679ca927a62a..8c2fe94122a2 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -72,7 +72,7 @@ pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
72pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o 72pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
73pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o 73pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
74pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o 74pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
75pxa2xx_cs-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
75pxa2xx_cs-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o 76pxa2xx_cs-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
76pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o 77pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
77pxa2xx_cs-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o 78pxa2xx_cs-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
78
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 1b07af5a2ed3..13f1e0fd3f31 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -30,6 +30,7 @@
30#include <asm/system.h> 30#include <asm/system.h>
31#include <mach/pxa-regs.h> 31#include <mach/pxa-regs.h>
32#include <mach/pxa2xx-regs.h> 32#include <mach/pxa2xx-regs.h>
33#include <asm/mach-types.h>
33 34
34#include <pcmcia/cs_types.h> 35#include <pcmcia/cs_types.h>
35#include <pcmcia/ss.h> 36#include <pcmcia/ss.h>
@@ -166,18 +167,32 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
166} 167}
167#endif 168#endif
168 169
170static void pxa2xx_configure_sockets(struct device *dev)
171{
172 struct pcmcia_low_level *ops = dev->platform_data;
173
174 /*
175 * We have at least one socket, so set MECR:CIT
176 * (Card Is There)
177 */
178 MECR |= MECR_CIT;
179
180 /* Set MECR:NOS (Number Of Sockets) */
181 if (ops->nr > 1 || machine_is_viper())
182 MECR |= MECR_NOS;
183 else
184 MECR &= ~MECR_NOS;
185}
186
169int __pxa2xx_drv_pcmcia_probe(struct device *dev) 187int __pxa2xx_drv_pcmcia_probe(struct device *dev)
170{ 188{
171 int ret; 189 int ret;
172 struct pcmcia_low_level *ops; 190 struct pcmcia_low_level *ops;
173 int first, nr;
174 191
175 if (!dev || !dev->platform_data) 192 if (!dev || !dev->platform_data)
176 return -ENODEV; 193 return -ENODEV;
177 194
178 ops = (struct pcmcia_low_level *)dev->platform_data; 195 ops = (struct pcmcia_low_level *)dev->platform_data;
179 first = ops->first;
180 nr = ops->nr;
181 196
182 /* Provide our PXA2xx specific timing routines. */ 197 /* Provide our PXA2xx specific timing routines. */
183 ops->set_timing = pxa2xx_pcmcia_set_timing; 198 ops->set_timing = pxa2xx_pcmcia_set_timing;
@@ -185,21 +200,10 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
185 ops->frequency_change = pxa2xx_pcmcia_frequency_change; 200 ops->frequency_change = pxa2xx_pcmcia_frequency_change;
186#endif 201#endif
187 202
188 ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr); 203 ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
189 204
190 if (ret == 0) { 205 if (!ret)
191 /* 206 pxa2xx_configure_sockets(dev);
192 * We have at least one socket, so set MECR:CIT
193 * (Card Is There)
194 */
195 MECR |= MECR_CIT;
196
197 /* Set MECR:NOS (Number Of Sockets) */
198 if (nr > 1)
199 MECR |= MECR_NOS;
200 else
201 MECR &= ~MECR_NOS;
202 }
203 207
204 return ret; 208 return ret;
205} 209}
@@ -223,11 +227,7 @@ static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t s
223 227
224static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) 228static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
225{ 229{
226 struct pcmcia_low_level *ops = dev->dev.platform_data; 230 pxa2xx_configure_sockets(&dev->dev);
227 int nr = ops ? ops->nr : 0;
228
229 MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
230
231 return pcmcia_socket_dev_resume(&dev->dev); 231 return pcmcia_socket_dev_resume(&dev->dev);
232} 232}
233 233
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
new file mode 100644
index 000000000000..dd10481be7bf
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -0,0 +1,179 @@
1/*
2 * VIPER PCMCIA support
3 * Copyright 2004 Arcom Control Systems
4 *
5 * Maintained by Marc Zyngier <maz@misterjones.org>
6 * <marc.zyngier@altran.com>
7 *
8 * Based on:
9 * iPAQ h2200 PCMCIA support
10 * Copyright 2004 Koen Kooi <koen@vestingbar.nl>
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file COPYING in the main directory of this archive for
14 * more details.
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/gpio.h>
24
25#include <pcmcia/ss.h>
26
27#include <asm/irq.h>
28
29#include <mach/pxa-regs.h>
30#include <mach/viper.h>
31#include <asm/mach-types.h>
32
33#include "soc_common.h"
34#include "pxa2xx_base.h"
35
36static struct pcmcia_irqs irqs[] = {
37 { 0, gpio_to_irq(VIPER_CF_CD_GPIO), "PCMCIA_CD" }
38};
39
40static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
41{
42 unsigned long flags;
43
44 skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
45
46 if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
47 goto err_request_cd;
48
49 if (gpio_request(VIPER_CF_RDY_GPIO, "CF ready"))
50 goto err_request_rdy;
51
52 if (gpio_request(VIPER_CF_POWER_GPIO, "CF power"))
53 goto err_request_pwr;
54
55 local_irq_save(flags);
56
57 /* GPIO 82 is the CF power enable line. initially off */
58 if (gpio_direction_output(VIPER_CF_POWER_GPIO, 0) ||
59 gpio_direction_input(VIPER_CF_CD_GPIO) ||
60 gpio_direction_input(VIPER_CF_RDY_GPIO)) {
61 local_irq_restore(flags);
62 goto err_dir;
63 }
64
65 local_irq_restore(flags);
66
67 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
68
69err_dir:
70 gpio_free(VIPER_CF_POWER_GPIO);
71err_request_pwr:
72 gpio_free(VIPER_CF_RDY_GPIO);
73err_request_rdy:
74 gpio_free(VIPER_CF_CD_GPIO);
75err_request_cd:
76 printk(KERN_ERR "viper: Failed to setup PCMCIA GPIOs\n");
77 return -1;
78}
79
80/*
81 * Release all resources.
82 */
83static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
84{
85 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
86 gpio_free(VIPER_CF_POWER_GPIO);
87 gpio_free(VIPER_CF_RDY_GPIO);
88 gpio_free(VIPER_CF_CD_GPIO);
89}
90
91static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
92 struct pcmcia_state *state)
93{
94 state->detect = gpio_get_value(VIPER_CF_CD_GPIO) ? 0 : 1;
95 state->ready = gpio_get_value(VIPER_CF_RDY_GPIO) ? 1 : 0;
96 state->bvd1 = 1;
97 state->bvd2 = 1;
98 state->wrprot = 0;
99 state->vs_3v = 1; /* Can only apply 3.3V */
100 state->vs_Xv = 0;
101}
102
103static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
104 const socket_state_t *state)
105{
106 /* Silently ignore Vpp, output enable, speaker enable. */
107 viper_cf_rst(state->flags & SS_RESET);
108
109 /* Apply socket voltage */
110 switch (state->Vcc) {
111 case 0:
112 gpio_set_value(VIPER_CF_POWER_GPIO, 0);
113 break;
114 case 33:
115 gpio_set_value(VIPER_CF_POWER_GPIO, 1);
116 break;
117 default:
118 printk(KERN_ERR "%s: Unsupported Vcc:%d\n",
119 __func__, state->Vcc);
120 return -1;
121 }
122
123 return 0;
124}
125
126static void viper_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
127{
128}
129
130static void viper_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
131{
132}
133
134static struct pcmcia_low_level viper_pcmcia_ops __initdata = {
135 .owner = THIS_MODULE,
136 .hw_init = viper_pcmcia_hw_init,
137 .hw_shutdown = viper_pcmcia_hw_shutdown,
138 .socket_state = viper_pcmcia_socket_state,
139 .configure_socket = viper_pcmcia_configure_socket,
140 .socket_init = viper_pcmcia_socket_init,
141 .socket_suspend = viper_pcmcia_socket_suspend,
142 .nr = 1,
143};
144
145static struct platform_device *viper_pcmcia_device;
146
147static int __init viper_pcmcia_init(void)
148{
149 int ret;
150
151 if (!machine_is_viper())
152 return -ENODEV;
153
154 viper_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
155 if (!viper_pcmcia_device)
156 return -ENOMEM;
157
158 ret = platform_device_add_data(viper_pcmcia_device,
159 &viper_pcmcia_ops,
160 sizeof(viper_pcmcia_ops));
161
162 if (!ret)
163 ret = platform_device_add(viper_pcmcia_device);
164
165 if (ret)
166 platform_device_put(viper_pcmcia_device);
167
168 return ret;
169}
170
171static void __exit viper_pcmcia_exit(void)
172{
173 platform_device_unregister(viper_pcmcia_device);
174}
175
176module_init(viper_pcmcia_init);
177module_exit(viper_pcmcia_exit);
178
179MODULE_LICENSE("GPL");