mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
clk: rs9: Support device specific dif bit calculation
The calculation DIFx is BIT(n) +1 is only true for 9FGV0241. With additional devices this is getting more complicated. Support a base bit for the DIF calculation, currently only devices with consecutive bits are supported, e.g. the 6-channel device needs additional logic. Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Marek Vasut <marex@denx.de> Link: https://lore.kernel.org/r/20230310075535.3476580-3-alexander.stein@ew.tq-group.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
committed by
Stephen Boyd
parent
51f2be462f
commit
603df193ec
@@ -18,7 +18,6 @@
|
|||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
#define RS9_REG_OE 0x0
|
#define RS9_REG_OE 0x0
|
||||||
#define RS9_REG_OE_DIF_OE(n) BIT((n) + 1)
|
|
||||||
#define RS9_REG_SS 0x1
|
#define RS9_REG_SS 0x1
|
||||||
#define RS9_REG_SS_AMP_0V6 0x0
|
#define RS9_REG_SS_AMP_0V6 0x0
|
||||||
#define RS9_REG_SS_AMP_0V7 0x1
|
#define RS9_REG_SS_AMP_0V7 0x1
|
||||||
@@ -31,9 +30,6 @@
|
|||||||
#define RS9_REG_SS_SSC_MASK (3 << 3)
|
#define RS9_REG_SS_SSC_MASK (3 << 3)
|
||||||
#define RS9_REG_SS_SSC_LOCK BIT(5)
|
#define RS9_REG_SS_SSC_LOCK BIT(5)
|
||||||
#define RS9_REG_SR 0x2
|
#define RS9_REG_SR 0x2
|
||||||
#define RS9_REG_SR_2V0_DIF(n) 0
|
|
||||||
#define RS9_REG_SR_3V0_DIF(n) BIT((n) + 1)
|
|
||||||
#define RS9_REG_SR_DIF_MASK(n) BIT((n) + 1)
|
|
||||||
#define RS9_REG_REF 0x3
|
#define RS9_REG_REF 0x3
|
||||||
#define RS9_REG_REF_OE BIT(4)
|
#define RS9_REG_REF_OE BIT(4)
|
||||||
#define RS9_REG_REF_OD BIT(5)
|
#define RS9_REG_REF_OD BIT(5)
|
||||||
@@ -159,17 +155,27 @@ static const struct regmap_config rs9_regmap_config = {
|
|||||||
.reg_read = rs9_regmap_i2c_read,
|
.reg_read = rs9_regmap_i2c_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
|
||||||
|
{
|
||||||
|
enum rs9_model model = rs9->chip_info->model;
|
||||||
|
|
||||||
|
if (model == RENESAS_9FGV0241)
|
||||||
|
return BIT(idx) + 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
|
static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = rs9->client;
|
struct i2c_client *client = rs9->client;
|
||||||
|
u8 dif = rs9_calc_dif(rs9, idx);
|
||||||
unsigned char name[5] = "DIF0";
|
unsigned char name[5] = "DIF0";
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
int ret;
|
int ret;
|
||||||
u32 sr;
|
u32 sr;
|
||||||
|
|
||||||
/* Set defaults */
|
/* Set defaults */
|
||||||
rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
|
rs9->clk_dif_sr |= dif;
|
||||||
rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
|
|
||||||
|
|
||||||
snprintf(name, 5, "DIF%d", idx);
|
snprintf(name, 5, "DIF%d", idx);
|
||||||
np = of_get_child_by_name(client->dev.of_node, name);
|
np = of_get_child_by_name(client->dev.of_node, name);
|
||||||
@@ -181,11 +187,9 @@ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
|
|||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (sr == 2000000) { /* 2V/ns */
|
if (sr == 2000000) { /* 2V/ns */
|
||||||
rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
|
rs9->clk_dif_sr &= ~dif;
|
||||||
rs9->clk_dif_sr |= RS9_REG_SR_2V0_DIF(idx);
|
|
||||||
} else if (sr == 3000000) { /* 3V/ns (default) */
|
} else if (sr == 3000000) { /* 3V/ns (default) */
|
||||||
rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
|
rs9->clk_dif_sr |= dif;
|
||||||
rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
|
|
||||||
} else
|
} else
|
||||||
ret = dev_err_probe(&client->dev, -EINVAL,
|
ret = dev_err_probe(&client->dev, -EINVAL,
|
||||||
"Invalid renesas,slew-rate value\n");
|
"Invalid renesas,slew-rate value\n");
|
||||||
@@ -256,11 +260,13 @@ static void rs9_update_config(struct rs9_driver_data *rs9)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < rs9->chip_info->num_clks; i++) {
|
for (i = 0; i < rs9->chip_info->num_clks; i++) {
|
||||||
if (rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i))
|
u8 dif = rs9_calc_dif(rs9, i);
|
||||||
|
|
||||||
|
if (rs9->clk_dif_sr & dif)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
regmap_update_bits(rs9->regmap, RS9_REG_SR, RS9_REG_SR_3V0_DIF(i),
|
regmap_update_bits(rs9->regmap, RS9_REG_SR, dif,
|
||||||
rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i));
|
rs9->clk_dif_sr & dif);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user