1 /*
2 * Copyright (c) 2021 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
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 "stm32mp1_i2c.h"
17
HdfCopyFromUser(void * to,const void * from,unsigned long n)18 static int HdfCopyFromUser(void *to, const void *from, unsigned long n)
19 {
20 int ret;
21 ret = LOS_CopyToKernel(to, n, from, n);
22 if (ret != LOS_OK) {
23 dprintf("%s: copy from kernel fail:%d", __func__, ret);
24 return HDF_FAILURE;
25 }
26 return HDF_SUCCESS;
27 }
28
HdfCopyToUser(void * to,const void * from,unsigned long n)29 static int HdfCopyToUser(void *to, const void *from, unsigned long n)
30 {
31 int ret;
32 ret = LOS_CopyFromKernel(to, n, from, n);
33 if (ret != LOS_OK) {
34 dprintf("%s: copy from kernel fail:%d", __func__, ret);
35 return HDF_FAILURE;
36 }
37 return HDF_SUCCESS;
38 }
39
GPIORemp(uint32_t port)40 static GPIO_TypeDef *GPIORemp(uint32_t port)
41 {
42 if (port > GPIO_Z) {
43 HDF_LOGE("%s: gpio remp stm32mp1 fail!", __func__);
44 return 0;
45 }
46 switch (port) {
47 case GPIO_A:
48 return OsalIoRemap(GPIOA_BASE, 0x400);
49 break;
50 case GPIO_B:
51 return OsalIoRemap(GPIOB_BASE, 0x400);
52 break;
53 case GPIO_C:
54 return OsalIoRemap(GPIOC_BASE, 0x400);
55 break;
56 case GPIO_D:
57 return OsalIoRemap(GPIOD_BASE, 0x400);
58 break;
59 case GPIO_E:
60 return OsalIoRemap(GPIOE_BASE, 0x400);
61 break;
62 case GPIO_F:
63 return OsalIoRemap(GPIOF_BASE, 0x400);
64 break;
65 case GPIO_G:
66 return OsalIoRemap(GPIOG_BASE, 0x400);
67 break;
68 case GPIO_H:
69 return OsalIoRemap(GPIOH_BASE, 0x400);
70 break;
71 case GPIO_I:
72 return OsalIoRemap(GPIOI_BASE, 0x400);
73 break;
74 case GPIO_J:
75 return OsalIoRemap(GPIOJ_BASE, 0x400);
76 break;
77 case GPIO_K:
78 return OsalIoRemap(GPIOK_BASE, 0x400);
79 break;
80 case GPIO_Z:
81 return OsalIoRemap(GPIOZ_BASE, 0x400);
82 break;
83
84 default:
85 break;
86 }
87 return 0;
88 }
89
Mp1xxI2cCntlrInit(struct Mp1xxI2cCntlr * stm32mp1)90 static void Mp1xxI2cCntlrInit(struct Mp1xxI2cCntlr *stm32mp1)
91 {
92 GPIO_InitTypeDef GPIO_Init = { 0 };
93 I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)&stm32mp1->hi2c;
94
95 /* init gpio */
96 GPIO_Init.Mode = GPIO_MODE_AF_OD; // 模式
97 GPIO_Init.Pull = GPIO_PULLUP; // 上拉
98 GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 频率
99 if (stm32mp1->bus == 1) {
100 GPIO_Init.Alternate = GPIO_AF5;
101 } else {
102 GPIO_Init.Alternate = GPIO_AF4;
103 }
104 GPIO_Init.Pin = 1 << stm32mp1->i2cClkIomux[1];
105 HAL_GPIO_Init(GPIORemp(stm32mp1->i2cClkIomux[0]), &GPIO_Init);
106 GPIO_Init.Pin = 1 << stm32mp1->i2cDataIomux[1];
107 HAL_GPIO_Init(GPIORemp(stm32mp1->i2cDataIomux[0]), &GPIO_Init);
108
109 HAL_I2C_Init(hi2c);
110 }
111
Mp1xxI2cXferOneMsgPolling(const struct Mp1xxI2cCntlr * stm32mp1,const struct Mp1xxTransferData * td)112 static int32_t Mp1xxI2cXferOneMsgPolling(const struct Mp1xxI2cCntlr *stm32mp1, const struct Mp1xxTransferData *td)
113 {
114 int32_t status = HDF_SUCCESS;
115 uint8_t val[255];
116 struct I2cMsg *msg = &td->msgs[td->index];
117 I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)&stm32mp1->hi2c;
118 if (msg->flags & I2C_FLAG_READ) {
119 HAL_I2C_Master_Receive(hi2c, msg->addr + 1, val, msg->len, I2C_TIMEOUT);
120 status = HdfCopyToUser((void *)msg->buf, (void *)val, msg->len);
121 if (status != HDF_SUCCESS) {
122 HDF_LOGE("%s: HdfCopyFromUser fail:%d", __func__, status);
123 goto end;
124 }
125 } else {
126 status = HdfCopyFromUser((void *)val, (void *)msg->buf, msg->len);
127 if (status != HDF_SUCCESS) {
128 HDF_LOGE("%s: copy to kernel fail:%d", __func__, status);
129 goto end;
130 }
131 HAL_I2C_Master_Transmit(hi2c, msg->addr, val, msg->len, I2C_TIMEOUT);
132 }
133
134 end:
135 return status;
136 }
137
Mp1xxI2cTransfer(struct I2cCntlr * cntlr,struct I2cMsg * msgs,int16_t count)138 static int32_t Mp1xxI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count)
139 {
140 int32_t ret = HDF_SUCCESS;
141 unsigned long irqSave;
142 struct Mp1xxI2cCntlr *stm32mp1 = NULL;
143 struct Mp1xxTransferData td;
144
145 if (cntlr == NULL || cntlr->priv == NULL) {
146 HDF_LOGE("%s: cntlr lor stm32mp1 null!", __func__);
147 return HDF_ERR_INVALID_OBJECT;
148 }
149 stm32mp1 = (struct Mp1xxI2cCntlr *)cntlr;
150
151 if (msgs == NULL || count <= 0) {
152 HDF_LOGE("%s: err parms! count:%d", __func__, count);
153 return HDF_ERR_INVALID_PARAM;
154 }
155
156 td.msgs = msgs;
157 td.count = count;
158 td.index = 0;
159 irqSave = LOS_IntLock();
160 while (td.index < td.count) {
161 ret = Mp1xxI2cXferOneMsgPolling(stm32mp1, &td);
162 if (ret != 0) {
163 break;
164 }
165 td.index++;
166 }
167 LOS_IntRestore(irqSave);
168 return (td.index > 0) ? td.index : ret;
169 }
170
171 static const struct I2cMethod g_method = {
172 .transfer = Mp1xxI2cTransfer,
173 };
174
Mp1xxI2cLock(struct I2cCntlr * cntlr)175 static int32_t Mp1xxI2cLock(struct I2cCntlr *cntlr)
176 {
177 struct Mp1xxI2cCntlr *stm32mp1 = (struct Mp1xxI2cCntlr *)cntlr;
178 if (stm32mp1 != NULL) {
179 return OsalSpinLock(&stm32mp1->spin);
180 }
181 return HDF_SUCCESS;
182 }
183
Mp1xxI2cUnlock(struct I2cCntlr * cntlr)184 static void Mp1xxI2cUnlock(struct I2cCntlr *cntlr)
185 {
186 struct Mp1xxI2cCntlr *stm32mp1 = (struct Mp1xxI2cCntlr *)cntlr;
187 if (stm32mp1 != NULL) {
188 (void)OsalSpinUnlock(&stm32mp1->spin);
189 }
190 }
191
192 static const struct I2cLockMethod g_lockOps = {
193 .lock = Mp1xxI2cLock,
194 .unlock = Mp1xxI2cUnlock,
195 };
196
Mp1xxI2cReadDrs(struct Mp1xxI2cCntlr * stm32mp1,const struct DeviceResourceNode * node)197 static int32_t Mp1xxI2cReadDrs(struct Mp1xxI2cCntlr *stm32mp1, const struct DeviceResourceNode *node)
198 {
199 int32_t ret;
200 struct DeviceResourceIface *drsOps = NULL;
201
202 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
203 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
204 HDF_LOGE("%s: invalid drs ops fail!", __func__);
205 return HDF_FAILURE;
206 }
207
208 ret = drsOps->GetUint32(node, "reg_pbase", &stm32mp1->regBasePhy, 0);
209 if (ret != HDF_SUCCESS) {
210 HDF_LOGE("%s: read regBase fail!", __func__);
211 return ret;
212 }
213
214 ret = drsOps->GetUint16(node, "reg_size", &stm32mp1->regSize, 0);
215 if (ret != HDF_SUCCESS) {
216 HDF_LOGE("%s: read reg_size fail!", __func__);
217 return ret;
218 }
219
220 ret = drsOps->GetUint16(node, "bus", (uint16_t *)&stm32mp1->bus, 0);
221 if (ret != HDF_SUCCESS) {
222 HDF_LOGE("%s: read bus fail!", __func__);
223 return ret;
224 }
225 ret = drsOps->GetUint32Array(node, "i2cClkIomux", stm32mp1->i2cClkIomux, CLK_IO_MUX_BUF_SIZE, 0);
226 if (ret != HDF_SUCCESS) {
227 HDF_LOGE("%s: read no_stretch_mode fail!", __func__);
228 return ret;
229 }
230 ret = drsOps->GetUint32Array(node, "i2cDataIomux", stm32mp1->i2cDataIomux, DATA_IO_MUX_BUF_SIZE, 0);
231 if (ret != HDF_SUCCESS) {
232 HDF_LOGE("%s: read no_stretch_mode fail!", __func__);
233 return ret;
234 }
235 ret = drsOps->GetUint32(node, "timing", &stm32mp1->hi2c.Init.Timing, 0);
236 if (ret != HDF_SUCCESS) {
237 HDF_LOGE("%s: read timing fail!", __func__);
238 return ret;
239 }
240
241 ret = drsOps->GetUint32(node, "own_address1", &stm32mp1->hi2c.Init.OwnAddress1, 0);
242 if (ret != HDF_SUCCESS) {
243 HDF_LOGE("%s: read own_address1 fail!", __func__);
244 return ret;
245 }
246
247 ret = drsOps->GetUint32(node, "addressing_mode", &stm32mp1->hi2c.Init.AddressingMode, 0);
248 if (ret != HDF_SUCCESS) {
249 HDF_LOGE("%s: read addressing_mode fail!", __func__);
250 return ret;
251 }
252
253 ret = drsOps->GetUint32(node, "dual_address_mode", &stm32mp1->hi2c.Init.DualAddressMode, 0);
254 if (ret != HDF_SUCCESS) {
255 HDF_LOGE("%s: read dual_address_mode fail!", __func__);
256 return ret;
257 }
258
259 ret = drsOps->GetUint32(node, "own_address2", &stm32mp1->hi2c.Init.OwnAddress2, 0);
260 if (ret != HDF_SUCCESS) {
261 HDF_LOGE("%s: read own_address2 fail!", __func__);
262 return ret;
263 }
264
265 ret = drsOps->GetUint32(node, "own_address_2_masks", &stm32mp1->hi2c.Init.OwnAddress2Masks, 0);
266 if (ret != HDF_SUCCESS) {
267 HDF_LOGE("%s: read own_address_2_masks fail!", __func__);
268 return ret;
269 }
270
271 ret = drsOps->GetUint32(node, "general_call_mode", &stm32mp1->hi2c.Init.GeneralCallMode, 0);
272 if (ret != HDF_SUCCESS) {
273 HDF_LOGE("%s: read general_call_mode fail!", __func__);
274 return ret;
275 }
276
277 ret = drsOps->GetUint32(node, "no_stretch_mode", &stm32mp1->hi2c.Init.NoStretchMode, 0);
278 if (ret != HDF_SUCCESS) {
279 HDF_LOGE("%s: read no_stretch_mode fail!", __func__);
280 return ret;
281 }
282 return HDF_SUCCESS;
283 }
284
Mp1xxI2cRccConfig(uint32_t bus)285 static void Mp1xxI2cRccConfig(uint32_t bus)
286 {
287 RCC_PeriphCLKInitTypeDef I2C2_clock_source_config;
288
289 switch (bus) {
290 case I2C_1:
291 __HAL_RCC_I2C1_CLK_ENABLE();
292 I2C2_clock_source_config.I2c12ClockSelection = RCC_I2C12CLKSOURCE_HSI;
293 I2C2_clock_source_config.PeriphClockSelection = RCC_PERIPHCLK_I2C12;
294 HAL_RCCEx_PeriphCLKConfig(&I2C2_clock_source_config);
295 break;
296 case I2C_2:
297 __HAL_RCC_I2C2_CLK_ENABLE();
298 I2C2_clock_source_config.I2c12ClockSelection = RCC_I2C12CLKSOURCE_HSI;
299 I2C2_clock_source_config.PeriphClockSelection = RCC_PERIPHCLK_I2C12;
300 HAL_RCCEx_PeriphCLKConfig(&I2C2_clock_source_config);
301 break;
302 case I2C_3:
303 __HAL_RCC_I2C3_CLK_ENABLE();
304 I2C2_clock_source_config.I2c35ClockSelection = RCC_I2C35CLKSOURCE_HSI;
305 I2C2_clock_source_config.PeriphClockSelection = RCC_PERIPHCLK_I2C35;
306 HAL_RCCEx_PeriphCLKConfig(&I2C2_clock_source_config);
307 break;
308 case I2C_4:
309 __HAL_RCC_I2C4_CLK_ENABLE();
310 I2C2_clock_source_config.I2c46ClockSelection = RCC_I2C46CLKSOURCE_HSI;
311 I2C2_clock_source_config.PeriphClockSelection = RCC_PERIPHCLK_I2C46;
312 HAL_RCCEx_PeriphCLKConfig(&I2C2_clock_source_config);
313 break;
314 case I2C_5:
315 __HAL_RCC_I2C5_CLK_ENABLE();
316 I2C2_clock_source_config.I2c35ClockSelection = RCC_I2C35CLKSOURCE_HSI;
317 I2C2_clock_source_config.PeriphClockSelection = RCC_PERIPHCLK_I2C35;
318 HAL_RCCEx_PeriphCLKConfig(&I2C2_clock_source_config);
319 break;
320 case I2C_6:
321 __HAL_RCC_I2C6_CLK_ENABLE();
322 I2C2_clock_source_config.I2c46ClockSelection = RCC_I2C46CLKSOURCE_HSI;
323 I2C2_clock_source_config.PeriphClockSelection = RCC_PERIPHCLK_I2C46;
324 HAL_RCCEx_PeriphCLKConfig(&I2C2_clock_source_config);
325 break;
326 default:
327 break;
328 }
329 }
330
Mp1xxI2cParseAndInit(struct HdfDeviceObject * device,const struct DeviceResourceNode * node)331 static int32_t Mp1xxI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
332 {
333 int32_t ret;
334 struct Mp1xxI2cCntlr *stm32mp1 = NULL;
335
336 (void)device;
337
338 stm32mp1 = (struct Mp1xxI2cCntlr *)OsalMemCalloc(sizeof(*stm32mp1));
339 if (stm32mp1 == NULL) {
340 HDF_LOGE("%s: malloc stm32mp1 fail!", __func__);
341 return HDF_ERR_MALLOC_FAIL;
342 }
343
344 ret = Mp1xxI2cReadDrs(stm32mp1, node);
345 if (ret != HDF_SUCCESS) {
346 HDF_LOGE("%s: read drs fail! ret:%d", __func__, ret);
347 goto __ERR__;
348 }
349
350 stm32mp1->hi2c.Instance = (I2C_TypeDef *)OsalIoRemap(stm32mp1->regBasePhy, stm32mp1->regSize);
351
352 if (stm32mp1->hi2c.Instance == NULL) {
353 HDF_LOGE("%s: ioremap regBase fail!", __func__);
354 ret = HDF_ERR_IO;
355 goto __ERR__;
356 }
357
358 Mp1xxI2cRccConfig(stm32mp1->bus);
359
360 Mp1xxI2cCntlrInit(stm32mp1);
361
362 stm32mp1->cntlr.priv = (void *)node;
363 stm32mp1->cntlr.busId = stm32mp1->bus;
364 stm32mp1->cntlr.ops = &g_method;
365 stm32mp1->cntlr.lockOps = &g_lockOps;
366 (void)OsalSpinInit(&stm32mp1->spin);
367 ret = I2cCntlrAdd(&stm32mp1->cntlr);
368 if (ret != HDF_SUCCESS) {
369 HDF_LOGE("%s: add i2c controller fail:%d!", __func__, ret);
370 (void)OsalSpinDestroy(&stm32mp1->spin);
371 goto __ERR__;
372 }
373 (void)I2cAddVfsById(stm32mp1->cntlr.busId);
374 return HDF_SUCCESS;
375 __ERR__:
376 if (stm32mp1 != NULL) {
377 if (stm32mp1->hi2c.Instance != NULL) {
378 OsalIoUnmap((void *)stm32mp1->hi2c.Instance);
379 stm32mp1->hi2c.Instance = NULL;
380 }
381 OsalMemFree(stm32mp1);
382 stm32mp1 = NULL;
383 }
384 return ret;
385 }
386
HdfI2cDeviceInit(struct HdfDeviceObject * device)387 int32_t HdfI2cDeviceInit(struct HdfDeviceObject *device)
388 {
389 int32_t ret;
390 const struct DeviceResourceNode *childNode = NULL;
391
392 HDF_LOGE("%s: Enter", __func__);
393 if (device == NULL || device->property == NULL) {
394 HDF_LOGE("%s: device or property is NULL", __func__);
395 return HDF_ERR_INVALID_OBJECT;
396 }
397
398 ret = HDF_SUCCESS;
399 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode)
400 {
401 ret = Mp1xxI2cParseAndInit(device, childNode);
402 if (ret != HDF_SUCCESS) {
403 break;
404 }
405 }
406
407 return ret;
408 }
Mp1xxI2cRemoveByNode(const struct DeviceResourceNode * node)409 static void Mp1xxI2cRemoveByNode(const struct DeviceResourceNode *node)
410 {
411 int32_t ret;
412 int16_t bus;
413 struct I2cCntlr *cntlr = NULL;
414 struct Mp1xxI2cCntlr *stm32mp1 = NULL;
415 struct DeviceResourceIface *drsOps = NULL;
416
417 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
418 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
419 HDF_LOGE("%s: invalid drs ops fail!", __func__);
420 return;
421 }
422
423 ret = drsOps->GetUint16(node, "bus", (uint16_t *)&bus, 0);
424 if (ret != HDF_SUCCESS) {
425 HDF_LOGE("%s: read bus fail!", __func__);
426 return;
427 }
428
429 cntlr = I2cCntlrGet(bus);
430 if (cntlr != NULL && cntlr->priv == node) {
431 I2cCntlrPut(cntlr);
432 I2cCntlrRemove(cntlr);
433 stm32mp1 = (struct Mp1xxI2cCntlr *)cntlr;
434 OsalIoUnmap((void *)stm32mp1->regBasePhy);
435 (void)OsalSpinDestroy(&stm32mp1->spin);
436 OsalMemFree(stm32mp1);
437 }
438 return;
439 }
440
HdfI2cDeviceRelease(struct HdfDeviceObject * device)441 void HdfI2cDeviceRelease(struct HdfDeviceObject *device)
442 {
443 const struct DeviceResourceNode *childNode = NULL;
444
445 HDF_LOGI("%s: enter", __func__);
446
447 if (device == NULL || device->property == NULL) {
448 HDF_LOGE("%s: device or property is NULL", __func__);
449 return;
450 }
451 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode)
452 {
453 Mp1xxI2cRemoveByNode(childNode);
454 }
455 }
456
457 struct HdfDriverEntry g_i2cDriverEntry = {
458 .moduleVersion = 1,
459 .Init = HdfI2cDeviceInit,
460 .Release = HdfI2cDeviceRelease,
461 .moduleName = "HDF_PLATFORM_I2C",
462 };
463 HDF_INIT(g_i2cDriverEntry);
464