1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/debug.h>
6 #include <ddk/device.h>
7 #include <ddk/platform-defs.h>
8 #include <ddk/protocol/platform/bus.h>
9
10 #include <soc/aml-s905x/s905x-gpio.h>
11 #include <soc/aml-s912/s912-gpio.h>
12 #include <soc/aml-s912/s912-hw.h>
13
14 #include <limits.h>
15
16 #include "vim.h"
17
18 // S905X and S912 have same MMIO addresses
19 static const pbus_mmio_t gpio_mmios[] = {
20 {
21 .base = S912_GPIO_BASE,
22 .length = S912_GPIO_LENGTH,
23 },
24 {
25 .base = S912_GPIO_AO_BASE,
26 .length = S912_GPIO_AO_LENGTH,
27 },
28 {
29 .base = S912_GPIO_INTERRUPT_BASE,
30 .length = S912_GPIO_INTERRUPT_LENGTH,
31 },
32 };
33
34 // S905X and S912 have same GPIO IRQ numbers
35 static const pbus_irq_t gpio_irqs[] = {
36 {
37 .irq = S912_GPIO_IRQ_0,
38 },
39 {
40 .irq = S912_GPIO_IRQ_1,
41 },
42 {
43 .irq = S912_GPIO_IRQ_2,
44 },
45 {
46 .irq = S912_GPIO_IRQ_3,
47 },
48 {
49 .irq = S912_GPIO_IRQ_4,
50 },
51 {
52 .irq = S912_GPIO_IRQ_5,
53 },
54 {
55 .irq = S912_GPIO_IRQ_6,
56 },
57 {
58 .irq = S912_GPIO_IRQ_7,
59 },
60 {
61 .irq = S912_AO_GPIO_IRQ_0,
62 },
63 {
64 .irq = S912_AO_GPIO_IRQ_1,
65 },
66 };
67
68 static const pbus_dev_t gpio_dev = {
69 .name = "gpio",
70 .vid = PDEV_VID_AMLOGIC,
71 .pid = PDEV_PID_AMLOGIC_S912,
72 .did = PDEV_DID_AMLOGIC_GPIO,
73 .mmio_list = gpio_mmios,
74 .mmio_count = countof(gpio_mmios),
75 .irq_list = gpio_irqs,
76 .irq_count = countof(gpio_irqs),
77 };
78
79
vim_gpio_init(vim_bus_t * bus,bool enable_test)80 zx_status_t vim_gpio_init(vim_bus_t* bus, bool enable_test) {
81
82 zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_GPIO_IMPL, &gpio_dev);
83 if (status != ZX_OK) {
84 zxlogf(ERROR, "vim_gpio_init: pbus_protocol_device_add failed: %d\n", status);
85 return status;
86 }
87
88 status = device_get_protocol(bus->parent, ZX_PROTOCOL_GPIO_IMPL, &bus->gpio);
89 if (status != ZX_OK) {
90 zxlogf(ERROR, "vim_gpio_init: device_get_protocol failed: %d\n", status);
91 return status;
92 }
93
94 if (enable_test) {
95 const pbus_gpio_t gpio_test_gpios[] = {
96 {
97 // SYS_LED
98 .gpio = S912_GPIOAO(9),
99 },
100 {
101 // GPIO PIN
102 .gpio = S912_GPIOAO(2),
103 },
104 };
105
106 const pbus_dev_t gpio_test_dev = {
107 .name = "vim-gpio-test",
108 .vid = PDEV_VID_GENERIC,
109 .pid = PDEV_PID_GENERIC,
110 .did = PDEV_DID_GPIO_TEST,
111 .gpio_list = gpio_test_gpios,
112 .gpio_count = countof(gpio_test_gpios),
113 };
114
115 status = pbus_device_add(&bus->pbus, &gpio_test_dev);
116 if (status != ZX_OK) {
117 zxlogf(ERROR, "vim_gpio_init could not add gpio_test_dev: %d\n", status);
118 return status;
119 }
120 }
121
122 return ZX_OK;
123 }
124