| .. | .. |
|---|
| 5 | 5 | #include <linux/err.h> |
|---|
| 6 | 6 | #include <linux/gpio/driver.h> |
|---|
| 7 | 7 | #include <linux/gpio/gpio-reg.h> |
|---|
| 8 | +#include <linux/gpio/machine.h> |
|---|
| 8 | 9 | #include <linux/init.h> |
|---|
| 9 | 10 | #include <linux/ioport.h> |
|---|
| 10 | 11 | #include <linux/irq.h> |
|---|
| 11 | 12 | #include <linux/kernel.h> |
|---|
| 12 | 13 | #include <linux/module.h> |
|---|
| 13 | | -#include <linux/platform_data/sa11x0-serial.h> |
|---|
| 14 | 14 | #include <linux/platform_device.h> |
|---|
| 15 | 15 | #include <linux/pm.h> |
|---|
| 16 | 16 | #include <linux/serial_core.h> |
|---|
| .. | .. |
|---|
| 20 | 20 | #include <asm/mach-types.h> |
|---|
| 21 | 21 | #include <asm/mach/map.h> |
|---|
| 22 | 22 | #include <asm/hardware/sa1111.h> |
|---|
| 23 | | -#include <asm/sizes.h> |
|---|
| 23 | +#include <linux/sizes.h> |
|---|
| 24 | 24 | |
|---|
| 25 | 25 | #include <mach/hardware.h> |
|---|
| 26 | 26 | #include <mach/assabet.h> |
|---|
| .. | .. |
|---|
| 48 | 48 | #define IRR_SA1111 (1 << 2) |
|---|
| 49 | 49 | |
|---|
| 50 | 50 | #define NCR_NGPIO 7 |
|---|
| 51 | | - |
|---|
| 52 | | -#define MDM_CTL0_RTS1 (1 << 0) |
|---|
| 53 | | -#define MDM_CTL0_DTR1 (1 << 1) |
|---|
| 54 | | -#define MDM_CTL0_RTS2 (1 << 2) |
|---|
| 55 | | -#define MDM_CTL0_DTR2 (1 << 3) |
|---|
| 56 | 51 | #define MDM_CTL0_NGPIO 4 |
|---|
| 57 | | - |
|---|
| 58 | | -#define MDM_CTL1_CTS1 (1 << 0) |
|---|
| 59 | | -#define MDM_CTL1_DSR1 (1 << 1) |
|---|
| 60 | | -#define MDM_CTL1_DCD1 (1 << 2) |
|---|
| 61 | | -#define MDM_CTL1_CTS2 (1 << 3) |
|---|
| 62 | | -#define MDM_CTL1_DSR2 (1 << 4) |
|---|
| 63 | | -#define MDM_CTL1_DCD2 (1 << 5) |
|---|
| 64 | 52 | #define MDM_CTL1_NGPIO 6 |
|---|
| 65 | | - |
|---|
| 66 | | -#define AUD_SEL_1341 (1 << 0) |
|---|
| 67 | | -#define AUD_MUTE_1341 (1 << 1) |
|---|
| 68 | 53 | #define AUD_NGPIO 2 |
|---|
| 69 | 54 | |
|---|
| 70 | 55 | extern void sa1110_mb_disable(void); |
|---|
| .. | .. |
|---|
| 96 | 81 | struct gpio_chip *gpio[4]; |
|---|
| 97 | 82 | }; |
|---|
| 98 | 83 | |
|---|
| 84 | +static struct gpiod_lookup_table neponset_uart1_gpio_table = { |
|---|
| 85 | + .dev_id = "sa11x0-uart.1", |
|---|
| 86 | + .table = { |
|---|
| 87 | + GPIO_LOOKUP("neponset-mdm-ctl0", 2, "rts", GPIO_ACTIVE_LOW), |
|---|
| 88 | + GPIO_LOOKUP("neponset-mdm-ctl0", 3, "dtr", GPIO_ACTIVE_LOW), |
|---|
| 89 | + GPIO_LOOKUP("neponset-mdm-ctl1", 3, "cts", GPIO_ACTIVE_LOW), |
|---|
| 90 | + GPIO_LOOKUP("neponset-mdm-ctl1", 4, "dsr", GPIO_ACTIVE_LOW), |
|---|
| 91 | + GPIO_LOOKUP("neponset-mdm-ctl1", 5, "dcd", GPIO_ACTIVE_LOW), |
|---|
| 92 | + { }, |
|---|
| 93 | + }, |
|---|
| 94 | +}; |
|---|
| 95 | + |
|---|
| 96 | +static struct gpiod_lookup_table neponset_uart3_gpio_table = { |
|---|
| 97 | + .dev_id = "sa11x0-uart.3", |
|---|
| 98 | + .table = { |
|---|
| 99 | + GPIO_LOOKUP("neponset-mdm-ctl0", 0, "rts", GPIO_ACTIVE_LOW), |
|---|
| 100 | + GPIO_LOOKUP("neponset-mdm-ctl0", 1, "dtr", GPIO_ACTIVE_LOW), |
|---|
| 101 | + GPIO_LOOKUP("neponset-mdm-ctl1", 0, "cts", GPIO_ACTIVE_LOW), |
|---|
| 102 | + GPIO_LOOKUP("neponset-mdm-ctl1", 1, "dsr", GPIO_ACTIVE_LOW), |
|---|
| 103 | + GPIO_LOOKUP("neponset-mdm-ctl1", 2, "dcd", GPIO_ACTIVE_LOW), |
|---|
| 104 | + { }, |
|---|
| 105 | + }, |
|---|
| 106 | +}; |
|---|
| 107 | + |
|---|
| 108 | +static struct gpiod_lookup_table neponset_pcmcia_table = { |
|---|
| 109 | + .dev_id = "1800", |
|---|
| 110 | + .table = { |
|---|
| 111 | + GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH), |
|---|
| 112 | + GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH), |
|---|
| 113 | + GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH), |
|---|
| 114 | + GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH), |
|---|
| 115 | + GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH), |
|---|
| 116 | + GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH), |
|---|
| 117 | + { }, |
|---|
| 118 | + }, |
|---|
| 119 | +}; |
|---|
| 120 | + |
|---|
| 99 | 121 | static struct neponset_drvdata *nep; |
|---|
| 100 | 122 | |
|---|
| 101 | 123 | void neponset_ncr_frob(unsigned int mask, unsigned int val) |
|---|
| .. | .. |
|---|
| 109 | 131 | WARN(1, "nep unset\n"); |
|---|
| 110 | 132 | } |
|---|
| 111 | 133 | EXPORT_SYMBOL(neponset_ncr_frob); |
|---|
| 112 | | - |
|---|
| 113 | | -static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) |
|---|
| 114 | | -{ |
|---|
| 115 | | - struct neponset_drvdata *n = nep; |
|---|
| 116 | | - unsigned long mask, val = 0; |
|---|
| 117 | | - |
|---|
| 118 | | - if (!n) |
|---|
| 119 | | - return; |
|---|
| 120 | | - |
|---|
| 121 | | - if (port->mapbase == _Ser1UTCR0) { |
|---|
| 122 | | - mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2; |
|---|
| 123 | | - |
|---|
| 124 | | - if (!(mctrl & TIOCM_RTS)) |
|---|
| 125 | | - val |= MDM_CTL0_RTS2; |
|---|
| 126 | | - |
|---|
| 127 | | - if (!(mctrl & TIOCM_DTR)) |
|---|
| 128 | | - val |= MDM_CTL0_DTR2; |
|---|
| 129 | | - } else if (port->mapbase == _Ser3UTCR0) { |
|---|
| 130 | | - mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1; |
|---|
| 131 | | - |
|---|
| 132 | | - if (!(mctrl & TIOCM_RTS)) |
|---|
| 133 | | - val |= MDM_CTL0_RTS1; |
|---|
| 134 | | - |
|---|
| 135 | | - if (!(mctrl & TIOCM_DTR)) |
|---|
| 136 | | - val |= MDM_CTL0_DTR1; |
|---|
| 137 | | - } |
|---|
| 138 | | - |
|---|
| 139 | | - n->gpio[1]->set_multiple(n->gpio[1], &mask, &val); |
|---|
| 140 | | -} |
|---|
| 141 | | - |
|---|
| 142 | | -static u_int neponset_get_mctrl(struct uart_port *port) |
|---|
| 143 | | -{ |
|---|
| 144 | | - void __iomem *base = nep->base; |
|---|
| 145 | | - u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; |
|---|
| 146 | | - u_int mdm_ctl1; |
|---|
| 147 | | - |
|---|
| 148 | | - if (!base) |
|---|
| 149 | | - return ret; |
|---|
| 150 | | - |
|---|
| 151 | | - mdm_ctl1 = readb_relaxed(base + MDM_CTL_1); |
|---|
| 152 | | - if (port->mapbase == _Ser1UTCR0) { |
|---|
| 153 | | - if (mdm_ctl1 & MDM_CTL1_DCD2) |
|---|
| 154 | | - ret &= ~TIOCM_CD; |
|---|
| 155 | | - if (mdm_ctl1 & MDM_CTL1_CTS2) |
|---|
| 156 | | - ret &= ~TIOCM_CTS; |
|---|
| 157 | | - if (mdm_ctl1 & MDM_CTL1_DSR2) |
|---|
| 158 | | - ret &= ~TIOCM_DSR; |
|---|
| 159 | | - } else if (port->mapbase == _Ser3UTCR0) { |
|---|
| 160 | | - if (mdm_ctl1 & MDM_CTL1_DCD1) |
|---|
| 161 | | - ret &= ~TIOCM_CD; |
|---|
| 162 | | - if (mdm_ctl1 & MDM_CTL1_CTS1) |
|---|
| 163 | | - ret &= ~TIOCM_CTS; |
|---|
| 164 | | - if (mdm_ctl1 & MDM_CTL1_DSR1) |
|---|
| 165 | | - ret &= ~TIOCM_DSR; |
|---|
| 166 | | - } |
|---|
| 167 | | - |
|---|
| 168 | | - return ret; |
|---|
| 169 | | -} |
|---|
| 170 | | - |
|---|
| 171 | | -static struct sa1100_port_fns neponset_port_fns = { |
|---|
| 172 | | - .set_mctrl = neponset_set_mctrl, |
|---|
| 173 | | - .get_mctrl = neponset_get_mctrl, |
|---|
| 174 | | -}; |
|---|
| 175 | 134 | |
|---|
| 176 | 135 | /* |
|---|
| 177 | 136 | * Install handler for Neponset IRQ. Note that we have to loop here |
|---|
| .. | .. |
|---|
| 374 | 333 | d->base + AUD_CTL, AUD_NGPIO, false, |
|---|
| 375 | 334 | neponset_aud_names); |
|---|
| 376 | 335 | |
|---|
| 336 | + gpiod_add_lookup_table(&neponset_uart1_gpio_table); |
|---|
| 337 | + gpiod_add_lookup_table(&neponset_uart3_gpio_table); |
|---|
| 338 | + gpiod_add_lookup_table(&neponset_pcmcia_table); |
|---|
| 339 | + |
|---|
| 377 | 340 | /* |
|---|
| 378 | 341 | * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately |
|---|
| 379 | 342 | * something on the Neponset activates this IRQ on sleep (eth?) |
|---|
| .. | .. |
|---|
| 385 | 348 | dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n", |
|---|
| 386 | 349 | d->irq_base, d->irq_base + NEP_IRQ_NR - 1); |
|---|
| 387 | 350 | nep = d; |
|---|
| 388 | | - |
|---|
| 389 | | - sa1100_register_uart_fns(&neponset_port_fns); |
|---|
| 390 | 351 | |
|---|
| 391 | 352 | /* Ensure that the memory bus request/grant signals are setup */ |
|---|
| 392 | 353 | sa1110_mb_disable(); |
|---|
| .. | .. |
|---|
| 424 | 385 | platform_device_unregister(d->sa1111); |
|---|
| 425 | 386 | if (!IS_ERR(d->smc91x)) |
|---|
| 426 | 387 | platform_device_unregister(d->smc91x); |
|---|
| 388 | + |
|---|
| 389 | + gpiod_remove_lookup_table(&neponset_pcmcia_table); |
|---|
| 390 | + gpiod_remove_lookup_table(&neponset_uart3_gpio_table); |
|---|
| 391 | + gpiod_remove_lookup_table(&neponset_uart1_gpio_table); |
|---|
| 392 | + |
|---|
| 427 | 393 | irq_set_chained_handler(irq, NULL); |
|---|
| 428 | 394 | irq_free_descs(d->irq_base, NEP_IRQ_NR); |
|---|
| 429 | 395 | nep = NULL; |
|---|