Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2125d05 authored by Russell King's avatar Russell King
Browse files

ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and gpiod APIs



Convert Neponset to use the gpiod API to specify which GPIOs are used
for PCMCIA, and use the MAX1600 power switch library for Neponset,
simplifying the neponset pcmcia driver as a result.

Acked-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent b96e6c01
Loading
Loading
Loading
Loading
+19 −0
Original line number Original line Diff line number Diff line
@@ -5,6 +5,7 @@
#include <linux/err.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/gpio-reg.h>
#include <linux/gpio/gpio-reg.h>
#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/irq.h>
@@ -96,6 +97,19 @@ struct neponset_drvdata {
	struct gpio_chip *gpio[4];
	struct gpio_chip *gpio[4];
};
};


static struct gpiod_lookup_table neponset_pcmcia_table = {
	.dev_id = "1800",
	.table = {
		GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct neponset_drvdata *nep;
static struct neponset_drvdata *nep;


void neponset_ncr_frob(unsigned int mask, unsigned int val)
void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -374,6 +388,8 @@ static int neponset_probe(struct platform_device *dev)
			   d->base + AUD_CTL, AUD_NGPIO, false,
			   d->base + AUD_CTL, AUD_NGPIO, false,
			   neponset_aud_names);
			   neponset_aud_names);


	gpiod_add_lookup_table(&neponset_pcmcia_table);

	/*
	/*
	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
	 * something on the Neponset activates this IRQ on sleep (eth?)
	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -424,6 +440,9 @@ static int neponset_remove(struct platform_device *dev)
		platform_device_unregister(d->sa1111);
		platform_device_unregister(d->sa1111);
	if (!IS_ERR(d->smc91x))
	if (!IS_ERR(d->smc91x))
		platform_device_unregister(d->smc91x);
		platform_device_unregister(d->smc91x);

	gpiod_remove_lookup_table(&neponset_pcmcia_table);

	irq_set_chained_handler(irq, NULL);
	irq_set_chained_handler(irq, NULL);
	irq_free_descs(d->irq_base, NEP_IRQ_NR);
	irq_free_descs(d->irq_base, NEP_IRQ_NR);
	nep = NULL;
	nep = NULL;
+1 −0
Original line number Original line Diff line number Diff line
@@ -194,6 +194,7 @@ config PCMCIA_SA1111
	select PCMCIA_SOC_COMMON
	select PCMCIA_SOC_COMMON
	select PCMCIA_SA11XX_BASE if ARCH_SA1100
	select PCMCIA_SA11XX_BASE if ARCH_SA1100
	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
	select PCMCIA_MAX1600 if ASSABET_NEPONSET
	help
	help
	  Say Y  here to include support for SA1111-based PCMCIA or CF
	  Say Y  here to include support for SA1111-based PCMCIA or CF
	  sockets, found on the Jornada 720, Graphicsmaster and other
	  sockets, found on the Jornada 720, Graphicsmaster and other
+18 −61
Original line number Original line Diff line number Diff line
@@ -10,12 +10,10 @@
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/init.h>


#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach-types.h>
#include <mach/neponset.h>
#include <asm/hardware/sa1111.h>


#include "sa1111_generic.h"
#include "sa1111_generic.h"
#include "max1600.h"


/*
/*
 * Neponset uses the Maxim MAX1600, with the following connections:
 * Neponset uses the Maxim MAX1600, with the following connections:
@@ -40,70 +38,36 @@
 * "Standard Intel code" mode. Refer to the Maxim data sheet for
 * "Standard Intel code" mode. Refer to the Maxim data sheet for
 * the corresponding truth table.
 * the corresponding truth table.
 */
 */

static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
static int
neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
{
	struct sa1111_pcmcia_socket *s = to_skt(skt);
	struct max1600 *m;
	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
	int ret;
	int ret;


	switch (skt->nr) {
	ret = max1600_init(skt->socket.dev.parent, &m,
	case 0:
			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
		pa_dwr_mask = GPIO_A0 | GPIO_A1;
			   MAX1600_CODE_LOW);
		ncr_mask = NCR_A0VPP | NCR_A1VPP;
	if (ret == 0)

		skt->driver_data = m;
		if (state->Vpp == 0)
			ncr_set = 0;
		else if (state->Vpp == 120)
			ncr_set = NCR_A1VPP;
		else if (state->Vpp == state->Vcc)
			ncr_set = NCR_A0VPP;
		else {
			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
			       __func__, state->Vpp);
			return -1;
		}
		break;

	case 1:
		pa_dwr_mask = GPIO_A2 | GPIO_A3;
		ncr_mask = 0;
		ncr_set = 0;

		if (state->Vpp != state->Vcc && state->Vpp != 0) {
			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
			       __func__, state->Vpp);
			return -1;
		}
		break;


	default:
	return ret;
		return -1;
}
}


	/*
static int
	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
	 * pa_dwr_mask selects which bits (and therefore socket) we change.
{
	 */
	struct max1600 *m = skt->driver_data;
	switch (state->Vcc) {
	int ret;
	default:
	case 0:  pa_dwr_set = 0;		break;
	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
	}


	ret = sa1111_pcmcia_configure_socket(skt, state);
	ret = sa1111_pcmcia_configure_socket(skt, state);
	if (ret == 0) {
	if (ret == 0)
		neponset_ncr_frob(ncr_mask, ncr_set);
		ret = max1600_configure(m, state->Vcc, state->Vpp);
		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
	}


	return ret;
	return ret;
}
}


static struct pcmcia_low_level neponset_pcmcia_ops = {
static struct pcmcia_low_level neponset_pcmcia_ops = {
	.owner			= THIS_MODULE,
	.owner			= THIS_MODULE,
	.hw_init		= neponset_pcmcia_hw_init,
	.configure_socket	= neponset_pcmcia_configure_socket,
	.configure_socket	= neponset_pcmcia_configure_socket,
	.first			= 0,
	.first			= 0,
	.nr			= 2,
	.nr			= 2,
@@ -111,13 +75,6 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {


int pcmcia_neponset_init(struct sa1111_dev *sadev)
int pcmcia_neponset_init(struct sa1111_dev *sadev)
{
{
	/*
	 * Set GPIO_A<3:0> to be outputs for the MAX1600,
	 * and switch to standby mode.
	 */
	sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
	sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
	sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
	sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
	sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
	return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
	return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
				 sa11xx_drv_pcmcia_add_one);
				 sa11xx_drv_pcmcia_add_one);