1 /* $OpenBSD: ofw_gpio.c,v 1.2 2016/07/27 21:13:49 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2016 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <sys/systm.h> 20 21 #include <dev/ofw/openfirm.h> 22 #include <dev/ofw/ofw_gpio.h> 23 24 LIST_HEAD(, gpio_controller) gpio_controllers = 25 LIST_HEAD_INITIALIZER(gpio_controllers); 26 27 void 28 gpio_controller_register(struct gpio_controller *gc) 29 { 30 gc->gc_cells = OF_getpropint(gc->gc_node, "#gpio-cells", 2); 31 gc->gc_phandle = OF_getpropint(gc->gc_node, "phandle", 0); 32 if (gc->gc_phandle == 0) 33 return; 34 35 LIST_INSERT_HEAD(&gpio_controllers, gc, gc_list); 36 } 37 38 void 39 gpio_controller_config_pin(uint32_t *cells, int config) 40 { 41 struct gpio_controller *gc; 42 uint32_t phandle = cells[0]; 43 44 LIST_FOREACH(gc, &gpio_controllers, gc_list) { 45 if (gc->gc_phandle == phandle) 46 break; 47 } 48 49 if (gc && gc->gc_config_pin) 50 gc->gc_config_pin(gc->gc_cookie, &cells[1], config); 51 } 52 53 int 54 gpio_controller_get_pin(uint32_t *cells) 55 { 56 struct gpio_controller *gc; 57 uint32_t phandle = cells[0]; 58 int val = 0; 59 60 LIST_FOREACH(gc, &gpio_controllers, gc_list) { 61 if (gc->gc_phandle == phandle) 62 break; 63 } 64 65 if (gc && gc->gc_get_pin) 66 val = gc->gc_get_pin(gc->gc_cookie, &cells[1]); 67 68 return val; 69 } 70 71 void 72 gpio_controller_set_pin(uint32_t *cells, int val) 73 { 74 struct gpio_controller *gc; 75 uint32_t phandle = cells[0]; 76 77 LIST_FOREACH(gc, &gpio_controllers, gc_list) { 78 if (gc->gc_phandle == phandle) 79 break; 80 } 81 82 if (gc && gc->gc_set_pin) 83 gc->gc_set_pin(gc->gc_cookie, &cells[1], val); 84 } 85 86 uint32_t * 87 gpio_controller_next_pin(uint32_t *cells) 88 { 89 struct gpio_controller *gc; 90 uint32_t phandle = cells[0]; 91 92 LIST_FOREACH(gc, &gpio_controllers, gc_list) 93 if (gc->gc_phandle == phandle) 94 return cells + gc->gc_cells + 1; 95 96 return NULL; 97 } 98