2 * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs
4 * Copyright 2009-2011 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/module.h>
10 #include <linux/err.h>
11 #include <asm/blackfin.h>
13 #include <asm/portmux.h>
15 #define DEFINE_REG(reg, off) \
16 static inline u16 read_##reg(void __iomem *port) \
17 { return bfin_read16(port + off); } \
18 static inline void write_##reg(void __iomem *port, u16 v) \
19 { bfin_write16(port + off, v); }
21 DEFINE_REG(PORTIO
, 0x00)
22 DEFINE_REG(PORTIO_CLEAR
, 0x10)
23 DEFINE_REG(PORTIO_SET
, 0x20)
24 DEFINE_REG(PORTIO_DIR
, 0x40)
25 DEFINE_REG(PORTIO_INEN
, 0x50)
27 static void __iomem
*gpio_chip_to_mmr(struct gpio_chip
*chip
)
30 default: /* not really needed, but keeps gcc happy */
31 case GPIO_PC0
: return (void __iomem
*)PORTCIO
;
32 case GPIO_PD0
: return (void __iomem
*)PORTDIO
;
33 case GPIO_PE0
: return (void __iomem
*)PORTEIO
;
37 static int bf538_gpio_get_value(struct gpio_chip
*chip
, unsigned gpio
)
39 void __iomem
*port
= gpio_chip_to_mmr(chip
);
40 return !!(read_PORTIO(port
) & (1u << gpio
));
43 static void bf538_gpio_set_value(struct gpio_chip
*chip
, unsigned gpio
, int value
)
45 void __iomem
*port
= gpio_chip_to_mmr(chip
);
47 write_PORTIO_SET(port
, (1u << gpio
));
49 write_PORTIO_CLEAR(port
, (1u << gpio
));
52 static int bf538_gpio_direction_input(struct gpio_chip
*chip
, unsigned gpio
)
54 void __iomem
*port
= gpio_chip_to_mmr(chip
);
55 write_PORTIO_DIR(port
, read_PORTIO_DIR(port
) & ~(1u << gpio
));
56 write_PORTIO_INEN(port
, read_PORTIO_INEN(port
) | (1u << gpio
));
60 static int bf538_gpio_direction_output(struct gpio_chip
*chip
, unsigned gpio
, int value
)
62 void __iomem
*port
= gpio_chip_to_mmr(chip
);
63 write_PORTIO_INEN(port
, read_PORTIO_INEN(port
) & ~(1u << gpio
));
64 bf538_gpio_set_value(port
, gpio
, value
);
65 write_PORTIO_DIR(port
, read_PORTIO_DIR(port
) | (1u << gpio
));
69 static int bf538_gpio_request(struct gpio_chip
*chip
, unsigned gpio
)
71 return bfin_special_gpio_request(chip
->base
+ gpio
, chip
->label
);
74 static void bf538_gpio_free(struct gpio_chip
*chip
, unsigned gpio
)
76 return bfin_special_gpio_free(chip
->base
+ gpio
);
79 /* We don't set the irq fields as these banks cannot generate interrupts */
81 static struct gpio_chip bf538_portc_chip
= {
83 .direction_input
= bf538_gpio_direction_input
,
84 .get
= bf538_gpio_get_value
,
85 .direction_output
= bf538_gpio_direction_output
,
86 .set
= bf538_gpio_set_value
,
87 .request
= bf538_gpio_request
,
88 .free
= bf538_gpio_free
,
90 .ngpio
= GPIO_PC9
- GPIO_PC0
+ 1,
93 static struct gpio_chip bf538_portd_chip
= {
95 .direction_input
= bf538_gpio_direction_input
,
96 .get
= bf538_gpio_get_value
,
97 .direction_output
= bf538_gpio_direction_output
,
98 .set
= bf538_gpio_set_value
,
99 .request
= bf538_gpio_request
,
100 .free
= bf538_gpio_free
,
102 .ngpio
= GPIO_PD13
- GPIO_PD0
+ 1,
105 static struct gpio_chip bf538_porte_chip
= {
107 .direction_input
= bf538_gpio_direction_input
,
108 .get
= bf538_gpio_get_value
,
109 .direction_output
= bf538_gpio_direction_output
,
110 .set
= bf538_gpio_set_value
,
111 .request
= bf538_gpio_request
,
112 .free
= bf538_gpio_free
,
114 .ngpio
= GPIO_PE15
- GPIO_PE0
+ 1,
117 static int __init
bf538_extgpio_setup(void)
119 return gpiochip_add(&bf538_portc_chip
) |
120 gpiochip_add(&bf538_portd_chip
) |
121 gpiochip_add(&bf538_porte_chip
);
123 arch_initcall(bf538_extgpio_setup
);
128 } gpio_bank_saved
[3];
130 static void __iomem
* const port_bases
[3] = {
136 void bfin_special_gpio_pm_hibernate_suspend(void)
140 for (i
= 0; i
< ARRAY_SIZE(port_bases
); ++i
) {
141 gpio_bank_saved
[i
].data
= read_PORTIO(port_bases
[i
]);
142 gpio_bank_saved
[i
].inen
= read_PORTIO_INEN(port_bases
[i
]);
143 gpio_bank_saved
[i
].dir
= read_PORTIO_DIR(port_bases
[i
]);
147 void bfin_special_gpio_pm_hibernate_restore(void)
151 for (i
= 0; i
< ARRAY_SIZE(port_bases
); ++i
) {
152 write_PORTIO_INEN(port_bases
[i
], gpio_bank_saved
[i
].inen
);
153 write_PORTIO_SET(port_bases
[i
],
154 gpio_bank_saved
[i
].data
& gpio_bank_saved
[i
].dir
);
155 write_PORTIO_DIR(port_bases
[i
], gpio_bank_saved
[i
].dir
);