STM32G0 provides an integrated USB Type-C and power delivery interface.
It can be programmed with a firmware to handle UCSI protocol over I2C
interface. A GPIO is used as an interrupt line.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier-rj0Iel/JR4NBDgjK7y7TUQ@xxxxxxxxxxxxxxxx>
---
drivers/usb/typec/ucsi/Kconfig | 10 ++
drivers/usb/typec/ucsi/Makefile | 1 +
drivers/usb/typec/ucsi/ucsi_stm32g0.c | 218 ++++++++++++++++++++++++++
3 files changed, 229 insertions(+)
create mode 100644 drivers/usb/typec/ucsi/ucsi_stm32g0.c
+static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, const void *val,
+ size_t len)
+{
+ struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
+ struct i2c_client *client = g0->client;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ }
+ };
+ unsigned char *buf;
+ int ret;
+
+ buf = kzalloc(len + 1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ buf[0] = offset;
+ memcpy(&buf[1], val, len);
+ msg[0].len = len + 1;
+ msg[0].buf = buf;
+
+ ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+ kfree(buf);
+ if (ret != ARRAY_SIZE(msg)) {
+ dev_err(g0->dev, "i2c write %02x, %02x error: %d\n", client->addr, buf[0], ret);
+
+ return ret < 0 ? ret : -EIO;
+ }
+
+ return 0;
+}
+