• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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