1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) Foundries Ltd. 2022 - All Rights Reserved
4 * Author: Jorge Ramirez-Ortiz <jorge@foundries.io>
5 */
6
7 #include <assert.h>
8 #include <drivers/stm32_i2c.h>
9 #include <i2c_native.h>
10 #include <kernel/boot.h>
11 #include <kernel/dt.h>
12 #include <libfdt.h>
13 #include <phNxpEsePal_i2c.h>
14
15 static_assert(CFG_CORE_SE05X_I2C_BUS < 10);
16 static struct i2c_handle_s i2c;
17
native_i2c_transfer(struct rpc_i2c_request * req,size_t * bytes)18 TEE_Result native_i2c_transfer(struct rpc_i2c_request *req, size_t *bytes)
19 {
20 if (req->mode == RPC_I2C_MODE_READ) {
21 if (stm32_i2c_master_receive(&i2c, req->chip << 1, req->buffer,
22 req->buffer_len, 25))
23 return TEE_ERROR_GENERIC;
24 } else {
25 if (stm32_i2c_master_transmit(&i2c, req->chip << 1, req->buffer,
26 req->buffer_len, 25))
27 return TEE_ERROR_GENERIC;
28 }
29
30 *bytes = req->buffer_len;
31
32 return TEE_SUCCESS;
33 }
34
dt_i2c_bus_config(struct stm32_i2c_init_s * init,struct stm32_pinctrl ** pctrl,size_t * pcnt)35 static int dt_i2c_bus_config(struct stm32_i2c_init_s *init,
36 struct stm32_pinctrl **pctrl, size_t *pcnt)
37 {
38 const fdt32_t *cuint = NULL;
39 const char *path = NULL;
40 char bus[6] = { };
41 void *fdt = NULL;
42 int node = 0;
43
44 fdt = get_embedded_dt();
45 if (!fdt)
46 return -FDT_ERR_NOTFOUND;
47
48 snprintf(bus, sizeof(bus), "i2c%d", CFG_CORE_SE05X_I2C_BUS);
49
50 path = fdt_get_alias(fdt, bus);
51 if (!path)
52 return -FDT_ERR_NOTFOUND;
53
54 node = fdt_path_offset(fdt, path);
55 if (node < 0)
56 return -FDT_ERR_NOTFOUND;
57
58 cuint = fdt_getprop(fdt, node, "clock-frequency", NULL);
59 if (cuint && fdt32_to_cpu(*cuint) != CFG_CORE_SE05X_BAUDRATE)
60 IMSG("SE05X ignoring CFG_CORE_SE05X_BAUDRATE, use DTB");
61 else if (I2C_STANDARD_RATE != CFG_CORE_SE05X_BAUDRATE)
62 IMSG("SE05x ignoring CFG_CORE_SE05X_BAUDRATE, use built-in");
63
64 return stm32_i2c_get_setup_from_fdt(fdt, node, init, pctrl, pcnt);
65 }
66
native_i2c_init(void)67 int native_i2c_init(void)
68 {
69 struct stm32_i2c_init_s i2c_init = { };
70 struct stm32_pinctrl *pinctrl = NULL;
71 size_t pin_count = 0;
72
73 /* No need to re-initialize */
74 if (i2c.base.pa)
75 return 0;
76
77 /* Support only one device on the platform */
78 if (dt_i2c_bus_config(&i2c_init, &pinctrl, &pin_count))
79 return -1;
80
81 /* Probe the device */
82 i2c_init.own_address1 = SMCOM_I2C_ADDRESS;
83 i2c_init.digital_filter_coef = 0;
84 i2c_init.analog_filter = true;
85 i2c.pinctrl_count = pin_count;
86 i2c.pinctrl = pinctrl;
87
88 stm32_i2c_resume(&i2c);
89
90 return stm32_i2c_init(&i2c, &i2c_init);
91 }
92