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 * Description: Provides i2c port template \n
16 *
17 * History: \n
18 * 2022-08-15, Create file. \n
19 */
20
21 #include "i2c_porting.h"
22 #include "hal_i2c.h"
23 #include "hal_i2c_v150.h"
24 #include "hal_i2c_v150_comm.h"
25 #include "pinctrl.h"
26 #include "osal_interrupt.h"
27 #include "chip_core_irq.h"
28 #include "arch_port.h"
29
30 #define BUS_CLOCK_TIME_24M 24000000UL
31 #define BUS_CLOCK_TIME_40M 40000000UL
32
33 #ifdef BOARD_FPGA
34 #define I2C_CLOCK_DEFAULT BUS_CLOCK_TIME_24M
35 #else
36 #define I2C_CLOCK_DEFAULT BUS_CLOCK_TIME_40M
37 #endif
38
39 typedef void (*i2c_porting_irq_handler)(void);
40
41 typedef struct i2c_irq_handler {
42 uint32_t irq_id;
43 i2c_porting_irq_handler irq_handler;
44 } i2c_irq_handler_t;
45
46
47 uintptr_t g_i2c_base_addrs[I2C_BUS_MAX_NUM] = {
48 (uintptr_t)I2C_BUS_0_BASE_ADDR,
49 (uintptr_t)I2C_BUS_1_BASE_ADDR,
50 #if I2C_BUS_MAX_NUM > 2
51 (uintptr_t)I2C_BUS_2_BASE_ADDR,
52 #if I2C_BUS_MAX_NUM > 3
53 (uintptr_t)I2C_BUS_3_BASE_ADDR,
54 #endif
55 #endif
56 };
57
58 uint32_t g_i2c_clock[I2C_BUS_MAX_NUM] = {
59 (uint32_t)I2C_CLOCK_DEFAULT,
60 (uint32_t)I2C_CLOCK_DEFAULT,
61 #if I2C_BUS_MAX_NUM > 2
62 (uint32_t)I2C_CLOCK_DEFAULT,
63 #if I2C_BUS_MAX_NUM > 3
64 (uint32_t)I2C_CLOCK_DEFAULT,
65 #endif
66 #endif
67 };
68
i2c_porting_base_addr_get(i2c_bus_t bus)69 uintptr_t i2c_porting_base_addr_get(i2c_bus_t bus)
70 {
71 return g_i2c_base_addrs[bus];
72 }
73
irq_i2c0_handler(void)74 static void irq_i2c0_handler(void)
75 {
76 hal_i2c_v150_irq_handler(I2C_BUS_0);
77 osal_irq_clear(I2C_0_IRQN);
78 }
79
irq_i2c1_handler(void)80 static void irq_i2c1_handler(void)
81 {
82 hal_i2c_v150_irq_handler(I2C_BUS_1);
83 osal_irq_clear(I2C_1_IRQN);
84 }
85
86 #if I2C_BUS_MAX_NUM > 2
irq_i2c2_handler(void)87 static void irq_i2c2_handler(void)
88 {
89 hal_i2c_v150_irq_handler(I2C_BUS_2);
90 }
91 #endif
92
93 #if I2C_BUS_MAX_NUM > 3
irq_i2c3_handler(void)94 static void irq_i2c3_handler(void)
95 {
96 hal_i2c_v150_irq_handler(I2C_BUS_3);
97 }
98 #endif
99
100 static i2c_irq_handler_t g_i2c_irq_id[I2C_BUS_MAX_NUM] = {
101 {
102 I2C_0_IRQN,
103 irq_i2c0_handler,
104 },
105 {
106 I2C_1_IRQN,
107 irq_i2c1_handler,
108 },
109 #if I2C_BUS_MAX_NUM > 2
110 {
111 I2C_2_IRQN,
112 irq_i2c2_handler,
113 },
114 #if I2C_BUS_MAX_NUM > 3
115 {
116 I2C_3_IRQN,
117 irq_i2c3_handler,
118 },
119 #endif
120 #endif
121 };
122
i2c_port_set_clock_value(i2c_bus_t bus,uint32_t clock)123 void i2c_port_set_clock_value(i2c_bus_t bus, uint32_t clock)
124 {
125 if (bus >= I2C_BUS_MAX_NUM) {
126 return;
127 }
128
129 g_i2c_clock[bus] = clock;
130 }
131
i2c_port_get_clock_value(i2c_bus_t bus)132 uint32_t i2c_port_get_clock_value(i2c_bus_t bus)
133 {
134 if (bus >= I2C_BUS_MAX_NUM) {
135 return 0;
136 }
137
138 return g_i2c_clock[bus];
139 }
140
i2c_port_register_irq(i2c_bus_t bus)141 void i2c_port_register_irq(i2c_bus_t bus)
142 {
143 osal_irq_request(g_i2c_irq_id[bus].irq_id, (osal_irq_handler)g_i2c_irq_id[bus].irq_handler, NULL, NULL, NULL);
144 osal_irq_set_priority(g_i2c_irq_id[bus].irq_id, irq_prio(g_i2c_irq_id[bus].irq_id));
145 osal_irq_enable(g_i2c_irq_id[bus].irq_id);
146 return;
147 }
148
i2c_port_unregister_irq(i2c_bus_t bus)149 void i2c_port_unregister_irq(i2c_bus_t bus)
150 {
151 osal_irq_disable(g_i2c_irq_id[bus].irq_id);
152 return;
153 }
154
i2c_porting_lock(i2c_bus_t bus)155 uint32_t i2c_porting_lock(i2c_bus_t bus)
156 {
157 unused(bus);
158 return osal_irq_lock();
159 }
160
i2c_porting_unlock(i2c_bus_t bus,uint32_t irq_sts)161 void i2c_porting_unlock(i2c_bus_t bus, uint32_t irq_sts)
162 {
163 unused(bus);
164 osal_irq_restore(irq_sts);
165 }
166
167 #ifdef TEST_SUITE
i2c_port_test_i2c_init_pin(void)168 void i2c_port_test_i2c_init_pin(void)
169 {
170 uapi_reg_write32(I2C_1_SCL_PIN_CTRL_REG, PIN_CTRL_MODE_2);
171 uapi_reg_write32(I2C_1_SDA_PIN_CTRL_REG, PIN_CTRL_MODE_2);
172 }
173 #endif
174