vf_gpio.c (266152) | vf_gpio.c (266274) |
---|---|
1/*- 2 * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 */ 26 27/* 28 * Vybrid Family General-Purpose Input/Output (GPIO) 29 * Chapter 7, Vybrid Reference Manual, Rev. 5, 07/2013 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 */ 26 27/* 28 * Vybrid Family General-Purpose Input/Output (GPIO) 29 * Chapter 7, Vybrid Reference Manual, Rev. 5, 07/2013 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_gpio.c 266152 2014-05-15 16:11:06Z ian $"); | 33__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_gpio.c 266274 2014-05-16 23:27:18Z ian $"); |
34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/bus.h> 38#include <sys/kernel.h> 39#include <sys/module.h> 40#include <sys/malloc.h> 41#include <sys/rman.h> --- 11 unchanged lines hidden (view full) --- 53#include <machine/bus.h> 54#include <machine/fdt.h> 55#include <machine/cpu.h> 56#include <machine/intr.h> 57 58#include "gpio_if.h" 59 60#include <arm/freescale/vybrid/vf_common.h> | 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/bus.h> 38#include <sys/kernel.h> 39#include <sys/module.h> 40#include <sys/malloc.h> 41#include <sys/rman.h> --- 11 unchanged lines hidden (view full) --- 53#include <machine/bus.h> 54#include <machine/fdt.h> 55#include <machine/cpu.h> 56#include <machine/intr.h> 57 58#include "gpio_if.h" 59 60#include <arm/freescale/vybrid/vf_common.h> |
61#include <arm/freescale/vybrid/vf_port.h> |
|
61 62#define GPIO_PDOR(n) (0x00 + 0x40 * (n >> 5)) 63#define GPIO_PSOR(n) (0x04 + 0x40 * (n >> 5)) 64#define GPIO_PCOR(n) (0x08 + 0x40 * (n >> 5)) 65#define GPIO_PTOR(n) (0x0C + 0x40 * (n >> 5)) 66#define GPIO_PDIR(n) (0x10 + 0x40 * (n >> 5)) 67 68#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 69#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 70 | 62 63#define GPIO_PDOR(n) (0x00 + 0x40 * (n >> 5)) 64#define GPIO_PSOR(n) (0x04 + 0x40 * (n >> 5)) 65#define GPIO_PCOR(n) (0x08 + 0x40 * (n >> 5)) 66#define GPIO_PTOR(n) (0x0C + 0x40 * (n >> 5)) 67#define GPIO_PDIR(n) (0x10 + 0x40 * (n >> 5)) 68 69#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 70#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 71 |
71#define NPORTS 5 72#define NGPIO (NPORTS * 32) | |
73#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) 74 75/* 76 * GPIO interface 77 */ 78static int vf_gpio_pin_max(device_t, int *); 79static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); 80static int vf_gpio_pin_getname(device_t, uint32_t, char *); 81static int vf_gpio_pin_getflags(device_t, uint32_t, uint32_t *); 82static int vf_gpio_pin_setflags(device_t, uint32_t, uint32_t); 83static int vf_gpio_pin_set(device_t, uint32_t, unsigned int); 84static int vf_gpio_pin_get(device_t, uint32_t, unsigned int *); 85static int vf_gpio_pin_toggle(device_t, uint32_t pin); 86 87struct vf_gpio_softc { | 72#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) 73 74/* 75 * GPIO interface 76 */ 77static int vf_gpio_pin_max(device_t, int *); 78static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); 79static int vf_gpio_pin_getname(device_t, uint32_t, char *); 80static int vf_gpio_pin_getflags(device_t, uint32_t, uint32_t *); 81static int vf_gpio_pin_setflags(device_t, uint32_t, uint32_t); 82static int vf_gpio_pin_set(device_t, uint32_t, unsigned int); 83static int vf_gpio_pin_get(device_t, uint32_t, unsigned int *); 84static int vf_gpio_pin_toggle(device_t, uint32_t pin); 85 86struct vf_gpio_softc { |
88 struct resource *res[6]; | 87 struct resource *res[1]; |
89 bus_space_tag_t bst; 90 bus_space_handle_t bsh; 91 92 struct mtx sc_mtx; 93 int gpio_npins; 94 struct gpio_pin gpio_pins[NGPIO]; | 88 bus_space_tag_t bst; 89 bus_space_handle_t bsh; 90 91 struct mtx sc_mtx; 92 int gpio_npins; 93 struct gpio_pin gpio_pins[NGPIO]; |
95 void *gpio_ih[NPORTS]; | |
96}; 97 98struct vf_gpio_softc *gpio_sc; 99 100static struct resource_spec vf_gpio_spec[] = { 101 { SYS_RES_MEMORY, 0, RF_ACTIVE }, | 94}; 95 96struct vf_gpio_softc *gpio_sc; 97 98static struct resource_spec vf_gpio_spec[] = { 99 { SYS_RES_MEMORY, 0, RF_ACTIVE }, |
102 { SYS_RES_IRQ, 0, RF_ACTIVE }, 103 { SYS_RES_IRQ, 1, RF_ACTIVE }, 104 { SYS_RES_IRQ, 2, RF_ACTIVE }, 105 { SYS_RES_IRQ, 3, RF_ACTIVE }, 106 { SYS_RES_IRQ, 4, RF_ACTIVE }, | |
107 { -1, 0 } 108}; 109 110static int | 100 { -1, 0 } 101}; 102 103static int |
111vf_gpio_intr(void *arg) 112{ 113 struct vf_gpio_softc *sc; 114 sc = arg; 115 116 /* TODO: interrupt handling */ 117 118 return (FILTER_HANDLED); 119} 120 121 122static int | |
123vf_gpio_probe(device_t dev) 124{ 125 126 if (!ofw_bus_status_okay(dev)) 127 return (ENXIO); 128 129 if (!ofw_bus_is_compatible(dev, "fsl,mvf600-gpio")) 130 return (ENXIO); 131 132 device_set_desc(dev, "Vybrid Family GPIO Unit"); 133 return (BUS_PROBE_DEFAULT); 134} 135 136static int 137vf_gpio_attach(device_t dev) 138{ 139 struct vf_gpio_softc *sc; | 104vf_gpio_probe(device_t dev) 105{ 106 107 if (!ofw_bus_status_okay(dev)) 108 return (ENXIO); 109 110 if (!ofw_bus_is_compatible(dev, "fsl,mvf600-gpio")) 111 return (ENXIO); 112 113 device_set_desc(dev, "Vybrid Family GPIO Unit"); 114 return (BUS_PROBE_DEFAULT); 115} 116 117static int 118vf_gpio_attach(device_t dev) 119{ 120 struct vf_gpio_softc *sc; |
140 int irq, i; | 121 int i; |
141 142 sc = device_get_softc(dev); 143 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 144 145 if (bus_alloc_resources(dev, vf_gpio_spec, sc->res)) { 146 device_printf(dev, "could not allocate resources\n"); 147 return (ENXIO); 148 } 149 | 122 123 sc = device_get_softc(dev); 124 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 125 126 if (bus_alloc_resources(dev, vf_gpio_spec, sc->res)) { 127 device_printf(dev, "could not allocate resources\n"); 128 return (ENXIO); 129 } 130 |
150 gpio_sc = sc; 151 | |
152 /* Memory interface */ 153 sc->bst = rman_get_bustag(sc->res[0]); 154 sc->bsh = rman_get_bushandle(sc->res[0]); 155 | 131 /* Memory interface */ 132 sc->bst = rman_get_bustag(sc->res[0]); 133 sc->bsh = rman_get_bushandle(sc->res[0]); 134 |
135 gpio_sc = sc; 136 |
|
156 sc->gpio_npins = NGPIO; 157 | 137 sc->gpio_npins = NGPIO; 138 |
158 for (irq = 0; irq < NPORTS; irq ++) { 159 if ((bus_setup_intr(dev, sc->res[1 + irq], INTR_TYPE_MISC, 160 vf_gpio_intr, NULL, sc, &sc->gpio_ih[irq]))) { 161 device_printf(dev, 162 "WARNING: unable to register interrupt handler\n"); 163 return (ENXIO); 164 } 165 } 166 | |
167 for (i = 0; i < sc->gpio_npins; i++) { 168 sc->gpio_pins[i].gp_pin = i; 169 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 170 sc->gpio_pins[i].gp_flags = 171 (READ4(sc, GPIO_PDOR(i)) & (1 << (i % 32))) ? 172 GPIO_PIN_OUTPUT: GPIO_PIN_INPUT; 173 snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, 174 "vf_gpio%d.%d", device_get_unit(dev), i); --- 232 unchanged lines hidden --- | 139 for (i = 0; i < sc->gpio_npins; i++) { 140 sc->gpio_pins[i].gp_pin = i; 141 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 142 sc->gpio_pins[i].gp_flags = 143 (READ4(sc, GPIO_PDOR(i)) & (1 << (i % 32))) ? 144 GPIO_PIN_OUTPUT: GPIO_PIN_INPUT; 145 snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, 146 "vf_gpio%d.%d", device_get_unit(dev), i); --- 232 unchanged lines hidden --- |