187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport/*
287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport * linux/drivers/pcmcia/pxa/pxa_cm_x270.c
387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport *
487944f3361fc033b73617aa663135c6e468957a7Mike Rapoport * This program is free software; you can redistribute it and/or modify
587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport * it under the terms of the GNU General Public License version 2 as
687944f3361fc033b73617aa663135c6e468957a7Mike Rapoport * published by the Free Software Foundation.
787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport *
8779c545d945eeb7778c27c531bae58df7767229dMike Rapoport * Compulab Ltd., 2003, 2007, 2008
987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport * Mike Rapoport <mike@compulab.co.il>
1087944f3361fc033b73617aa663135c6e468957a7Mike Rapoport *
1187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport */
1287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
1387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport#include <linux/platform_device.h>
1487944f3361fc033b73617aa663135c6e468957a7Mike Rapoport#include <linux/irq.h>
1587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport#include <linux/delay.h>
16779c545d945eeb7778c27c531bae58df7767229dMike Rapoport#include <linux/gpio.h>
17402b20de62f4183d70fae335ca33b0327bdf0afdPaul Gortmaker#include <linux/export.h>
1887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
1987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport#include "soc_common.h"
2087944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
21779c545d945eeb7778c27c531bae58df7767229dMike Rapoport#define GPIO_PCMCIA_S0_CD_VALID	(84)
22779c545d945eeb7778c27c531bae58df7767229dMike Rapoport#define GPIO_PCMCIA_S0_RDYINT	(82)
23779c545d945eeb7778c27c531bae58df7767229dMike Rapoport#define GPIO_PCMCIA_RESET	(53)
24779c545d945eeb7778c27c531bae58df7767229dMike Rapoport
2587944f3361fc033b73617aa663135c6e468957a7Mike Rapoportstatic int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
2687944f3361fc033b73617aa663135c6e468957a7Mike Rapoport{
27779c545d945eeb7778c27c531bae58df7767229dMike Rapoport	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
28779c545d945eeb7778c27c531bae58df7767229dMike Rapoport	if (ret)
29779c545d945eeb7778c27c531bae58df7767229dMike Rapoport		return ret;
30779c545d945eeb7778c27c531bae58df7767229dMike Rapoport	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
31779c545d945eeb7778c27c531bae58df7767229dMike Rapoport
32a9bb5a4bf9f84256499c802fd397d56d55227e4fRussell King	skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
33a9bb5a4bf9f84256499c802fd397d56d55227e4fRussell King	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
34a9bb5a4bf9f84256499c802fd397d56d55227e4fRussell King	skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
35a9bb5a4bf9f84256499c802fd397d56d55227e4fRussell King	skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
36779c545d945eeb7778c27c531bae58df7767229dMike Rapoport
37779c545d945eeb7778c27c531bae58df7767229dMike Rapoport	return ret;
3887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport}
3987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
4087944f3361fc033b73617aa663135c6e468957a7Mike Rapoportstatic void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
4187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport{
42779c545d945eeb7778c27c531bae58df7767229dMike Rapoport	gpio_free(GPIO_PCMCIA_RESET);
4387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport}
4487944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
4587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
4687944f3361fc033b73617aa663135c6e468957a7Mike Rapoportstatic void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
4787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport				       struct pcmcia_state *state)
4887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport{
4987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	state->vs_3v  = 0;
5087944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	state->vs_Xv  = 0;
5187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport}
5287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
5387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
5487944f3361fc033b73617aa663135c6e468957a7Mike Rapoportstatic int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
5587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport					  const socket_state_t *state)
5687944f3361fc033b73617aa663135c6e468957a7Mike Rapoport{
5787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	switch (skt->nr) {
5887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	case 0:
5987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport		if (state->flags & SS_RESET) {
60779c545d945eeb7778c27c531bae58df7767229dMike Rapoport			gpio_set_value(GPIO_PCMCIA_RESET, 1);
6187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport			udelay(10);
62779c545d945eeb7778c27c531bae58df7767229dMike Rapoport			gpio_set_value(GPIO_PCMCIA_RESET, 0);
6387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport		}
6487944f3361fc033b73617aa663135c6e468957a7Mike Rapoport		break;
6587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	}
6687944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
6787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	return 0;
6887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport}
6987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
704e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell Kingstatic struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
7187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	.owner			= THIS_MODULE,
7287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	.hw_init		= cmx270_pcmcia_hw_init,
7387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	.hw_shutdown		= cmx270_pcmcia_shutdown,
7487944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	.socket_state		= cmx270_pcmcia_socket_state,
7587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	.configure_socket	= cmx270_pcmcia_configure_socket,
76779c545d945eeb7778c27c531bae58df7767229dMike Rapoport	.nr			= 1,
7787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport};
7887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
7987944f3361fc033b73617aa663135c6e468957a7Mike Rapoportstatic struct platform_device *cmx270_pcmcia_device;
8087944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
818616e2fb6930103a8408998777ec8a2332f5e89dMike Rapoportint __init cmx270_pcmcia_init(void)
8287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport{
8387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	int ret;
8487944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
8587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
8687944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
8787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	if (!cmx270_pcmcia_device)
8887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport		return -ENOMEM;
8987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
904e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell King	ret = platform_device_add_data(cmx270_pcmcia_device, &cmx270_pcmcia_ops,
914e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell King				       sizeof(cmx270_pcmcia_ops));
9287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
934e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell King	if (ret == 0) {
944e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell King		printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n");
954e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell King		ret = platform_device_add(cmx270_pcmcia_device);
964e5e8de0dbdeb08df2b4c15fa2b0ba2216091793Russell King	}
9787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
9887944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	if (ret)
9987944f3361fc033b73617aa663135c6e468957a7Mike Rapoport		platform_device_put(cmx270_pcmcia_device);
10087944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
10187944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	return ret;
10287944f3361fc033b73617aa663135c6e468957a7Mike Rapoport}
10387944f3361fc033b73617aa663135c6e468957a7Mike Rapoport
1048616e2fb6930103a8408998777ec8a2332f5e89dMike Rapoportvoid __exit cmx270_pcmcia_exit(void)
10587944f3361fc033b73617aa663135c6e468957a7Mike Rapoport{
10687944f3361fc033b73617aa663135c6e468957a7Mike Rapoport	platform_device_unregister(cmx270_pcmcia_device);
10787944f3361fc033b73617aa663135c6e468957a7Mike Rapoport}
108