2 * Copyright (c) 2016, NVIDIA CORPORATION.
4 * SPDX-License-Identifier: GPL-2.0
11 #include <asm/arch-tegra/bpmp_abi.h>
13 DECLARE_GLOBAL_DATA_PTR
;
15 struct tegra186_bpmp_i2c
{
19 static inline void serialize_u16(uint8_t **p
, uint16_t val
)
26 /* These just happen to have the same values as I2C_M_* and SERIALI2C_* */
27 #define SUPPORTED_FLAGS \
32 I2C_M_REV_DIR_ADDR | \
37 static int tegra186_bpmp_i2c_xfer(struct udevice
*dev
, struct i2c_msg
*msg
,
40 struct tegra186_bpmp_i2c
*priv
= dev_get_priv(dev
);
41 struct mrq_i2c_request req
;
42 struct mrq_i2c_response resp
;
46 req
.cmd
= CMD_I2C_XFER
;
47 req
.xfer
.bus_id
= priv
->bpmp_bus_id
;
48 p
= &req
.xfer
.data_buf
[0];
49 left
= ARRAY_SIZE(req
.xfer
.data_buf
);
50 for (i
= 0; i
< nmsgs
; i
++) {
52 if (!(msg
[i
].flags
& I2C_M_RD
))
54 if ((len
>= BIT(16)) || (len
> left
))
57 if (msg
[i
].flags
& ~SUPPORTED_FLAGS
)
60 serialize_u16(&p
, msg
[i
].addr
);
61 serialize_u16(&p
, msg
[i
].flags
);
62 serialize_u16(&p
, msg
[i
].len
);
63 if (!(msg
[i
].flags
& I2C_M_RD
)) {
64 memcpy(p
, msg
[i
].buf
, msg
[i
].len
);
68 req
.xfer
.data_size
= p
- &req
.xfer
.data_buf
[0];
70 ret
= misc_call(dev
->parent
, MRQ_I2C
, &req
, sizeof(req
), &resp
,
75 p
= &resp
.xfer
.data_buf
[0];
76 left
= resp
.xfer
.data_size
;
77 if (left
> ARRAY_SIZE(resp
.xfer
.data_buf
))
79 for (i
= 0; i
< nmsgs
; i
++) {
80 if (msg
[i
].flags
& I2C_M_RD
) {
81 memcpy(msg
[i
].buf
, p
, msg
[i
].len
);
89 static int tegra186_bpmp_i2c_probe(struct udevice
*dev
)
91 struct tegra186_bpmp_i2c
*priv
= dev_get_priv(dev
);
93 priv
->bpmp_bus_id
= fdtdec_get_uint(gd
->fdt_blob
, dev_of_offset(dev
),
94 "nvidia,bpmp-bus-id", U32_MAX
);
95 if (priv
->bpmp_bus_id
== U32_MAX
) {
96 debug("%s: could not parse nvidia,bpmp-bus-id\n", __func__
);
103 static const struct dm_i2c_ops tegra186_bpmp_i2c_ops
= {
104 .xfer
= tegra186_bpmp_i2c_xfer
,
107 static const struct udevice_id tegra186_bpmp_i2c_ids
[] = {
108 { .compatible
= "nvidia,tegra186-bpmp-i2c" },
112 U_BOOT_DRIVER(i2c_gpio
) = {
113 .name
= "tegra186_bpmp_i2c",
115 .of_match
= tegra186_bpmp_i2c_ids
,
116 .probe
= tegra186_bpmp_i2c_probe
,
117 .priv_auto_alloc_size
= sizeof(struct tegra186_bpmp_i2c
),
118 .ops
= &tegra186_bpmp_i2c_ops
,