Linux Audio

Check our new training course

Loading...
v3.1
 
  1/*
  2 * linux/drivers/pcmcia/pxa2xx_vpac270.c
  3 *
  4 * Driver for Voipac PXA270 PCMCIA and CF sockets
  5 *
  6 * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License version 2 as
 10 * published by the Free Software Foundation.
 11 *
 12 */
 13
 14#include <linux/gpio.h>
 15#include <linux/module.h>
 16#include <linux/platform_device.h>
 17
 18#include <asm/mach-types.h>
 19
 20#include <mach/gpio.h>
 21#include <mach/vpac270.h>
 22
 23#include "soc_common.h"
 24
 25static struct gpio vpac270_pcmcia_gpios[] = {
 26	{ GPIO84_VPAC270_PCMCIA_CD,	GPIOF_IN,	"PCMCIA Card Detect" },
 27	{ GPIO35_VPAC270_PCMCIA_RDY,	GPIOF_IN,	"PCMCIA Ready" },
 28	{ GPIO107_VPAC270_PCMCIA_PPEN,	GPIOF_INIT_LOW,	"PCMCIA PPEN" },
 29	{ GPIO11_VPAC270_PCMCIA_RESET,	GPIOF_INIT_LOW,	"PCMCIA Reset" },
 30};
 31
 32static struct gpio vpac270_cf_gpios[] = {
 33	{ GPIO17_VPAC270_CF_CD,		GPIOF_IN,	"CF Card Detect" },
 34	{ GPIO12_VPAC270_CF_RDY,	GPIOF_IN,	"CF Ready" },
 35	{ GPIO16_VPAC270_CF_RESET,	GPIOF_INIT_LOW,	"CF Reset" },
 36};
 37
 38static struct pcmcia_irqs cd_irqs[] = {
 39	{
 40		.sock = 0,
 41		.irq  = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD),
 42		.str  = "PCMCIA CD"
 43	},
 44	{
 45		.sock = 1,
 46		.irq  = IRQ_GPIO(GPIO17_VPAC270_CF_CD),
 47		.str  = "CF CD"
 48	},
 49};
 50
 51static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 52{
 53	int ret;
 54
 55	if (skt->nr == 0) {
 56		ret = gpio_request_array(vpac270_pcmcia_gpios,
 57				ARRAY_SIZE(vpac270_pcmcia_gpios));
 58
 59		skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
 60
 61		if (!ret)
 62			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
 63	} else {
 64		ret = gpio_request_array(vpac270_cf_gpios,
 65				ARRAY_SIZE(vpac270_cf_gpios));
 66
 67		skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
 68
 69		if (!ret)
 70			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
 71	}
 72
 73	return ret;
 74}
 75
 76static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 77{
 78	if (skt->nr == 0)
 79		gpio_free_array(vpac270_pcmcia_gpios,
 80					ARRAY_SIZE(vpac270_pcmcia_gpios));
 81	else
 82		gpio_free_array(vpac270_cf_gpios,
 83					ARRAY_SIZE(vpac270_cf_gpios));
 84}
 85
 86static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 87					struct pcmcia_state *state)
 88{
 89	if (skt->nr == 0) {
 90		state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
 91		state->ready  = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
 92	} else {
 93		state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
 94		state->ready  = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
 95	}
 96	state->bvd1   = 1;
 97	state->bvd2   = 1;
 98	state->wrprot = 0;
 99	state->vs_3v  = 1;
100	state->vs_Xv  = 0;
101}
102
103static int
104vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
105				const socket_state_t *state)
106{
107	if (skt->nr == 0) {
108		gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET,
109			(state->flags & SS_RESET));
110		gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN,
111			!(state->Vcc == 33 || state->Vcc == 50));
112	} else {
113		gpio_set_value(GPIO16_VPAC270_CF_RESET,
114			(state->flags & SS_RESET));
115	}
116
117	return 0;
118}
119
120static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
121{
122}
123
124static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
125{
126}
127
128static struct pcmcia_low_level vpac270_pcmcia_ops = {
129	.owner			= THIS_MODULE,
130
131	.first			= 0,
132	.nr			= 2,
133
134	.hw_init		= vpac270_pcmcia_hw_init,
135	.hw_shutdown		= vpac270_pcmcia_hw_shutdown,
136
137	.socket_state		= vpac270_pcmcia_socket_state,
138	.configure_socket	= vpac270_pcmcia_configure_socket,
139
140	.socket_init		= vpac270_pcmcia_socket_init,
141	.socket_suspend		= vpac270_pcmcia_socket_suspend,
142};
143
144static struct platform_device *vpac270_pcmcia_device;
145
146static int __init vpac270_pcmcia_init(void)
147{
148	int ret;
149
150	if (!machine_is_vpac270())
151		return -ENODEV;
152
153	vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
154	if (!vpac270_pcmcia_device)
155		return -ENOMEM;
156
157	ret = platform_device_add_data(vpac270_pcmcia_device,
158		&vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops));
159
160	if (!ret)
161		ret = platform_device_add(vpac270_pcmcia_device);
162
163	if (ret)
164		platform_device_put(vpac270_pcmcia_device);
165
166	return ret;
167}
168
169static void __exit vpac270_pcmcia_exit(void)
170{
171	platform_device_unregister(vpac270_pcmcia_device);
172}
173
174module_init(vpac270_pcmcia_init);
175module_exit(vpac270_pcmcia_exit);
176
177MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
178MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270");
179MODULE_ALIAS("platform:pxa2xx-pcmcia");
180MODULE_LICENSE("GPL");
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * linux/drivers/pcmcia/pxa2xx_vpac270.c
  4 *
  5 * Driver for Voipac PXA270 PCMCIA and CF sockets
  6 *
  7 * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
 
 
 
 
 
  8 */
  9
 10#include <linux/gpio.h>
 11#include <linux/module.h>
 12#include <linux/platform_device.h>
 13
 14#include <asm/mach-types.h>
 15
 
 16#include <mach/vpac270.h>
 17
 18#include "soc_common.h"
 19
 20static struct gpio vpac270_pcmcia_gpios[] = {
 
 
 21	{ GPIO107_VPAC270_PCMCIA_PPEN,	GPIOF_INIT_LOW,	"PCMCIA PPEN" },
 22	{ GPIO11_VPAC270_PCMCIA_RESET,	GPIOF_INIT_LOW,	"PCMCIA Reset" },
 23};
 24
 25static struct gpio vpac270_cf_gpios[] = {
 
 
 26	{ GPIO16_VPAC270_CF_RESET,	GPIOF_INIT_LOW,	"CF Reset" },
 27};
 28
 
 
 
 
 
 
 
 
 
 
 
 
 
 29static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 30{
 31	int ret;
 32
 33	if (skt->nr == 0) {
 34		ret = gpio_request_array(vpac270_pcmcia_gpios,
 35				ARRAY_SIZE(vpac270_pcmcia_gpios));
 36
 37		skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
 38		skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
 39		skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
 40		skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 41	} else {
 42		ret = gpio_request_array(vpac270_cf_gpios,
 43				ARRAY_SIZE(vpac270_cf_gpios));
 44
 45		skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
 46		skt->stat[SOC_STAT_CD].name = "CF CD";
 47		skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
 48		skt->stat[SOC_STAT_RDY].name = "CF Ready";
 49	}
 50
 51	return ret;
 52}
 53
 54static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 55{
 56	if (skt->nr == 0)
 57		gpio_free_array(vpac270_pcmcia_gpios,
 58					ARRAY_SIZE(vpac270_pcmcia_gpios));
 59	else
 60		gpio_free_array(vpac270_cf_gpios,
 61					ARRAY_SIZE(vpac270_cf_gpios));
 62}
 63
 64static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 65					struct pcmcia_state *state)
 66{
 
 
 
 
 
 
 
 
 
 
 67	state->vs_3v  = 1;
 68	state->vs_Xv  = 0;
 69}
 70
 71static int
 72vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 73				const socket_state_t *state)
 74{
 75	if (skt->nr == 0) {
 76		gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET,
 77			(state->flags & SS_RESET));
 78		gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN,
 79			!(state->Vcc == 33 || state->Vcc == 50));
 80	} else {
 81		gpio_set_value(GPIO16_VPAC270_CF_RESET,
 82			(state->flags & SS_RESET));
 83	}
 84
 85	return 0;
 86}
 87
 
 
 
 
 
 
 
 
 88static struct pcmcia_low_level vpac270_pcmcia_ops = {
 89	.owner			= THIS_MODULE,
 90
 91	.first			= 0,
 92	.nr			= 2,
 93
 94	.hw_init		= vpac270_pcmcia_hw_init,
 95	.hw_shutdown		= vpac270_pcmcia_hw_shutdown,
 96
 97	.socket_state		= vpac270_pcmcia_socket_state,
 98	.configure_socket	= vpac270_pcmcia_configure_socket,
 
 
 
 99};
100
101static struct platform_device *vpac270_pcmcia_device;
102
103static int __init vpac270_pcmcia_init(void)
104{
105	int ret;
106
107	if (!machine_is_vpac270())
108		return -ENODEV;
109
110	vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
111	if (!vpac270_pcmcia_device)
112		return -ENOMEM;
113
114	ret = platform_device_add_data(vpac270_pcmcia_device,
115		&vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops));
116
117	if (!ret)
118		ret = platform_device_add(vpac270_pcmcia_device);
119
120	if (ret)
121		platform_device_put(vpac270_pcmcia_device);
122
123	return ret;
124}
125
126static void __exit vpac270_pcmcia_exit(void)
127{
128	platform_device_unregister(vpac270_pcmcia_device);
129}
130
131module_init(vpac270_pcmcia_init);
132module_exit(vpac270_pcmcia_exit);
133
134MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
135MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270");
136MODULE_ALIAS("platform:pxa2xx-pcmcia");
137MODULE_LICENSE("GPL");