1// Copyright 2016 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/binding.h>
6#include <ddk/protocol/pci.h>
7#include <hw/pci.h>
8
9#include <zircon/listnode.h>
10
11#include <zircon/syscalls.h>
12#include <zircon/types.h>
13
14#include <stdio.h>
15
16#include <intel-serialio/serialio.h>
17
18static zx_status_t intel_serialio_bind(void* ctx, zx_device_t* dev) {
19    pci_protocol_t pci;
20    zx_status_t res;
21
22    if (device_get_protocol(dev, ZX_PROTOCOL_PCI, &pci))
23        return ZX_ERR_NOT_SUPPORTED;
24
25    uint16_t device_id;
26    pci_config_read16(&pci, PCI_CONFIG_DEVICE_ID, &device_id);
27
28    switch (device_id) {
29    case INTEL_WILDCAT_POINT_SERIALIO_DMA_DID:
30        res = intel_serialio_bind_dma(dev);
31        break;
32    case INTEL_WILDCAT_POINT_SERIALIO_SDIO_DID:
33        res = intel_serialio_bind_sdio(dev);
34        break;
35    case INTEL_WILDCAT_POINT_SERIALIO_SPI0_DID:
36        res = intel_serialio_bind_spi(dev);
37        break;
38    case INTEL_WILDCAT_POINT_SERIALIO_SPI1_DID:
39        res = intel_serialio_bind_spi(dev);
40        break;
41    case INTEL_WILDCAT_POINT_SERIALIO_UART0_DID:
42        res = intel_serialio_bind_uart(dev);
43        break;
44    case INTEL_WILDCAT_POINT_SERIALIO_UART1_DID:
45        res = intel_serialio_bind_uart(dev);
46        break;
47    default:
48        res = ZX_ERR_NOT_SUPPORTED;
49        break;
50    }
51
52    return res;
53}
54
55static zx_driver_ops_t intel_serialio_driver_ops = {
56    .version = DRIVER_OPS_VERSION,
57    .bind = intel_serialio_bind,
58};
59
60// clang-format off
61ZIRCON_DRIVER_BEGIN(intel_serialio, intel_serialio_driver_ops, "zircon", "0.1", 14)
62    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
63    BI_ABORT_IF(NE, BIND_PCI_VID, INTEL_VID),
64    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_DMA_DID),
65    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_I2C0_DID),
66    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_I2C1_DID),
67    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_SDIO_DID),
68    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_SPI0_DID),
69    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_SPI1_DID),
70    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_UART0_DID),
71    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_UART1_DID),
72    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C0_DID),
73    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C1_DID),
74    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C2_DID),
75    BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C3_DID),
76ZIRCON_DRIVER_END(intel_serialio)
77