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 <assert.h> 6#include <stdint.h> 7#include <stdio.h> 8#include <stdlib.h> 9#include <string.h> 10#include <threads.h> 11#include <unistd.h> 12 13#include <ddk/binding.h> 14#include <ddk/debug.h> 15#include <ddk/device.h> 16#include <ddk/driver.h> 17#include <ddk/protocol/platform-defs.h> 18#include <gpio/pl061/pl061.h> 19 20#include <zircon/process.h> 21#include <zircon/syscalls.h> 22#include <zircon/assert.h> 23 24#include <soc/hi3660/hi3660.h> 25#include <soc/hi3660/hi3660-hw.h> 26#include <soc/hi3660/hi3660-regs.h> 27#include <hw/reg.h> 28 29zx_status_t hi3660_enable_ldo3(hi3660_t* hi3660) { 30 volatile void* iopmu = io_buffer_virt(&hi3660->pmu_ssio); 31 writel(LDO3_ENABLE_BIT, iopmu + LDO3_ENABLE_REG); 32 return ZX_OK; 33} 34 35zx_status_t hi3660_init(zx_handle_t resource, zx_handle_t bti, hi3660_t** out) { 36 hi3660_t* hi3660 = calloc(1, sizeof(hi3660_t)); 37 if (!hi3660) { 38 return ZX_ERR_NO_MEMORY; 39 } 40 list_initialize(&hi3660->gpios); 41 42 zx_status_t status; 43 if ((status = io_buffer_init_physical(&hi3660->usb3otg_bc, bti, MMIO_USB3OTG_BC_BASE, 44 MMIO_USB3OTG_BC_LENGTH, resource, 45 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK || 46 (status = io_buffer_init_physical(&hi3660->peri_crg, bti, MMIO_PERI_CRG_BASE, 47 MMIO_PERI_CRG_LENGTH, resource, 48 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK || 49 (status = io_buffer_init_physical(&hi3660->pctrl, bti, MMIO_PCTRL_BASE, MMIO_PCTRL_LENGTH, 50 resource, ZX_CACHE_POLICY_UNCACHED_DEVICE) != ZX_OK) || 51 (status = io_buffer_init_physical(&hi3660->iomg_pmx4, bti, MMIO_IOMG_PMX4_BASE, 52 MMIO_IOMG_PMX4_LENGTH, resource, 53 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK || 54 (status = io_buffer_init_physical(&hi3660->pmu_ssio, bti, MMIO_PMU_SSI0_BASE, 55 MMIO_PMU_SSI0_LENGTH, resource, 56 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK || 57 (status = io_buffer_init_physical(&hi3660->iomcu, bti, MMIO_IOMCU_CONFIG_BASE, 58 MMIO_IOMCU_CONFIG_LENGTH, resource, 59 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK) { 60 goto fail; 61 } 62 63 status = hi3660_gpio_init(hi3660, bti); 64 if (status != ZX_OK) { 65 goto fail; 66 } 67 status = hi3660_usb_init(hi3660); 68 if (status != ZX_OK) { 69 goto fail; 70 } 71 72 status = hi3660_i2c1_init(hi3660); 73 if (status != ZX_OK) { 74 goto fail; 75 } 76 77 status = hi3660_enable_ldo3(hi3660); 78 if (status != ZX_OK) { 79 goto fail; 80 } 81 82 status = hi3660_i2c_pinmux(hi3660); 83 if (status != ZX_OK) { 84 goto fail; 85 } 86 87 *out = hi3660; 88 return ZX_OK; 89 90fail: 91 zxlogf(ERROR, "hi3660_init failed %d\n", status); 92 hi3660_release(hi3660); 93 return status; 94} 95 96zx_status_t hi3660_get_protocol(hi3660_t* hi3660, uint32_t proto_id, void* out) { 97 switch (proto_id) { 98 case ZX_PROTOCOL_GPIO_IMPL: 99 memcpy(out, &hi3660->gpio, sizeof(hi3660->gpio)); 100 return ZX_OK; 101 default: 102 return ZX_ERR_NOT_SUPPORTED; 103 } 104} 105 106void hi3660_release(hi3660_t* hi3660) { 107 hi3660_gpio_release(hi3660); 108 io_buffer_release(&hi3660->usb3otg_bc); 109 io_buffer_release(&hi3660->peri_crg); 110 io_buffer_release(&hi3660->pctrl); 111 free(hi3660); 112} 113