iPXE
gpio.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <ipxe/gpio.h>
29 
30 /** @file
31  *
32  * General purpose I/O
33  *
34  */
35 
36 /** List of GPIO controllers */
37 static LIST_HEAD ( all_gpios );
38 
39 /**
40  * Allocate GPIO controller
41  *
42  * @v count Number of GPIO pins
43  * @v priv_len Size of driver-private data
44  * @ret gpios GPIO controller, or NULL
45  */
46 struct gpios * alloc_gpios ( unsigned int count, size_t priv_len ) {
47  struct gpios *gpios;
48  struct gpio *gpio;
49  size_t len;
50  unsigned int i;
51 
52  /* Allocate and initialise structure */
53  len = ( sizeof ( *gpios ) + ( count * sizeof ( *gpio ) ) + priv_len );
54  gpios = zalloc ( len );
55  if ( ! gpios )
56  return NULL;
57  gpios->count = count;
58  gpios->gpio = ( ( ( void * ) gpios ) + sizeof ( *gpios ) );
59  gpios->priv = ( ( ( void * ) gpios ) + sizeof ( *gpios ) +
60  ( count * sizeof ( *gpio ) ) );
61 
62  /* Initialise GPIO pins */
63  for ( i = 0 ; i < count ; i++ ) {
64  gpio = &gpios->gpio[i];
65  gpio->gpios = gpios;
66  gpio->index = i;
67  }
68 
69  return gpios;
70 }
71 
72 /**
73  * Register GPIO controller
74  *
75  * @v gpios GPIO controller
76  * @ret rc Return status code
77  */
78 int gpios_register ( struct gpios *gpios ) {
79 
80  /* Add to list of GPIO controllers */
81  gpios_get ( gpios );
82  list_add_tail ( &gpios->list, &all_gpios );
83  DBGC ( gpios, "GPIO %s registered with %d GPIOs\n",
84  gpios->dev->name, gpios->count );
85 
86  return 0;
87 }
88 
89 /**
90  * Unregister GPIO controller
91  *
92  * @v gpios GPIO controller
93  */
94 void gpios_unregister ( struct gpios *gpios ) {
95 
96  /* Remove from list of GPIO controllers */
97  DBGC ( gpios, "GPIO %s unregistered\n", gpios->dev->name );
98  list_del ( &gpios->list );
99  gpios_put ( gpios );
100 }
101 
102 /**
103  * Find GPIO controller
104  *
105  * @v bus_type Bus type
106  * @v location Bus location
107  * @ret gpios GPIO controller, or NULL
108  */
109 struct gpios * gpios_find ( unsigned int bus_type, unsigned int location ) {
110  struct gpios *gpios;
111 
112  /* Scan through list of registered GPIO controllers */
113  list_for_each_entry ( gpios, &all_gpios, list ) {
114  if ( ( gpios->dev->desc.bus_type == bus_type ) &&
115  ( gpios->dev->desc.location == location ) )
116  return gpios;
117  }
118 
119  return NULL;
120 }
121 
122 /**
123  * Get null GPIO input value
124  *
125  * @v gpios GPIO controller
126  * @v gpio GPIO pin
127  * @ret active Pin is in the active state
128  */
129 static int null_gpio_in ( struct gpios *gpios __unused,
130  struct gpio *gpio __unused ) {
131  return 0;
132 }
133 
134 /**
135  * Set null GPIO output value
136  *
137  * @v gpios GPIO controller
138  * @v gpio GPIO pin
139  * @v active Set pin to active state
140  */
141 static void null_gpio_out ( struct gpios *gpios __unused,
142  struct gpio *gpio __unused, int active __unused ) {
143  /* Nothing to do */
144 }
145 
146 /**
147  * Configure null GPIO pin
148  *
149  * @v gpios GPIO controller
150  * @v gpio GPIO pin
151  * @v config Configuration
152  * @ret rc Return status code
153  */
154 static int null_gpio_config ( struct gpios *gpios __unused,
155  struct gpio *gpio __unused,
156  unsigned int config __unused ) {
157  return -ENODEV;
158 }
159 
160 /** Null GPIO operations */
162  .in = null_gpio_in,
163  .out = null_gpio_out,
164  .config = null_gpio_config,
165 };
struct gpio_operations null_gpio_operations
Null GPIO operations.
Definition: gpio.c:161
struct gpios * gpios_find(unsigned int bus_type, unsigned int location)
Find GPIO controller.
Definition: gpio.c:109
struct gpios * gpios
GPIO controller.
Definition: gpio.h:20
Error codes.
static void gpios_put(struct gpios *gpios)
Drop reference to GPIO controller.
Definition: gpio.h:106
General purpose I/O.
unsigned int index
Pin index.
Definition: gpio.h:22
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:78
struct device * dev
Generic device.
Definition: gpio.h:43
static int null_gpio_in(struct gpios *gpios __unused, struct gpio *gpio __unused)
Get null GPIO input value.
Definition: gpio.c:129
struct gpios * alloc_gpios(unsigned int count, size_t priv_len)
Allocate GPIO controller.
Definition: gpio.c:46
pseudo_bit_t gpio[0x00001]
Definition: arbel.h:30
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int(* in)(struct gpios *gpios, struct gpio *gpio)
Get current GPIO input value.
Definition: gpio.h:65
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
ring len
Length.
Definition: dwmac.h:231
void gpios_unregister(struct gpios *gpios)
Unregister GPIO controller.
Definition: gpio.c:94
static unsigned int count
Number of entries.
Definition: dwmac.h:225
GPIO operations.
Definition: gpio.h:57
unsigned int location
Location.
Definition: device.h:29
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
struct list_head list
List of GPIO controllers.
Definition: gpio.h:41
A GPIO controller.
Definition: gpio.h:37
#define ENODEV
No such device.
Definition: errno.h:509
int gpios_register(struct gpios *gpios)
Register GPIO controller.
Definition: gpio.c:78
unsigned int bus_type
Bus type.
Definition: device.h:24
struct device_description desc
Device description.
Definition: device.h:82
static int null_gpio_config(struct gpios *gpios __unused, struct gpio *gpio __unused, unsigned int config __unused)
Configure null GPIO pin.
Definition: gpio.c:154
A GPIO pin.
Definition: gpio.h:18
static LIST_HEAD(all_gpios)
List of GPIO controllers.
unsigned int count
Number of GPIOs.
Definition: gpio.h:45
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static void null_gpio_out(struct gpios *gpios __unused, struct gpio *gpio __unused, int active __unused)
Set null GPIO output value.
Definition: gpio.c:141
static struct gpios * gpios_get(struct gpios *gpios)
Get reference to GPIO controller.
Definition: gpio.h:95
struct gpio * gpio
Individual GPIOs.
Definition: gpio.h:48
void * priv
Driver-private data.
Definition: gpio.h:53