summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/max310x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/max310x.c')
-rw-r--r--drivers/tty/serial/max310x.c417
1 files changed, 236 insertions, 181 deletions
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 8d71e4047bb..2a99d0c61b9 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1,7 +1,7 @@
/*
* Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver
*
- * Copyright (C) 2012-2013 Alexander Shiyan <shc_work@mail.ru>
+ * Copyright (C) 2012-2014 Alexander Shiyan <shc_work@mail.ru>
*
* Based on max3100.c, by Christian Pellegrin <chripell@evolware.org>
* Based on max3110.c, by Feng Tang <feng.tang@intel.com>
@@ -13,19 +13,21 @@
* (at your option) any later version.
*/
-#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
-#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#include <linux/regmap.h>
-#include <linux/gpio.h>
#include <linux/spi/spi.h>
-
-#include <linux/platform_data/max310x.h>
+#include <linux/uaccess.h>
#define MAX310X_NAME "max310x"
#define MAX310X_MAJOR 204
@@ -161,10 +163,6 @@
/* IRDA register bits */
#define MAX310X_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */
#define MAX310X_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */
-#define MAX310X_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */
-#define MAX310X_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */
-#define MAX310X_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */
-#define MAX310X_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */
/* Flow control trigger level register masks */
#define MAX310X_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */
@@ -220,26 +218,6 @@
* XOFF2
*/
-/* GPIO configuration register bits */
-#define MAX310X_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */
-#define MAX310X_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */
-#define MAX310X_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */
-#define MAX310X_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */
-#define MAX310X_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */
-#define MAX310X_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */
-#define MAX310X_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */
-#define MAX310X_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */
-
-/* GPIO DATA register bits */
-#define MAX310X_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */
-#define MAX310X_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */
-#define MAX310X_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */
-#define MAX310X_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */
-#define MAX310X_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */
-#define MAX310X_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */
-#define MAX310X_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */
-#define MAX310X_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */
-
/* PLL configuration register masks */
#define MAX310X_PLLCFG_PREDIV_MASK (0x3f) /* PLL predivision value */
#define MAX310X_PLLCFG_PLLFACTOR_MASK (0xc0) /* PLL multiplication factor */
@@ -283,16 +261,15 @@ struct max310x_devtype {
struct max310x_one {
struct uart_port port;
struct work_struct tx_work;
+ struct work_struct md_work;
};
struct max310x_port {
struct uart_driver uart;
struct max310x_devtype *devtype;
struct regmap *regmap;
- struct regmap_config regcfg;
struct mutex mutex;
- struct max310x_pdata *pdata;
- int gpio_used;
+ struct clk *clk;
#ifdef CONFIG_GPIOLIB
struct gpio_chip gpio;
#endif
@@ -504,25 +481,33 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)
return false;
}
-static void max310x_set_baud(struct uart_port *port, int baud)
+static int max310x_set_baud(struct uart_port *port, int baud)
{
- unsigned int mode = 0, div = port->uartclk / baud;
+ unsigned int mode = 0, clk = port->uartclk, div = clk / baud;
- if (!(div / 16)) {
+ /* Check for minimal value for divider */
+ if (div < 16)
+ div = 16;
+
+ if (clk % baud && (div / 16) < 0x8000) {
/* Mode x2 */
mode = MAX310X_BRGCFG_2XMODE_BIT;
- div = (port->uartclk * 2) / baud;
- }
-
- if (!(div / 16)) {
- /* Mode x4 */
- mode = MAX310X_BRGCFG_4XMODE_BIT;
- div = (port->uartclk * 4) / baud;
+ clk = port->uartclk * 2;
+ div = clk / baud;
+
+ if (clk % baud && (div / 16) < 0x8000) {
+ /* Mode x4 */
+ mode = MAX310X_BRGCFG_4XMODE_BIT;
+ clk = port->uartclk * 4;
+ div = clk / baud;
+ }
}
max310x_port_write(port, MAX310X_BRGDIVMSB_REG, (div / 16) >> 8);
max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div / 16);
max310x_port_write(port, MAX310X_BRGCFG_REG, (div % 16) | mode);
+
+ return DIV_ROUND_CLOSEST(clk, div);
}
static int max310x_update_best_err(unsigned long f, long *besterr)
@@ -538,18 +523,19 @@ static int max310x_update_best_err(unsigned long f, long *besterr)
return 1;
}
-static int max310x_set_ref_clk(struct max310x_port *s)
+static int max310x_set_ref_clk(struct max310x_port *s, unsigned long freq,
+ bool xtal)
{
unsigned int div, clksrc, pllcfg = 0;
long besterr = -1;
- unsigned long fdiv, fmul, bestfreq = s->pdata->frequency;
+ unsigned long fdiv, fmul, bestfreq = freq;
/* First, update error without PLL */
- max310x_update_best_err(s->pdata->frequency, &besterr);
+ max310x_update_best_err(freq, &besterr);
/* Try all possible PLL dividers */
for (div = 1; (div <= 63) && besterr; div++) {
- fdiv = DIV_ROUND_CLOSEST(s->pdata->frequency, div);
+ fdiv = DIV_ROUND_CLOSEST(freq, div);
/* Try multiplier 6 */
fmul = fdiv * 6;
@@ -582,10 +568,7 @@ static int max310x_set_ref_clk(struct max310x_port *s)
}
/* Configure clock source */
- if (s->pdata->driver_flags & MAX310X_EXT_CLK)
- clksrc = MAX310X_CLKSRC_EXTCLK_BIT;
- else
- clksrc = MAX310X_CLKSRC_CRYST_BIT;
+ clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT;
/* Configure PLL */
if (pllcfg) {
@@ -597,7 +580,7 @@ static int max310x_set_ref_clk(struct max310x_port *s)
regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc);
/* Wait for crystal */
- if (pllcfg && !(s->pdata->driver_flags & MAX310X_EXT_CLK))
+ if (pllcfg && xtal)
msleep(10);
return (int)bestfreq;
@@ -782,11 +765,21 @@ static unsigned int max310x_get_mctrl(struct uart_port *port)
return TIOCM_DSR | TIOCM_CAR;
}
+static void max310x_md_proc(struct work_struct *ws)
+{
+ struct max310x_one *one = container_of(ws, struct max310x_one, md_work);
+
+ max310x_port_update(&one->port, MAX310X_MODE2_REG,
+ MAX310X_MODE2_LOOPBACK_BIT,
+ (one->port.mctrl & TIOCM_LOOP) ?
+ MAX310X_MODE2_LOOPBACK_BIT : 0);
+}
+
static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- /* DCD and DSR are not wired and CTS/RTS is hadnled automatically
- * so do nothing
- */
+ struct max310x_one *one = container_of(port, struct max310x_one, port);
+
+ schedule_work(&one->md_work);
}
static void max310x_break_ctl(struct uart_port *port, int break_state)
@@ -875,40 +868,76 @@ static void max310x_set_termios(struct uart_port *port,
port->uartclk / 4);
/* Setup baudrate generator */
- max310x_set_baud(port, baud);
+ baud = max310x_set_baud(port, baud);
/* Update timeout according to new baud rate */
uart_update_timeout(port, termios->c_cflag, baud);
}
+static int max310x_ioctl(struct uart_port *port, unsigned int cmd,
+ unsigned long arg)
+{
+#if defined(TIOCSRS485) && defined(TIOCGRS485)
+ struct serial_rs485 rs485;
+ unsigned int val;
+
+ switch (cmd) {
+ case TIOCSRS485:
+ if (copy_from_user(&rs485, (void __user *)arg, sizeof(rs485)))
+ return -EFAULT;
+ if (rs485.delay_rts_before_send > 0x0f ||
+ rs485.delay_rts_after_send > 0x0f)
+ return -ERANGE;
+ val = (rs485.delay_rts_before_send << 4) |
+ rs485.delay_rts_after_send;
+ max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val);
+ if (rs485.flags & SER_RS485_ENABLED) {
+ max310x_port_update(port, MAX310X_MODE1_REG,
+ MAX310X_MODE1_TRNSCVCTRL_BIT,
+ MAX310X_MODE1_TRNSCVCTRL_BIT);
+ max310x_port_update(port, MAX310X_MODE2_REG,
+ MAX310X_MODE2_ECHOSUPR_BIT,
+ MAX310X_MODE2_ECHOSUPR_BIT);
+ } else {
+ max310x_port_update(port, MAX310X_MODE1_REG,
+ MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
+ max310x_port_update(port, MAX310X_MODE2_REG,
+ MAX310X_MODE2_ECHOSUPR_BIT, 0);
+ }
+ return 0;
+ case TIOCGRS485:
+ memset(&rs485, 0, sizeof(rs485));
+ val = max310x_port_read(port, MAX310X_MODE1_REG);
+ rs485.flags = (val & MAX310X_MODE1_TRNSCVCTRL_BIT) ?
+ SER_RS485_ENABLED : 0;
+ rs485.flags |= SER_RS485_RTS_ON_SEND;
+ val = max310x_port_read(port, MAX310X_HDPIXDELAY_REG);
+ rs485.delay_rts_before_send = val >> 4;
+ rs485.delay_rts_after_send = val & 0x0f;
+ if (copy_to_user((void __user *)arg, &rs485, sizeof(rs485)))
+ return -EFAULT;
+ return 0;
+ default:
+ break;
+ }
+#endif
+
+ return -ENOIOCTLCMD;
+}
+
static int max310x_startup(struct uart_port *port)
{
- unsigned int val, line = port->line;
struct max310x_port *s = dev_get_drvdata(port->dev);
+ unsigned int val;
s->devtype->power(port, 1);
- /* Configure baud rate, 9600 as default */
- max310x_set_baud(port, 9600);
-
- /* Configure LCR register, 8N1 mode by default */
- max310x_port_write(port, MAX310X_LCR_REG, MAX310X_LCR_WORD_LEN_8);
-
/* Configure MODE1 register */
max310x_port_update(port, MAX310X_MODE1_REG,
- MAX310X_MODE1_TRNSCVCTRL_BIT,
- (s->pdata->uart_flags[line] & MAX310X_AUTO_DIR_CTRL)
- ? MAX310X_MODE1_TRNSCVCTRL_BIT : 0);
-
- /* Configure MODE2 register */
- val = MAX310X_MODE2_RXEMPTINV_BIT;
- if (s->pdata->uart_flags[line] & MAX310X_LOOPBACK)
- val |= MAX310X_MODE2_LOOPBACK_BIT;
- if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS)
- val |= MAX310X_MODE2_ECHOSUPR_BIT;
-
- /* Reset FIFOs */
- val |= MAX310X_MODE2_FIFORST_BIT;
+ MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
+
+ /* Configure MODE2 register & Reset FIFOs*/
+ val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT;
max310x_port_write(port, MAX310X_MODE2_REG, val);
max310x_port_update(port, MAX310X_MODE2_REG,
MAX310X_MODE2_FIFORST_BIT, 0);
@@ -989,6 +1018,7 @@ static const struct uart_ops max310x_ops = {
.release_port = max310x_null_void,
.config_port = max310x_config_port,
.verify_port = max310x_verify_port,
+ .ioctl = max310x_ioctl,
};
static int __maybe_unused max310x_suspend(struct device *dev)
@@ -1017,6 +1047,8 @@ static int __maybe_unused max310x_resume(struct device *dev)
return 0;
}
+static SIMPLE_DEV_PM_OPS(max310x_pm_ops, max310x_suspend, max310x_resume);
+
#ifdef CONFIG_GPIOLIB
static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset)
{
@@ -1063,23 +1095,16 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip,
}
#endif
-static int max310x_probe(struct device *dev, int is_spi,
- struct max310x_devtype *devtype, int irq)
+static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
+ struct regmap *regmap, int irq, unsigned long flags)
{
+ int i, ret, fmin, fmax, freq, uartclk;
+ struct clk *clk_osc, *clk_xtal;
struct max310x_port *s;
- struct max310x_pdata *pdata = dev_get_platdata(dev);
- int i, ret, uartclk;
-
- /* Check for IRQ */
- if (irq <= 0) {
- dev_err(dev, "No IRQ specified\n");
- return -ENOTSUPP;
- }
+ bool xtal = false;
- if (!pdata) {
- dev_err(dev, "No platform data supplied\n");
- return -EINVAL;
- }
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
/* Alloc port structure */
s = devm_kzalloc(dev, sizeof(*s) +
@@ -1089,52 +1114,44 @@ static int max310x_probe(struct device *dev, int is_spi,
return -ENOMEM;
}
- /* Check input frequency */
- if ((pdata->driver_flags & MAX310X_EXT_CLK) &&
- ((pdata->frequency < 500000) || (pdata->frequency > 35000000)))
- goto err_freq;
- /* Check frequency for quartz */
- if (!(pdata->driver_flags & MAX310X_EXT_CLK) &&
- ((pdata->frequency < 1000000) || (pdata->frequency > 4000000)))
- goto err_freq;
-
- s->pdata = pdata;
- s->devtype = devtype;
- dev_set_drvdata(dev, s);
-
- mutex_init(&s->mutex);
+ clk_osc = devm_clk_get(dev, "osc");
+ clk_xtal = devm_clk_get(dev, "xtal");
+ if (!IS_ERR(clk_osc)) {
+ s->clk = clk_osc;
+ fmin = 500000;
+ fmax = 35000000;
+ } else if (!IS_ERR(clk_xtal)) {
+ s->clk = clk_xtal;
+ fmin = 1000000;
+ fmax = 4000000;
+ xtal = true;
+ } else if (PTR_ERR(clk_osc) == -EPROBE_DEFER ||
+ PTR_ERR(clk_xtal) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else {
+ dev_err(dev, "Cannot get clock\n");
+ return -EINVAL;
+ }
- /* Setup regmap */
- s->regcfg.reg_bits = 8;
- s->regcfg.val_bits = 8;
- s->regcfg.read_flag_mask = 0x00;
- s->regcfg.write_flag_mask = 0x80;
- s->regcfg.cache_type = REGCACHE_RBTREE;
- s->regcfg.writeable_reg = max310x_reg_writeable;
- s->regcfg.volatile_reg = max310x_reg_volatile;
- s->regcfg.precious_reg = max310x_reg_precious;
- s->regcfg.max_register = devtype->nr * 0x20 - 1;
-
- if (IS_ENABLED(CONFIG_SPI_MASTER) && is_spi) {
- struct spi_device *spi = to_spi_device(dev);
-
- s->regmap = devm_regmap_init_spi(spi, &s->regcfg);
- } else
- return -ENOTSUPP;
+ ret = clk_prepare_enable(s->clk);
+ if (ret)
+ return ret;
- if (IS_ERR(s->regmap)) {
- dev_err(dev, "Failed to initialize register map\n");
- return PTR_ERR(s->regmap);
+ freq = clk_get_rate(s->clk);
+ /* Check frequency limits */
+ if (freq < fmin || freq > fmax) {
+ ret = -ERANGE;
+ goto out_clk;
}
- /* Board specific configure */
- if (s->pdata->init)
- s->pdata->init();
+ s->regmap = regmap;
+ s->devtype = devtype;
+ dev_set_drvdata(dev, s);
/* Check device to ensure we are talking to what we expect */
ret = devtype->detect(dev);
if (ret)
- return ret;
+ goto out_clk;
for (i = 0; i < devtype->nr; i++) {
unsigned int offs = i << 5;
@@ -1156,7 +1173,7 @@ static int max310x_probe(struct device *dev, int is_spi,
MAX310X_MODE1_AUTOSLEEP_BIT);
}
- uartclk = max310x_set_ref_clk(s);
+ uartclk = max310x_set_ref_clk(s, freq, xtal);
dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
/* Register UART driver */
@@ -1168,9 +1185,28 @@ static int max310x_probe(struct device *dev, int is_spi,
ret = uart_register_driver(&s->uart);
if (ret) {
dev_err(dev, "Registering UART driver failed\n");
- return ret;
+ goto out_clk;
}
+#ifdef CONFIG_GPIOLIB
+ /* Setup GPIO cotroller */
+ s->gpio.owner = THIS_MODULE;
+ s->gpio.dev = dev;
+ s->gpio.label = dev_name(dev);
+ s->gpio.direction_input = max310x_gpio_direction_input;
+ s->gpio.get = max310x_gpio_get;
+ s->gpio.direction_output= max310x_gpio_direction_output;
+ s->gpio.set = max310x_gpio_set;
+ s->gpio.base = -1;
+ s->gpio.ngpio = devtype->nr * 4;
+ s->gpio.can_sleep = 1;
+ ret = gpiochip_add(&s->gpio);
+ if (ret)
+ goto out_uart;
+#endif
+
+ mutex_init(&s->mutex);
+
for (i = 0; i < devtype->nr; i++) {
/* Initialize port data */
s->p[i].port.line = i;
@@ -1178,8 +1214,7 @@ static int max310x_probe(struct device *dev, int is_spi,
s->p[i].port.irq = irq;
s->p[i].port.type = PORT_MAX310X;
s->p[i].port.fifosize = MAX310X_FIFO_SIZE;
- s->p[i].port.flags = UPF_SKIP_TEST | UPF_FIXED_TYPE |
- UPF_LOW_LATENCY;
+ s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
s->p[i].port.iotype = UPIO_PORT;
s->p[i].port.iobase = i * 0x20;
s->p[i].port.membase = (void __iomem *)~0;
@@ -1195,48 +1230,35 @@ static int max310x_probe(struct device *dev, int is_spi,
MAX310X_MODE1_IRQSEL_BIT);
/* Initialize queue for start TX */
INIT_WORK(&s->p[i].tx_work, max310x_wq_proc);
+ /* Initialize queue for changing mode */
+ INIT_WORK(&s->p[i].md_work, max310x_md_proc);
/* Register port */
uart_add_one_port(&s->uart, &s->p[i].port);
/* Go to suspend mode */
devtype->power(&s->p[i].port, 0);
}
-#ifdef CONFIG_GPIOLIB
- /* Setup GPIO cotroller */
- if (s->pdata->gpio_base) {
- s->gpio.owner = THIS_MODULE;
- s->gpio.dev = dev;
- s->gpio.label = dev_name(dev);
- s->gpio.direction_input = max310x_gpio_direction_input;
- s->gpio.get = max310x_gpio_get;
- s->gpio.direction_output= max310x_gpio_direction_output;
- s->gpio.set = max310x_gpio_set;
- s->gpio.base = s->pdata->gpio_base;
- s->gpio.ngpio = devtype->nr * 4;
- s->gpio.can_sleep = 1;
- if (!gpiochip_add(&s->gpio))
- s->gpio_used = 1;
- } else
- dev_info(dev, "GPIO support not enabled\n");
-#endif
-
/* Setup interrupt */
ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- dev_name(dev), s);
- if (ret) {
- dev_err(dev, "Unable to reguest IRQ %i\n", irq);
+ IRQF_ONESHOT | flags, dev_name(dev), s);
+ if (!ret)
+ return 0;
+
+ dev_err(dev, "Unable to reguest IRQ %i\n", irq);
+
+ mutex_destroy(&s->mutex);
+
#ifdef CONFIG_GPIOLIB
- if (s->gpio_used)
- WARN_ON(gpiochip_remove(&s->gpio));
+ WARN_ON(gpiochip_remove(&s->gpio));
+
+out_uart:
#endif
- }
+ uart_unregister_driver(&s->uart);
- return ret;
+out_clk:
+ clk_disable_unprepare(s->clk);
-err_freq:
- dev_err(dev, "Frequency parameter incorrect\n");
- return -EINVAL;
+ return ret;
}
static int max310x_remove(struct device *dev)
@@ -1244,30 +1266,51 @@ static int max310x_remove(struct device *dev)
struct max310x_port *s = dev_get_drvdata(dev);
int i, ret = 0;
+#ifdef CONFIG_GPIOLIB
+ ret = gpiochip_remove(&s->gpio);
+ if (ret)
+ return ret;
+#endif
+
for (i = 0; i < s->uart.nr; i++) {
cancel_work_sync(&s->p[i].tx_work);
+ cancel_work_sync(&s->p[i].md_work);
uart_remove_one_port(&s->uart, &s->p[i].port);
s->devtype->power(&s->p[i].port, 0);
}
+ mutex_destroy(&s->mutex);
uart_unregister_driver(&s->uart);
-
-#ifdef CONFIG_GPIOLIB
- if (s->gpio_used)
- ret = gpiochip_remove(&s->gpio);
-#endif
-
- if (s->pdata->exit)
- s->pdata->exit();
+ clk_disable_unprepare(s->clk);
return ret;
}
+static const struct of_device_id __maybe_unused max310x_dt_ids[] = {
+ { .compatible = "maxim,max3107", .data = &max3107_devtype, },
+ { .compatible = "maxim,max3108", .data = &max3108_devtype, },
+ { .compatible = "maxim,max3109", .data = &max3109_devtype, },
+ { .compatible = "maxim,max14830", .data = &max14830_devtype },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max310x_dt_ids);
+
+static struct regmap_config regcfg = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .write_flag_mask = 0x80,
+ .cache_type = REGCACHE_RBTREE,
+ .writeable_reg = max310x_reg_writeable,
+ .volatile_reg = max310x_reg_volatile,
+ .precious_reg = max310x_reg_precious,
+};
+
#ifdef CONFIG_SPI_MASTER
static int max310x_spi_probe(struct spi_device *spi)
{
- struct max310x_devtype *devtype =
- (struct max310x_devtype *)spi_get_device_id(spi)->driver_data;
+ struct max310x_devtype *devtype;
+ unsigned long flags = 0;
+ struct regmap *regmap;
int ret;
/* Setup SPI bus */
@@ -1275,12 +1318,25 @@ static int max310x_spi_probe(struct spi_device *spi)
spi->mode = spi->mode ? : SPI_MODE_0;
spi->max_speed_hz = spi->max_speed_hz ? : 26000000;
ret = spi_setup(spi);
- if (ret) {
- dev_err(&spi->dev, "SPI setup failed\n");
+ if (ret)
return ret;
+
+ if (spi->dev.of_node) {
+ const struct of_device_id *of_id =
+ of_match_device(max310x_dt_ids, &spi->dev);
+
+ devtype = (struct max310x_devtype *)of_id->data;
+ } else {
+ const struct spi_device_id *id_entry = spi_get_device_id(spi);
+
+ devtype = (struct max310x_devtype *)id_entry->driver_data;
+ flags = IRQF_TRIGGER_FALLING;
}
- return max310x_probe(&spi->dev, 1, devtype, spi->irq);
+ regcfg.max_register = devtype->nr * 0x20 - 1;
+ regmap = devm_regmap_init_spi(spi, &regcfg);
+
+ return max310x_probe(&spi->dev, devtype, regmap, spi->irq, flags);
}
static int max310x_spi_remove(struct spi_device *spi)
@@ -1288,8 +1344,6 @@ static int max310x_spi_remove(struct spi_device *spi)
return max310x_remove(&spi->dev);
}
-static SIMPLE_DEV_PM_OPS(max310x_pm_ops, max310x_suspend, max310x_resume);
-
static const struct spi_device_id max310x_id_table[] = {
{ "max3107", (kernel_ulong_t)&max3107_devtype, },
{ "max3108", (kernel_ulong_t)&max3108_devtype, },
@@ -1301,9 +1355,10 @@ MODULE_DEVICE_TABLE(spi, max310x_id_table);
static struct spi_driver max310x_uart_driver = {
.driver = {
- .name = MAX310X_NAME,
- .owner = THIS_MODULE,
- .pm = &max310x_pm_ops,
+ .name = MAX310X_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(max310x_dt_ids),
+ .pm = &max310x_pm_ops,
},
.probe = max310x_spi_probe,
.remove = max310x_spi_remove,