summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-11-28 08:57:23 -0500
committerRussell King <rmk+kernel@armlinux.org.uk>2018-12-04 17:37:38 -0500
commite2125d0517c0be28c39890916048ea9cfe00b9bf (patch)
tree65a842b78769cab8bcb58178068bf4a643585ca5
parentb96e6c01bafbb25bf49ac74e339ef81dddbce194 (diff)
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: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--arch/arm/mach-sa1100/neponset.c19
-rw-r--r--drivers/pcmcia/Kconfig1
-rw-r--r--drivers/pcmcia/sa1111_neponset.c79
3 files changed, 38 insertions, 61 deletions
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index b1823f445358..eb60a71cf125 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -5,6 +5,7 @@
5#include <linux/err.h> 5#include <linux/err.h>
6#include <linux/gpio/driver.h> 6#include <linux/gpio/driver.h>
7#include <linux/gpio/gpio-reg.h> 7#include <linux/gpio/gpio-reg.h>
8#include <linux/gpio/machine.h>
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/ioport.h> 10#include <linux/ioport.h>
10#include <linux/irq.h> 11#include <linux/irq.h>
@@ -96,6 +97,19 @@ struct neponset_drvdata {
96 struct gpio_chip *gpio[4]; 97 struct gpio_chip *gpio[4];
97}; 98};
98 99
100static struct gpiod_lookup_table neponset_pcmcia_table = {
101 .dev_id = "1800",
102 .table = {
103 GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
104 GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
105 GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
106 GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
107 GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
108 GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
109 { },
110 },
111};
112
99static struct neponset_drvdata *nep; 113static struct neponset_drvdata *nep;
100 114
101void neponset_ncr_frob(unsigned int mask, unsigned int val) 115void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -374,6 +388,8 @@ static int neponset_probe(struct platform_device *dev)
374 d->base + AUD_CTL, AUD_NGPIO, false, 388 d->base + AUD_CTL, AUD_NGPIO, false,
375 neponset_aud_names); 389 neponset_aud_names);
376 390
391 gpiod_add_lookup_table(&neponset_pcmcia_table);
392
377 /* 393 /*
378 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately 394 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
379 * something on the Neponset activates this IRQ on sleep (eth?) 395 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -424,6 +440,9 @@ static int neponset_remove(struct platform_device *dev)
424 platform_device_unregister(d->sa1111); 440 platform_device_unregister(d->sa1111);
425 if (!IS_ERR(d->smc91x)) 441 if (!IS_ERR(d->smc91x))
426 platform_device_unregister(d->smc91x); 442 platform_device_unregister(d->smc91x);
443
444 gpiod_remove_lookup_table(&neponset_pcmcia_table);
445
427 irq_set_chained_handler(irq, NULL); 446 irq_set_chained_handler(irq, NULL);
428 irq_free_descs(d->irq_base, NEP_IRQ_NR); 447 irq_free_descs(d->irq_base, NEP_IRQ_NR);
429 nep = NULL; 448 nep = NULL;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1a257a323923..8e8db3aa9fce 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -194,6 +194,7 @@ config PCMCIA_SA1111
194 select PCMCIA_SOC_COMMON 194 select PCMCIA_SOC_COMMON
195 select PCMCIA_SA11XX_BASE if ARCH_SA1100 195 select PCMCIA_SA11XX_BASE if ARCH_SA1100
196 select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111 196 select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
197 select PCMCIA_MAX1600 if ASSABET_NEPONSET
197 help 198 help
198 Say Y here to include support for SA1111-based PCMCIA or CF 199 Say Y here to include support for SA1111-based PCMCIA or CF
199 sockets, found on the Jornada 720, Graphicsmaster and other 200 sockets, found on the Jornada 720, Graphicsmaster and other
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index 0ccf05a28a4b..de0ce13355b4 100644
--- a/drivers/pcmcia/sa1111_neponset.c
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -10,12 +10,10 @@
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/init.h> 11#include <linux/init.h>
12 12
13#include <mach/hardware.h>
14#include <asm/mach-types.h> 13#include <asm/mach-types.h>
15#include <mach/neponset.h>
16#include <asm/hardware/sa1111.h>
17 14
18#include "sa1111_generic.h" 15#include "sa1111_generic.h"
16#include "max1600.h"
19 17
20/* 18/*
21 * Neponset uses the Maxim MAX1600, with the following connections: 19 * Neponset uses the Maxim MAX1600, with the following connections:
@@ -40,70 +38,36 @@
40 * "Standard Intel code" mode. Refer to the Maxim data sheet for 38 * "Standard Intel code" mode. Refer to the Maxim data sheet for
41 * the corresponding truth table. 39 * the corresponding truth table.
42 */ 40 */
43 41static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
44static int
45neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
46{ 42{
47 struct sa1111_pcmcia_socket *s = to_skt(skt); 43 struct max1600 *m;
48 unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
49 int ret; 44 int ret;
50 45
51 switch (skt->nr) { 46 ret = max1600_init(skt->socket.dev.parent, &m,
52 case 0: 47 skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
53 pa_dwr_mask = GPIO_A0 | GPIO_A1; 48 MAX1600_CODE_LOW);
54 ncr_mask = NCR_A0VPP | NCR_A1VPP; 49 if (ret == 0)
55 50 skt->driver_data = m;
56 if (state->Vpp == 0)
57 ncr_set = 0;
58 else if (state->Vpp == 120)
59 ncr_set = NCR_A1VPP;
60 else if (state->Vpp == state->Vcc)
61 ncr_set = NCR_A0VPP;
62 else {
63 printk(KERN_ERR "%s(): unrecognized VPP %u\n",
64 __func__, state->Vpp);
65 return -1;
66 }
67 break;
68
69 case 1:
70 pa_dwr_mask = GPIO_A2 | GPIO_A3;
71 ncr_mask = 0;
72 ncr_set = 0;
73
74 if (state->Vpp != state->Vcc && state->Vpp != 0) {
75 printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
76 __func__, state->Vpp);
77 return -1;
78 }
79 break;
80 51
81 default: 52 return ret;
82 return -1; 53}
83 }
84 54
85 /* 55static int
86 * pa_dwr_set is the mask for selecting Vcc on both sockets. 56neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
87 * pa_dwr_mask selects which bits (and therefore socket) we change. 57{
88 */ 58 struct max1600 *m = skt->driver_data;
89 switch (state->Vcc) { 59 int ret;
90 default:
91 case 0: pa_dwr_set = 0; break;
92 case 33: pa_dwr_set = GPIO_A1|GPIO_A2; break;
93 case 50: pa_dwr_set = GPIO_A0|GPIO_A3; break;
94 }
95 60
96 ret = sa1111_pcmcia_configure_socket(skt, state); 61 ret = sa1111_pcmcia_configure_socket(skt, state);
97 if (ret == 0) { 62 if (ret == 0)
98 neponset_ncr_frob(ncr_mask, ncr_set); 63 ret = max1600_configure(m, state->Vcc, state->Vpp);
99 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
100 }
101 64
102 return ret; 65 return ret;
103} 66}
104 67
105static struct pcmcia_low_level neponset_pcmcia_ops = { 68static struct pcmcia_low_level neponset_pcmcia_ops = {
106 .owner = THIS_MODULE, 69 .owner = THIS_MODULE,
70 .hw_init = neponset_pcmcia_hw_init,
107 .configure_socket = neponset_pcmcia_configure_socket, 71 .configure_socket = neponset_pcmcia_configure_socket,
108 .first = 0, 72 .first = 0,
109 .nr = 2, 73 .nr = 2,
@@ -111,13 +75,6 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
111 75
112int pcmcia_neponset_init(struct sa1111_dev *sadev) 76int pcmcia_neponset_init(struct sa1111_dev *sadev)
113{ 77{
114 /*
115 * Set GPIO_A<3:0> to be outputs for the MAX1600,
116 * and switch to standby mode.
117 */
118 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
119 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
120 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
121 sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); 78 sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
122 return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, 79 return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
123 sa11xx_drv_pcmcia_add_one); 80 sa11xx_drv_pcmcia_add_one);