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