1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/i2c/busses/i2c-tegra-bpmp.c
5 * Copyright (c) 2016 NVIDIA Corporation. All rights reserved.
7 * Author: Shardar Shariff Md <smohammed@nvidia.com>
10 #include <linux/err.h>
11 #include <linux/i2c.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
19 #include <soc/tegra/bpmp-abi.h>
20 #include <soc/tegra/bpmp.h>
23 * Serialized I2C message header size is 6 bytes and includes address, flags
26 #define SERIALI2C_HDR_SIZE 6
28 struct tegra_bpmp_i2c
{
29 struct i2c_adapter adapter
;
32 struct tegra_bpmp
*bpmp
;
37 * Linux flags are translated to BPMP defined I2C flags that are used in BPMP
38 * firmware I2C driver to avoid any issues in future if Linux I2C flags are
41 static int tegra_bpmp_xlate_flags(u16 flags
, u16
*out
)
43 if (flags
& I2C_M_TEN
) {
44 *out
|= SERIALI2C_TEN
;
48 if (flags
& I2C_M_RD
) {
53 if (flags
& I2C_M_STOP
) {
54 *out
|= SERIALI2C_STOP
;
58 if (flags
& I2C_M_NOSTART
) {
59 *out
|= SERIALI2C_NOSTART
;
60 flags
&= ~I2C_M_NOSTART
;
63 if (flags
& I2C_M_REV_DIR_ADDR
) {
64 *out
|= SERIALI2C_REV_DIR_ADDR
;
65 flags
&= ~I2C_M_REV_DIR_ADDR
;
68 if (flags
& I2C_M_IGNORE_NAK
) {
69 *out
|= SERIALI2C_IGNORE_NAK
;
70 flags
&= ~I2C_M_IGNORE_NAK
;
73 if (flags
& I2C_M_NO_RD_ACK
) {
74 *out
|= SERIALI2C_NO_RD_ACK
;
75 flags
&= ~I2C_M_NO_RD_ACK
;
78 if (flags
& I2C_M_RECV_LEN
) {
79 *out
|= SERIALI2C_RECV_LEN
;
80 flags
&= ~I2C_M_RECV_LEN
;
83 return (flags
!= 0) ? -EINVAL
: 0;
87 * The serialized I2C format is simply the following:
88 * [addr little-endian][flags little-endian][len little-endian][data if write]
89 * [addr little-endian][flags little-endian][len little-endian][data if write]
92 * The flags are translated from Linux kernel representation to seriali2c
93 * representation. Any undefined flag being set causes an error.
95 * The data is there only for writes. Reads have the data transferred in the
96 * other direction, and thus data is not present.
98 * See deserialize_i2c documentation for the data format in the other direction.
100 static int tegra_bpmp_serialize_i2c_msg(struct tegra_bpmp_i2c
*i2c
,
101 struct mrq_i2c_request
*request
,
102 struct i2c_msg
*msgs
,
105 char *buf
= request
->xfer
.data_buf
;
106 unsigned int i
, j
, pos
= 0;
109 for (i
= 0; i
< num
; i
++) {
110 struct i2c_msg
*msg
= &msgs
[i
];
113 err
= tegra_bpmp_xlate_flags(msg
->flags
, &flags
);
117 buf
[pos
++] = msg
->addr
& 0xff;
118 buf
[pos
++] = (msg
->addr
& 0xff00) >> 8;
119 buf
[pos
++] = flags
& 0xff;
120 buf
[pos
++] = (flags
& 0xff00) >> 8;
121 buf
[pos
++] = msg
->len
& 0xff;
122 buf
[pos
++] = (msg
->len
& 0xff00) >> 8;
124 if ((flags
& SERIALI2C_RD
) == 0) {
125 for (j
= 0; j
< msg
->len
; j
++)
126 buf
[pos
++] = msg
->buf
[j
];
130 request
->xfer
.data_size
= pos
;
136 * The data in the BPMP -> CPU direction is composed of sequential blocks for
137 * those messages that have I2C_M_RD. So, for example, if you have:
139 * - !I2C_M_RD, len == 5, data == a0 01 02 03 04
140 * - !I2C_M_RD, len == 1, data == a0
141 * - I2C_M_RD, len == 2, data == [uninitialized buffer 1]
142 * - !I2C_M_RD, len == 1, data == a2
143 * - I2C_M_RD, len == 2, data == [uninitialized buffer 2]
145 * ...then the data in the BPMP -> CPU direction would be 4 bytes total, and
146 * would contain 2 bytes that will go to uninitialized buffer 1, and 2 bytes
147 * that will go to uninitialized buffer 2.
149 static int tegra_bpmp_i2c_deserialize(struct tegra_bpmp_i2c
*i2c
,
150 struct mrq_i2c_response
*response
,
151 struct i2c_msg
*msgs
,
154 size_t size
= response
->xfer
.data_size
, len
= 0, pos
= 0;
155 char *buf
= response
->xfer
.data_buf
;
158 for (i
= 0; i
< num
; i
++)
159 if (msgs
[i
].flags
& I2C_M_RD
)
165 for (i
= 0; i
< num
; i
++) {
166 if (msgs
[i
].flags
& I2C_M_RD
) {
167 memcpy(msgs
[i
].buf
, buf
+ pos
, msgs
[i
].len
);
175 static int tegra_bpmp_i2c_msg_len_check(struct i2c_msg
*msgs
, unsigned int num
)
177 size_t tx_len
= 0, rx_len
= 0;
180 for (i
= 0; i
< num
; i
++)
181 if (!(msgs
[i
].flags
& I2C_M_RD
))
182 tx_len
+= SERIALI2C_HDR_SIZE
+ msgs
[i
].len
;
184 if (tx_len
> TEGRA_I2C_IPC_MAX_IN_BUF_SIZE
)
187 for (i
= 0; i
< num
; i
++)
188 if ((msgs
[i
].flags
& I2C_M_RD
))
189 rx_len
+= msgs
[i
].len
;
191 if (rx_len
> TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE
)
197 static int tegra_bpmp_i2c_msg_xfer(struct tegra_bpmp_i2c
*i2c
,
198 struct mrq_i2c_request
*request
,
199 struct mrq_i2c_response
*response
,
202 struct tegra_bpmp_message msg
;
205 request
->cmd
= CMD_I2C_XFER
;
206 request
->xfer
.bus_id
= i2c
->bus
;
208 memset(&msg
, 0, sizeof(msg
));
210 msg
.tx
.data
= request
;
211 msg
.tx
.size
= sizeof(*request
);
212 msg
.rx
.data
= response
;
213 msg
.rx
.size
= sizeof(*response
);
216 err
= tegra_bpmp_transfer_atomic(i2c
->bpmp
, &msg
);
218 err
= tegra_bpmp_transfer(i2c
->bpmp
, &msg
);
223 static int tegra_bpmp_i2c_xfer_common(struct i2c_adapter
*adapter
,
224 struct i2c_msg
*msgs
, int num
,
227 struct tegra_bpmp_i2c
*i2c
= i2c_get_adapdata(adapter
);
228 struct mrq_i2c_response response
;
229 struct mrq_i2c_request request
;
232 err
= tegra_bpmp_i2c_msg_len_check(msgs
, num
);
234 dev_err(i2c
->dev
, "unsupported message length\n");
238 memset(&request
, 0, sizeof(request
));
239 memset(&response
, 0, sizeof(response
));
241 err
= tegra_bpmp_serialize_i2c_msg(i2c
, &request
, msgs
, num
);
243 dev_err(i2c
->dev
, "failed to serialize message: %d\n", err
);
247 err
= tegra_bpmp_i2c_msg_xfer(i2c
, &request
, &response
, atomic
);
249 dev_err(i2c
->dev
, "failed to transfer message: %d\n", err
);
253 err
= tegra_bpmp_i2c_deserialize(i2c
, &response
, msgs
, num
);
255 dev_err(i2c
->dev
, "failed to deserialize message: %d\n", err
);
262 static int tegra_bpmp_i2c_xfer(struct i2c_adapter
*adapter
,
263 struct i2c_msg
*msgs
, int num
)
265 return tegra_bpmp_i2c_xfer_common(adapter
, msgs
, num
, false);
268 static int tegra_bpmp_i2c_xfer_atomic(struct i2c_adapter
*adapter
,
269 struct i2c_msg
*msgs
, int num
)
271 return tegra_bpmp_i2c_xfer_common(adapter
, msgs
, num
, true);
274 static u32
tegra_bpmp_i2c_func(struct i2c_adapter
*adapter
)
276 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
| I2C_FUNC_10BIT_ADDR
|
277 I2C_FUNC_PROTOCOL_MANGLING
| I2C_FUNC_NOSTART
;
280 static const struct i2c_algorithm tegra_bpmp_i2c_algo
= {
281 .master_xfer
= tegra_bpmp_i2c_xfer
,
282 .master_xfer_atomic
= tegra_bpmp_i2c_xfer_atomic
,
283 .functionality
= tegra_bpmp_i2c_func
,
286 static int tegra_bpmp_i2c_probe(struct platform_device
*pdev
)
288 struct tegra_bpmp_i2c
*i2c
;
292 i2c
= devm_kzalloc(&pdev
->dev
, sizeof(*i2c
), GFP_KERNEL
);
296 i2c
->dev
= &pdev
->dev
;
298 i2c
->bpmp
= dev_get_drvdata(pdev
->dev
.parent
);
302 err
= of_property_read_u32(pdev
->dev
.of_node
, "nvidia,bpmp-bus-id",
309 i2c_set_adapdata(&i2c
->adapter
, i2c
);
310 i2c
->adapter
.owner
= THIS_MODULE
;
311 strlcpy(i2c
->adapter
.name
, "Tegra BPMP I2C adapter",
312 sizeof(i2c
->adapter
.name
));
313 i2c
->adapter
.algo
= &tegra_bpmp_i2c_algo
;
314 i2c
->adapter
.dev
.parent
= &pdev
->dev
;
315 i2c
->adapter
.dev
.of_node
= pdev
->dev
.of_node
;
317 platform_set_drvdata(pdev
, i2c
);
319 return i2c_add_adapter(&i2c
->adapter
);
322 static int tegra_bpmp_i2c_remove(struct platform_device
*pdev
)
324 struct tegra_bpmp_i2c
*i2c
= platform_get_drvdata(pdev
);
326 i2c_del_adapter(&i2c
->adapter
);
331 static const struct of_device_id tegra_bpmp_i2c_of_match
[] = {
332 { .compatible
= "nvidia,tegra186-bpmp-i2c", },
335 MODULE_DEVICE_TABLE(of
, tegra_bpmp_i2c_of_match
);
337 static struct platform_driver tegra_bpmp_i2c_driver
= {
339 .name
= "tegra-bpmp-i2c",
340 .of_match_table
= tegra_bpmp_i2c_of_match
,
342 .probe
= tegra_bpmp_i2c_probe
,
343 .remove
= tegra_bpmp_i2c_remove
,
345 module_platform_driver(tegra_bpmp_i2c_driver
);
347 MODULE_DESCRIPTION("NVIDIA Tegra BPMP I2C bus controller driver");
348 MODULE_AUTHOR("Shardar Shariff Md <smohammed@nvidia.com>");
349 MODULE_AUTHOR("Juha-Matti Tilli");
350 MODULE_LICENSE("GPL v2");