Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2 * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
  3 *
  4 * This program is free software; you can redistribute it and/or modify
  5 * it under the terms of the GNU General Public License version 2 as
  6 * published by the Free Software Foundation.
  7 *
  8 * Compulab Ltd., 2003, 2007, 2008
  9 * Mike Rapoport <mike@compulab.co.il>
 10 *
 11 */
 12
 13#include <linux/platform_device.h>
 14#include <linux/irq.h>
 15#include <linux/delay.h>
 16#include <linux/gpio.h>
 17
 18#include <asm/mach-types.h>
 19
 20#include "soc_common.h"
 21
 22#define GPIO_PCMCIA_SKTSEL	(54)
 23#define GPIO_PCMCIA_S0_CD_VALID	(16)
 24#define GPIO_PCMCIA_S1_CD_VALID	(17)
 25#define GPIO_PCMCIA_S0_RDYINT	(6)
 26#define GPIO_PCMCIA_S1_RDYINT	(8)
 27#define GPIO_PCMCIA_RESET	(9)
 28
 29#define PCMCIA_S0_CD_VALID	IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID)
 30#define PCMCIA_S1_CD_VALID	IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID)
 31#define PCMCIA_S0_RDYINT	IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT)
 32#define PCMCIA_S1_RDYINT	IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT)
 33
 34
 35static struct pcmcia_irqs irqs[] = {
 36	{ 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
 37	{ 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
 38};
 39
 40static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 41{
 42	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
 43	if (ret)
 44		return ret;
 45	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 46
 47	skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
 48	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 49	if (!ret)
 50		gpio_free(GPIO_PCMCIA_RESET);
 51
 52	return ret;
 53}
 54
 55static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 56{
 57	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 58	gpio_free(GPIO_PCMCIA_RESET);
 59}
 60
 61
 62static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 63				       struct pcmcia_state *state)
 64{
 65	int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
 66	int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
 67
 68	state->detect = !gpio_get_value(cd);
 69	state->ready  = !!gpio_get_value(rdy);
 70	state->bvd1   = 1;
 71	state->bvd2   = 1;
 72	state->vs_3v  = 0;
 73	state->vs_Xv  = 0;
 74	state->wrprot = 0;  /* not available */
 75}
 76
 77
 78static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 79					  const socket_state_t *state)
 80{
 81	switch (skt->nr) {
 82	case 0:
 83		if (state->flags & SS_RESET) {
 84			gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
 85			udelay(1);
 86			gpio_set_value(GPIO_PCMCIA_RESET, 1);
 87			udelay(10);
 88			gpio_set_value(GPIO_PCMCIA_RESET, 0);
 89		}
 90		break;
 91	case 1:
 92		if (state->flags & SS_RESET) {
 93			gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
 94			udelay(1);
 95			gpio_set_value(GPIO_PCMCIA_RESET, 1);
 96			udelay(10);
 97			gpio_set_value(GPIO_PCMCIA_RESET, 0);
 98		}
 99		break;
100	}
101
102	return 0;
103}
104
105static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
106	.owner			= THIS_MODULE,
107	.hw_init		= cmx255_pcmcia_hw_init,
108	.hw_shutdown		= cmx255_pcmcia_shutdown,
109	.socket_state		= cmx255_pcmcia_socket_state,
110	.configure_socket	= cmx255_pcmcia_configure_socket,
111	.nr			= 1,
112};
113
114static struct platform_device *cmx255_pcmcia_device;
115
116int __init cmx255_pcmcia_init(void)
117{
118	int ret;
119
120	cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
121
122	if (!cmx255_pcmcia_device)
123		return -ENOMEM;
124
125	ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
126				       sizeof(cmx255_pcmcia_ops));
127
128	if (ret == 0) {
129		printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
130		ret = platform_device_add(cmx255_pcmcia_device);
131	}
132
133	if (ret)
134		platform_device_put(cmx255_pcmcia_device);
135
136	return ret;
137}
138
139void __exit cmx255_pcmcia_exit(void)
140{
141	platform_device_unregister(cmx255_pcmcia_device);
142}