Lines 64-71
__FBSDID("$FreeBSD$");
Link Here
|
64 |
#endif |
64 |
#endif |
65 |
|
65 |
|
66 |
#define BCM_GPIO_IRQS 4 |
66 |
#define BCM_GPIO_IRQS 4 |
67 |
#define BCM_GPIO_PINS 54 |
|
|
68 |
#define BCM_GPIO_PINS_PER_BANK 32 |
67 |
#define BCM_GPIO_PINS_PER_BANK 32 |
|
|
68 |
#define BCM2835_GPIO_PINS 54 |
69 |
#define BCM2711_GPIO_PINS 58 |
70 |
#define BCM_GPIO_PINS BCM2711_GPIO_PINS |
69 |
|
71 |
|
70 |
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ |
72 |
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ |
71 |
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \ |
73 |
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \ |
Lines 85-90
__FBSDID("$FreeBSD$");
Link Here
|
85 |
#define BCM2835_PUD_DOWN 1 |
87 |
#define BCM2835_PUD_DOWN 1 |
86 |
#define BCM2835_PUD_UP 2 |
88 |
#define BCM2835_PUD_UP 2 |
87 |
|
89 |
|
|
|
90 |
#define BCM2711_PUD_OFF 0 |
91 |
#define BCM2711_PUD_DOWN 2 |
92 |
#define BCM2711_PUD_UP 1 |
93 |
|
88 |
static struct resource_spec bcm_gpio_res_spec[] = { |
94 |
static struct resource_spec bcm_gpio_res_spec[] = { |
89 |
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, |
95 |
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, |
90 |
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* bank 0 interrupt */ |
96 |
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* bank 0 interrupt */ |
Lines 109-114
struct bcm_gpio_softc {
Link Here
|
109 |
device_t sc_busdev; |
115 |
device_t sc_busdev; |
110 |
struct mtx sc_mtx; |
116 |
struct mtx sc_mtx; |
111 |
struct resource * sc_res[BCM_GPIO_IRQS + 1]; |
117 |
struct resource * sc_res[BCM_GPIO_IRQS + 1]; |
|
|
118 |
bool sc_is2711; |
119 |
u_int sc_maxpins; |
112 |
bus_space_tag_t sc_bst; |
120 |
bus_space_tag_t sc_bst; |
113 |
bus_space_handle_t sc_bsh; |
121 |
bus_space_handle_t sc_bsh; |
114 |
void * sc_intrhand[BCM_GPIO_IRQS]; |
122 |
void * sc_intrhand[BCM_GPIO_IRQS]; |
Lines 151-159
enum bcm_gpio_pud {
Link Here
|
151 |
#define BCM_GPIO_GPLEN(_bank) (0x70 + _bank * 4) /* Low Level irq */ |
159 |
#define BCM_GPIO_GPLEN(_bank) (0x70 + _bank * 4) /* Low Level irq */ |
152 |
#define BCM_GPIO_GPAREN(_bank) (0x7c + _bank * 4) /* Async Rising Edge */ |
160 |
#define BCM_GPIO_GPAREN(_bank) (0x7c + _bank * 4) /* Async Rising Edge */ |
153 |
#define BCM_GPIO_GPAFEN(_bank) (0x88 + _bank * 4) /* Async Falling Egde */ |
161 |
#define BCM_GPIO_GPAFEN(_bank) (0x88 + _bank * 4) /* Async Falling Egde */ |
154 |
#define BCM_GPIO_GPPUD(_bank) (0x94) /* Pin Pull up/down */ |
162 |
#define BCM2835_GPIO_GPPUD(_bank) (0x94) /* Pin Pull up/down */ |
155 |
#define BCM_GPIO_GPPUDCLK(_bank) (0x98 + _bank * 4) /* Pin Pull up clock */ |
163 |
#define BCM2835_GPIO_GPPUDCLK(_bank) (0x98 + _bank * 4) /* Pin Pull up clock */ |
156 |
|
164 |
|
|
|
165 |
#define BCM2711_GPIO_GPPUD(x) (0x0e4 + (x) * sizeof(uint32_t)) /* Pin Pull up/down */ |
166 |
#define BCM2711_GPIO_MASK(n) (0x3 << ((n) % 16)*2) |
167 |
#define BCM2711_GPIO_REGID(n) ((n) / 16) |
168 |
|
157 |
static struct ofw_compat_data compat_data[] = { |
169 |
static struct ofw_compat_data compat_data[] = { |
158 |
{"broadcom,bcm2835-gpio", 1}, |
170 |
{"broadcom,bcm2835-gpio", 1}, |
159 |
{"brcm,bcm2835-gpio", 1}, |
171 |
{"brcm,bcm2835-gpio", 1}, |
Lines 289-304
bcm_gpio_set_function(struct bcm_gpio_softc *sc, uint3
Link Here
|
289 |
static void |
301 |
static void |
290 |
bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state) |
302 |
bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state) |
291 |
{ |
303 |
{ |
292 |
uint32_t bank; |
|
|
293 |
|
294 |
/* Must be called with lock held. */ |
304 |
/* Must be called with lock held. */ |
295 |
BCM_GPIO_LOCK_ASSERT(sc); |
305 |
BCM_GPIO_LOCK_ASSERT(sc); |
296 |
|
306 |
|
297 |
bank = BCM_GPIO_BANK(pin); |
307 |
if (sc->sc_is2711 == false) { /* BCM2835 */ |
298 |
BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), state); |
308 |
uint32_t bank; |
299 |
BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), BCM_GPIO_MASK(pin)); |
309 |
|
300 |
BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), 0); |
310 |
bank = BCM_GPIO_BANK(pin); |
301 |
BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0); |
311 |
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUD(0), state); |
|
|
312 |
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUDCLK(bank), BCM_GPIO_MASK(pin)); |
313 |
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUD(0), 0); |
314 |
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUDCLK(bank), 0); |
315 |
} else { /* BCM2711 */ |
316 |
u_int mask = BCM2711_GPIO_MASK(pin); |
317 |
u_int regid = BCM2711_GPIO_REGID(pin); |
318 |
uint32_t reg; |
319 |
|
320 |
switch (state) { |
321 |
case BCM2835_PUD_OFF: |
322 |
state = BCM2711_PUD_OFF; |
323 |
break; |
324 |
case BCM2835_PUD_DOWN: |
325 |
state = BCM2711_PUD_DOWN; |
326 |
break; |
327 |
case BCM2835_PUD_UP: |
328 |
state = BCM2711_PUD_UP; |
329 |
break; |
330 |
} |
331 |
|
332 |
reg = BCM_GPIO_READ(sc, BCM2711_GPIO_GPPUD(regid)); |
333 |
reg &= ~mask; |
334 |
#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) |
335 |
#define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask)) |
336 |
reg |= __SHIFTIN(state, mask); |
337 |
BCM_GPIO_WRITE(sc, BCM2711_GPIO_GPPUD(regid), reg); |
338 |
} |
302 |
} |
339 |
} |
303 |
|
340 |
|
304 |
static void |
341 |
static void |
Lines 376-383
bcm_gpio_get_bus(device_t dev)
Link Here
|
376 |
static int |
413 |
static int |
377 |
bcm_gpio_pin_max(device_t dev, int *maxpin) |
414 |
bcm_gpio_pin_max(device_t dev, int *maxpin) |
378 |
{ |
415 |
{ |
|
|
416 |
struct bcm_gpio_softc *sc; |
379 |
|
417 |
|
380 |
*maxpin = BCM_GPIO_PINS - 1; |
418 |
sc = device_get_softc(dev); |
|
|
419 |
*maxpin = sc->sc_maxpins - 1; |
381 |
return (0); |
420 |
return (0); |
382 |
} |
421 |
} |
383 |
|
422 |
|
Lines 770-785
bcm_gpio_attach(device_t dev)
Link Here
|
770 |
} |
809 |
} |
771 |
sc->sc_bst = rman_get_bustag(sc->sc_res[0]); |
810 |
sc->sc_bst = rman_get_bustag(sc->sc_res[0]); |
772 |
sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); |
811 |
sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); |
773 |
/* Setup the GPIO interrupt handler. */ |
|
|
774 |
if (bcm_gpio_intr_attach(dev)) { |
775 |
device_printf(dev, "unable to setup the gpio irq handler\n"); |
776 |
goto fail; |
777 |
} |
778 |
/* Find our node. */ |
812 |
/* Find our node. */ |
779 |
gpio = ofw_bus_get_node(sc->sc_dev); |
813 |
gpio = ofw_bus_get_node(sc->sc_dev); |
780 |
if (!OF_hasprop(gpio, "gpio-controller")) |
814 |
if (!OF_hasprop(gpio, "gpio-controller")) |
781 |
/* Node is not a GPIO controller. */ |
815 |
/* Node is not a GPIO controller. */ |
782 |
goto fail; |
816 |
goto fail; |
|
|
817 |
/* Guess I'm BCM2711 or not. */ |
818 |
sc->sc_is2711 = ofw_bus_node_is_compatible(gpio, "brcm,bcm2711-gpio") |
819 |
? true : false; |
820 |
sc->sc_maxpins = sc->sc_is2711 ? BCM2711_GPIO_PINS : BCM2835_GPIO_PINS; |
821 |
/* Setup the GPIO interrupt handler. */ |
822 |
if (bcm_gpio_intr_attach(dev)) { |
823 |
device_printf(dev, "unable to setup the gpio irq handler\n"); |
824 |
goto fail; |
825 |
} |
783 |
/* |
826 |
/* |
784 |
* Find the read-only pins. These are pins we never touch or bad |
827 |
* Find the read-only pins. These are pins we never touch or bad |
785 |
* things could happen. |
828 |
* things could happen. |
Lines 787-793
bcm_gpio_attach(device_t dev)
Link Here
|
787 |
if (bcm_gpio_get_reserved_pins(sc) == -1) |
830 |
if (bcm_gpio_get_reserved_pins(sc) == -1) |
788 |
goto fail; |
831 |
goto fail; |
789 |
/* Initialize the software controlled pins. */ |
832 |
/* Initialize the software controlled pins. */ |
790 |
for (i = 0, j = 0; j < BCM_GPIO_PINS; j++) { |
833 |
for (i = 0, j = 0; j < sc->sc_maxpins; j++) { |
791 |
snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, |
834 |
snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, |
792 |
"pin %d", j); |
835 |
"pin %d", j); |
793 |
func = bcm_gpio_get_function(sc, j); |
836 |
func = bcm_gpio_get_function(sc, j); |
Lines 958-964
bcm_gpio_pic_attach(struct bcm_gpio_softc *sc)
Link Here
|
958 |
const char *name; |
1001 |
const char *name; |
959 |
|
1002 |
|
960 |
name = device_get_nameunit(sc->sc_dev); |
1003 |
name = device_get_nameunit(sc->sc_dev); |
961 |
for (irq = 0; irq < BCM_GPIO_PINS; irq++) { |
1004 |
for (irq = 0; irq < sc->sc_maxpins; irq++) { |
962 |
sc->sc_isrcs[irq].bgi_irq = irq; |
1005 |
sc->sc_isrcs[irq].bgi_irq = irq; |
963 |
sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq); |
1006 |
sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq); |
964 |
sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_CONFORM; |
1007 |
sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_CONFORM; |
Lines 1046-1052
bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, struct
Link Here
|
1046 |
return (EINVAL); |
1089 |
return (EINVAL); |
1047 |
|
1090 |
|
1048 |
irq = daf->cells[0]; |
1091 |
irq = daf->cells[0]; |
1049 |
if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq)) |
1092 |
if (irq >= sc->sc_maxpins || bcm_gpio_pin_is_ro(sc, irq)) |
1050 |
return (EINVAL); |
1093 |
return (EINVAL); |
1051 |
|
1094 |
|
1052 |
/* Only reasonable modes are supported. */ |
1095 |
/* Only reasonable modes are supported. */ |
Lines 1077-1083
bcm_gpio_pic_map_gpio(struct bcm_gpio_softc *sc, struc
Link Here
|
1077 |
uint32_t mode; |
1120 |
uint32_t mode; |
1078 |
|
1121 |
|
1079 |
irq = dag->gpio_pin_num; |
1122 |
irq = dag->gpio_pin_num; |
1080 |
if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq)) |
1123 |
if (irq >= sc->sc_maxpins || bcm_gpio_pin_is_ro(sc, irq)) |
1081 |
return (EINVAL); |
1124 |
return (EINVAL); |
1082 |
|
1125 |
|
1083 |
mode = dag->gpio_intr_mode; |
1126 |
mode = dag->gpio_intr_mode; |