Commit 74fe93ea authored by Hugo Villeneuve's avatar Hugo Villeneuve Committed by Greg Kroah-Hartman

serial: max310x: use common detect function for all variants

Simplify driver by defining a common function to handle the detection
of all variants.
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: default avatarHugo Villeneuve <hvilleneuve@dimonoff.com>
Link: https://lore.kernel.org/r/20240118152213.2644269-14-hugo@hugovil.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 08ad4824
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#define MAX310X_BRGDIVMSB_REG (0x1d) /* Baud rate divisor MSB */ #define MAX310X_BRGDIVMSB_REG (0x1d) /* Baud rate divisor MSB */
#define MAX310X_CLKSRC_REG (0x1e) /* Clock source */ #define MAX310X_CLKSRC_REG (0x1e) /* Clock source */
#define MAX310X_REG_1F (0x1f) #define MAX310X_REG_1F (0x1f)
#define MAX310X_EXTREG_START (0x20) /* Only relevant in SPI mode. */
#define MAX310X_REVID_REG MAX310X_REG_1F /* Revision ID */ #define MAX310X_REVID_REG MAX310X_REG_1F /* Revision ID */
...@@ -74,9 +75,9 @@ ...@@ -74,9 +75,9 @@
#define MAX310X_GLOBALCMD_REG MAX310X_REG_1F /* Global Command (WO) */ #define MAX310X_GLOBALCMD_REG MAX310X_REG_1F /* Global Command (WO) */
/* Extended registers */ /* Extended registers */
#define MAX310X_SPI_REVID_EXTREG MAX310X_REG_05 /* Revision ID */ #define MAX310X_REVID_EXTREG (0x25) /* Revision ID
#define MAX310X_I2C_REVID_EXTREG (0x25) /* Revision ID */ * (extended addressing space)
*/
/* IRQ register bits */ /* IRQ register bits */
#define MAX310X_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ #define MAX310X_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */
#define MAX310X_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ #define MAX310X_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */
...@@ -250,8 +251,7 @@ ...@@ -250,8 +251,7 @@
struct max310x_if_cfg { struct max310x_if_cfg {
int (*extended_reg_enable)(struct device *dev, bool enable); int (*extended_reg_enable)(struct device *dev, bool enable);
u8 rev_id_offset;
unsigned int rev_id_reg;
}; };
struct max310x_devtype { struct max310x_devtype {
...@@ -260,10 +260,11 @@ struct max310x_devtype { ...@@ -260,10 +260,11 @@ struct max310x_devtype {
unsigned short max; unsigned short max;
} slave_addr; } slave_addr;
int nr; int nr;
int (*detect)(struct device *);
void (*power)(struct uart_port *, int); void (*power)(struct uart_port *, int);
char name[9]; char name[9];
u8 mode1; u8 mode1;
u8 rev_id_val;
u8 rev_id_reg; /* Relevant only if rev_id_val is defined. */
}; };
struct max310x_one { struct max310x_one {
...@@ -324,62 +325,52 @@ static void max310x_port_update(struct uart_port *port, u8 reg, u8 mask, u8 val) ...@@ -324,62 +325,52 @@ static void max310x_port_update(struct uart_port *port, u8 reg, u8 mask, u8 val)
regmap_update_bits(one->regmap, reg, mask, val); regmap_update_bits(one->regmap, reg, mask, val);
} }
static int max3107_detect(struct device *dev) static int max310x_detect(struct device *dev)
{ {
struct max310x_port *s = dev_get_drvdata(dev); struct max310x_port *s = dev_get_drvdata(dev);
unsigned int val = 0; unsigned int val = 0;
int ret; int ret;
ret = regmap_read(s->regmap, MAX310X_REVID_REG, &val); /* Check if variant supports REV ID register: */
if (s->devtype->rev_id_val) {
u8 rev_id_reg = s->devtype->rev_id_reg;
/* Check if REV ID is in extended addressing space: */
if (s->devtype->rev_id_reg >= MAX310X_EXTREG_START) {
ret = s->if_cfg->extended_reg_enable(dev, true);
if (ret) if (ret)
return ret; return ret;
if (((val & MAX310x_REV_MASK) != MAX3107_REV_ID)) { /* Adjust REV ID extended addressing space address: */
dev_err(dev, if (s->if_cfg->rev_id_offset)
"%s ID 0x%02x does not match\n", s->devtype->name, val); rev_id_reg -= s->if_cfg->rev_id_offset;
return -ENODEV;
} }
return 0; regmap_read(s->regmap, rev_id_reg, &val);
}
static int max3108_detect(struct device *dev)
{
struct max310x_port *s = dev_get_drvdata(dev);
unsigned int val = 0;
int ret;
/* MAX3108 have not REV ID register, we just check default value if (s->devtype->rev_id_reg >= MAX310X_EXTREG_START) {
* from clocksource register to make sure everything works. ret = s->if_cfg->extended_reg_enable(dev, false);
*/
ret = regmap_read(s->regmap, MAX310X_CLKSRC_REG, &val);
if (ret) if (ret)
return ret; return ret;
if (val != (MAX310X_CLKSRC_EXTCLK_BIT | MAX310X_CLKSRC_PLLBYP_BIT)) {
dev_err(dev, "%s not present\n", s->devtype->name);
return -ENODEV;
} }
return 0; if (((val & MAX310x_REV_MASK) != s->devtype->rev_id_val))
} return dev_err_probe(dev, -ENODEV,
"%s ID 0x%02x does not match\n",
static int max3109_detect(struct device *dev) s->devtype->name, val);
{ } else {
struct max310x_port *s = dev_get_drvdata(dev); /*
unsigned int val = 0; * For variant without REV ID register, just check default value
int ret; * from clocksource register to make sure everything works.
*/
ret = s->if_cfg->extended_reg_enable(dev, true); ret = regmap_read(s->regmap, MAX310X_CLKSRC_REG, &val);
if (ret) if (ret)
return ret; return ret;
regmap_read(s->regmap, s->if_cfg->rev_id_reg, &val); if (val != (MAX310X_CLKSRC_EXTCLK_BIT | MAX310X_CLKSRC_PLLBYP_BIT))
s->if_cfg->extended_reg_enable(dev, false); return dev_err_probe(dev, -ENODEV,
if (((val & MAX310x_REV_MASK) != MAX3109_REV_ID)) { "%s not present\n",
dev_err(dev, s->devtype->name);
"%s ID 0x%02x does not match\n", s->devtype->name, val);
return -ENODEV;
} }
return 0; return 0;
...@@ -394,27 +385,6 @@ static void max310x_power(struct uart_port *port, int on) ...@@ -394,27 +385,6 @@ static void max310x_power(struct uart_port *port, int on)
msleep(50); msleep(50);
} }
static int max14830_detect(struct device *dev)
{
struct max310x_port *s = dev_get_drvdata(dev);
unsigned int val = 0;
int ret;
ret = s->if_cfg->extended_reg_enable(dev, true);
if (ret)
return ret;
regmap_read(s->regmap, s->if_cfg->rev_id_reg, &val);
s->if_cfg->extended_reg_enable(dev, false);
if (((val & MAX310x_REV_MASK) != MAX14830_REV_ID)) {
dev_err(dev,
"%s ID 0x%02x does not match\n", s->devtype->name, val);
return -ENODEV;
}
return 0;
}
static void max14830_power(struct uart_port *port, int on) static void max14830_power(struct uart_port *port, int on)
{ {
max310x_port_update(port, MAX310X_BRGCFG_REG, max310x_port_update(port, MAX310X_BRGCFG_REG,
...@@ -428,7 +398,8 @@ static const struct max310x_devtype max3107_devtype = { ...@@ -428,7 +398,8 @@ static const struct max310x_devtype max3107_devtype = {
.name = "MAX3107", .name = "MAX3107",
.nr = 1, .nr = 1,
.mode1 = MAX310X_MODE1_AUTOSLEEP_BIT | MAX310X_MODE1_IRQSEL_BIT, .mode1 = MAX310X_MODE1_AUTOSLEEP_BIT | MAX310X_MODE1_IRQSEL_BIT,
.detect = max3107_detect, .rev_id_val = MAX3107_REV_ID,
.rev_id_reg = MAX310X_REVID_REG,
.power = max310x_power, .power = max310x_power,
.slave_addr = { .slave_addr = {
.min = 0x2c, .min = 0x2c,
...@@ -440,7 +411,8 @@ static const struct max310x_devtype max3108_devtype = { ...@@ -440,7 +411,8 @@ static const struct max310x_devtype max3108_devtype = {
.name = "MAX3108", .name = "MAX3108",
.nr = 1, .nr = 1,
.mode1 = MAX310X_MODE1_AUTOSLEEP_BIT, .mode1 = MAX310X_MODE1_AUTOSLEEP_BIT,
.detect = max3108_detect, .rev_id_val = 0, /* Unsupported. */
.rev_id_reg = 0, /* Irrelevant when rev_id_val is not defined. */
.power = max310x_power, .power = max310x_power,
.slave_addr = { .slave_addr = {
.min = 0x60, .min = 0x60,
...@@ -452,7 +424,8 @@ static const struct max310x_devtype max3109_devtype = { ...@@ -452,7 +424,8 @@ static const struct max310x_devtype max3109_devtype = {
.name = "MAX3109", .name = "MAX3109",
.nr = 2, .nr = 2,
.mode1 = MAX310X_MODE1_AUTOSLEEP_BIT, .mode1 = MAX310X_MODE1_AUTOSLEEP_BIT,
.detect = max3109_detect, .rev_id_val = MAX3109_REV_ID,
.rev_id_reg = MAX310X_REVID_EXTREG,
.power = max310x_power, .power = max310x_power,
.slave_addr = { .slave_addr = {
.min = 0x60, .min = 0x60,
...@@ -464,7 +437,8 @@ static const struct max310x_devtype max14830_devtype = { ...@@ -464,7 +437,8 @@ static const struct max310x_devtype max14830_devtype = {
.name = "MAX14830", .name = "MAX14830",
.nr = 4, .nr = 4,
.mode1 = MAX310X_MODE1_IRQSEL_BIT, .mode1 = MAX310X_MODE1_IRQSEL_BIT,
.detect = max14830_detect, .rev_id_val = MAX14830_REV_ID,
.rev_id_reg = MAX310X_REVID_EXTREG,
.power = max14830_power, .power = max14830_power,
.slave_addr = { .slave_addr = {
.min = 0x60, .min = 0x60,
...@@ -1322,7 +1296,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty ...@@ -1322,7 +1296,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
dev_set_drvdata(dev, s); dev_set_drvdata(dev, s);
/* Check device to ensure we are talking to what we expect */ /* Check device to ensure we are talking to what we expect */
ret = devtype->detect(dev); ret = max310x_detect(dev);
if (ret) if (ret)
goto out_clk; goto out_clk;
...@@ -1501,7 +1475,7 @@ static int max310x_spi_extended_reg_enable(struct device *dev, bool enable) ...@@ -1501,7 +1475,7 @@ static int max310x_spi_extended_reg_enable(struct device *dev, bool enable)
static const struct max310x_if_cfg __maybe_unused max310x_spi_if_cfg = { static const struct max310x_if_cfg __maybe_unused max310x_spi_if_cfg = {
.extended_reg_enable = max310x_spi_extended_reg_enable, .extended_reg_enable = max310x_spi_extended_reg_enable,
.rev_id_reg = MAX310X_SPI_REVID_EXTREG, .rev_id_offset = MAX310X_EXTREG_START,
}; };
static int max310x_spi_probe(struct spi_device *spi) static int max310x_spi_probe(struct spi_device *spi)
...@@ -1574,7 +1548,7 @@ static struct regmap_config regcfg_i2c = { ...@@ -1574,7 +1548,7 @@ static struct regmap_config regcfg_i2c = {
.writeable_reg = max310x_reg_writeable, .writeable_reg = max310x_reg_writeable,
.volatile_reg = max310x_reg_volatile, .volatile_reg = max310x_reg_volatile,
.precious_reg = max310x_reg_precious, .precious_reg = max310x_reg_precious,
.max_register = MAX310X_I2C_REVID_EXTREG, .max_register = MAX310X_REVID_EXTREG,
.writeable_noinc_reg = max310x_reg_noinc, .writeable_noinc_reg = max310x_reg_noinc,
.readable_noinc_reg = max310x_reg_noinc, .readable_noinc_reg = max310x_reg_noinc,
.max_raw_read = MAX310X_FIFO_SIZE, .max_raw_read = MAX310X_FIFO_SIZE,
...@@ -1583,7 +1557,7 @@ static struct regmap_config regcfg_i2c = { ...@@ -1583,7 +1557,7 @@ static struct regmap_config regcfg_i2c = {
static const struct max310x_if_cfg max310x_i2c_if_cfg = { static const struct max310x_if_cfg max310x_i2c_if_cfg = {
.extended_reg_enable = max310x_i2c_extended_reg_enable, .extended_reg_enable = max310x_i2c_extended_reg_enable,
.rev_id_reg = MAX310X_I2C_REVID_EXTREG, .rev_id_offset = 0, /* No offset in I2C mode. */
}; };
static unsigned short max310x_i2c_slave_addr(unsigned short addr, static unsigned short max310x_i2c_slave_addr(unsigned short addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment