1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <dm.h> 8 #include <irq-generic.h> 9 #include "irq-gpio-switch.h" 10 11 static struct gpio_bank gpio_banks[GPIO_BANK_NUM] = { 12 #if GPIO_BANK_NUM >= 1 13 GPIO_BANK_REGISTER(0, GPIO_BANK_PINS), 14 #endif 15 #if GPIO_BANK_NUM >= 2 16 GPIO_BANK_REGISTER(1, GPIO_BANK_PINS), 17 #endif 18 #if GPIO_BANK_NUM >= 3 19 GPIO_BANK_REGISTER(2, GPIO_BANK_PINS), 20 #endif 21 #if GPIO_BANK_NUM >= 4 22 GPIO_BANK_REGISTER(3, GPIO_BANK_PINS), 23 #endif 24 #if GPIO_BANK_NUM >= 5 25 GPIO_BANK_REGISTER(4, GPIO_BANK_PINS), 26 #endif 27 #if GPIO_BANK_NUM >= 6 28 GPIO_BANK_REGISTER(5, GPIO_BANK_PINS), 29 #endif 30 #if GPIO_BANK_NUM >= 7 31 GPIO_BANK_REGISTER(6, GPIO_BANK_PINS), 32 #endif 33 #if GPIO_BANK_NUM >= 8 34 GPIO_BANK_REGISTER(7, GPIO_BANK_PINS), 35 #endif 36 #if GPIO_BANK_NUM >= 9 37 GPIO_BANK_REGISTER(8, GPIO_BANK_PINS), 38 #endif 39 #if GPIO_BANK_NUM >= 10 40 GPIO_BANK_REGISTER(9, GPIO_BANK_PINS), 41 #endif 42 }; 43 44 static int gpio_is_valid(u32 gpio) 45 { 46 if ((gpio == EINVAL_GPIO) || !GPIO_BANK_VALID(gpio) || 47 !GPIO_PIN_VALID(gpio)) { 48 printf("gpio = 0x%x is not valid!\n", gpio); 49 return 0; 50 } 51 52 return 1; 53 } 54 55 static int _hard_gpio_to_irq(u32 gpio) 56 { 57 int idx, bank = 0, pin = 0; 58 59 if (!gpio_is_valid(gpio)) 60 return -EINVAL; 61 62 bank = (gpio & GPIO_BANK_MASK) >> GPIO_BANK_OFFSET; 63 pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_OFFSET; 64 65 for (idx = 0; idx < ARRAY_SIZE(gpio_banks); idx++) { 66 if (gpio_banks[idx].id == bank) 67 return (gpio_banks[idx].irq_base + pin); 68 } 69 70 return -EINVAL; 71 } 72 73 static int _irq_to_gpio(int irq) 74 { 75 int bank, pin, idx; 76 77 bank = (irq - PIN_BASE) / GPIO_BANK_PINS; 78 pin = (irq - PIN_BASE) % GPIO_BANK_PINS; 79 80 for (idx = 0; idx < ARRAY_SIZE(gpio_banks); idx++) { 81 if (gpio_banks[idx].id == bank) { 82 return (bank << GPIO_BANK_OFFSET) | 83 (pin << GPIO_PIN_OFFSET); 84 } 85 } 86 87 return -EINVAL; 88 } 89 90 int gpio_to_irq(struct gpio_desc *gpio) 91 { 92 int irq_gpio, bank; 93 bool found; 94 char *name; 95 96 if (!gpio->dev->name) { 97 printf("can't find device name for the gpio bank\n"); 98 return EINVAL_GPIO; 99 } 100 101 name = strtok((char *)gpio->dev->name, "@"); 102 if (!name) { 103 printf("can't find correct device name for the gpio bank\n"); 104 return EINVAL_GPIO; 105 } 106 107 for (bank = 0; bank < ARRAY_SIZE(gpio_banks); bank++) { 108 if (!strcmp(gpio_banks[bank].name, name)) { 109 found = true; 110 break; 111 } 112 } 113 114 if (!found) { 115 printf("irq gpio framework can't find %s\n", name); 116 return EINVAL_GPIO; 117 } 118 119 irq_gpio = RK_IRQ_GPIO(bank, gpio->offset); 120 if (!gpio_is_valid(irq_gpio)) 121 return EINVAL_GPIO; 122 123 return _hard_gpio_to_irq(irq_gpio); 124 } 125 126 int hard_gpio_to_irq(u32 gpio) 127 { 128 if (!gpio_is_valid(gpio)) 129 return EINVAL_GPIO; 130 131 return _hard_gpio_to_irq(gpio); 132 } 133 134 int irq_to_gpio(int irq) 135 { 136 return _irq_to_gpio(irq); 137 } 138 139 struct gpio_bank *gpio_id_to_bank(u32 id) 140 { 141 int idx; 142 143 for (idx = 0; idx < ARRAY_SIZE(gpio_banks); idx++) { 144 if (gpio_banks[idx].id == id) 145 return &gpio_banks[idx]; 146 } 147 148 return NULL; 149 } 150 151 struct gpio_bank *gpio_to_bank(u32 gpio) 152 { 153 int id; 154 155 if (!gpio_is_valid(gpio)) 156 return NULL; 157 158 id = (gpio & GPIO_BANK_MASK) >> GPIO_BANK_OFFSET; 159 160 return gpio_id_to_bank(id); 161 } 162