root/drivers/pcmcia/pxa2xx_mainstone.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mst_pcmcia_hw_init
  2. mst_pcmcia_socket_state
  3. mst_pcmcia_configure_socket
  4. mst_pcmcia_init
  5. mst_pcmcia_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/drivers/pcmcia/pxa2xx_mainstone.c
   4  *
   5  * Mainstone PCMCIA specific routines.
   6  *
   7  * Created:     May 12, 2004
   8  * Author:      Nicolas Pitre
   9  * Copyright:   MontaVista Software Inc.
  10  */
  11 #include <linux/gpio/consumer.h>
  12 #include <linux/module.h>
  13 #include <linux/init.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/kernel.h>
  16 #include <linux/errno.h>
  17 #include <linux/platform_device.h>
  18 
  19 #include <pcmcia/ss.h>
  20 
  21 #include <asm/mach-types.h>
  22 
  23 #include "soc_common.h"
  24 #include "max1600.h"
  25 
  26 static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  27 {
  28         struct device *dev = skt->socket.dev.parent;
  29         struct max1600 *m;
  30         int ret;
  31 
  32         skt->stat[SOC_STAT_CD].name = skt->nr ? "bdetect" : "adetect";
  33         skt->stat[SOC_STAT_BVD1].name = skt->nr ? "bbvd1" : "abvd1";
  34         skt->stat[SOC_STAT_BVD2].name = skt->nr ? "bbvd2" : "abvd2";
  35         skt->stat[SOC_STAT_RDY].name = skt->nr ? "bready" : "aready";
  36         skt->stat[SOC_STAT_VS1].name = skt->nr ? "bvs1" : "avs1";
  37         skt->stat[SOC_STAT_VS2].name = skt->nr ? "bvs2" : "avs2";
  38 
  39         skt->gpio_reset = devm_gpiod_get(dev, skt->nr ? "breset" : "areset",
  40                                          GPIOD_OUT_HIGH);
  41         if (IS_ERR(skt->gpio_reset))
  42                 return PTR_ERR(skt->gpio_reset);
  43 
  44         ret = max1600_init(dev, &m, skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
  45                            MAX1600_CODE_HIGH);
  46         if (ret)
  47                 return ret;
  48 
  49         skt->driver_data = m;
  50 
  51         return soc_pcmcia_request_gpiods(skt);
  52 }
  53 
  54 static unsigned int mst_pcmcia_bvd1_status[2];
  55 
  56 static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  57                                     struct pcmcia_state *state)
  58 {
  59         unsigned int flip = mst_pcmcia_bvd1_status[skt->nr] ^ state->bvd1;
  60 
  61         /*
  62          * Workaround for STSCHG which can't be deasserted:
  63          * We therefore disable/enable corresponding IRQs
  64          * as needed to avoid IRQ locks.
  65          */
  66         if (flip) {
  67                 mst_pcmcia_bvd1_status[skt->nr] = state->bvd1;
  68                 if (state->bvd1)
  69                         enable_irq(skt->stat[SOC_STAT_BVD1].irq);
  70                 else
  71                         disable_irq(skt->stat[SOC_STAT_BVD2].irq);
  72         }
  73 }
  74 
  75 static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  76                                        const socket_state_t *state)
  77 {
  78         return max1600_configure(skt->driver_data, state->Vcc, state->Vpp);
  79 }
  80 
  81 static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
  82         .owner                  = THIS_MODULE,
  83         .hw_init                = mst_pcmcia_hw_init,
  84         .socket_state           = mst_pcmcia_socket_state,
  85         .configure_socket       = mst_pcmcia_configure_socket,
  86         .nr                     = 2,
  87 };
  88 
  89 static struct platform_device *mst_pcmcia_device;
  90 
  91 static int __init mst_pcmcia_init(void)
  92 {
  93         int ret;
  94 
  95         if (!machine_is_mainstone())
  96                 return -ENODEV;
  97 
  98         mst_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
  99         if (!mst_pcmcia_device)
 100                 return -ENOMEM;
 101 
 102         ret = platform_device_add_data(mst_pcmcia_device, &mst_pcmcia_ops,
 103                                        sizeof(mst_pcmcia_ops));
 104         if (ret == 0)
 105                 ret = platform_device_add(mst_pcmcia_device);
 106 
 107         if (ret)
 108                 platform_device_put(mst_pcmcia_device);
 109 
 110         return ret;
 111 }
 112 
 113 static void __exit mst_pcmcia_exit(void)
 114 {
 115         platform_device_unregister(mst_pcmcia_device);
 116 }
 117 
 118 fs_initcall(mst_pcmcia_init);
 119 module_exit(mst_pcmcia_exit);
 120 
 121 MODULE_LICENSE("GPL");
 122 MODULE_ALIAS("platform:pxa2xx-pcmcia");

/* [<][>][^][v][top][bottom][index][help] */