2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/ioport.h>
12 #include <linux/timer.h>
13 #include <linux/platform_device.h>
14 #include <linux/delay.h>
15 #include <linux/pci.h>
16 #include <linux/gpio.h>
18 #include <bcm63xx_regs.h>
19 #include <bcm63xx_io.h>
20 #include "bcm63xx_pcmcia.h"
22 #define PFX "bcm63xx_pcmcia: "
25 /* if cardbus is used, platform device needs reference to actual pci
27 static struct pci_dev
*bcm63xx_cb_dev
;
31 * read/write helper for pcmcia regs
33 static inline u32
pcmcia_readl(struct bcm63xx_pcmcia_socket
*skt
, u32 off
)
35 return bcm_readl(skt
->base
+ off
);
38 static inline void pcmcia_writel(struct bcm63xx_pcmcia_socket
*skt
,
41 bcm_writel(val
, skt
->base
+ off
);
45 * (Re-)Initialise the socket, turning on status interrupts and PCMCIA
46 * bus. This must wait for power to stabilise so that the card status
47 * signals report correctly.
49 static int bcm63xx_pcmcia_sock_init(struct pcmcia_socket
*sock
)
51 struct bcm63xx_pcmcia_socket
*skt
;
52 skt
= sock
->driver_data
;
57 * Remove power on the socket, disable IRQs from the card.
58 * Turn off status interrupts, and disable the PCMCIA bus.
60 static int bcm63xx_pcmcia_suspend(struct pcmcia_socket
*sock
)
62 struct bcm63xx_pcmcia_socket
*skt
;
63 skt
= sock
->driver_data
;
68 * Implements the set_socket() operation for the in-kernel PCMCIA
69 * service (formerly SS_SetSocket in Card Services). We more or
70 * less punt all of this work and let the kernel handle the details
71 * of power configuration, reset, &c. We also record the value of
72 * `state' in order to regurgitate it to the PCMCIA core later.
74 static int bcm63xx_pcmcia_set_socket(struct pcmcia_socket
*sock
,
75 socket_state_t
*state
)
77 struct bcm63xx_pcmcia_socket
*skt
;
81 skt
= sock
->driver_data
;
83 spin_lock_irqsave(&skt
->lock
, flags
);
85 /* apply requested socket power */
86 /* FIXME: hardware can't do this */
88 /* apply socket reset */
89 val
= pcmcia_readl(skt
, PCMCIA_C1_REG
);
90 if (state
->flags
& SS_RESET
)
91 val
|= PCMCIA_C1_RESET_MASK
;
93 val
&= ~PCMCIA_C1_RESET_MASK
;
95 /* reverse reset logic for cardbus card */
96 if (skt
->card_detected
&& (skt
->card_type
& CARD_CARDBUS
))
97 val
^= PCMCIA_C1_RESET_MASK
;
99 pcmcia_writel(skt
, val
, PCMCIA_C1_REG
);
101 /* keep requested state for event reporting */
102 skt
->requested_state
= *state
;
104 spin_unlock_irqrestore(&skt
->lock
, flags
);
110 * identity cardtype from VS[12] input, CD[12] input while only VS2 is
111 * floating, and CD[12] input while only VS1 is floating
116 IN_CD1_VS2H
= (1 << 2),
117 IN_CD2_VS2H
= (1 << 3),
118 IN_CD1_VS1H
= (1 << 4),
119 IN_CD2_VS1H
= (1 << 5),
122 static const u8 vscd_to_cardtype
[] = {
124 /* VS1 float, VS2 float */
125 [IN_VS1
| IN_VS2
] = (CARD_PCCARD
| CARD_5V
),
127 /* VS1 grounded, VS2 float */
128 [IN_VS2
] = (CARD_PCCARD
| CARD_5V
| CARD_3V
),
130 /* VS1 grounded, VS2 grounded */
131 [0] = (CARD_PCCARD
| CARD_5V
| CARD_3V
| CARD_XV
),
133 /* VS1 tied to CD1, VS2 float */
134 [IN_VS1
| IN_VS2
| IN_CD1_VS1H
] = (CARD_CARDBUS
| CARD_3V
),
136 /* VS1 grounded, VS2 tied to CD2 */
137 [IN_VS2
| IN_CD2_VS2H
] = (CARD_CARDBUS
| CARD_3V
| CARD_XV
),
139 /* VS1 tied to CD2, VS2 grounded */
140 [IN_VS1
| IN_CD2_VS1H
] = (CARD_CARDBUS
| CARD_3V
| CARD_XV
| CARD_YV
),
142 /* VS1 float, VS2 grounded */
143 [IN_VS1
] = (CARD_PCCARD
| CARD_XV
),
145 /* VS1 float, VS2 tied to CD2 */
146 [IN_VS1
| IN_VS2
| IN_CD2_VS2H
] = (CARD_CARDBUS
| CARD_3V
),
148 /* VS1 float, VS2 tied to CD1 */
149 [IN_VS1
| IN_VS2
| IN_CD1_VS2H
] = (CARD_CARDBUS
| CARD_XV
| CARD_YV
),
151 /* VS1 tied to CD2, VS2 float */
152 [IN_VS1
| IN_VS2
| IN_CD2_VS1H
] = (CARD_CARDBUS
| CARD_YV
),
154 /* VS2 grounded, VS1 is tied to CD1, CD2 is grounded */
155 [IN_VS1
| IN_CD1_VS1H
] = 0, /* ignore cardbay */
159 * poll hardware to check card insertion status
161 static unsigned int __get_socket_status(struct bcm63xx_pcmcia_socket
*skt
)
168 /* check CD for card presence */
169 val
= pcmcia_readl(skt
, PCMCIA_C1_REG
);
171 if (!(val
& PCMCIA_C1_CD1_MASK
) && !(val
& PCMCIA_C1_CD2_MASK
))
174 /* if new insertion, detect cardtype */
175 if ((stat
& SS_DETECT
) && !skt
->card_detected
) {
176 unsigned int stat
= 0;
178 /* float VS1, float VS2 */
179 val
|= PCMCIA_C1_VS1OE_MASK
;
180 val
|= PCMCIA_C1_VS2OE_MASK
;
181 pcmcia_writel(skt
, val
, PCMCIA_C1_REG
);
183 /* wait for output to stabilize and read VS[12] */
185 val
= pcmcia_readl(skt
, PCMCIA_C1_REG
);
186 stat
|= (val
& PCMCIA_C1_VS1_MASK
) ? IN_VS1
: 0;
187 stat
|= (val
& PCMCIA_C1_VS2_MASK
) ? IN_VS2
: 0;
189 /* drive VS1 low, float VS2 */
190 val
&= ~PCMCIA_C1_VS1OE_MASK
;
191 val
|= PCMCIA_C1_VS2OE_MASK
;
192 pcmcia_writel(skt
, val
, PCMCIA_C1_REG
);
194 /* wait for output to stabilize and read CD[12] */
196 val
= pcmcia_readl(skt
, PCMCIA_C1_REG
);
197 stat
|= (val
& PCMCIA_C1_CD1_MASK
) ? IN_CD1_VS2H
: 0;
198 stat
|= (val
& PCMCIA_C1_CD2_MASK
) ? IN_CD2_VS2H
: 0;
200 /* float VS1, drive VS2 low */
201 val
|= PCMCIA_C1_VS1OE_MASK
;
202 val
&= ~PCMCIA_C1_VS2OE_MASK
;
203 pcmcia_writel(skt
, val
, PCMCIA_C1_REG
);
205 /* wait for output to stabilize and read CD[12] */
207 val
= pcmcia_readl(skt
, PCMCIA_C1_REG
);
208 stat
|= (val
& PCMCIA_C1_CD1_MASK
) ? IN_CD1_VS1H
: 0;
209 stat
|= (val
& PCMCIA_C1_CD2_MASK
) ? IN_CD2_VS1H
: 0;
211 /* guess cardtype from all this */
212 skt
->card_type
= vscd_to_cardtype
[stat
];
214 printk(KERN_ERR PFX
"unsupported card type\n");
216 /* drive both VS pin to 0 again */
217 val
&= ~(PCMCIA_C1_VS1OE_MASK
| PCMCIA_C1_VS2OE_MASK
);
219 /* enable correct logic */
220 val
&= ~(PCMCIA_C1_EN_PCMCIA_MASK
| PCMCIA_C1_EN_CARDBUS_MASK
);
221 if (skt
->card_type
& CARD_PCCARD
)
222 val
|= PCMCIA_C1_EN_PCMCIA_MASK
;
224 val
|= PCMCIA_C1_EN_CARDBUS_MASK
;
226 pcmcia_writel(skt
, val
, PCMCIA_C1_REG
);
228 skt
->card_detected
= (stat
& SS_DETECT
) ? 1 : 0;
230 /* report card type/voltage */
231 if (skt
->card_type
& CARD_CARDBUS
)
233 if (skt
->card_type
& CARD_3V
)
235 if (skt
->card_type
& CARD_XV
)
239 if (gpio_get_value(skt
->pd
->ready_gpio
))
246 * core request to get current socket status
248 static int bcm63xx_pcmcia_get_status(struct pcmcia_socket
*sock
,
249 unsigned int *status
)
251 struct bcm63xx_pcmcia_socket
*skt
;
253 skt
= sock
->driver_data
;
255 spin_lock_bh(&skt
->lock
);
256 *status
= __get_socket_status(skt
);
257 spin_unlock_bh(&skt
->lock
);
263 * socket polling timer callback
265 static void bcm63xx_pcmcia_poll(unsigned long data
)
267 struct bcm63xx_pcmcia_socket
*skt
;
268 unsigned int stat
, events
;
270 skt
= (struct bcm63xx_pcmcia_socket
*)data
;
272 spin_lock_bh(&skt
->lock
);
274 stat
= __get_socket_status(skt
);
276 /* keep only changed bits, and mask with required one from the
278 events
= (stat
^ skt
->old_status
) & skt
->requested_state
.csc_mask
;
279 skt
->old_status
= stat
;
280 spin_unlock_bh(&skt
->lock
);
283 pcmcia_parse_events(&skt
->socket
, events
);
285 mod_timer(&skt
->timer
,
286 jiffies
+ msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE
));
289 static int bcm63xx_pcmcia_set_io_map(struct pcmcia_socket
*sock
,
290 struct pccard_io_map
*map
)
292 /* this doesn't seem to be called by pcmcia layer if static
297 static int bcm63xx_pcmcia_set_mem_map(struct pcmcia_socket
*sock
,
298 struct pccard_mem_map
*map
)
300 struct bcm63xx_pcmcia_socket
*skt
;
301 struct resource
*res
;
303 skt
= sock
->driver_data
;
304 if (map
->flags
& MAP_ATTRIB
)
307 res
= skt
->common_res
;
309 map
->static_start
= res
->start
+ map
->card_start
;
313 static struct pccard_operations bcm63xx_pcmcia_operations
= {
314 .init
= bcm63xx_pcmcia_sock_init
,
315 .suspend
= bcm63xx_pcmcia_suspend
,
316 .get_status
= bcm63xx_pcmcia_get_status
,
317 .set_socket
= bcm63xx_pcmcia_set_socket
,
318 .set_io_map
= bcm63xx_pcmcia_set_io_map
,
319 .set_mem_map
= bcm63xx_pcmcia_set_mem_map
,
323 * register pcmcia socket to core
325 static int bcm63xx_drv_pcmcia_probe(struct platform_device
*pdev
)
327 struct bcm63xx_pcmcia_socket
*skt
;
328 struct pcmcia_socket
*sock
;
329 struct resource
*res
, *irq_res
;
330 unsigned int regmem_size
= 0, iomem_size
= 0;
334 skt
= kzalloc(sizeof(*skt
), GFP_KERNEL
);
337 spin_lock_init(&skt
->lock
);
339 sock
->driver_data
= skt
;
341 /* make sure we have all resources we need */
342 skt
->common_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
343 skt
->attr_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 2);
344 irq_res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
345 skt
->pd
= pdev
->dev
.platform_data
;
346 if (!skt
->common_res
|| !skt
->attr_res
|| !irq_res
|| !skt
->pd
) {
351 /* remap pcmcia registers */
352 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
353 regmem_size
= res
->end
- res
->start
+ 1;
354 if (!request_mem_region(res
->start
, regmem_size
, "bcm63xx_pcmcia")) {
360 skt
->base
= ioremap(res
->start
, regmem_size
);
366 /* remap io registers */
367 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 3);
368 iomem_size
= res
->end
- res
->start
+ 1;
369 skt
->io_base
= ioremap(res
->start
, iomem_size
);
375 /* resources are static */
376 sock
->resource_ops
= &pccard_static_ops
;
377 sock
->ops
= &bcm63xx_pcmcia_operations
;
378 sock
->owner
= THIS_MODULE
;
379 sock
->dev
.parent
= &pdev
->dev
;
380 sock
->features
= SS_CAP_STATIC_MAP
| SS_CAP_PCCARD
;
381 sock
->io_offset
= (unsigned long)skt
->io_base
;
382 sock
->pci_irq
= irq_res
->start
;
384 #ifdef CONFIG_CARDBUS
385 sock
->cb_dev
= bcm63xx_cb_dev
;
387 sock
->features
|= SS_CAP_CARDBUS
;
390 /* assume common & attribute memory have the same size */
391 sock
->map_size
= skt
->common_res
->end
- skt
->common_res
->start
+ 1;
393 /* initialize polling timer */
394 setup_timer(&skt
->timer
, bcm63xx_pcmcia_poll
, (unsigned long)skt
);
396 /* initialize pcmcia control register, drive VS[12] to 0,
397 * leave CB IDSEL to the old value since it is set by the PCI
399 val
= pcmcia_readl(skt
, PCMCIA_C1_REG
);
400 val
&= PCMCIA_C1_CBIDSEL_MASK
;
401 val
|= PCMCIA_C1_EN_PCMCIA_GPIO_MASK
;
402 pcmcia_writel(skt
, val
, PCMCIA_C1_REG
);
404 /* FIXME set correct pcmcia timings */
405 val
= PCMCIA_C2_DATA16_MASK
;
406 val
|= 10 << PCMCIA_C2_RWCOUNT_SHIFT
;
407 val
|= 6 << PCMCIA_C2_INACTIVE_SHIFT
;
408 val
|= 3 << PCMCIA_C2_SETUP_SHIFT
;
409 val
|= 3 << PCMCIA_C2_HOLD_SHIFT
;
410 pcmcia_writel(skt
, val
, PCMCIA_C2_REG
);
412 /* request and setup ready gpio */
413 ret
= gpio_request(skt
->pd
->ready_gpio
, "bcm63xx_pcmcia");
417 ret
= gpio_direction_input(skt
->pd
->ready_gpio
);
421 ret
= pcmcia_register_socket(sock
);
425 /* start polling socket */
426 mod_timer(&skt
->timer
,
427 jiffies
+ msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE
));
429 platform_set_drvdata(pdev
, skt
);
433 gpio_free(skt
->pd
->ready_gpio
);
437 iounmap(skt
->io_base
);
441 release_mem_region(skt
->reg_res
->start
, regmem_size
);
446 static int bcm63xx_drv_pcmcia_remove(struct platform_device
*pdev
)
448 struct bcm63xx_pcmcia_socket
*skt
;
449 struct resource
*res
;
451 skt
= platform_get_drvdata(pdev
);
452 del_timer_sync(&skt
->timer
);
454 iounmap(skt
->io_base
);
456 release_mem_region(res
->start
, res
->end
- res
->start
+ 1);
457 gpio_free(skt
->pd
->ready_gpio
);
462 struct platform_driver bcm63xx_pcmcia_driver
= {
463 .probe
= bcm63xx_drv_pcmcia_probe
,
464 .remove
= __devexit_p(bcm63xx_drv_pcmcia_remove
),
466 .name
= "bcm63xx_pcmcia",
467 .owner
= THIS_MODULE
,
471 #ifdef CONFIG_CARDBUS
472 static int __devinit
bcm63xx_cb_probe(struct pci_dev
*dev
,
473 const struct pci_device_id
*id
)
475 /* keep pci device */
476 bcm63xx_cb_dev
= dev
;
477 return platform_driver_register(&bcm63xx_pcmcia_driver
);
480 static void __devexit
bcm63xx_cb_exit(struct pci_dev
*dev
)
482 platform_driver_unregister(&bcm63xx_pcmcia_driver
);
483 bcm63xx_cb_dev
= NULL
;
486 static struct pci_device_id bcm63xx_cb_table
[] = {
488 .vendor
= PCI_VENDOR_ID_BROADCOM
,
489 .device
= PCI_ANY_ID
,
490 .subvendor
= PCI_VENDOR_ID_BROADCOM
,
491 .subdevice
= PCI_ANY_ID
,
492 .class = PCI_CLASS_BRIDGE_CARDBUS
<< 8,
498 MODULE_DEVICE_TABLE(pci
, bcm63xx_cb_table
);
500 static struct pci_driver bcm63xx_cardbus_driver
= {
501 .name
= "yenta_cardbus",
502 .id_table
= bcm63xx_cb_table
,
503 .probe
= bcm63xx_cb_probe
,
504 .remove
= __devexit_p(bcm63xx_cb_exit
),
509 * if cardbus support is enabled, register our platform device after
510 * our fake cardbus bridge has been registered
512 static int __init
bcm63xx_pcmcia_init(void)
514 #ifdef CONFIG_CARDBUS
515 return pci_register_driver(&bcm63xx_cardbus_driver
);
517 return platform_driver_register(&bcm63xx_pcmcia_driver
);
521 static void __exit
bcm63xx_pcmcia_exit(void)
523 #ifdef CONFIG_CARDBUS
524 return pci_unregister_driver(&bcm63xx_cardbus_driver
);
526 platform_driver_unregister(&bcm63xx_pcmcia_driver
);
530 module_init(bcm63xx_pcmcia_init
);
531 module_exit(bcm63xx_pcmcia_exit
);
533 MODULE_LICENSE("GPL");
534 MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
535 MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm63xx Socket Controller");