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