• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/pcmcia/
1/*
2 * linux/drivers/pcmcia/pxa2xx_balloon3.c
3 *
4 * Balloon3 PCMCIA specific routines.
5 *
6 *  Author:	Nick Bane
7 *  Created:	June, 2006
8 *  Copyright:	Toby Churchill Ltd
9 *  Derived from pxa2xx_mainstone.c, by Nico Pitre
10 *
11 * Various modification by Marek Vasut <marek.vasut@gmail.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/module.h>
19#include <linux/gpio.h>
20#include <linux/errno.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/irq.h>
24#include <linux/io.h>
25
26#include <mach/balloon3.h>
27
28#include "soc_common.h"
29
30/*
31 * These are a list of interrupt sources that provokes a polled
32 * check of status
33 */
34static struct pcmcia_irqs irqs[] = {
35	{ 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" },
36	{ 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" },
37};
38
39static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
40{
41	uint16_t ver;
42	int ret;
43	static void __iomem *fpga_ver;
44
45	ver = __raw_readw(BALLOON3_FPGA_VER);
46	if (ver > 0x0201)
47		pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. "
48			"PCMCIA/CF support might be broken in this version!",
49			ver);
50
51	skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ;
52	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
53}
54
55static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
56{
57	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
58}
59
60static unsigned long balloon3_pcmcia_status[2] = {
61	BALLOON3_CF_nSTSCHG_BVD1,
62	BALLOON3_CF_nSTSCHG_BVD1
63};
64
65static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
66				    struct pcmcia_state *state)
67{
68	uint16_t status;
69	int flip;
70
71	/* This actually reads the STATUS register */
72	status = __raw_readw(BALLOON3_CF_STATUS_REG);
73	flip = (status ^ balloon3_pcmcia_status[skt->nr])
74		& BALLOON3_CF_nSTSCHG_BVD1;
75	if (flip) {
76		balloon3_pcmcia_status[skt->nr] = status;
77		if (status & BALLOON3_CF_nSTSCHG_BVD1)
78			enable_irq(BALLOON3_BP_NSTSCHG_IRQ);
79		else
80			disable_irq(BALLOON3_BP_NSTSCHG_IRQ);
81	}
82
83	state->detect	= !gpio_get_value(BALLOON3_GPIO_S0_CD);
84	state->ready	= !!(status & BALLOON3_CF_nIRQ);
85	state->bvd1	= !!(status & BALLOON3_CF_nSTSCHG_BVD1);
86	state->bvd2	= 0;	/* not available */
87	state->vs_3v	= 1;	/* Always true its a CF card */
88	state->vs_Xv	= 0;	/* not available */
89	state->wrprot	= 0;	/* not available */
90}
91
92static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
93				       const socket_state_t *state)
94{
95	__raw_writew((state->flags & SS_RESET) ? BALLOON3_CF_RESET : 0,
96			BALLOON3_CF_CONTROL_REG);
97	return 0;
98}
99
100static void balloon3_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
101{
102}
103
104static void balloon3_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
105{
106}
107
108static struct pcmcia_low_level balloon3_pcmcia_ops = {
109	.owner			= THIS_MODULE,
110	.hw_init		= balloon3_pcmcia_hw_init,
111	.hw_shutdown		= balloon3_pcmcia_hw_shutdown,
112	.socket_state		= balloon3_pcmcia_socket_state,
113	.configure_socket	= balloon3_pcmcia_configure_socket,
114	.socket_init		= balloon3_pcmcia_socket_init,
115	.socket_suspend		= balloon3_pcmcia_socket_suspend,
116	.first			= 0,
117	.nr			= 1,
118};
119
120static struct platform_device *balloon3_pcmcia_device;
121
122static int __init balloon3_pcmcia_init(void)
123{
124	int ret;
125
126	balloon3_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
127	if (!balloon3_pcmcia_device)
128		return -ENOMEM;
129
130	ret = platform_device_add_data(balloon3_pcmcia_device,
131			&balloon3_pcmcia_ops, sizeof(balloon3_pcmcia_ops));
132
133	if (!ret)
134		ret = platform_device_add(balloon3_pcmcia_device);
135
136	if (ret)
137		platform_device_put(balloon3_pcmcia_device);
138
139	return ret;
140}
141
142static void __exit balloon3_pcmcia_exit(void)
143{
144	platform_device_unregister(balloon3_pcmcia_device);
145}
146
147module_init(balloon3_pcmcia_init);
148module_exit(balloon3_pcmcia_exit);
149
150MODULE_LICENSE("GPL");
151MODULE_AUTHOR("Nick Bane <nick@cecomputing.co.uk>");
152MODULE_ALIAS("platform:pxa2xx-pcmcia");
153MODULE_DESCRIPTION("Balloon3 board CF/PCMCIA driver");
154