1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hi_flashboot_io.h"
17
18 #include <hi_types.h>
19
20 #define GPIO_SWPORT_DR 0x00
21 #define GPIO_SWPORT_DDR 0x04
22 #define GPIO_EXT_PORT 0x50
23 #define IO_MUX_REG_BASE_ADDR 0x604 /* Base address for the I/O function multiplexing register */
24 #define IO_CTRL_REG_BASE_ADDR 0x904 /* Base address of the I/O control register, which is used to
25 configure the drive capability and pull-up/pull-down */
26 #define IO_DRV_PULL_MASK 0x3
27 #define IO_DRV_STRENGTH_MASK 0x7
28 #define IO_DRV_PULL_START_BIT 8
29 #define IO_DRV_STRENGTH_START_BIT 4
30 #define OFFSET_10_B 10
31 #define OFFSET_2_B 2
32 #define IE_MSK 0x1
33
hi_io_get_func(hi_io_name id,hi_u8 * val)34 hi_u32 hi_io_get_func(hi_io_name id, hi_u8* val)
35 {
36 if ((id >= HI_IO_NAME_MAX) || (val == HI_NULL)) {
37 return HI_ERR_GPIO_INVALID_PARAMETER;
38 }
39 hi_u32 reg_addr;
40 hi_u32 reg_val = 0;
41 reg_addr = HI_IOCFG_REG_BASE + IO_MUX_REG_BASE_ADDR + ((hi_u32)id << 2); /* lift shift 2 bits */
42 hi_reg_read(reg_addr, reg_val);
43 *val = (hi_u8)reg_val;
44 return HI_ERR_SUCCESS;
45 }
46
hi_io_get_pull(hi_io_name id,hi_io_pull * val)47 hi_u32 hi_io_get_pull(hi_io_name id, hi_io_pull* val)
48 {
49 if ((id >= HI_IO_NAME_MAX) || (val == HI_NULL)) {
50 return HI_ERR_GPIO_INVALID_PARAMETER;
51 }
52 hi_u32 reg_val = 0;
53 hi_reg_read((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << 2)), reg_val); /* lift shift 2 bits */
54 *val = (hi_io_pull) ((reg_val >> IO_DRV_PULL_START_BIT) & IO_DRV_PULL_MASK);
55
56 return HI_ERR_SUCCESS;
57 }
58
hi_io_set_driver_strength(hi_io_name id,hi_io_driver_strength val)59 hi_u32 hi_io_set_driver_strength(hi_io_name id, hi_io_driver_strength val)
60 {
61 if ((id >= HI_IO_NAME_MAX) || (val >= HI_IO_DRIVER_STRENGTH_MAX)) {
62 return HI_ERR_GPIO_INVALID_PARAMETER;
63 }
64 hi_u32 reg_val = 0;
65
66 if (((id <= HI_IO_NAME_GPIO_11) || (id == HI_IO_NAME_GPIO_13) || (id == HI_IO_NAME_GPIO_14))
67 && (val >= HI_IO_DRIVER_STRENGTH_4)) {
68 return HI_ERR_GPIO_NOT_SUPPORT;
69 }
70 hi_reg_read((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << 2)), reg_val); /* lift shift 2 bits */
71 reg_val &= ~(IO_DRV_STRENGTH_MASK << IO_DRV_STRENGTH_START_BIT);
72 reg_val |= ((hi_u32) val & IO_DRV_STRENGTH_MASK) << IO_DRV_STRENGTH_START_BIT;
73 hi_reg_write((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << 2)), reg_val); /* lift shift 2 bits */
74
75 return HI_ERR_SUCCESS;
76 }
77
hi_io_get_driver_strength(hi_io_name id,hi_io_driver_strength * val)78 hi_u32 hi_io_get_driver_strength(hi_io_name id, hi_io_driver_strength* val)
79 {
80 if ((id >= HI_IO_NAME_MAX) || (val == HI_NULL)) {
81 return HI_ERR_GPIO_INVALID_PARAMETER;
82 }
83 hi_u32 reg_val = 0;
84
85 hi_reg_read((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << 2)), reg_val); /* lift shift 2 bits */
86
87 *val = (hi_io_driver_strength) ((reg_val >> IO_DRV_STRENGTH_START_BIT) & IO_DRV_STRENGTH_MASK);
88 return HI_ERR_SUCCESS;
89 }
90
hi_io_set_input_enable(hi_io_name id,hi_bool state)91 hi_u32 hi_io_set_input_enable(hi_io_name id, hi_bool state)
92 {
93 hi_u32 reg_val;
94 if (id >= HI_IO_NAME_MAX) {
95 return HI_ERR_GPIO_INVALID_PARAMETER;
96 }
97 hi_reg_read((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << OFFSET_2_B)), reg_val);
98 reg_val &= ~(IE_MSK << OFFSET_10_B);
99 reg_val |= (state & IE_MSK) << OFFSET_10_B;
100 hi_reg_write((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << OFFSET_2_B)), reg_val);
101 return HI_ERR_SUCCESS;
102 }
103
hi_io_get_input_enable(hi_io_name id,hi_bool * state)104 hi_u32 hi_io_get_input_enable(hi_io_name id, hi_bool *state)
105 {
106 hi_u32 reg_val;
107 if ((id >= HI_IO_NAME_MAX) || (state == HI_NULL)) {
108 return HI_ERR_GPIO_INVALID_PARAMETER;
109 }
110 hi_reg_read((HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + ((hi_u32)id << OFFSET_2_B)), reg_val);
111 *state = (reg_val >> OFFSET_10_B) & IE_MSK;
112 return HI_ERR_SUCCESS;
113 }
114