Deleted Added
full compact
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 ---