| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <ddk/binding.h> |
| #include <ddk/protocol/pci.h> |
| #include <hw/pci.h> |
| |
| #include <zircon/listnode.h> |
| |
| #include <zircon/syscalls.h> |
| #include <zircon/types.h> |
| |
| #include <stdio.h> |
| |
| #include <intel-serialio/serialio.h> |
| |
| static zx_status_t intel_serialio_bind(void* ctx, zx_device_t* dev, void** cookie) { |
| pci_protocol_t pci; |
| zx_status_t res; |
| |
| if (device_get_protocol(dev, ZX_PROTOCOL_PCI, &pci)) |
| return ZX_ERR_NOT_SUPPORTED; |
| |
| const pci_config_t* pci_config; |
| size_t config_size; |
| zx_handle_t config_handle = ZX_HANDLE_INVALID; |
| res = pci_map_resource(&pci, PCI_RESOURCE_CONFIG, ZX_CACHE_POLICY_UNCACHED_DEVICE, |
| (void**)&pci_config, &config_size, &config_handle); |
| |
| if (res != ZX_OK) { |
| xprintf("serialio: failed to map pci config: %d\n", res); |
| return res; |
| } |
| |
| switch (pci_config->device_id) { |
| case INTEL_WILDCAT_POINT_SERIALIO_DMA_DID: |
| res = intel_serialio_bind_dma(dev); |
| break; |
| case INTEL_WILDCAT_POINT_SERIALIO_I2C0_DID: |
| case INTEL_WILDCAT_POINT_SERIALIO_I2C1_DID: |
| case INTEL_SUNRISE_POINT_SERIALIO_I2C0_DID: |
| case INTEL_SUNRISE_POINT_SERIALIO_I2C1_DID: |
| case INTEL_SUNRISE_POINT_SERIALIO_I2C2_DID: |
| case INTEL_SUNRISE_POINT_SERIALIO_I2C3_DID: |
| res = intel_serialio_bind_i2c(dev); |
| break; |
| case INTEL_WILDCAT_POINT_SERIALIO_SDIO_DID: |
| res = intel_serialio_bind_sdio(dev); |
| break; |
| case INTEL_WILDCAT_POINT_SERIALIO_SPI0_DID: |
| res = intel_serialio_bind_spi(dev); |
| break; |
| case INTEL_WILDCAT_POINT_SERIALIO_SPI1_DID: |
| res = intel_serialio_bind_spi(dev); |
| break; |
| case INTEL_WILDCAT_POINT_SERIALIO_UART0_DID: |
| res = intel_serialio_bind_uart(dev); |
| break; |
| case INTEL_WILDCAT_POINT_SERIALIO_UART1_DID: |
| res = intel_serialio_bind_uart(dev); |
| break; |
| default: |
| res = ZX_ERR_NOT_SUPPORTED; |
| break; |
| } |
| |
| zx_handle_close(config_handle); |
| return res; |
| } |
| |
| static zx_driver_ops_t intel_serialio_driver_ops = { |
| .version = DRIVER_OPS_VERSION, |
| .bind = intel_serialio_bind, |
| }; |
| |
| // clang-format off |
| ZIRCON_DRIVER_BEGIN(intel_serialio, intel_serialio_driver_ops, "zircon", "0.1", 14) |
| BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI), |
| BI_ABORT_IF(NE, BIND_PCI_VID, INTEL_VID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_DMA_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_I2C0_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_I2C1_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_SDIO_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_SPI0_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_SPI1_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_UART0_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_WILDCAT_POINT_SERIALIO_UART1_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C0_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C1_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C2_DID), |
| BI_MATCH_IF(EQ, BIND_PCI_DID, INTEL_SUNRISE_POINT_SERIALIO_I2C3_DID), |
| ZIRCON_DRIVER_END(intel_serialio) |