1 /* 2 * Copyright (C) 2013 Google, Inc 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <fdtdec.h> 9 #include <dm.h> 10 #include <dm/root.h> 11 #include <dm/ut.h> 12 #include <dm/test.h> 13 #include <dm/util.h> 14 #include <asm/gpio.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 /* Test that sandbox GPIOs work correctly */ 19 static int dm_test_gpio(struct dm_test_state *dms) 20 { 21 unsigned int offset, gpio; 22 struct dm_gpio_ops *ops; 23 struct udevice *dev; 24 const char *name; 25 int offset_count; 26 char buf[80]; 27 28 /* 29 * We expect to get 3 banks. One is anonymous (just numbered) and 30 * comes from platdata. The other two are named a (20 gpios) 31 * and b (10 gpios) and come from the device tree. See 32 * test/dm/test.dts. 33 */ 34 ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio)); 35 ut_asserteq_str(dev->name, "extra-gpios"); 36 ut_asserteq(4, offset); 37 ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 20 + 4, gpio); 38 39 name = gpio_get_bank_info(dev, &offset_count); 40 ut_asserteq_str("b", name); 41 ut_asserteq(10, offset_count); 42 43 /* Get the operations for this device */ 44 ops = gpio_get_ops(dev); 45 ut_assert(ops->get_function); 46 47 /* Cannot get a value until it is reserved */ 48 ut_asserteq(-EBUSY, gpio_get_value(gpio + 1)); 49 /* 50 * Now some tests that use the 'sandbox' back door. All GPIOs 51 * should default to input, include b4 that we are using here. 52 */ 53 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 54 ut_asserteq_str("b4: input: 0 [ ]", buf); 55 56 /* Change it to an output */ 57 sandbox_gpio_set_direction(dev, offset, 1); 58 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 59 ut_asserteq_str("b4: output: 0 [ ]", buf); 60 61 sandbox_gpio_set_value(dev, offset, 1); 62 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 63 ut_asserteq_str("b4: output: 1 [ ]", buf); 64 65 ut_assertok(gpio_request(gpio, "testing")); 66 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 67 ut_asserteq_str("b4: output: 1 [x] testing", buf); 68 69 /* Change the value a bit */ 70 ut_asserteq(1, ops->get_value(dev, offset)); 71 ut_assertok(ops->set_value(dev, offset, 0)); 72 ut_asserteq(0, ops->get_value(dev, offset)); 73 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 74 ut_asserteq_str("b4: output: 0 [x] testing", buf); 75 ut_assertok(ops->set_value(dev, offset, 1)); 76 ut_asserteq(1, ops->get_value(dev, offset)); 77 78 /* Make it an input */ 79 ut_assertok(ops->direction_input(dev, offset)); 80 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 81 ut_asserteq_str("b4: input: 1 [x] testing", buf); 82 sandbox_gpio_set_value(dev, offset, 0); 83 ut_asserteq(0, sandbox_gpio_get_value(dev, offset)); 84 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 85 ut_asserteq_str("b4: input: 0 [x] testing", buf); 86 87 ut_assertok(gpio_free(gpio)); 88 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 89 ut_asserteq_str("b4: input: 0 [ ]", buf); 90 91 /* Check the 'a' bank also */ 92 ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio)); 93 ut_asserteq_str(dev->name, "base-gpios"); 94 ut_asserteq(15, offset); 95 ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 15, gpio); 96 97 name = gpio_get_bank_info(dev, &offset_count); 98 ut_asserteq_str("a", name); 99 ut_asserteq(20, offset_count); 100 101 return 0; 102 } 103 DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 104 105 /* Test that sandbox anonymous GPIOs work correctly */ 106 static int dm_test_gpio_anon(struct dm_test_state *dms) 107 { 108 unsigned int offset, gpio; 109 struct udevice *dev; 110 const char *name; 111 int offset_count; 112 113 /* And the anonymous bank */ 114 ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio)); 115 ut_asserteq_str(dev->name, "gpio_sandbox"); 116 ut_asserteq(14, offset); 117 ut_asserteq(14, gpio); 118 119 name = gpio_get_bank_info(dev, &offset_count); 120 ut_asserteq_ptr(NULL, name); 121 ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT, offset_count); 122 123 return 0; 124 } 125 DM_TEST(dm_test_gpio_anon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 126 127 /* Test that gpio_requestf() works as expected */ 128 static int dm_test_gpio_requestf(struct dm_test_state *dms) 129 { 130 unsigned int offset, gpio; 131 struct udevice *dev; 132 char buf[80]; 133 134 ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio)); 135 ut_assertok(gpio_requestf(gpio, "testing %d %s", 1, "hi")); 136 sandbox_gpio_set_direction(dev, offset, 1); 137 sandbox_gpio_set_value(dev, offset, 1); 138 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 139 ut_asserteq_str("b5: output: 1 [x] testing 1 hi", buf); 140 141 return 0; 142 } 143 DM_TEST(dm_test_gpio_requestf, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 144 145 /* Test that gpio_request() copies its string */ 146 static int dm_test_gpio_copy(struct dm_test_state *dms) 147 { 148 unsigned int offset, gpio; 149 struct udevice *dev; 150 char buf[80], name[10]; 151 152 ut_assertok(gpio_lookup_name("b6", &dev, &offset, &gpio)); 153 strcpy(name, "odd_name"); 154 ut_assertok(gpio_request(gpio, name)); 155 sandbox_gpio_set_direction(dev, offset, 1); 156 sandbox_gpio_set_value(dev, offset, 1); 157 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 158 ut_asserteq_str("b6: output: 1 [x] odd_name", buf); 159 strcpy(name, "nothing"); 160 ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); 161 ut_asserteq_str("b6: output: 1 [x] odd_name", buf); 162 163 return 0; 164 } 165 DM_TEST(dm_test_gpio_copy, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 166 167 /* Test that we don't leak memory with GPIOs */ 168 static int dm_test_gpio_leak(struct dm_test_state *dms) 169 { 170 ut_assertok(dm_test_gpio(dms)); 171 ut_assertok(dm_test_gpio_anon(dms)); 172 ut_assertok(dm_test_gpio_requestf(dms)); 173 ut_assertok(dm_leak_check_end(dms)); 174 175 return 0; 176 } 177 DM_TEST(dm_test_gpio_leak, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 178 179 /* Test that we can find GPIOs using phandles */ 180 static int dm_test_gpio_phandles(struct dm_test_state *dms) 181 { 182 struct gpio_desc desc, desc_list[8], desc_list2[8]; 183 struct udevice *dev, *gpio_a, *gpio_b; 184 185 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); 186 ut_asserteq_str("a-test", dev->name); 187 188 ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0)); 189 ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a)); 190 ut_assertok(uclass_get_device(UCLASS_GPIO, 2, &gpio_b)); 191 ut_asserteq_str("base-gpios", gpio_a->name); 192 ut_asserteq(true, !!device_active(gpio_a)); 193 ut_asserteq_ptr(gpio_a, desc.dev); 194 ut_asserteq(4, desc.offset); 195 /* GPIOF_INPUT is the sandbox GPIO driver default */ 196 ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL)); 197 ut_assertok(dm_gpio_free(dev, &desc)); 198 199 ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 3, &desc, 200 0)); 201 ut_asserteq_ptr(NULL, desc.dev); 202 ut_asserteq(desc.offset, 0); 203 ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 5, &desc, 204 0)); 205 206 /* Last GPIO is ignord as it comes after <0> */ 207 ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, 208 ARRAY_SIZE(desc_list), 0)); 209 ut_asserteq(-EBUSY, gpio_request_list_by_name(dev, "test-gpios", 210 desc_list2, 211 ARRAY_SIZE(desc_list2), 212 0)); 213 ut_assertok(gpio_free_list(dev, desc_list, 3)); 214 ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, 215 ARRAY_SIZE(desc_list), 216 GPIOD_IS_OUT | 217 GPIOD_IS_OUT_ACTIVE)); 218 ut_asserteq_ptr(gpio_a, desc_list[0].dev); 219 ut_asserteq(1, desc_list[0].offset); 220 ut_asserteq_ptr(gpio_a, desc_list[1].dev); 221 ut_asserteq(4, desc_list[1].offset); 222 ut_asserteq_ptr(gpio_b, desc_list[2].dev); 223 ut_asserteq(5, desc_list[2].offset); 224 ut_asserteq(1, dm_gpio_get_value(desc_list)); 225 ut_assertok(gpio_free_list(dev, desc_list, 3)); 226 227 ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list, 228 ARRAY_SIZE(desc_list), 0)); 229 /* This was set to output previously, so still will be */ 230 ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL)); 231 232 /* Active low should invert the input value */ 233 ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL)); 234 ut_asserteq(1, dm_gpio_get_value(&desc_list[2])); 235 236 ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 7, NULL)); 237 ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 8, NULL)); 238 ut_asserteq(0, dm_gpio_get_value(&desc_list[4])); 239 ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL)); 240 ut_asserteq(1, dm_gpio_get_value(&desc_list[5])); 241 242 243 return 0; 244 } 245 DM_TEST(dm_test_gpio_phandles, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 246