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