drivers/pcmcia/xxs1500_ss.c

Source file repositories/reference/linux-study-clean/drivers/pcmcia/xxs1500_ss.c

File Facts

System
Linux kernel
Corpus path
drivers/pcmcia/xxs1500_ss.c
Extension
.c
Size
7994 bytes
Lines
327
Domain
Driver Families
Bucket
drivers/pcmcia
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct xxs1500_pcmcia_sock {
	struct pcmcia_socket	socket;
	void		*virt_io;

	phys_addr_t	phys_io;
	phys_addr_t	phys_attr;
	phys_addr_t	phys_mem;

	/* previous flags for set_socket() */
	unsigned int old_flags;
};

#define to_xxs_socket(x) container_of(x, struct xxs1500_pcmcia_sock, socket)

static irqreturn_t cdirq(int irq, void *data)
{
	struct xxs1500_pcmcia_sock *sock = data;

	pcmcia_parse_events(&sock->socket, SS_DETECT);

	return IRQ_HANDLED;
}

static int xxs1500_pcmcia_configure(struct pcmcia_socket *skt,
				    struct socket_state_t *state)
{
	struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
	unsigned int changed;

	/* power control */
	switch (state->Vcc) {
	case 0:
		gpio_set_value(GPIO_POWER, 1);	/* power off */
		break;
	case 33:
		gpio_set_value(GPIO_POWER, 0);	/* power on */
		break;
	case 50:
	default:
		return -EINVAL;
	}

	changed = state->flags ^ sock->old_flags;

	if (changed & SS_RESET) {
		if (state->flags & SS_RESET) {
			gpio_set_value(GPIO_RESET, 1);	/* assert reset */
			gpio_set_value(GPIO_OUTEN, 1);	/* buffers off */
		} else {
			gpio_set_value(GPIO_RESET, 0);	/* deassert reset */
			gpio_set_value(GPIO_OUTEN, 0);	/* buffers on */
			msleep(500);
		}
	}

	sock->old_flags = state->flags;

	return 0;
}

static int xxs1500_pcmcia_get_status(struct pcmcia_socket *skt,
				     unsigned int *value)
{
	unsigned int status;
	int i;

	status = 0;

	/* check carddetects: GPIO[0:1] must both be low */
	if (!gpio_get_value(GPIO_CDA) && !gpio_get_value(GPIO_CDB))
		status |= SS_DETECT;

	/* determine card voltage: GPIO[208:209] binary value */
	i = (!!gpio_get_value(GPIO_VSL)) | ((!!gpio_get_value(GPIO_VSH)) << 1);

	switch (i) {
	case 0:
	case 1:
	case 2:
		status |= SS_3VCARD;	/* 3V card */
		break;
	case 3:				/* 5V card, unsupported */
	default:
		status |= SS_XVCARD;	/* treated as unsupported in core */
	}

	/* GPIO214: low active power switch */
	status |= gpio_get_value(GPIO_POWER) ? 0 : SS_POWERON;

	/* GPIO204: high-active reset line */

Annotation

Implementation Notes