xref: /freebsd/sys/dev/gpio/gpiobusvar.h (revision bc0d10d01c3c69004d600e14d53cd0dceffe4b09)
16b34b16eSOleksandr Tymoshenko /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
46b34b16eSOleksandr Tymoshenko  * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
56b34b16eSOleksandr Tymoshenko  * All rights reserved.
66b34b16eSOleksandr Tymoshenko  *
76b34b16eSOleksandr Tymoshenko  * Redistribution and use in source and binary forms, with or without
86b34b16eSOleksandr Tymoshenko  * modification, are permitted provided that the following conditions
96b34b16eSOleksandr Tymoshenko  * are met:
106b34b16eSOleksandr Tymoshenko  * 1. Redistributions of source code must retain the above copyright
116b34b16eSOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer.
126b34b16eSOleksandr Tymoshenko  * 2. Redistributions in binary form must reproduce the above copyright
136b34b16eSOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer in the
146b34b16eSOleksandr Tymoshenko  *    documentation and/or other materials provided with the distribution.
156b34b16eSOleksandr Tymoshenko  *
165f958b85SOleksandr Tymoshenko  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
175f958b85SOleksandr Tymoshenko  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185f958b85SOleksandr Tymoshenko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
195f958b85SOleksandr Tymoshenko  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
205f958b85SOleksandr Tymoshenko  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215f958b85SOleksandr Tymoshenko  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
225f958b85SOleksandr Tymoshenko  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
235f958b85SOleksandr Tymoshenko  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245f958b85SOleksandr Tymoshenko  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
255f958b85SOleksandr Tymoshenko  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
265f958b85SOleksandr Tymoshenko  * SUCH DAMAGE.
276b34b16eSOleksandr Tymoshenko  *
286b34b16eSOleksandr Tymoshenko  */
296b34b16eSOleksandr Tymoshenko 
306b34b16eSOleksandr Tymoshenko #ifndef	__GPIOBUS_H__
316b34b16eSOleksandr Tymoshenko #define	__GPIOBUS_H__
326b34b16eSOleksandr Tymoshenko 
336d866ed3SLuiz Otavio O Souza #include "opt_platform.h"
346d866ed3SLuiz Otavio O Souza 
356b34b16eSOleksandr Tymoshenko #include <sys/lock.h>
366b34b16eSOleksandr Tymoshenko #include <sys/mutex.h>
37138bf909SLuiz Otavio O Souza #include <sys/rman.h>
386b34b16eSOleksandr Tymoshenko 
396d866ed3SLuiz Otavio O Souza #ifdef FDT
406d866ed3SLuiz Otavio O Souza #include <dev/ofw/ofw_bus_subr.h>
416d866ed3SLuiz Otavio O Souza #endif
426d866ed3SLuiz Otavio O Souza 
4301decb50SAdrian Chadd #ifdef	INTRNG
4401decb50SAdrian Chadd #include <sys/intr.h>
4501decb50SAdrian Chadd #endif
4601decb50SAdrian Chadd 
478d250595SLuiz Otavio O Souza #include "gpio_if.h"
488d250595SLuiz Otavio O Souza 
49b09d4398SLuiz Otavio O Souza #ifdef FDT
50b09d4398SLuiz Otavio O Souza #define	GPIOBUS_IVAR(d) (struct gpiobus_ivar *)				\
51b09d4398SLuiz Otavio O Souza 	&((struct ofw_gpiobus_devinfo *)device_get_ivars(d))->opd_dinfo
52b09d4398SLuiz Otavio O Souza #else
536b34b16eSOleksandr Tymoshenko #define	GPIOBUS_IVAR(d) (struct gpiobus_ivar *) device_get_ivars(d)
54b09d4398SLuiz Otavio O Souza #endif
556b34b16eSOleksandr Tymoshenko #define	GPIOBUS_SOFTC(d) (struct gpiobus_softc *) device_get_softc(d)
566d866ed3SLuiz Otavio O Souza #define	GPIOBUS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
576d866ed3SLuiz Otavio O Souza #define	GPIOBUS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
586d866ed3SLuiz Otavio O Souza #define	GPIOBUS_LOCK_INIT(_sc) mtx_init(&_sc->sc_mtx,			\
596d866ed3SLuiz Otavio O Souza 	    device_get_nameunit(_sc->sc_dev), "gpiobus", MTX_DEF)
606d866ed3SLuiz Otavio O Souza #define	GPIOBUS_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx)
616d866ed3SLuiz Otavio O Souza #define	GPIOBUS_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED)
626d866ed3SLuiz Otavio O Souza #define	GPIOBUS_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED)
636b34b16eSOleksandr Tymoshenko 
649d35acacSLuiz Otavio O Souza #define	GPIOBUS_WAIT		1
659d35acacSLuiz Otavio O Souza #define	GPIOBUS_DONTWAIT	2
669d35acacSLuiz Otavio O Souza 
6739f6c1bdSMichal Meloun /* Use default interrupt mode -  for gpio_alloc_intr_resource */
6839f6c1bdSMichal Meloun #define GPIO_INTR_CONFORM	GPIO_INTR_NONE
6939f6c1bdSMichal Meloun 
70d752f0f6SLuiz Otavio O Souza struct gpiobus_pin_data
71d752f0f6SLuiz Otavio O Souza {
72d752f0f6SLuiz Otavio O Souza 	int		mapped;		/* pin is mapped/reserved. */
73d752f0f6SLuiz Otavio O Souza 	char		*name;		/* pin name. */
74d752f0f6SLuiz Otavio O Souza };
75d752f0f6SLuiz Otavio O Souza 
76895c8b1cSMichal Meloun #ifdef INTRNG
77949883bdSMichal Meloun struct intr_map_data_gpio {
78949883bdSMichal Meloun 	struct intr_map_data	hdr;
79949883bdSMichal Meloun 	u_int			gpio_pin_num;
80949883bdSMichal Meloun 	u_int			gpio_pin_flags;
81949883bdSMichal Meloun 	u_int		 	gpio_intr_mode;
82949883bdSMichal Meloun };
83895c8b1cSMichal Meloun #endif
84949883bdSMichal Meloun 
856b34b16eSOleksandr Tymoshenko struct gpiobus_softc
866b34b16eSOleksandr Tymoshenko {
876b34b16eSOleksandr Tymoshenko 	struct mtx	sc_mtx;		/* bus mutex */
88138bf909SLuiz Otavio O Souza 	struct rman	sc_intr_rman;	/* isr resources */
896b34b16eSOleksandr Tymoshenko 	device_t	sc_busdev;	/* bus device */
906b34b16eSOleksandr Tymoshenko 	device_t	sc_owner;	/* bus owner */
916b34b16eSOleksandr Tymoshenko 	device_t	sc_dev;		/* driver device */
926b34b16eSOleksandr Tymoshenko 	int		sc_npins;	/* total pins on bus */
93d752f0f6SLuiz Otavio O Souza 	struct gpiobus_pin_data	*sc_pins; /* pin data */
946b34b16eSOleksandr Tymoshenko };
956b34b16eSOleksandr Tymoshenko 
96e8da3e8aSLuiz Otavio O Souza struct gpiobus_pin
97e8da3e8aSLuiz Otavio O Souza {
98e8da3e8aSLuiz Otavio O Souza 	device_t	dev;	/* gpio device */
99e8da3e8aSLuiz Otavio O Souza 	uint32_t	flags;	/* pin flags */
100e8da3e8aSLuiz Otavio O Souza 	uint32_t	pin;	/* pin number */
101e8da3e8aSLuiz Otavio O Souza };
1028a4ba038SMichal Meloun typedef struct gpiobus_pin *gpio_pin_t;
103e8da3e8aSLuiz Otavio O Souza 
1046b34b16eSOleksandr Tymoshenko struct gpiobus_ivar
1056b34b16eSOleksandr Tymoshenko {
106138bf909SLuiz Otavio O Souza 	struct resource_list	rl;	/* isr resource list */
1076b34b16eSOleksandr Tymoshenko 	uint32_t	npins;	/* pins total */
1086b34b16eSOleksandr Tymoshenko 	uint32_t	*pins;	/* pins map */
1096b34b16eSOleksandr Tymoshenko };
1106b34b16eSOleksandr Tymoshenko 
111061b38cdSAndriy Gapon enum gpiobus_ivars {
112061b38cdSAndriy Gapon 	GPIOBUS_IVAR_NPINS	= 10500,
113061b38cdSAndriy Gapon 	GPIOBUS_IVAR_PINS,
114061b38cdSAndriy Gapon };
115061b38cdSAndriy Gapon 
116061b38cdSAndriy Gapon #define GPIOBUS_ACCESSOR(var, ivar, type)                                 \
117061b38cdSAndriy Gapon         __BUS_ACCESSOR(gpiobus, var, GPIOBUS, ivar, type)
118061b38cdSAndriy Gapon 
119061b38cdSAndriy Gapon GPIOBUS_ACCESSOR(npins,		NPINS,		uint32_t)
120061b38cdSAndriy Gapon GPIOBUS_ACCESSOR(pins,		PINS,		const uint32_t *)
121061b38cdSAndriy Gapon 
122061b38cdSAndriy Gapon #undef GPIOBUS_ACCESSOR
123061b38cdSAndriy Gapon 
1246d866ed3SLuiz Otavio O Souza #ifdef FDT
125628a40b5SLuiz Otavio O Souza struct ofw_gpiobus_devinfo {
126628a40b5SLuiz Otavio O Souza 	struct gpiobus_ivar	opd_dinfo;
127628a40b5SLuiz Otavio O Souza 	struct ofw_bus_devinfo	opd_obdinfo;
128628a40b5SLuiz Otavio O Souza };
129628a40b5SLuiz Otavio O Souza 
1308d250595SLuiz Otavio O Souza static __inline int
gpio_map_gpios(device_t bus,phandle_t dev,phandle_t gparent,int gcells,pcell_t * gpios,uint32_t * pin,uint32_t * flags)1318d250595SLuiz Otavio O Souza gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
1328d250595SLuiz Otavio O Souza     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
1338d250595SLuiz Otavio O Souza {
1348d250595SLuiz Otavio O Souza 	return (GPIO_MAP_GPIOS(bus, dev, gparent, gcells, gpios, pin, flags));
1358d250595SLuiz Otavio O Souza }
1368d250595SLuiz Otavio O Souza 
137e8da3e8aSLuiz Otavio O Souza device_t ofw_gpiobus_add_fdt_child(device_t, const char *, phandle_t);
138e8da3e8aSLuiz Otavio O Souza int ofw_gpiobus_parse_gpios(device_t, char *, struct gpiobus_pin **);
139dbdb1205SLuiz Otavio O Souza void ofw_gpiobus_register_provider(device_t);
140dbdb1205SLuiz Otavio O Souza void ofw_gpiobus_unregister_provider(device_t);
1418a4ba038SMichal Meloun 
14237045806SIan Lepore /* Acquire a pin by parsing FDT data. */
14351702162SOleksandr Tymoshenko int gpio_pin_get_by_ofw_name(device_t consumer, phandle_t node,
14451702162SOleksandr Tymoshenko     char *name, gpio_pin_t *gpio);
14551702162SOleksandr Tymoshenko int gpio_pin_get_by_ofw_idx(device_t consumer, phandle_t node,
14651702162SOleksandr Tymoshenko     int idx, gpio_pin_t *gpio);
14751702162SOleksandr Tymoshenko int gpio_pin_get_by_ofw_property(device_t consumer, phandle_t node,
14851702162SOleksandr Tymoshenko     char *name, gpio_pin_t *gpio);
149dc027dc6SIan Lepore int gpio_pin_get_by_ofw_propidx(device_t consumer, phandle_t node,
150dc027dc6SIan Lepore     char *name, int idx, gpio_pin_t *gpio);
15137045806SIan Lepore #endif /* FDT */
15237045806SIan Lepore 
15337045806SIan Lepore /* Acquire a pin by bus and pin number. */
15437045806SIan Lepore int gpio_pin_get_by_bus_pinnum(device_t _bus, uint32_t _pinnum, gpio_pin_t *_gp);
15537045806SIan Lepore 
15637045806SIan Lepore /* Acquire a pin by child and index (used by direct children of gpiobus). */
15737045806SIan Lepore int gpio_pin_get_by_child_index(device_t _child, uint32_t _idx, gpio_pin_t *_gp);
15837045806SIan Lepore 
15937045806SIan Lepore /* Release a pin acquired via any gpio_pin_get_xxx() function. */
1608a4ba038SMichal Meloun void gpio_pin_release(gpio_pin_t gpio);
16137045806SIan Lepore 
16237045806SIan Lepore /* Work with gpio pins acquired using the functions above. */
1635030d499SIan Lepore int gpio_pin_getcaps(gpio_pin_t pin, uint32_t *caps);
1648a4ba038SMichal Meloun int gpio_pin_is_active(gpio_pin_t pin, bool *active);
1658a4ba038SMichal Meloun int gpio_pin_set_active(gpio_pin_t pin, bool active);
1668a4ba038SMichal Meloun int gpio_pin_setflags(gpio_pin_t pin, uint32_t flags);
16739f6c1bdSMichal Meloun struct resource *gpio_alloc_intr_resource(device_t consumer_dev, int *rid,
16839f6c1bdSMichal Meloun     u_int alloc_flags, gpio_pin_t pin, uint32_t intr_mode);
16937045806SIan Lepore 
17037045806SIan Lepore /*
17137045806SIan Lepore  * Functions shared between gpiobus and other bus classes that derive from it;
17237045806SIan Lepore  * these should not be called directly by other drivers.
17337045806SIan Lepore  */
174667357dcSLuiz Otavio O Souza int gpio_check_flags(uint32_t, uint32_t);
1757836352bSLuiz Otavio O Souza device_t gpiobus_attach_bus(device_t);
1767836352bSLuiz Otavio O Souza int gpiobus_detach_bus(device_t);
17792adaa58SAhmad Khalifa int gpiobus_attach(device_t);
17892adaa58SAhmad Khalifa int gpiobus_detach(device_t);
17988516632SLuiz Otavio O Souza int gpiobus_init_softc(device_t);
18050196301SLuiz Otavio O Souza int gpiobus_alloc_ivars(struct gpiobus_ivar *);
18150196301SLuiz Otavio O Souza void gpiobus_free_ivars(struct gpiobus_ivar *);
182*bc0d10d0SColin Percival int gpiobus_read_ivar(device_t, device_t, int, uintptr_t *);
183c45b8422SIan Lepore int gpiobus_acquire_pin(device_t, uint32_t);
1843381a389SOleksandr Tymoshenko int gpiobus_release_pin(device_t, uint32_t);
1856d866ed3SLuiz Otavio O Souza 
1866d866ed3SLuiz Otavio O Souza extern driver_t gpiobus_driver;
1876d866ed3SLuiz Otavio O Souza 
1886b34b16eSOleksandr Tymoshenko #endif	/* __GPIOBUS_H__ */
189