1 /* 2 * GPIO driver for Ingenic X1600. 3 * (See below for additional copyright and licensing notices.) 4 * 5 * Copyright (C) 2017, 2018, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA 21 * 22 * 23 * Subject to other copyrights, being derived from the bcm2835.cc and 24 * omap.cc GPIO driver implementations. 25 * 26 * This file is part of TUD:OS and distributed under the terms of the 27 * GNU General Public License 2. 28 * Please see the COPYING-GPL-2 file for details. 29 */ 30 31 #pragma once 32 33 #include <l4/sys/types.h> 34 #include <stdint.h> 35 #include "gpio-generic.h" 36 37 38 39 #ifdef __cplusplus 40 41 #include <l4/devices/hw_mmio_register_block.h> 42 43 // GPIO device control. 44 45 class Gpio_x1600_irq_pin : public Hw::Gpio_irq_pin 46 { 47 unsigned _pin; 48 49 // Register blocks for the conventional and optional shadow registers. 50 51 Hw::Register_block<32> _regs, _shadow_regs; 52 uint8_t _port_number; 53 bool _shadow; 54 55 // Convenience method for obtaining the bit corresponding to a pin. 56 57 l4_uint32_t _pin_bit(unsigned pin) 58 { return 1 << (pin & 31); } 59 60 void write_reg_pin(unsigned reg); 61 62 public: 63 Gpio_x1600_irq_pin(unsigned pin, Hw::Register_block<32> const ®s, 64 Hw::Register_block<32> const &shadow_regs, 65 uint8_t port_number); 66 67 Gpio_x1600_irq_pin(unsigned pin, Hw::Register_block<32> const ®s); 68 69 void do_mask(); 70 void do_unmask(); 71 bool do_set_mode(unsigned mode); 72 int clear(); 73 bool enabled(); 74 }; 75 76 class Gpio_x1600_chip : public Hw::Gpio_chip 77 { 78 private: 79 // Register blocks for the conventional and optional shadow registers. 80 81 Hw::Register_block<32> _regs, _shadow_regs; 82 83 l4_addr_t _start; 84 struct gpio_port *_pull_config; 85 86 // Optional shadow port configuration. 87 88 l4_addr_t _shadow_start; 89 uint8_t _port_number; 90 bool _shadow; 91 92 void write_reg_pin(unsigned reg, unsigned pin); 93 94 public: 95 explicit Gpio_x1600_chip(l4_addr_t start, uint8_t port_number, 96 bool shadow = false); 97 98 // Configuration methods. 99 100 void setup(unsigned pin, unsigned mode, int value = 0); 101 void config_pull(unsigned pin, unsigned mode); 102 void config_pad(unsigned pin, unsigned func, unsigned value); 103 void config_get(unsigned pin, unsigned reg, unsigned *value); 104 void config_pad_get(unsigned pin, unsigned *func, unsigned *value); 105 106 // Multiple pin configuration methods. 107 108 void multi_setup(Pin_slice const &mask, unsigned mode, unsigned outvalues = 0); 109 void multi_config_pad(Pin_slice const &mask, unsigned func, unsigned value = 0); 110 void multi_set(Pin_slice const &mask, unsigned data); 111 unsigned multi_get(unsigned offset); 112 113 // IRQ pin configuration. 114 115 Hw::Gpio_irq_pin *get_irq(unsigned pin); 116 117 // Pin/port data methods. 118 119 int get(unsigned pin); 120 void set(unsigned pin, int value); 121 122 private: 123 void config(unsigned pin, unsigned mode); 124 }; 125 126 Hw::Gpio_chip *x1600_gpio_chip(l4_addr_t start, uint8_t port_number, 127 bool shadow = false); 128 129 #endif /* __cplusplus */ 130 131 132 133 /* C language interface. */ 134 135 EXTERN_C_BEGIN 136 137 void *x1600_gpio_init(l4_addr_t start, uint8_t port_number); 138 139 void *x1600_gpio_init_shadow(l4_addr_t start, uint8_t port_number); 140 141 void x1600_gpio_setup(void *gpio, unsigned pin, unsigned mode, int value); 142 void x1600_gpio_config_pull(void *gpio, unsigned pin, unsigned mode); 143 void x1600_gpio_config_pad(void *gpio, unsigned pin, unsigned func, unsigned value); 144 void x1600_gpio_config_get(void *gpio, unsigned pin, unsigned reg, unsigned *value); 145 void x1600_gpio_config_pad_get(void *gpio, unsigned pin, unsigned *func, unsigned *value); 146 147 void x1600_gpio_multi_setup(void *gpio, Pin_slice const *mask, unsigned mode, unsigned outvalues); 148 void x1600_gpio_multi_config_pad(void *gpio, Pin_slice const *mask, unsigned func, unsigned value); 149 void x1600_gpio_multi_set(void *gpio, Pin_slice const *mask, unsigned data); 150 unsigned x1600_gpio_multi_get(void *gpio, unsigned offset); 151 152 int x1600_gpio_get(void *gpio, unsigned pin); 153 void x1600_gpio_set(void *gpio, unsigned pin, int value); 154 155 void *x1600_gpio_get_irq(void *gpio, unsigned pin); 156 bool x1600_gpio_irq_set_mode(void *gpio_irq, unsigned mode); 157 158 EXTERN_C_END