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/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
hi3660_enable_ldo3(hi3660_t * hi3660)29 zx_status_t hi3660_enable_ldo3(hi3660_t* hi3660) {
30 writel(LDO3_ENABLE_BIT, hi3660->pmu_ssio.vaddr + LDO3_ENABLE_REG);
31 return ZX_OK;
32 }
33
hi3660_init(zx_handle_t resource,hi3660_t ** out)34 zx_status_t hi3660_init(zx_handle_t resource, hi3660_t** out) {
35 hi3660_t* hi3660 = calloc(1, sizeof(hi3660_t));
36 if (!hi3660) {
37 return ZX_ERR_NO_MEMORY;
38 }
39 list_initialize(&hi3660->gpios);
40
41 zx_status_t status;
42 if ((status = mmio_buffer_init_physical(&hi3660->usb3otg_bc, MMIO_USB3OTG_BC_BASE,
43 MMIO_USB3OTG_BC_LENGTH, resource,
44 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK ||
45 (status = mmio_buffer_init_physical(&hi3660->peri_crg, MMIO_PERI_CRG_BASE,
46 MMIO_PERI_CRG_LENGTH, resource,
47 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK ||
48 (status = mmio_buffer_init_physical(&hi3660->pctrl, MMIO_PCTRL_BASE, MMIO_PCTRL_LENGTH,
49 resource, ZX_CACHE_POLICY_UNCACHED_DEVICE) != ZX_OK) ||
50 (status = mmio_buffer_init_physical(&hi3660->iomg_pmx4, MMIO_IOMG_PMX4_BASE,
51 MMIO_IOMG_PMX4_LENGTH, resource,
52 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK ||
53 (status = mmio_buffer_init_physical(&hi3660->pmu_ssio, MMIO_PMU_SSI0_BASE,
54 MMIO_PMU_SSI0_LENGTH, resource,
55 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK ||
56 (status = mmio_buffer_init_physical(&hi3660->iomcu, MMIO_IOMCU_CONFIG_BASE,
57 MMIO_IOMCU_CONFIG_LENGTH, resource,
58 ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK) {
59 goto fail;
60 }
61
62 status = hi3660_gpio_init(hi3660);
63 if (status != ZX_OK) {
64 goto fail;
65 }
66 status = hi3660_usb_init(hi3660);
67 if (status != ZX_OK) {
68 goto fail;
69 }
70
71 status = hi3660_i2c1_init(hi3660);
72 if (status != ZX_OK) {
73 goto fail;
74 }
75
76 status = hi3660_enable_ldo3(hi3660);
77 if (status != ZX_OK) {
78 goto fail;
79 }
80
81 status = hi3660_i2c_pinmux(hi3660);
82 if (status != ZX_OK) {
83 goto fail;
84 }
85
86 *out = hi3660;
87 return ZX_OK;
88
89 fail:
90 zxlogf(ERROR, "hi3660_init failed %d\n", status);
91 hi3660_release(hi3660);
92 return status;
93 }
94
hi3660_get_protocol(hi3660_t * hi3660,uint32_t proto_id,void * out)95 zx_status_t hi3660_get_protocol(hi3660_t* hi3660, uint32_t proto_id, void* out) {
96 switch (proto_id) {
97 case ZX_PROTOCOL_GPIO_IMPL:
98 memcpy(out, &hi3660->gpio, sizeof(hi3660->gpio));
99 return ZX_OK;
100 default:
101 return ZX_ERR_NOT_SUPPORTED;
102 }
103 }
104
hi3660_release(hi3660_t * hi3660)105 void hi3660_release(hi3660_t* hi3660) {
106 hi3660_gpio_release(hi3660);
107 mmio_buffer_release(&hi3660->usb3otg_bc);
108 mmio_buffer_release(&hi3660->peri_crg);
109 mmio_buffer_release(&hi3660->pctrl);
110 mmio_buffer_release(&hi3660->iomg_pmx4);
111 mmio_buffer_release(&hi3660->pmu_ssio);
112 mmio_buffer_release(&hi3660->iomcu);
113 free(hi3660);
114 }
115