i2c: add i2c tee driver for s7 [2/2]

PD#SWPL-135762

Problem:
there is no s7 pwm tee driver

Solution:
add s7 i2c tee driver

Verify:
s7 pxp

Change-Id: I9fa4081a7426c3bbe7138ec848bc7ae8a7d49ad4
Signed-off-by: junyi.zhao <junyi.zhao@amlogic.com>
This commit is contained in:
junyi.zhao
2023-09-26 14:12:02 +08:00
committed by Luan Yuan
parent 0313db6878
commit 28e7e0436f
+43 -8
View File
@@ -20,6 +20,8 @@
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/pinctrl/consumer.h>
#include <linux/arm-smccc.h>
#include <linux/amlogic/secure_pwm_i2c.h>
#endif
/* Meson I2C register map */
@@ -69,6 +71,11 @@ enum {
STATE_WRITE,
};
struct meson_i2c_data {
bool tee;
u32 tee_reg;
};
/**
* struct meson_i2c - Meson I2C device private data
*
@@ -112,8 +119,20 @@ struct meson_i2c {
int retain_fastmode;
int irq;
#endif
struct meson_i2c_data *data;
};
static void meson_i2c_writel(struct meson_i2c *i2c, u32 data, int reg)
{
struct arm_smccc_res res;
if (i2c->data->tee)
arm_smccc_smc(SECURE_PWM_I2C, SECID_I2C, 0,
i2c->data->tee_reg + reg, data, 0, 0, 0, &res);
else
writel(data, i2c->regs + reg);
}
static void meson_i2c_set_mask(struct meson_i2c *i2c, int reg, u32 mask,
u32 val)
{
@@ -122,7 +141,7 @@ static void meson_i2c_set_mask(struct meson_i2c *i2c, int reg, u32 mask,
data = readl(i2c->regs + reg);
data &= ~mask;
data |= val & mask;
writel(data, i2c->regs + reg);
meson_i2c_writel(i2c, data, reg);
}
static void meson_i2c_reset_tokens(struct meson_i2c *i2c)
@@ -303,8 +322,8 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len)
for (i = 4; i < min(8, len); i++)
wdata1 |= *buf++ << ((i - 4) * 8);
writel(wdata0, i2c->regs + REG_TOK_WDATA0);
writel(wdata1, i2c->regs + REG_TOK_WDATA1);
meson_i2c_writel(i2c, wdata0, REG_TOK_WDATA0);
meson_i2c_writel(i2c, wdata1, REG_TOK_WDATA1);
dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__,
wdata0, wdata1, len);
@@ -332,9 +351,8 @@ static void meson_i2c_prepare_xfer(struct meson_i2c *i2c)
if (i2c->last && i2c->pos + i2c->count >= i2c->msg->len)
meson_i2c_add_token(i2c, TOKEN_STOP);
writel(i2c->tokens[0], i2c->regs + REG_TOK_LIST0);
writel(i2c->tokens[1], i2c->regs + REG_TOK_LIST1);
meson_i2c_writel(i2c, i2c->tokens[0], REG_TOK_LIST0);
meson_i2c_writel(i2c, i2c->tokens[1], REG_TOK_LIST1);
}
static irqreturn_t meson_i2c_irq(int irqno, void *dev_id)
@@ -401,7 +419,7 @@ static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg)
meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, GENMASK(7, 0),
(unsigned int)((msg->addr << 1) & GENMASK(7, 0)));
#else
writel(msg->addr << 1, i2c->regs + REG_SLAVE_ADDR);
meson_i2c_writel(i2c, msg->addr << 1, REG_SLAVE_ADDR);
#endif
meson_i2c_add_token(i2c, TOKEN_START);
meson_i2c_add_token(i2c, token);
@@ -564,6 +582,7 @@ static int meson_i2c_probe(struct platform_device *pdev)
if (fwnode_property_present(&np->fwnode, "retain-fast-mode"))
i2c->retain_fastmode = 1;
i2c->data = (struct meson_i2c_data *)of_device_get_match_data(&pdev->dev);
#endif
i2c->dev = &pdev->dev;
platform_set_drvdata(pdev, i2c);
@@ -578,6 +597,8 @@ static int meson_i2c_probe(struct platform_device *pdev)
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
if (i2c->data->tee)
i2c->data->tee_reg = mem->start;
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);
@@ -742,8 +763,22 @@ static const struct dev_pm_ops meson_i2c_pm_ops = {
};
#endif
static struct meson_i2c_data i2c_tee_data = {
.tee = true,
};
static struct meson_i2c_data i2c_normal_data = {
.tee = false,
};
static const struct of_device_id meson_i2c_match[] = {
{ .compatible = "amlogic,meson-i2c" },
{ .compatible = "amlogic,meson-i2c",
.data = &i2c_normal_data
},
{
.compatible = "amlogic,meson-tee-i2c",
.data = &i2c_tee_data
},
{},
};