16d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut/*
26d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut * linux/drivers/pcmcia/pxa2xx_palmld.c
36d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut *
46d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut * Driver for Palm LifeDrive PCMCIA
56d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut *
66d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
79ed3fbf1cbc2b747b3532985059f4738c15f4c07Marek Vasut * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
86d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut *
96d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut * This program is free software; you can redistribute it and/or modify
106d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut * it under the terms of the GNU General Public License version 2 as
116d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut * published by the Free Software Foundation.
126d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut *
136d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut */
146d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
156d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut#include <linux/module.h>
166d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut#include <linux/platform_device.h>
176d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut#include <linux/gpio.h>
186d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
196d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut#include <asm/mach-types.h>
206d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut#include <mach/palmld.h>
216d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut#include "soc_common.h"
226d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
232070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasutstatic struct gpio palmld_pcmcia_gpios[] = {
242070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut	{ GPIO_NR_PALMLD_PCMCIA_POWER,	GPIOF_INIT_LOW,	"PCMCIA Power" },
252070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut	{ GPIO_NR_PALMLD_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
262070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut};
272070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut
286d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
296d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut{
306d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	int ret;
316d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
322070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut	ret = gpio_request_array(palmld_pcmcia_gpios,
332070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut				ARRAY_SIZE(palmld_pcmcia_gpios));
346d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
35a9bb5a4bf9f84256499c802fd397d56d55227e4fRussell King	skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY;
36a9bb5a4bf9f84256499c802fd397d56d55227e4fRussell King	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
376d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
386d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	return ret;
396d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut}
406d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
416d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
426d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut{
432070417dffa9e75b370a5c0dee8c5dc3605e1c4dMarek Vasut	gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios));
446d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut}
456d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
466d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
476d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut					struct pcmcia_state *state)
486d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut{
496d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	state->detect = 1; /* always inserted */
506d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	state->vs_3v  = 1;
516d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	state->vs_Xv  = 0;
526d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut}
536d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
546d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
556d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut					const socket_state_t *state)
566d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut{
576d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
586d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
596d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut			!!(state->flags & SS_RESET));
606d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
616d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	return 0;
626d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut}
636d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
646d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic struct pcmcia_low_level palmld_pcmcia_ops = {
656d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	.owner			= THIS_MODULE,
666d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
67d66ea8d4c2aa7199cf4e5c977eb25764e5fc5da9Marek Vasut	.first			= 1,
68d66ea8d4c2aa7199cf4e5c977eb25764e5fc5da9Marek Vasut	.nr			= 1,
696d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
706d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	.hw_init		= palmld_pcmcia_hw_init,
716d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	.hw_shutdown		= palmld_pcmcia_hw_shutdown,
726d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
736d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	.socket_state		= palmld_pcmcia_socket_state,
746d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	.configure_socket	= palmld_pcmcia_configure_socket,
756d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut};
766d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
776d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic struct platform_device *palmld_pcmcia_device;
786d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
796d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic int __init palmld_pcmcia_init(void)
806d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut{
816d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	int ret;
826d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
836d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	if (!machine_is_palmld())
846d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut		return -ENODEV;
856d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
866d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	palmld_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
876d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	if (!palmld_pcmcia_device)
886d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut		return -ENOMEM;
896d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
906d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
916d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut					sizeof(palmld_pcmcia_ops));
926d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
936d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	if (!ret)
946d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut		ret = platform_device_add(palmld_pcmcia_device);
956d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
966d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	if (ret)
976d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut		platform_device_put(palmld_pcmcia_device);
986d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
996d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	return ret;
1006d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut}
1016d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
1026d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutstatic void __exit palmld_pcmcia_exit(void)
1036d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut{
1046d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	platform_device_unregister(palmld_pcmcia_device);
1056d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut}
1066d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
1076d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutmodule_init(palmld_pcmcia_init);
1086d341675f8e715464849e5d5563a72c1d39e800dMarek Vašutmodule_exit(palmld_pcmcia_exit);
1096d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut
1106d341675f8e715464849e5d5563a72c1d39e800dMarek VašutMODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
1116d341675f8e715464849e5d5563a72c1d39e800dMarek Vašut	    " Marek Vasut <marek.vasut@gmail.com>");
1126d341675f8e715464849e5d5563a72c1d39e800dMarek VašutMODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
1136d341675f8e715464849e5d5563a72c1d39e800dMarek VašutMODULE_ALIAS("platform:pxa2xx-pcmcia");
1146d341675f8e715464849e5d5563a72c1d39e800dMarek VašutMODULE_LICENSE("GPL");
115