mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
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:
@@ -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
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user