1// Copyright 2018 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/protocol/platform-bus.h> 8#include <ddk/protocol/platform-defs.h> 9 10#include <soc/aml-s905d2/s905d2-gpio.h> 11#include <soc/aml-s905d2/s905d2-hw.h> 12 13#include <limits.h> 14 15#include "astro.h" 16 17// uncomment to disable LED blinky test 18// #define GPIO_TEST 1 19 20static const pbus_mmio_t gpio_mmios[] = { 21 { 22 .base = S905D2_GPIO_BASE, 23 .length = S905D2_GPIO_LENGTH, 24 }, 25 { 26 .base = S905D2_GPIO_A0_BASE, 27 .length = S905D2_GPIO_AO_LENGTH, 28 }, 29 { 30 .base = S905D2_GPIO_INTERRUPT_BASE, 31 .length = S905D2_GPIO_INTERRUPT_LENGTH, 32 }, 33}; 34 35static const pbus_irq_t gpio_irqs[] = { 36 { 37 .irq = S905D2_GPIO_IRQ_0, 38 }, 39 { 40 .irq = S905D2_GPIO_IRQ_1, 41 }, 42 { 43 .irq = S905D2_GPIO_IRQ_2, 44 }, 45 { 46 .irq = S905D2_GPIO_IRQ_3, 47 }, 48 { 49 .irq = S905D2_GPIO_IRQ_4, 50 }, 51 { 52 .irq = S905D2_GPIO_IRQ_5, 53 }, 54 { 55 .irq = S905D2_GPIO_IRQ_6, 56 }, 57 { 58 .irq = S905D2_GPIO_IRQ_7, 59 }, 60 /* 61 { 62 .irq = S905D2_A0_GPIO_IRQ_0, 63 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH, 64 }, 65 { 66 .irq = S905D2_A0_GPIO_IRQ_1, 67 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH, 68 }, 69 */ 70}; 71 72static pbus_dev_t gpio_dev = { 73 .name = "gpio", 74 .vid = PDEV_VID_AMLOGIC, 75 .pid = PDEV_PID_AMLOGIC_S905D2, 76 .did = PDEV_DID_AMLOGIC_GPIO, 77 .mmios = gpio_mmios, 78 .mmio_count = countof(gpio_mmios), 79 .irqs = gpio_irqs, 80 .irq_count = countof(gpio_irqs), 81}; 82 83zx_status_t aml_gpio_init(aml_bus_t* bus) { 84 zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_GPIO_IMPL, &gpio_dev); 85 if (status != ZX_OK) { 86 zxlogf(ERROR, "aml_gpio_init: pbus_protocol_device_add failed: %d\n", status); 87 return status; 88 } 89 90 status = device_get_protocol(bus->parent, ZX_PROTOCOL_GPIO_IMPL, &bus->gpio); 91 if (status != ZX_OK) { 92 zxlogf(ERROR, "aml_gpio_init: device_get_protocol failed: %d\n", status); 93 return status; 94 } 95 96#if GPIO_TEST 97 const pbus_gpio_t gpio_test_gpios[] = { 98 { 99 // SYS_LED 100 .gpio = S905D2_GPIOAO(11), 101 }, 102 { 103 // JTAG Adapter Pin 104 .gpio = S905D2_GPIOAO(6), 105 } 106 }; 107 108 const pbus_dev_t gpio_test_dev = { 109 .name = "aml-gpio-test", 110 .vid = PDEV_VID_GENERIC, 111 .pid = PDEV_PID_GENERIC, 112 .did = PDEV_DID_GPIO_TEST, 113 .gpios = gpio_test_gpios, 114 .gpio_count = countof(gpio_test_gpios), 115 }; 116 117 if ((status = pbus_device_add(&bus->pbus, &gpio_test_dev, 0)) != ZX_OK) { 118 zxlogf(ERROR, "aml_gpio_init could not add gpio_test_dev: %d\n", status); 119 return status; 120 } 121#endif 122 123 return ZX_OK; 124} 125