1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) Foundries Ltd. 2020 - All Rights Reserved
4  * Author: Jorge Ramirez <jorge@foundries.io>
5  */
6 
7 #include <compiler.h>
8 #include <drivers/imx_i2c.h>
9 #include <glue.h>
10 #include <initcall.h>
11 #include <kernel/rpc_io_i2c.h>
12 #include <phNxpEsePal_i2c.h>
13 
14 static TEE_Result (*transfer)(struct rpc_i2c_request *req, size_t *bytes);
15 
native_i2c_transfer(struct rpc_i2c_request * req,size_t * bytes)16 static TEE_Result native_i2c_transfer(struct rpc_i2c_request *req,
17 				      size_t *bytes)
18 {
19 	TEE_Result ret = TEE_ERROR_GENERIC;
20 
21 	if (req->mode == RPC_I2C_MODE_READ)
22 		ret = imx_i2c_read(req->bus, req->chip, req->buffer,
23 				   req->buffer_len);
24 	else
25 		ret = imx_i2c_write(req->bus, req->chip, req->buffer,
26 				    req->buffer_len);
27 
28 	if (!ret)
29 		*bytes = req->buffer_len;
30 
31 	return ret;
32 }
33 
i2c_transfer(uint8_t * buffer,int len,enum rpc_i2c_mode mode)34 static int i2c_transfer(uint8_t *buffer, int len, enum rpc_i2c_mode mode)
35 {
36 	struct rpc_i2c_request request = {
37 		.bus = CFG_CORE_SE05X_I2C_BUS,
38 		.chip = SMCOM_I2C_ADDRESS >> 1,
39 		.mode = mode,
40 		.buffer = buffer,
41 		.buffer_len = len,
42 		.flags = 0,
43 	};
44 	size_t bytes = 0;
45 	int retry = 5;
46 
47 	do {
48 		if ((*transfer)(&request, &bytes) == TEE_SUCCESS)
49 			return bytes;
50 	} while (--retry);
51 
52 	return -1;
53 }
54 
glue_i2c_read(uint8_t * buffer,int len)55 int glue_i2c_read(uint8_t *buffer, int len)
56 {
57 	return i2c_transfer(buffer, len, RPC_I2C_MODE_READ);
58 }
59 
glue_i2c_write(uint8_t * buffer,int len)60 int glue_i2c_write(uint8_t *buffer, int len)
61 {
62 	return i2c_transfer(buffer, len, RPC_I2C_MODE_WRITE);
63 }
64 
glue_i2c_init(void)65 int glue_i2c_init(void)
66 {
67 	if (transfer == rpc_io_i2c_transfer)
68 		return 0;
69 
70 	transfer = native_i2c_transfer;
71 
72 	if (imx_i2c_init(CFG_CORE_SE05X_I2C_BUS, CFG_CORE_SE05X_BAUDRATE))
73 		return -1;
74 
75 	if (imx_i2c_probe(CFG_CORE_SE05X_I2C_BUS, SMCOM_I2C_ADDRESS >> 1))
76 		return -1;
77 
78 	return 0;
79 }
80 
load_trampoline(void)81 static TEE_Result load_trampoline(void)
82 {
83 	transfer = rpc_io_i2c_transfer;
84 
85 	return TEE_SUCCESS;
86 }
87 
88 boot_final(load_trampoline);
89