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/metadata.h>
7#include <ddk/protocol/platform-defs.h>
8#include <hw/reg.h>
9#include <soc/aml-s912/s912-hw.h>
10#include <soc/aml-a113/a113-hw.h>
11#include <soc/aml-s912/s912-gpio.h>
12#include <soc/aml-common/aml-sd-emmc.h>
13#include <wifi/wifi-config.h>
14
15#include "vim.h"
16
17static const pbus_gpio_t wifi_gpios[] = {
18    {
19        .gpio = S912_WIFI_SDIO_WAKE_HOST,
20    },
21    {
22        // For debugging purposes.
23        .gpio = S912_GPIODV(13),
24    },
25};
26
27static const wifi_config_t wifi_config = {
28    .oob_irq_mode = ZX_INTERRUPT_MODE_LEVEL_HIGH,
29};
30
31static const pbus_metadata_t wifi_metadata[] = {
32    {
33        .type       = DEVICE_METADATA_PRIVATE,
34        .data       = &wifi_config,
35        .len        = sizeof(wifi_config),
36    }
37};
38
39static const pbus_dev_t sdio_children[] = {
40    {
41        // Wifi driver.
42        .name = "vim2-wifi",
43        .gpios = wifi_gpios,
44        .gpio_count = countof(wifi_gpios),
45        .metadata = wifi_metadata,
46        .metadata_count = countof(wifi_metadata),
47    },
48};
49
50static const pbus_dev_t aml_sd_emmc_children[] = {
51    {
52        // Generic SDIO driver.
53        .name = "sdio",
54        .children = sdio_children,
55        .child_count = countof(sdio_children),
56    },
57};
58
59static const pbus_mmio_t aml_sd_emmc_mmios[] = {
60    {
61        .base = 0xD0070000,
62        .length = 0x2000,
63    }
64};
65
66static const pbus_irq_t aml_sd_emmc_irqs[] = {
67    {
68        .irq = 248,
69    },
70};
71
72static const pbus_bti_t aml_sd_emmc_btis[] = {
73    {
74        .iommu_index = 0,
75        .bti_id = BTI_SDIO,
76    },
77};
78
79static const pbus_gpio_t aml_sd_emmc_gpios[] = {
80    {
81        .gpio = S912_GPIOX(6),
82    },
83};
84
85static aml_sd_emmc_config_t config = {
86    .supports_dma = true,
87    .max_freq = 125000000,
88    .min_freq = 400000,
89};
90
91static const pbus_metadata_t aml_sd_emmc_metadata[] = {
92    {
93        .type       = DEVICE_METADATA_PRIVATE,
94        .data       = &config,
95        .len        = sizeof(config),
96    }
97};
98
99static const pbus_dev_t aml_sd_emmc_dev = {
100    .name = "aml-sdio",
101    .vid = PDEV_VID_AMLOGIC,
102    .pid = PDEV_PID_GENERIC,
103    .did = PDEV_DID_AMLOGIC_SD_EMMC,
104    .mmios = aml_sd_emmc_mmios,
105    .mmio_count = countof(aml_sd_emmc_mmios),
106    .irqs = aml_sd_emmc_irqs,
107    .irq_count = countof(aml_sd_emmc_irqs),
108    .btis = aml_sd_emmc_btis,
109    .bti_count = countof(aml_sd_emmc_btis),
110    .gpios = aml_sd_emmc_gpios,
111    .gpio_count = countof(aml_sd_emmc_gpios),
112    .metadata = aml_sd_emmc_metadata,
113    .metadata_count = countof(aml_sd_emmc_metadata),
114    .children = aml_sd_emmc_children,
115    .child_count = countof(aml_sd_emmc_children),
116};
117
118zx_status_t vim_sdio_init(vim_bus_t* bus) {
119    zx_status_t status;
120
121    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D0, S912_WIFI_SDIO_D0_FN);
122    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D1, S912_WIFI_SDIO_D1_FN);
123    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D2, S912_WIFI_SDIO_D2_FN);
124    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_D3, S912_WIFI_SDIO_D3_FN);
125    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_CLK, S912_WIFI_SDIO_CLK_FN);
126    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_CMD, S912_WIFI_SDIO_CMD_FN);
127    gpio_impl_set_alt_function(&bus->gpio, S912_WIFI_SDIO_WAKE_HOST, S912_WIFI_SDIO_WAKE_HOST_FN);
128
129    if ((status = pbus_device_add(&bus->pbus, &aml_sd_emmc_dev)) != ZX_OK) {
130        zxlogf(ERROR, "vim_sdio_init could not add aml_sd_emmc_dev: %d\n", status);
131        return status;
132    }
133
134    return ZX_OK;
135}
136