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