Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pxa2xx_stargate2.c
Go to the documentation of this file.
1 /*
2  * linux/drivers/pcmcia/pxa2xx_stargate2.c
3  *
4  * Stargate 2 PCMCIA specific routines.
5  *
6  * Created: December 6, 2005
7  * Author: Ed C. Epp
8  * Copyright: Intel Corp 2005
9  * Jonathan Cameron <[email protected]> 2009
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15 
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/platform_device.h>
22 #include <linux/gpio.h>
23 
24 #include <pcmcia/ss.h>
25 
26 #include <asm/irq.h>
27 #include <asm/mach-types.h>
28 
29 #include "soc_common.h"
30 
31 #define SG2_S0_POWER_CTL 108
32 #define SG2_S0_GPIO_RESET 82
33 #define SG2_S0_GPIO_DETECT 53
34 #define SG2_S0_GPIO_READY 81
35 
36 static struct gpio sg2_pcmcia_gpios[] = {
37  { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
38  { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
39 };
40 
41 static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
42 {
43  skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT;
44  skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
45  skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY;
46  skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
47  return 0;
48 }
49 
50 static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
51  struct pcmcia_state *state)
52 {
53  state->bvd1 = 0; /* not available - battery detect on card */
54  state->bvd2 = 0; /* not available */
55  state->vs_3v = 1; /* not available - voltage detect for card */
56  state->vs_Xv = 0; /* not available */
57 }
58 
59 static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
60  const socket_state_t *state)
61 {
62  /* Enable card power */
63  switch (state->Vcc) {
64  case 0:
65  /* sets power ctl register high */
67  break;
68  case 33:
69  case 50:
70  /* sets power control register low (clear) */
72  msleep(100);
73  break;
74  default:
75  pr_err("%s(): bad Vcc %u\n",
76  __func__, state->Vcc);
77  return -1;
78  }
79 
80  /* reset */
82 
83  return 0;
84 }
85 
86 static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
87  .owner = THIS_MODULE,
88  .hw_init = sg2_pcmcia_hw_init,
89  .socket_state = sg2_pcmcia_socket_state,
90  .configure_socket = sg2_pcmcia_configure_socket,
91  .nr = 1,
92 };
93 
94 static struct platform_device *sg2_pcmcia_device;
95 
96 static int __init sg2_pcmcia_init(void)
97 {
98  int ret;
99 
100  if (!machine_is_stargate2())
101  return -ENODEV;
102 
103  sg2_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
104  if (!sg2_pcmcia_device)
105  return -ENOMEM;
106 
107  ret = gpio_request_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
108  if (ret)
109  goto error_put_platform_device;
110 
111  ret = platform_device_add_data(sg2_pcmcia_device,
112  &sg2_pcmcia_ops,
113  sizeof(sg2_pcmcia_ops));
114  if (ret)
115  goto error_free_gpios;
116 
117  ret = platform_device_add(sg2_pcmcia_device);
118  if (ret)
119  goto error_free_gpios;
120 
121  return 0;
122 error_free_gpios:
123  gpio_free_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
124 error_put_platform_device:
125  platform_device_put(sg2_pcmcia_device);
126 
127  return ret;
128 }
129 
130 static void __exit sg2_pcmcia_exit(void)
131 {
132  platform_device_unregister(sg2_pcmcia_device);
133  gpio_free_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
134 }
135 
136 fs_initcall(sg2_pcmcia_init);
137 module_exit(sg2_pcmcia_exit);
138 
139 MODULE_LICENSE("GPL");
140 MODULE_ALIAS("platform:pxa2xx-pcmcia");