Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/ioport.h>
0012 #include <linux/timer.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/slab.h>
0015 #include <linux/delay.h>
0016 #include <linux/pci.h>
0017 #include <linux/gpio.h>
0018 
0019 #include <bcm63xx_regs.h>
0020 #include <bcm63xx_io.h>
0021 #include "bcm63xx_pcmcia.h"
0022 
0023 #define PFX "bcm63xx_pcmcia: "
0024 
0025 #ifdef CONFIG_CARDBUS
0026 /* if cardbus is used, platform device needs reference to actual pci
0027  * device */
0028 static struct pci_dev *bcm63xx_cb_dev;
0029 #endif
0030 
0031 /*
0032  * read/write helper for pcmcia regs
0033  */
0034 static inline u32 pcmcia_readl(struct bcm63xx_pcmcia_socket *skt, u32 off)
0035 {
0036     return bcm_readl(skt->base + off);
0037 }
0038 
0039 static inline void pcmcia_writel(struct bcm63xx_pcmcia_socket *skt,
0040                  u32 val, u32 off)
0041 {
0042     bcm_writel(val, skt->base + off);
0043 }
0044 
0045 /*
0046  * This callback should (re-)initialise the socket, turn on status
0047  * interrupts and PCMCIA bus, and wait for power to stabilise so that
0048  * the card status signals report correctly.
0049  *
0050  * Hardware cannot do that.
0051  */
0052 static int bcm63xx_pcmcia_sock_init(struct pcmcia_socket *sock)
0053 {
0054     return 0;
0055 }
0056 
0057 /*
0058  * This callback should remove power on the socket, disable IRQs from
0059  * the card, turn off status interrupts, and disable the PCMCIA bus.
0060  *
0061  * Hardware cannot do that.
0062  */
0063 static int bcm63xx_pcmcia_suspend(struct pcmcia_socket *sock)
0064 {
0065     return 0;
0066 }
0067 
0068 /*
0069  * Implements the set_socket() operation for the in-kernel PCMCIA
0070  * service (formerly SS_SetSocket in Card Services). We more or
0071  * less punt all of this work and let the kernel handle the details
0072  * of power configuration, reset, &c. We also record the value of
0073  * `state' in order to regurgitate it to the PCMCIA core later.
0074  */
0075 static int bcm63xx_pcmcia_set_socket(struct pcmcia_socket *sock,
0076                      socket_state_t *state)
0077 {
0078     struct bcm63xx_pcmcia_socket *skt;
0079     unsigned long flags;
0080     u32 val;
0081 
0082     skt = sock->driver_data;
0083 
0084     spin_lock_irqsave(&skt->lock, flags);
0085 
0086     /* note: hardware cannot control socket power, so we will
0087      * always report SS_POWERON */
0088 
0089     /* apply socket reset */
0090     val = pcmcia_readl(skt, PCMCIA_C1_REG);
0091     if (state->flags & SS_RESET)
0092         val |= PCMCIA_C1_RESET_MASK;
0093     else
0094         val &= ~PCMCIA_C1_RESET_MASK;
0095 
0096     /* reverse reset logic for cardbus card */
0097     if (skt->card_detected && (skt->card_type & CARD_CARDBUS))
0098         val ^= PCMCIA_C1_RESET_MASK;
0099 
0100     pcmcia_writel(skt, val, PCMCIA_C1_REG);
0101 
0102     /* keep requested state for event reporting */
0103     skt->requested_state = *state;
0104 
0105     spin_unlock_irqrestore(&skt->lock, flags);
0106 
0107     return 0;
0108 }
0109 
0110 /*
0111  * identity cardtype from VS[12] input, CD[12] input while only VS2 is
0112  * floating, and CD[12] input while only VS1 is floating
0113  */
0114 enum {
0115     IN_VS1 = (1 << 0),
0116     IN_VS2 = (1 << 1),
0117     IN_CD1_VS2H = (1 << 2),
0118     IN_CD2_VS2H = (1 << 3),
0119     IN_CD1_VS1H = (1 << 4),
0120     IN_CD2_VS1H = (1 << 5),
0121 };
0122 
0123 static const u8 vscd_to_cardtype[] = {
0124 
0125     /* VS1 float, VS2 float */
0126     [IN_VS1 | IN_VS2] = (CARD_PCCARD | CARD_5V),
0127 
0128     /* VS1 grounded, VS2 float */
0129     [IN_VS2] = (CARD_PCCARD | CARD_5V | CARD_3V),
0130 
0131     /* VS1 grounded, VS2 grounded */
0132     [0] = (CARD_PCCARD | CARD_5V | CARD_3V | CARD_XV),
0133 
0134     /* VS1 tied to CD1, VS2 float */
0135     [IN_VS1 | IN_VS2 | IN_CD1_VS1H] = (CARD_CARDBUS | CARD_3V),
0136 
0137     /* VS1 grounded, VS2 tied to CD2 */
0138     [IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V | CARD_XV),
0139 
0140     /* VS1 tied to CD2, VS2 grounded */
0141     [IN_VS1 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_3V | CARD_XV | CARD_YV),
0142 
0143     /* VS1 float, VS2 grounded */
0144     [IN_VS1] = (CARD_PCCARD | CARD_XV),
0145 
0146     /* VS1 float, VS2 tied to CD2 */
0147     [IN_VS1 | IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V),
0148 
0149     /* VS1 float, VS2 tied to CD1 */
0150     [IN_VS1 | IN_VS2 | IN_CD1_VS2H] = (CARD_CARDBUS | CARD_XV | CARD_YV),
0151 
0152     /* VS1 tied to CD2, VS2 float */
0153     [IN_VS1 | IN_VS2 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_YV),
0154 
0155     /* VS2 grounded, VS1 is tied to CD1, CD2 is grounded */
0156     [IN_VS1 | IN_CD1_VS1H] = 0, /* ignore cardbay */
0157 };
0158 
0159 /*
0160  * poll hardware to check card insertion status
0161  */
0162 static unsigned int __get_socket_status(struct bcm63xx_pcmcia_socket *skt)
0163 {
0164     unsigned int stat;
0165     u32 val;
0166 
0167     stat = 0;
0168 
0169     /* check CD for card presence */
0170     val = pcmcia_readl(skt, PCMCIA_C1_REG);
0171 
0172     if (!(val & PCMCIA_C1_CD1_MASK) && !(val & PCMCIA_C1_CD2_MASK))
0173         stat |= SS_DETECT;
0174 
0175     /* if new insertion, detect cardtype */
0176     if ((stat & SS_DETECT) && !skt->card_detected) {
0177         unsigned int stat = 0;
0178 
0179         /* float VS1, float VS2 */
0180         val |= PCMCIA_C1_VS1OE_MASK;
0181         val |= PCMCIA_C1_VS2OE_MASK;
0182         pcmcia_writel(skt, val, PCMCIA_C1_REG);
0183 
0184         /* wait for output to stabilize and read VS[12] */
0185         udelay(10);
0186         val = pcmcia_readl(skt, PCMCIA_C1_REG);
0187         stat |= (val & PCMCIA_C1_VS1_MASK) ? IN_VS1 : 0;
0188         stat |= (val & PCMCIA_C1_VS2_MASK) ? IN_VS2 : 0;
0189 
0190         /* drive VS1 low, float VS2 */
0191         val &= ~PCMCIA_C1_VS1OE_MASK;
0192         val |= PCMCIA_C1_VS2OE_MASK;
0193         pcmcia_writel(skt, val, PCMCIA_C1_REG);
0194 
0195         /* wait for output to stabilize and read CD[12] */
0196         udelay(10);
0197         val = pcmcia_readl(skt, PCMCIA_C1_REG);
0198         stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS2H : 0;
0199         stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS2H : 0;
0200 
0201         /* float VS1, drive VS2 low */
0202         val |= PCMCIA_C1_VS1OE_MASK;
0203         val &= ~PCMCIA_C1_VS2OE_MASK;
0204         pcmcia_writel(skt, val, PCMCIA_C1_REG);
0205 
0206         /* wait for output to stabilize and read CD[12] */
0207         udelay(10);
0208         val = pcmcia_readl(skt, PCMCIA_C1_REG);
0209         stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS1H : 0;
0210         stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS1H : 0;
0211 
0212         /* guess cardtype from all this */
0213         skt->card_type = vscd_to_cardtype[stat];
0214         if (!skt->card_type)
0215             dev_err(&skt->socket.dev, "unsupported card type\n");
0216 
0217         /* drive both VS pin to 0 again */
0218         val &= ~(PCMCIA_C1_VS1OE_MASK | PCMCIA_C1_VS2OE_MASK);
0219 
0220         /* enable correct logic */
0221         val &= ~(PCMCIA_C1_EN_PCMCIA_MASK | PCMCIA_C1_EN_CARDBUS_MASK);
0222         if (skt->card_type & CARD_PCCARD)
0223             val |= PCMCIA_C1_EN_PCMCIA_MASK;
0224         else
0225             val |= PCMCIA_C1_EN_CARDBUS_MASK;
0226 
0227         pcmcia_writel(skt, val, PCMCIA_C1_REG);
0228     }
0229     skt->card_detected = (stat & SS_DETECT) ? 1 : 0;
0230 
0231     /* report card type/voltage */
0232     if (skt->card_type & CARD_CARDBUS)
0233         stat |= SS_CARDBUS;
0234     if (skt->card_type & CARD_3V)
0235         stat |= SS_3VCARD;
0236     if (skt->card_type & CARD_XV)
0237         stat |= SS_XVCARD;
0238     stat |= SS_POWERON;
0239 
0240     if (gpio_get_value(skt->pd->ready_gpio))
0241         stat |= SS_READY;
0242 
0243     return stat;
0244 }
0245 
0246 /*
0247  * core request to get current socket status
0248  */
0249 static int bcm63xx_pcmcia_get_status(struct pcmcia_socket *sock,
0250                      unsigned int *status)
0251 {
0252     struct bcm63xx_pcmcia_socket *skt;
0253 
0254     skt = sock->driver_data;
0255 
0256     spin_lock_bh(&skt->lock);
0257     *status = __get_socket_status(skt);
0258     spin_unlock_bh(&skt->lock);
0259 
0260     return 0;
0261 }
0262 
0263 /*
0264  * socket polling timer callback
0265  */
0266 static void bcm63xx_pcmcia_poll(struct timer_list *t)
0267 {
0268     struct bcm63xx_pcmcia_socket *skt;
0269     unsigned int stat, events;
0270 
0271     skt = from_timer(skt, t, timer);
0272 
0273     spin_lock_bh(&skt->lock);
0274 
0275     stat = __get_socket_status(skt);
0276 
0277     /* keep only changed bits, and mask with required one from the
0278      * core */
0279     events = (stat ^ skt->old_status) & skt->requested_state.csc_mask;
0280     skt->old_status = stat;
0281     spin_unlock_bh(&skt->lock);
0282 
0283     if (events)
0284         pcmcia_parse_events(&skt->socket, events);
0285 
0286     mod_timer(&skt->timer,
0287           jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
0288 }
0289 
0290 static int bcm63xx_pcmcia_set_io_map(struct pcmcia_socket *sock,
0291                      struct pccard_io_map *map)
0292 {
0293     /* this doesn't seem to be called by pcmcia layer if static
0294      * mapping is used */
0295     return 0;
0296 }
0297 
0298 static int bcm63xx_pcmcia_set_mem_map(struct pcmcia_socket *sock,
0299                       struct pccard_mem_map *map)
0300 {
0301     struct bcm63xx_pcmcia_socket *skt;
0302     struct resource *res;
0303 
0304     skt = sock->driver_data;
0305     if (map->flags & MAP_ATTRIB)
0306         res = skt->attr_res;
0307     else
0308         res = skt->common_res;
0309 
0310     map->static_start = res->start + map->card_start;
0311     return 0;
0312 }
0313 
0314 static struct pccard_operations bcm63xx_pcmcia_operations = {
0315     .init           = bcm63xx_pcmcia_sock_init,
0316     .suspend        = bcm63xx_pcmcia_suspend,
0317     .get_status     = bcm63xx_pcmcia_get_status,
0318     .set_socket     = bcm63xx_pcmcia_set_socket,
0319     .set_io_map     = bcm63xx_pcmcia_set_io_map,
0320     .set_mem_map        = bcm63xx_pcmcia_set_mem_map,
0321 };
0322 
0323 /*
0324  * register pcmcia socket to core
0325  */
0326 static int bcm63xx_drv_pcmcia_probe(struct platform_device *pdev)
0327 {
0328     struct bcm63xx_pcmcia_socket *skt;
0329     struct pcmcia_socket *sock;
0330     struct resource *res;
0331     unsigned int regmem_size = 0, iomem_size = 0;
0332     u32 val;
0333     int ret;
0334     int irq;
0335 
0336     skt = kzalloc(sizeof(*skt), GFP_KERNEL);
0337     if (!skt)
0338         return -ENOMEM;
0339     spin_lock_init(&skt->lock);
0340     sock = &skt->socket;
0341     sock->driver_data = skt;
0342 
0343     /* make sure we have all resources we need */
0344     skt->common_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0345     skt->attr_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
0346     irq = platform_get_irq(pdev, 0);
0347     skt->pd = pdev->dev.platform_data;
0348     if (!skt->common_res || !skt->attr_res || (irq < 0) || !skt->pd) {
0349         ret = -EINVAL;
0350         goto err;
0351     }
0352 
0353     /* remap pcmcia registers */
0354     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0355     regmem_size = resource_size(res);
0356     if (!request_mem_region(res->start, regmem_size, "bcm63xx_pcmcia")) {
0357         ret = -EINVAL;
0358         goto err;
0359     }
0360     skt->reg_res = res;
0361 
0362     skt->base = ioremap(res->start, regmem_size);
0363     if (!skt->base) {
0364         ret = -ENOMEM;
0365         goto err;
0366     }
0367 
0368     /* remap io registers */
0369     res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
0370     iomem_size = resource_size(res);
0371     skt->io_base = ioremap(res->start, iomem_size);
0372     if (!skt->io_base) {
0373         ret = -ENOMEM;
0374         goto err;
0375     }
0376 
0377     /* resources are static */
0378     sock->resource_ops = &pccard_static_ops;
0379     sock->ops = &bcm63xx_pcmcia_operations;
0380     sock->owner = THIS_MODULE;
0381     sock->dev.parent = &pdev->dev;
0382     sock->features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
0383     sock->io_offset = (unsigned long)skt->io_base;
0384     sock->pci_irq = irq;
0385 
0386 #ifdef CONFIG_CARDBUS
0387     sock->cb_dev = bcm63xx_cb_dev;
0388     if (bcm63xx_cb_dev)
0389         sock->features |= SS_CAP_CARDBUS;
0390 #endif
0391 
0392     /* assume common & attribute memory have the same size */
0393     sock->map_size = resource_size(skt->common_res);
0394 
0395     /* initialize polling timer */
0396     timer_setup(&skt->timer, bcm63xx_pcmcia_poll, 0);
0397 
0398     /* initialize  pcmcia  control register,  drive  VS[12] to  0,
0399      * leave CB IDSEL to the old  value since it is set by the PCI
0400      * layer */
0401     val = pcmcia_readl(skt, PCMCIA_C1_REG);
0402     val &= PCMCIA_C1_CBIDSEL_MASK;
0403     val |= PCMCIA_C1_EN_PCMCIA_GPIO_MASK;
0404     pcmcia_writel(skt, val, PCMCIA_C1_REG);
0405 
0406     /*
0407      * Hardware has only one set of timings registers, not one for
0408      * each memory access type, so we configure them for the
0409      * slowest one: attribute memory.
0410      */
0411     val = PCMCIA_C2_DATA16_MASK;
0412     val |= 10 << PCMCIA_C2_RWCOUNT_SHIFT;
0413     val |= 6 << PCMCIA_C2_INACTIVE_SHIFT;
0414     val |= 3 << PCMCIA_C2_SETUP_SHIFT;
0415     val |= 3 << PCMCIA_C2_HOLD_SHIFT;
0416     pcmcia_writel(skt, val, PCMCIA_C2_REG);
0417 
0418     ret = pcmcia_register_socket(sock);
0419     if (ret)
0420         goto err;
0421 
0422     /* start polling socket */
0423     mod_timer(&skt->timer,
0424           jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
0425 
0426     platform_set_drvdata(pdev, skt);
0427     return 0;
0428 
0429 err:
0430     if (skt->io_base)
0431         iounmap(skt->io_base);
0432     if (skt->base)
0433         iounmap(skt->base);
0434     if (skt->reg_res)
0435         release_mem_region(skt->reg_res->start, regmem_size);
0436     kfree(skt);
0437     return ret;
0438 }
0439 
0440 static int bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
0441 {
0442     struct bcm63xx_pcmcia_socket *skt;
0443     struct resource *res;
0444 
0445     skt = platform_get_drvdata(pdev);
0446     del_timer_sync(&skt->timer);
0447     iounmap(skt->base);
0448     iounmap(skt->io_base);
0449     res = skt->reg_res;
0450     release_mem_region(res->start, resource_size(res));
0451     kfree(skt);
0452     return 0;
0453 }
0454 
0455 struct platform_driver bcm63xx_pcmcia_driver = {
0456     .probe  = bcm63xx_drv_pcmcia_probe,
0457     .remove = bcm63xx_drv_pcmcia_remove,
0458     .driver = {
0459         .name   = "bcm63xx_pcmcia",
0460         .owner  = THIS_MODULE,
0461     },
0462 };
0463 
0464 #ifdef CONFIG_CARDBUS
0465 static int bcm63xx_cb_probe(struct pci_dev *dev,
0466                       const struct pci_device_id *id)
0467 {
0468     /* keep pci device */
0469     bcm63xx_cb_dev = dev;
0470     return platform_driver_register(&bcm63xx_pcmcia_driver);
0471 }
0472 
0473 static void bcm63xx_cb_exit(struct pci_dev *dev)
0474 {
0475     platform_driver_unregister(&bcm63xx_pcmcia_driver);
0476     bcm63xx_cb_dev = NULL;
0477 }
0478 
0479 static const struct pci_device_id bcm63xx_cb_table[] = {
0480     {
0481         .vendor     = PCI_VENDOR_ID_BROADCOM,
0482         .device     = BCM6348_CPU_ID,
0483         .subvendor  = PCI_VENDOR_ID_BROADCOM,
0484         .subdevice  = PCI_ANY_ID,
0485         .class      = PCI_CLASS_BRIDGE_CARDBUS << 8,
0486         .class_mask = ~0,
0487     },
0488 
0489     {
0490         .vendor     = PCI_VENDOR_ID_BROADCOM,
0491         .device     = BCM6358_CPU_ID,
0492         .subvendor  = PCI_VENDOR_ID_BROADCOM,
0493         .subdevice  = PCI_ANY_ID,
0494         .class      = PCI_CLASS_BRIDGE_CARDBUS << 8,
0495         .class_mask = ~0,
0496     },
0497 
0498     { },
0499 };
0500 
0501 MODULE_DEVICE_TABLE(pci, bcm63xx_cb_table);
0502 
0503 static struct pci_driver bcm63xx_cardbus_driver = {
0504     .name       = "bcm63xx_cardbus",
0505     .id_table   = bcm63xx_cb_table,
0506     .probe      = bcm63xx_cb_probe,
0507     .remove     = bcm63xx_cb_exit,
0508 };
0509 #endif
0510 
0511 /*
0512  * if cardbus support is enabled, register our platform device after
0513  * our fake cardbus bridge has been registered
0514  */
0515 static int __init bcm63xx_pcmcia_init(void)
0516 {
0517 #ifdef CONFIG_CARDBUS
0518     return pci_register_driver(&bcm63xx_cardbus_driver);
0519 #else
0520     return platform_driver_register(&bcm63xx_pcmcia_driver);
0521 #endif
0522 }
0523 
0524 static void __exit bcm63xx_pcmcia_exit(void)
0525 {
0526 #ifdef CONFIG_CARDBUS
0527     return pci_unregister_driver(&bcm63xx_cardbus_driver);
0528 #else
0529     platform_driver_unregister(&bcm63xx_pcmcia_driver);
0530 #endif
0531 }
0532 
0533 module_init(bcm63xx_pcmcia_init);
0534 module_exit(bcm63xx_pcmcia_exit);
0535 
0536 MODULE_LICENSE("GPL");
0537 MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
0538 MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm63xx Socket Controller");