From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3sTcy04ChWzDrvP for ; Wed, 7 Sep 2016 19:05:44 +1000 (AEST) Received: from tccbw2.etn.com (mail2.eaton.com [192.104.67.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sTcxy43Gsz9s9x for ; Wed, 7 Sep 2016 19:05:41 +1000 (AEST) Received: from SIMTCSGWY01.napa.ad.etn.com (simtcsgwy01.napa.ad.etn.com [151.110.126.183]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by tccbw2.etn.com (Eaton Corp) with ESMTPS id 85ECDB6CA1DF2C89 for ; Wed, 7 Sep 2016 05:05:38 -0400 (EDT) From: To: CC: , Subject: [PATCH] tty/serial : Add I2C support to Max310x driver (linux-3.8.13) Date: Wed, 7 Sep 2016 09:05:36 +0000 Message-ID: Content-Type: multipart/alternative; boundary="_000_CDD76EB921100341B75E76FF5FC7731F1F14067FSIMTCSMB06napaa_" MIME-Version: 1.0 List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , --_000_CDD76EB921100341B75E76FF5FC7731F1F14067FSIMTCSMB06napaa_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MAX3107/8 chip supports both SPI and I2C protocol. Currently, max310x driver support only SPI protocol. This patch adds I2C support to the driver. With I2C support, we have added bulk read/write functionality which can be enabled using BULK_RW_ENABLE variable. Signed-off-by: Meghan Saitwal MeghanSaitwal@Eaton.com Tested-by: Devidas Kalane DevidasKalane@Eaton.com Suggested-by: Ashwin Patwekar AshwinPatwekar@Eaton.com drivers/tty/serial/Kconfig | 38 +++- drivers/tty/serial/Makefile | 2 drivers/tty/serial/max310x.c | 268 +++++++++++++++++++++++++++------ 3 files changed, 254 insertions(+), 54 deletions(-) diff -purN a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig --- a/drivers/tty/serial/Kconfig 2016-09-01 12:05:32.092474214 +0530 +++ b/drivers/tty/serial/Kconfig 2016-09-01 12:11:12.93850720= 8 +0530 @@ -276,19 +276,45 @@ config SERIAL_MAX3100 help MAX3100 chip support +config SERIAL_MAX310X_CORE + tristate + config SERIAL_MAX310X - bool "MAX310X support" - depends on SPI + tristate "MAX310X support" + depends on (SPI && !I2C) || I2C select SERIAL_CORE - select REGMAP_SPI if SPI - default n help This selects support for an advanced UART from Maxim (Dall= as). Supported ICs are MAX3107, MAX3108. Each IC contains 128 words each of receive and transmit FI= FO - that can be controlled through I2C or high-speed SPI. + that can be controlled through I2C or high-speed SPI. + Select SPI or I2C bus using options below. + +config SERIAL_MAX310X_SPI + bool "MAX310x for spi interface" + depends on SERIAL_MAX310X + depends on SPI + select SERIAL_MAX310X_CORE if SERIAL_MAX310X + select REGMAP_SPI if SPI + default y + help + Enable MAX310x driver on SPI bus, + If required say y, and say n to spi if not required, + Enabled by default to support oldconfig. + You must select at least one bus for the driver to be buil= t. + +config SERIAL_MAX310X_I2C + bool "MAX310x for I2C interface" + depends on SERIAL_MAX310X + depends on I2C + select SERIAL_MAX310XX_CORE if SERIAL_MAX310X + select REGMAP_I2C if I2C + help + Enable MAX310x driver on I2C bus, + If required say y, and say n to i2c if not required, + This is additional support to existing driver. + You must select at least one bus for the driver to be buil= t. - Say Y here if you want to support this ICs. config SERIAL_DZ bool "DECstation DZ serial driver" diff -purN a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile --- a/drivers/tty/serial/Makefile 2016-09-01 12:07:31.8154858= 04 +0530 +++ b/drivers/tty/serial/Makefile 2016-09-01 12:11:40.576509884 = +0530 @@ -28,7 +28,7 @@ obj-$(CONFIG_SERIAL_BFIN) +=3D bfin_uart.o obj-$(CONFIG_SERIAL_BFIN_SPORT) +=3D bfin_sport_uart.o obj-$(CONFIG_SERIAL_SAMSUNG) +=3D samsung.o obj-$(CONFIG_SERIAL_MAX3100) +=3D max3100.o -obj-$(CONFIG_SERIAL_MAX310X) +=3D max310x.o +obj-$(CONFIG_SERIAL_MAX310X_CORE) +=3D max310x.o obj-$(CONFIG_SERIAL_IP22_ZILOG) +=3D ip22zilog.o obj-$(CONFIG_SERIAL_MUX) +=3D mux.o obj-$(CONFIG_SERIAL_68328) +=3D 68328serial.o diff -purN a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c --- a/drivers/tty/serial/max310x.c 2013-05-12 02:27:46.000000000= +0530 +++ b/drivers/tty/serial/max310x.c 2016-08-12 10:22:40.000000000 +0= 530 @@ -25,8 +25,11 @@ #include #include #include +#include #include +#define BULK_RW_ENABLE 0 + #define MAX310X_MAJOR 204 #define MAX310X_MINOR 209 @@ -272,6 +275,8 @@ struct max310x_port { const char *name; int uartclk; + unsigned char buf[MAX310X_FIFO_SIZE]; + unsigned int nr_gpio; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio; @@ -459,7 +464,7 @@ static int max310x_set_ref_clk(struct ma static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) { - unsigned int sts =3D 0, ch =3D 0, flag; + unsigned int sts =3D 0, ch =3D 0, flag, bytes_read, i; struct tty_struct *tty =3D tty_port_tty_get(&s->port.state->= port); if (!tty) @@ -473,7 +478,64 @@ static void max310x_handle_rx(struct max dev_dbg(s->port.dev, "RX Len =3D %u\n", rxlen); - while (rxlen--) { + #if BULK_RW_ENABLE + + while (rxlen) { + regmap_read(s->regmap, MAX310X_LSR_IRQSTS_REG= , &sts); + sts &=3D MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_= FRERR_BIT | + MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RX= BRK_BIT; + if(sts) + { + regmap_read(s->regmap,MAX310X= _RHR_REG, s->buf); + bytes_read =3D 1; + } else { + regcache_cache_bypass(s->regm= ap, true); + regmap_raw_read(s->regmap, MAX310X_RHR_REG, s= ->buf, rxlen); + regcache_cache_bypass(s->regmap, false); + bytes_read =3D rxlen; + } + + s->port.icount.rx++; + flag =3D TTY_NORMAL; + + if (unlikely(sts)) { + if (sts & MAX310X_LSR_RXBRK_B= IT) { + s->port.icoun= t.brk++; + if (uart_hand= le_break(&s->port)) + = continue; + } else if (sts & MAX310X_LSR_= RXPAR_BIT) + s->port.icoun= t.parity++; + else if (sts & MAX310X_LSR_FR= ERR_BIT) + s->port.icoun= t.frame++; + else if (sts & MAX310X_LSR_RX= OVR_BIT) + s->port.icoun= t.overrun++; + + sts &=3D s->port.read_status_= mask; + if (sts & MAX310X_LSR_RXBRK_B= IT) + flag =3D TTY_= BREAK; + else if (sts & MAX310X_LSR_RX= PAR_BIT) + flag =3D TTY_= PARITY; + else if (sts & MAX310X_LSR_FR= ERR_BIT) + flag =3D TTY_= FRAME; + else if (sts & MAX310X_LSR_RX= OVR_BIT) + flag =3D TTY_= OVERRUN; + } + + for(i=3D0; i< bytes_read; i++) + { + if (uart_handle_sysrq_char(s-= >port, s->buf[i])) + continue; + + if (sts & s->port.ignore_stat= us_mask) + continue; + + uart_insert_char(&s->port, st= s, MAX310X_LSR_RXOVR_BIT, + s->buf[i], fl= ag); + } + rxlen -=3D bytes_read; + } + #else + while (rxlen--) { regmap_read(s->regmap, MAX310X_RHR_REG, &ch)= ; regmap_read(s->regmap, MAX310X_LSR_IRQSTS_RE= G, &sts); @@ -514,8 +576,8 @@ static void max310x_handle_rx(struct max uart_insert_char(&s->port, sts, MAX310X_LSR= _RXOVR_BIT, ch, flag); - } - + } + #endif tty_flip_buffer_push(tty); tty_kref_put(tty); @@ -524,8 +586,7 @@ static void max310x_handle_rx(struct max static void max310x_handle_tx(struct max310x_port *s) { struct circ_buf *xmit =3D &s->port.state->xmit; - unsigned int txlen =3D 0, to_send; - + unsigned int txlen =3D 0, to_send =3D 0, i; if (unlikely(s->port.x_char)) { regmap_write(s->regmap, MAX310X_THR_REG, s->= port.x_char); s->port.icount.tx++; @@ -545,7 +606,18 @@ static void max310x_handle_tx(struct max to_send =3D (to_send > txlen) ? txlen : to_s= end; dev_dbg(s->port.dev, "TX Len =3D %u\n", to_= send); - +#if BULK_RW_ENABLE + /* Add data to send */ + s->port.icount.tx +=3D to_send; + for(i=3D0; i < to_send; ++i) + { + s->buf[i] =3D xmit->buf[xmit-= >tail]; + xmit->tail =3D (xmit->tail + = 1) & (UART_XMIT_SIZE - 1); + } + regcache_cache_bypass(s->regmap, true); + regmap_raw_write(s->regmap, MAX310X_THR_REG, = s->buf, to_send); + regcache_cache_bypass(s->regmap, false); +#else /* Add data to send */ s->port.icount.tx +=3D to_send; while (to_send--) { @@ -553,6 +625,7 @@ static void max310x_handle_tx(struct max xmit->b= uf[xmit->tail]); xmit->tail =3D (xmit->tail += 1) & (UART_XMIT_SIZE - 1); }; +#endif } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -593,7 +666,7 @@ static irqreturn_t max310x_ist(int irq, static void max310x_wq_proc(struct work_struct *ws) { struct max310x_port *s =3D container_of(ws, struct max310x_p= ort, tx_work); - + mutex_lock(&s->max310x_mutex); max310x_handle_tx(s); mutex_unlock(&s->max310x_mutex); @@ -887,12 +960,12 @@ static struct uart_ops max310x_ops =3D { .verify_port =3D max310x_verify_port, }; -static int max310x_suspend(struct spi_device *spi, pm_message_t state) +static int max310x_suspend(struct device *dev) { int ret; - struct max310x_port *s =3D dev_get_drvdata(&spi->dev); + struct max310x_port *s =3D dev_get_drvdata(dev); - dev_dbg(&spi->dev, "Suspend\n"); + dev_dbg(dev, "Suspend\n"); ret =3D uart_suspend_port(&s->uart, &s->port); @@ -911,11 +984,11 @@ static int max310x_suspend(struct spi_de return ret; } -static int max310x_resume(struct spi_device *spi) +static int max310x_resume(struct device *dev) { - struct max310x_port *s =3D dev_get_drvdata(&spi->dev); + struct max310x_port *s =3D dev_get_drvdata(dev); - dev_dbg(&spi->dev, "Resume\n"); + dev_dbg(dev, "Resume\n"); if (s->pdata->suspend) s->pdata->suspend(0); @@ -995,17 +1068,15 @@ static struct max310x_pdata generic_plat .frequency =3D 26000000, }; -static int max310x_probe(struct spi_device *spi) +static int max310x_probe(struct device *dev, int chiptype, struct regmap *= regmap, int irq) { struct max310x_port *s; - struct device *dev =3D &spi->dev; - int chiptype =3D spi_get_device_id(spi)->driver_data; struct max310x_pdata *pdata =3D dev->platform_data; unsigned int val =3D 0; int ret; /* Check for IRQ */ - if (spi->irq <=3D 0) { + if (irq <=3D 0) { dev_err(dev, "No IRQ specified\n"); return -ENOTSUPP; } @@ -1023,6 +1094,7 @@ static int max310x_probe(struct spi_devi pdata =3D &generic_plat_data; } s->pdata =3D pdata; + s->regmap =3D regmap; /* Individual chip settings */ switch (chiptype) { @@ -1030,13 +1102,11 @@ static int max310x_probe(struct spi_devi s->name =3D "MAX3107"; s->nr_gpio =3D 4; s->uart.nr =3D 1; - s->regcfg.max_register =3D 0x1f; break; case MAX310X_TYPE_MAX3108: s->name =3D "MAX3108"; s->nr_gpio =3D 4; s->uart.nr =3D 1; - s->regcfg.max_register =3D 0x1e; break; default: dev_err(dev, "Unsupported chip type %i\n", c= hiptype); @@ -1054,32 +1124,16 @@ static int max310x_probe(struct spi_devi mutex_init(&s->max310x_mutex); - /* Setup SPI bus */ - spi->mode =3D SPI_MODE_0; - spi->bits_per_word =3D 8; - spi->max_speed_hz =3D 26000000; - spi_setup(spi); - - /* Setup regmap */ - s->regcfg.reg_bits =3D 8; - s->regcfg.val_bits =3D 8; - s->regcfg.read_flag_mask =3D 0x00; - s->regcfg.write_flag_mask =3D 0x80; - s->regcfg.cache_type =3D REGCACHE_RBTREE; - s->regcfg.writeable_reg =3D ma= x3107_8_reg_writeable; - s->regcfg.volatile_reg =3D max310x_reg_vo= latile; - s->regcfg.precious_reg =3D max310x_reg_preci= ous; - s->regmap =3D devm_regmap_init_spi(spi, &s->regcfg); if (IS_ERR(s->regmap)) { ret =3D PTR_ERR(s->regmap); dev_err(dev, "Failed to initialize register = map\n"); goto err_out; } - /* Reset chip & check SPI function */ + /* Reset chip & check SPI/I2C function */ ret =3D regmap_write(s->regmap, MAX310X_MODE2_REG, MAX310X_M= ODE2_RST_BIT); if (ret) { - dev_err(dev, "SPI transfer failed\n"); + dev_err(dev, "SPI/I2C transfer failed\n"); goto err_out; } /* Clear chip reset */ @@ -1129,11 +1183,12 @@ static int max310x_probe(struct spi_devi regmap_write(s->regmap, MAX310X_MODE1_REG, val); /* Setup interrupt */ - ret =3D devm_request_threaded_irq(dev, spi->irq, NULL, max31= 0x_ist, + /* Used IRQF_TRIGGER_LOW in case of I2C */ + ret =3D 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", s= pi->irq); + dev_err(dev, "Unable to reguest IRQ %i\n", ir= q); goto err_out; } @@ -1156,7 +1211,7 @@ static int max310x_probe(struct spi_devi /* Initialize UART port data */ s->port.line =3D 0; s->port.dev =3D dev; - s->port.irq =3D spi->irq; + s->port.irq =3D irq; s->port.type =3D PORT_MAX310X; s->port.fifosize =3D MAX310X_FIFO_SIZE; s->port.flags =3D UPF_SKIP_TEST | UPF_F= IXED_TYPE; @@ -1203,9 +1258,8 @@ err_out: return ret; } -static int max310x_remove(struct spi_device *spi) +static int max310x_remove(struct device *dev) { - struct device *dev =3D &spi->dev; struct max310x_port *s =3D dev_get_drvdata(dev); int ret =3D 0; @@ -1237,6 +1291,63 @@ static int max310x_remove(struct spi_dev return ret; } +static struct regmap_config regcfg =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .read_flag_mask =3D 0x00, + .write_flag_mask =3D 0x80, // may need to remove this mask + .cache_type =3D REGCACHE_RBTREE, + .writeable_reg =3D max3107_8_reg_writeable, + .volatile_reg =3D max310x_reg_volatile, + .precious_reg =3D max310x_reg_precious, +}; + +#ifdef CONFIG_SERIAL_MAX310X_SPI + +static int max310x_spi_probe(struct spi_device *spi) +{ + struct regmap *regmap; + int chiptype =3D spi_get_device_id(spi)->driver_data; + + /* Setup SPI bus */ + spi->mode =3D SPI_MODE_0; + spi->bits_per_word =3D 8; + spi->max_speed_hz =3D 26000000; + spi_setup(spi); + + switch (chiptype) { + case MAX310X_TYPE_MAX3107: + regcfg.max_register =3D 0x1f; + break; + case MAX310X_TYPE_MAX3108: + regcfg.max_register =3D 0x1e; + break; + default: + dev_err(&spi->dev, "Unsupported chip type %i\= n", chiptype); + return -ENOTSUPP; + } + + + regmap =3D devm_regmap_init_spi(spi, ®cfg); + + return max310x_probe(&spi->dev, chiptype, regmap, spi->irq); +} + +static int max310x_spi_remove(struct spi_device *spi) +{ + return max310x_remove(&spi->dev); +} + +static int max310x_suspend(struct spi_device *spi, pm_message_t state) +{ + return max310x_suspend(&spi->dev); +} + +static int max310x_resume(struct spi_device *spi) +{ + return max310x_resume(&spi->dev); +} + static const struct spi_device_id max310x_id_table[] =3D { { "max3107", MAX310X_TYPE_MAX3107 }, { "max3108", MAX310X_TYPE_MAX3108 }, @@ -1249,13 +1360,76 @@ static struct spi_driver max310x_driver .name =3D "max310x", .owner =3D THIS_MODULE, }, - .probe =3D max310x_probe, - .remove =3D max310x_remove, - .suspend =3D max310x_suspend, - .resume =3D max310x_resume, + .probe =3D max310x_spi_probe, + .remove =3D max310x_spi_remove, + .suspend =3D max310x_spi_suspend, + .resume =3D max310x_spi_resume, .id_table =3D max310x_id_table, }; module_spi_driver(max310x_driver); +#endif + +#ifdef CONFIG_SERIAL_MAX310X_I2C + +static int max310x_i2c_probe(struct i2c_client *i2c,const struct i2c_devic= e_id *id) +{ + struct regmap *regmap; + int chiptype =3D id->driver_data; + printk("chiptype =3D %d \n",chiptype); + switch (chiptype) { + case MAX310X_TYPE_MAX3107: + regcfg.max_register =3D 0x1f; + break; + case MAX310X_TYPE_MAX3108: + regcfg.max_register =3D 0x1e; + break; + default: + dev_err(&i2c->dev, "Unsupported chip type %i\= n", chiptype); + return -ENOTSUPP; + } + + + regmap =3D devm_regmap_init_i2c(i2c, ®cfg); + + return max310x_probe(&i2c->dev, chiptype, regmap, i2c->irq); +} + +static int max310x_i2c_remove(struct i2c_client *i2c) +{ + return max310x_remove(&i2c->dev); +} + +static int max310x_i2c_suspend(struct i2c_client *i2c, pm_message_t state) +{ + return max310x_suspend(&i2c->dev); +} + +static int max310x_i2c_resume(struct i2c_client *i2c) +{ + return max310x_resume(&i2c->dev); +} + + +static const struct i2c_device_id max310x_id_table[] =3D { + { "max3107", MAX310X_TYPE_MAX3107 }, + { "max3108", MAX310X_TYPE_MAX3108 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max310x_id_table); + +static struct i2c_driver max310x_driver =3D { + .driver =3D { + .name =3D "max310x", + .owner =3D THIS_MODULE, + }, + .probe =3D max310x_i2c_probe, + .remove =3D max310x_i2c_remove, + .suspend =3D max310x_i2c_suspend, + .resume =3D max310x_i2c_resume, + .id_table =3D max310x_id_table, +}; +module_i2c_driver(max310x_driver); +#endif MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Alexander Shiyan >= "); --_000_CDD76EB921100341B75E76FF5FC7731F1F14067FSIMTCSMB06napaa_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

 

MAX3107/8 chip supports both SPI and I2C protocol. C= urrently, max310x

driver support only SPI protocol. This patch adds I2= C support to the

driver. With I2C support, we have added bulk read/wr= ite functionality

which can be enabled using BULK_RW_ENABLE variable.<= o:p>

 

Signed-off-by: Meghan Saitwal MeghanSaitwal@Eaton.com

Tested-by: Devidas Kalane DevidasKalane@Eaton.com

Suggested-by: Ashw= in Patwekar AshwinPatwekar@Eaton.com

drivers/tty/serial/Kco= nfig   |   38 +++-

drivers/tty/serial/Mak= efile  |    2

drivers/tty/serial/max= 310x.c |  268 +++++++++++&= #43;++++++++++++++&= #43;------

3 files changed, 254 insertions(+), 54 deletions= (-)

 

diff -purN a/drivers/tty/serial/Kconfig b/drivers/tt= y/serial/Kconfig

--- a/drivers/tty/serial/Kconfig  2016-09-01 12= :05:32.092474214 +0530

+++ b/drivers/tty/serial/Kconfig &n= bsp;            = ; 2016-09-01 12:11:12.938507208 +0530

@@ -276,19 +276,45 @@ config SERIAL_MAX3100=

        &nbs= p;      help

        &nbs= p;        MAX3100 chip support

 

+config SERIAL_MAX310X_CORE

+        = ;     tristate

+        = ;    

config SERIAL_MAX310X

-        &nb= sp;     bool "MAX310X support"

-        &nb= sp;     depends on SPI

+        = ;     tristate "MAX310X support"

+        = ;     depends on (SPI && !I2C) || I2C

        &nbs= p;      select SERIAL_CORE

-        &nb= sp;     select REGMAP_SPI if SPI

-        &nb= sp;     default n

        &nbs= p;      help

        &nbs= p;        This selects support for an ad= vanced UART from Maxim (Dallas).

        &nbs= p;        Supported ICs are MAX3107, MAX= 3108.

        &nbs= p;        Each IC contains 128 words eac= h of receive and transmit FIFO

-        &nb= sp;       that can be controlled through I2C or hi= gh-speed SPI.

+        = ;       that can be controlled through I2C or high= -speed SPI.

+        = ;       Select SPI or I2C bus using options below.=

+        = ;      

+config SERIAL_MAX310X_SPI

+        = ;     bool "MAX310x for spi interface"

+        = ;     depends on SERIAL_MAX310X

+        = ;     depends on SPI

+        = ;     select SERIAL_MAX310X_CORE if SERIAL_MAX310X=

+        = ;     select REGMAP_SPI if SPI

+        = ;     default y

+        = ;     help

+        = ;        Enable MAX310x driver on SPI bus,

+        = ;        If required say y, and say n to spi = if not required,

+        = ;        Enabled by default to support oldcon= fig.

+        = ;        You must select at least one bus for= the driver to be built.

+        = ;      

+config SERIAL_MAX310X_I2C

+        = ;     bool "MAX310x for I2C interface"

+        = ;     depends on SERIAL_MAX310X

+        = ;     depends on I2C

+        = ;     select SERIAL_MAX310XX_CORE if SERIAL_MAX310X

+        = ;     select REGMAP_I2C if I2C

+        = ;     help

+        = ;        Enable MAX310x driver on I2C bus,

+        = ;        If required say y, and say n to i2c = if not required,

+        = ;        This is additional support to existi= ng driver.

+        = ;        You must select at least one bus for= the driver to be built.

 

-        &nb= sp;       Say Y here if you want to support this I= Cs.

 

 config SERIAL_DZ

        &nbs= p;      bool "DECstation DZ serial driver&quo= t;

diff -purN a/drivers/tty/serial/Makefile b/drivers/t= ty/serial/Makefile

--- a/drivers/tty/serial/Makefile   &= nbsp;           2016-09-0= 1 12:07:31.815485804 +0530

+++ b/drivers/tty/serial/Makefile &= nbsp;          2016-09-01 12:1= 1:40.576509884 +0530

@@ -28,7 +28,7 @@ obj-$(CONFIG_SERIAL_BFIN) += ;=3D bfin_uart.o

obj-$(CONFIG_SERIAL_BFIN_SPORT) +=3D bfin_sport_= uart.o

obj-$(CONFIG_SERIAL_SAMSUNG) +=3D samsung.o=

obj-$(CONFIG_SERIAL_MAX3100) +=3D max3100.o=

-obj-$(CONFIG_SERIAL_MAX310X) +=3D max310x.o

+obj-$(CONFIG_SERIAL_MAX310X_CORE) +=3D max3= 10x.o

obj-$(CONFIG_SERIAL_IP22_ZILOG) +=3D ip22zilog.o=

obj-$(CONFIG_SERIAL_MUX) +=3D mux.o

obj-$(CONFIG_SERIAL_68328) +=3D 68328serial.o

diff -purN a/drivers/tty/serial/max310x.c b/drivers/= tty/serial/max310x.c

--- a/drivers/tty/serial/max310x.c   =          2013-05-12 02:27:46.000000= 000 +0530

+++ b/drivers/tty/serial/max310x.c =         2016-08-12 10:22:40.000000000 &#= 43;0530

@@ -25,8 +25,11 @@

#include <linux/regmap.h>

#include <linux/gpio.h>

#include <linux/spi/spi.h>

+#include <linux/i2c.h>

#include <linux/platform_data/max310x.h><= /o:p>

 

+#define BULK_RW_ENABLE    &= nbsp; 0

+

#define MAX310X_MAJOR     &= nbsp;           &nbs= p;            &= nbsp;          204<= /p>

#define MAX310X_MINOR     &= nbsp;           &nbs= p;            &= nbsp;          209<= /p>

 

@@ -272,6 +275,8 @@ struct max310x_port {

        &nbs= p;      const char     &n= bsp;            = ;         *name;

        &nbs= p;      int      &nb= sp;            =             &nb= sp;           uartclk;

 

+        = ;     unsigned char       = ;             b= uf[MAX310X_FIFO_SIZE];

+

        &nbs= p;      unsigned int     =             &nb= sp;     nr_gpio;

#ifdef CONFIG_GPIOLIB

        &nbs= p;      struct gpio_chip    &n= bsp;           gpio;=

@@ -459,7 +464,7 @@ static int max310x_set_ref_c= lk(struct ma

 

 static void max310x_handle_rx(struct max310x_p= ort *s, unsigned int rxlen)

{

-        &nb= sp;     unsigned int sts =3D 0, ch =3D 0, flag;

+        = ;     unsigned int sts =3D 0, ch =3D 0, flag, bytes_rea= d, i;

        &nbs= p;      struct tty_struct *tty =3D tty_port_tty_ge= t(&s->port.state->port);

 

        &nbs= p;       if (!tty)

@@ -473,7 +478,64 @@ static void max310x_handle_= rx(struct max

 

        &nbs= p;       dev_dbg(s->port.dev, "RX Len= =3D %u\n", rxlen);

 

-        &nb= sp;     while (rxlen--) {

+        = ;     #if BULK_RW_ENABLE

+

+        = ;     while (rxlen) {

+        = ;            &n= bsp;        regmap_read(s->regmap, MA= X310X_LSR_IRQSTS_REG, &sts);

+        = ;            &n= bsp;        sts &=3D MAX310X_LSR_RXP= AR_BIT | MAX310X_LSR_FRERR_BIT |

+        = ;            &n= bsp;            &nbs= p;  MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RXBRK_BIT;

+        = ;            &n= bsp;        if(sts)

+        = ;            &n= bsp;        {

+        = ;            &n= bsp;            = ;            regmap_= read(s->regmap,MAX310X_RHR_REG, s->buf);

+        = ;            &n= bsp;            = ;            bytes_r= ead =3D 1;

+        = ;            &n= bsp;        } else {

+        = ;            &n= bsp;            = ;            regcach= e_cache_bypass(s->regmap, true);

+        &nbs= p;            &= nbsp;       regmap_raw_read(s->regmap, MAX= 310X_RHR_REG, s->buf, rxlen);

+        = ;             &= nbsp;       regcache_cache_bypass(s->regma= p, false);

+        = ;            &n= bsp;            = ;            bytes_r= ead =3D rxlen;

+        = ;            &n= bsp;        }

+        = ;            &n= bsp;       

+        = ;            &n= bsp;        s->port.icount.rx+= 3;;

+        = ;            &n= bsp;        flag =3D TTY_NORMAL;

+

+        = ;            &n= bsp;        if (unlikely(sts)) {

+        = ;            &n= bsp;            = ;            if (sts= & MAX310X_LSR_RXBRK_BIT) {

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   s->port.icount.brk++;

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   if (uart_handle_break(&s->port))

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;      continue;

+        = ;            &n= bsp;            = ;            } else = if (sts & MAX310X_LSR_RXPAR_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   s->port.icount.parity++;

+        = ;            &n= bsp;            = ;            else if= (sts & MAX310X_LSR_FRERR_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   s->port.icount.frame++;

+        = ;            &n= bsp;            = ;            else if= (sts & MAX310X_LSR_RXOVR_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   s->port.icount.overrun++;

+

+        = ;            &n= bsp;            = ;            sts &am= p;=3D s->port.read_status_mask;

+        = ;            &n= bsp;            = ;            if (sts= & MAX310X_LSR_RXBRK_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   flag =3D TTY_BREAK;

+        = ;            &n= bsp;            = ;            else if= (sts & MAX310X_LSR_RXPAR_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   flag =3D TTY_PARITY;

+        = ;            &n= bsp;            = ;            else if= (sts & MAX310X_LSR_FRERR_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   flag =3D TTY_FRAME;

+        = ;            &n= bsp;            = ;            else if= (sts & MAX310X_LSR_RXOVR_BIT)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   flag =3D TTY_OVERRUN;

+        = ;            &n= bsp;        }

+        = ;            &n= bsp;       

+        = ;            &n= bsp;        for(i=3D0; i< bytes_read;= i++)

+        = ;            &n= bsp;        {

+        = ;            &n= bsp;            = ;            if (uar= t_handle_sysrq_char(s->port, s->buf[i]))

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   continue;

+

+        = ;            &n= bsp;            = ;            if (sts= & s->port.ignore_status_mask)

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   continue;

+

+        = ;            &n= bsp;            = ;            uart_in= sert_char(&s->port, sts, MAX310X_LSR_RXOVR_BIT,

+        = ;            &n= bsp;            = ;            &n= bsp;            = ;   s->buf[i], flag);

+        = ;            &n= bsp;        }

+        = ;            &n= bsp;        rxlen -=3D bytes_read;<= /o:p>

+        = ;     }

+        = ;     #else

+        = ;            &n= bsp;        while (rxlen--) {=

        &nbs= p;            &= nbsp;         regmap_read(s->reg= map, MAX310X_RHR_REG, &ch);

        &nbs= p;            &= nbsp;         regmap_read(s->reg= map, MAX310X_LSR_IRQSTS_REG, &sts);

 

@@ -514,8 +576,8 @@ static void max310x_handle_r= x(struct max

 

        &nbs= p;            &= nbsp;          uart_insert_cha= r(&s->port, sts, MAX310X_LSR_RXOVR_BIT,

        &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;     ch, flag);

-        &nb= sp;     }

-

+        = ;            &n= bsp;        }

+        = ;     #endif

        &nbs= p;      tty_flip_buffer_push(tty);

 

        &nbs= p;       tty_kref_put(tty);

@@ -524,8 +586,7 @@ static void max310x_handle_r= x(struct max

static void max310x_handle_tx(struct max310x_port *s= )

{

        &nbs= p;      struct circ_buf *xmit =3D &s->port.= state->xmit;

-        &nb= sp;     unsigned int txlen =3D 0, to_send;

-

+        = ;     unsigned int txlen =3D 0, to_send =3D 0, i;<= /o:p>

        &nbs= p;      if (unlikely(s->port.x_char)) {

        &nbs= p;            &= nbsp;         regmap_write(s->re= gmap, MAX310X_THR_REG, s->port.x_char);

        &nbs= p;            &= nbsp;         s->port.icount.tx&= #43;+;

@@ -545,7 +606,18 @@ static void max310x_handle_= tx(struct max

        &nbs= p;            &= nbsp;         to_send =3D (to_send = > txlen) ? txlen : to_send;

 

        &nbs= p;            &= nbsp;          dev_dbg(s->p= ort.dev, "TX Len =3D %u\n", to_send);

-

+#if BULK_RW_ENABLE

+        = ;            &n= bsp;        /* Add data to send */<= /o:p>

+        = ;            &n= bsp;        s->port.icount.tx += =3D to_send;

+        = ;            &n= bsp;        for(i=3D0; i < to_send; &= #43;+i)

+        = ;            &n= bsp;        {

+        = ;            &n= bsp;            = ;            s->b= uf[i] =3D xmit->buf[xmit->tail];

+        = ;            &n= bsp;            = ;            xmit-&g= t;tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1);

+        = ;            &n= bsp;        }

+        = ;            &n= bsp;        regcache_cache_bypass(s->= regmap, true);

+        &nbs= p;            &= nbsp;       regmap_raw_write(s->regmap, MA= X310X_THR_REG, s->buf, to_send);

+        &nbs= p;            &= nbsp;       regcache_cache_bypass(s->regma= p, false);

+#else

        &nbs= p;            &= nbsp;          /* Add data to = send */

        &nbs= p;            &= nbsp;         s->port.icount.tx = +=3D to_send;

        &nbs= p;            &= nbsp;         while (to_send--) {

@@ -553,6 +625,7 @@ static void max310x_handle_t= x(struct max

        &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;         xmit->buf[xmit->ta= il]);

        &nbs= p;            &= nbsp;           &nbs= p;             = xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1);<= /o:p>

        &nbs= p;            &= nbsp;         };

+#endif

        &nbs= p;      }

 

        &nbs= p;       if (uart_circ_chars_pending(xmit) &l= t; WAKEUP_CHARS)

@@ -593,7 +666,7 @@ static irqreturn_t max310x_i= st(int irq,

static void max310x_wq_proc(struct work_struct *ws)<= o:p>

{

        &nbs= p;      struct max310x_port *s =3D container_of(ws= , struct max310x_port, tx_work);

-

+        = ;    

        &nbs= p;      mutex_lock(&s->max310x_mutex);=

        &nbs= p;      max310x_handle_tx(s);

        &nbs= p;      mutex_unlock(&s->max310x_mutex);

@@ -887,12 +960,12 @@ static struct uart_ops max= 310x_ops =3D {

        &nbs= p;      .verify_port     =    =3D max310x_verify_port,

};

 

-static int max310x_suspend(struct spi_device *spi, = pm_message_t state)

+static int max310x_suspend(struct device *dev)<= o:p>

{

        &nbs= p;      int ret;

-        &nb= sp;     struct max310x_port *s =3D dev_get_drvdata(&= ;spi->dev);

+        = ;     struct max310x_port *s =3D dev_get_drvdata(dev);<= o:p>

 

-        &nb= sp;     dev_dbg(&spi->dev, "Suspend\n"= );

+        = ;     dev_dbg(dev, "Suspend\n");

 

        &nbs= p;       ret =3D uart_suspend_port(&s->= ;uart, &s->port);

 

@@ -911,11 +984,11 @@ static int max310x_suspend= (struct spi_de

        &nbs= p;      return ret;

}

 

-static int max310x_resume(struct spi_device *spi)

+static int max310x_resume(struct device *dev)

{

-        &nb= sp;     struct max310x_port *s =3D dev_get_drvdata(&= ;spi->dev);

+        = ;     struct max310x_port *s =3D dev_get_drvdata(dev);<= o:p>

 

-        &nb= sp;     dev_dbg(&spi->dev, "Resume\n")= ;

+        = ;     dev_dbg(dev, "Resume\n");

 

        &nbs= p;       if (s->pdata->suspend)

        &nbs= p;            &= nbsp;         s->pdata->suspe= nd(0);

@@ -995,17 +1068,15 @@ static struct max310x_pda= ta generic_plat

        &nbs= p;      .frequency     &n= bsp;    =3D 26000000,

};

 

-static int max310x_probe(struct spi_device *spi)

+static int max310x_probe(struct device *dev, in= t chiptype, struct regmap *regmap, int irq)

{

        &nbs= p;      struct max310x_port *s;

-        &nb= sp;     struct device *dev =3D &spi->dev;

-        &nb= sp;     int chiptype =3D spi_get_device_id(spi)->dri= ver_data;

        &nbs= p;      struct max310x_pdata *pdata =3D dev->pl= atform_data;

        &nbs= p;      unsigned int val =3D 0;

        &nbs= p;      int ret;

 

        &nbs= p;       /* Check for IRQ */

-        &nb= sp;     if (spi->irq <=3D 0) {

+        = ;     if (irq <=3D 0) {

        &nbs= p;            &= nbsp;         dev_err(dev, "No= IRQ specified\n");

        &nbs= p;            &= nbsp;         return -ENOTSUPP;

        &nbs= p;      }

@@ -1023,6 +1094,7 @@ static int max310x_probe(s= truct spi_devi

        &nbs= p;            &= nbsp;         pdata =3D &generi= c_plat_data;

        &nbs= p;      }

        &nbs= p;      s->pdata =3D pdata;

+    s->regmap =3D regmap;

 

        &nbs= p;       /* Individual chip settings */<= /o:p>

        &nbs= p;      switch (chiptype) {

@@ -1030,13 +1102,11 @@ static int max310x_probe= (struct spi_devi

        &nbs= p;            &= nbsp;         s->name =3D "= MAX3107";

        &nbs= p;            &= nbsp;         s->nr_gpio =3D 4;<= o:p>

        &nbs= p;            &= nbsp;         s->uart.nr =3D 1;<= o:p>

-        &nb= sp;            =          s->regcfg.max_register = =3D 0x1f;

        &nbs= p;            &= nbsp;         break;

        &nbs= p;      case MAX310X_TYPE_MAX3108:

        &nbs= p;            &= nbsp;         s->name =3D "= MAX3108";

        &nbs= p;            &= nbsp;         s->nr_gpio =3D 4;<= o:p>

        &nbs= p;            &= nbsp;         s->uart.nr =3D 1;<= o:p>

-        &nb= sp;            =          s->regcfg.max_register = =3D 0x1e;

        &nbs= p;            &= nbsp;         break;

        &nbs= p;      default:

        &nbs= p;            &= nbsp;         dev_err(dev, "Un= supported chip type %i\n", chiptype);

@@ -1054,32 +1124,16 @@ static int max310x_probe= (struct spi_devi

 

        &nbs= p;       mutex_init(&s->max310x_mutex)= ;

 

-        &nb= sp;     /* Setup SPI bus */

-        &nb= sp;     spi->mode      = ;            &n= bsp;       =3D SPI_MODE_0;

-        &nb= sp;     spi->bits_per_word    &n= bsp;   =3D 8;

-        &nb= sp;     spi->max_speed_hz    &nb= sp;  =3D 26000000;

-        &nb= sp;     spi_setup(spi);

-

-        &nb= sp;     /* Setup regmap */

-        &nb= sp;     s->regcfg.reg_bits    &n= bsp;            = ;          =3D 8;

-        &nb= sp;     s->regcfg.val_bits    &n= bsp;            = ;           =3D 8;

-        &nb= sp;     s->regcfg.read_flag_mask   &n= bsp;       =3D 0x00;

-        &nb= sp;     s->regcfg.write_flag_mask   &= nbsp;      =3D 0x80;

-        &nb= sp;     s->regcfg.cache_type    =             &nb= sp;   =3D REGCACHE_RBTREE;

-        &nb= sp;     s->regcfg.writeable_reg   &nb= sp;            =             &nb= sp;  =3D max3107_8_reg_writeable;

-        &nb= sp;     s->regcfg.volatile_reg   &nbs= p;            &= nbsp;   =3D max310x_reg_volatile;

-        &nb= sp;     s->regcfg.precious_reg   &nbs= p;             = =3D max310x_reg_precious;

-        &nb= sp;     s->regmap =3D devm_regmap_init_spi(spi, &= ;s->regcfg);

        &nbs= p;      if (IS_ERR(s->regmap)) {

        &nbs= p;            &= nbsp;         ret =3D PTR_ERR(s->= ;regmap);

        &nbs= p;            &= nbsp;         dev_err(dev, "Fa= iled to initialize register map\n");

        &nbs= p;            &= nbsp;         goto err_out;

        &nbs= p;      }

 

-        &nb= sp;     /* Reset chip & check SPI function */<= /o:p>

+        = ;     /* Reset chip & check SPI/I2C function */

        &nbs= p;      ret =3D regmap_write(s->regmap, MAX310X= _MODE2_REG, MAX310X_MODE2_RST_BIT);

        &nbs= p;      if (ret) {

-        &nb= sp;            =          dev_err(dev, "SPI tra= nsfer failed\n");

+        = ;            &n= bsp;        dev_err(dev, "SPI/I2C t= ransfer failed\n");

        &nbs= p;            &= nbsp;         goto err_out;

        &nbs= p;      }

        &nbs= p;      /* Clear chip reset */

@@ -1129,11 +1183,12 @@ static int max310x_probe= (struct spi_devi

        &nbs= p;      regmap_write(s->regmap, MAX310X_MODE1_R= EG, val);

 

        &nbs= p;       /* Setup interrupt */

-        &nb= sp;     ret =3D devm_request_threaded_irq(dev, spi->= irq, NULL, max310x_ist,

+        = ;     /* Used IRQF_TRIGGER_LOW in case of I2C */

+        = ;     ret =3D devm_request_threaded_irq(dev, irq, NULL,= max310x_ist,

        &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;       IRQF_TRIGGER_FALLING | IRQF_ONESH= OT,

        &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;       dev_name(dev), s);

        &nbs= p;      if (ret) {

-        &nb= sp;            =          dev_err(dev, "Unable = to reguest IRQ %i\n", spi->irq);

+        = ;            &n= bsp;        dev_err(dev, "Unable to= reguest IRQ %i\n", irq);

        &nbs= p;            &= nbsp;         goto err_out;

        &nbs= p;      }

 

@@ -1156,7 +1211,7 @@ static int max310x_probe(s= truct spi_devi

        &nbs= p;      /* Initialize UART port data */=

        &nbs= p;      s->port.line    &nb= sp;            =        =3D 0;

        &nbs= p;      s->port.dev    &nbs= p;            &= nbsp;      =3D dev;

-        &nb= sp;     s->port.irq     &nb= sp;            =         =3D spi->irq;

+        = ;     s->port.irq      = ;            &n= bsp;       =3D irq;

        &nbs= p;      s->port.type    &nb= sp;            =      =3D PORT_MAX310X;

        &nbs= p;      s->port.fifosize =3D MAX310X_FIFO_SIZE;=

        &nbs= p;      s->port.flags    &n= bsp;            = ;     =3D UPF_SKIP_TEST | UPF_FIXED_TYPE;

@@ -1203,9 +1258,8 @@ err_out:

        &nbs= p;      return ret;

}

 

-static int max310x_remove(struct spi_device *spi)

+static int max310x_remove(struct device *dev)

{

-        &nb= sp;     struct device *dev =3D &spi->dev;

        &nbs= p;      struct max310x_port *s =3D dev_get_drvdata= (dev);

        &nbs= p;      int ret =3D 0;

 

@@ -1237,6 +1291,63 @@ static int max310x_remove= (struct spi_dev

        &nbs= p;      return ret;

}

 

+static struct regmap_config regcfg =3D {

+    .reg_bits =3D 8,<= /p>

+    .val_bits =3D 8,<= /p>

+    .read_flag_mask =3D 0x00,

+    .write_flag_mask =3D 0x80,&n= bsp;     // may need to remove this mask

+    .cache_type =3D REGCACHE_RBT= REE,

+    .writeable_reg =3D max3107_8= _reg_writeable,

+    .volatile_reg =3D max310x_re= g_volatile,

+    .precious_reg =3D max310x_re= g_precious,

+};

+

+#ifdef CONFIG_SERIAL_MAX310X_SPI

+

+static int max310x_spi_probe(struct spi_device = *spi)

+{

+        = ;     struct regmap *regmap;

+    int chiptype =3D spi_get_dev= ice_id(spi)->driver_data;

+   

+        = ;     /* Setup SPI bus */

+        = ;     spi->mode      &= nbsp;           &nbs= p;       =3D SPI_MODE_0;

+        = ;     spi->bits_per_word    &nbs= p;   =3D 8;

+        = ;     spi->max_speed_hz     = ;  =3D 26000000;

+        = ;     spi_setup(spi);

+   

+        &nbs= p;    switch (chiptype) {

+        = ;     case MAX310X_TYPE_MAX3107:

+        = ;            &n= bsp;        regcfg.max_register =3D 0x1f= ;

+        = ;            &n= bsp;        break;

+        = ;     case MAX310X_TYPE_MAX3108:

+        = ;            &n= bsp;        regcfg.max_register =3D 0x1e= ;

+        = ;            &n= bsp;        break;

+        = ;     default:

+        = ;            &n= bsp;        dev_err(&spi->dev, &q= uot;Unsupported chip type %i\n", chiptype);

+        = ;            &n= bsp;        return -ENOTSUPP;=

+        = ;     }

+   

+   

+        = ;     regmap =3D devm_regmap_init_spi(spi, &regcfg)= ;

+   

+    return max310x_probe(&sp= i->dev, chiptype, regmap, spi->irq);

+}

+

+static int max310x_spi_remove(struct spi_device= *spi)

+{

+        = ;     return max310x_remove(&spi->dev);

+}

+

+static int max310x_suspend(struct spi_device *s= pi, pm_message_t state)

+{

+    return max310x_suspend(&= spi->dev);

+}

+

+static int max310x_resume(struct spi_device *sp= i)

+{

+    return max310x_resume(&s= pi->dev);

+}

+

static const struct spi_device_id max310x_id_table[]= =3D {

        &nbs= p;      { "max3107",   &n= bsp;  MAX310X_TYPE_MAX3107 },

        &nbs= p;      { "max3108",   &n= bsp;  MAX310X_TYPE_MAX3108 },

@@ -1249,13 +1360,76 @@ static struct spi_driver= max310x_driver

        &nbs= p;            &= nbsp;         .name   =3D= "max310x",

        &nbs= p;            &= nbsp;         .owner =3D THIS_MODUL= E,

        &nbs= p;      },

-        &nb= sp;     .probe       = ;           =3D max310x_p= robe,

-        &nb= sp;     .remove      &nbs= p;            &= nbsp;           =3D max31= 0x_remove,

-        &nb= sp;     .suspend      &nb= sp;      =3D max310x_suspend,

-        &nb= sp;     .resume      &nbs= p;            &= nbsp;           =3D max31= 0x_resume,

+        = ;     .probe       &= nbsp;          =3D max310x_spi= _probe,

+        = ;     .remove       =             &nb= sp;           =3D max310x= _spi_remove,

+        = ;     .suspend       = ;      =3D max310x_spi_suspend,

+        = ;     .resume       =             &nb= sp;           =3D max310x= _spi_resume,

        &nbs= p;      .id_table     &nb= sp;        =3D max310x_id_table,

};

module_spi_driver(max310x_driver);

+#endif

+

+#ifdef CONFIG_SERIAL_MAX310X_I2C

+

+static int max310x_i2c_probe(struct i2c_client = *i2c,const struct i2c_device_id *id)

+{

+    struct regmap *regmap;<= /o:p>

+        = ;     int chiptype =3D id->driver_data;

+    printk("chiptype =3D %d= \n",chiptype);

+        &nbs= p;    switch (chiptype) {

+        = ;     case MAX310X_TYPE_MAX3107:

+        = ;            &n= bsp;        regcfg.max_register =3D 0x1f= ;

+        = ;            &n= bsp;        break;

+        = ;     case MAX310X_TYPE_MAX3108:

+        = ;            &n= bsp;        regcfg.max_register =3D 0x1e= ;

+        = ;            &n= bsp;        break;

+        = ;     default:

+        = ;            &n= bsp;        dev_err(&i2c->dev, &q= uot;Unsupported chip type %i\n", chiptype);

+        = ;            &n= bsp;        return -ENOTSUPP;=

+        = ;     }

+   

+

+    regmap =3D devm_regmap_init_= i2c(i2c, &regcfg);

+

+    return max310x_probe(&i2= c->dev, chiptype, regmap,  i2c->irq);

+}

+

+static int max310x_i2c_remove(struct i2c_client= *i2c)

+{

+        = ;     return max310x_remove(&i2c->dev);

+}

+

+static int max310x_i2c_suspend(struct i2c_clien= t *i2c, pm_message_t state)

+{

+    return max310x_suspend(&= i2c->dev);

+}

+

+static int max310x_i2c_resume(struct i2c_client= *i2c)

+{

+    return max310x_resume(&i= 2c->dev);

+}

+

+

+static const struct i2c_device_id max310x_id_ta= ble[] =3D {

+        = ;     { "max3107",    &nb= sp; MAX310X_TYPE_MAX3107 },

+        = ;     { "max3108",    &nb= sp; MAX310X_TYPE_MAX3108 },

+        = ;     { }

+};

+MODULE_DEVICE_TABLE(i2c, max310x_id_table);

+

+static struct i2c_driver max310x_driver =3D {

+        = ;     .driver =3D {

+        = ;            &n= bsp;        .name   =3D "= max310x",

+        = ;            &n= bsp;        .owner =3D THIS_MODULE,=

+        = ;     },

+        = ;     .probe       &= nbsp;          =3D max310x_i2c= _probe,

+        = ;     .remove       =             &nb= sp;           =3D max310x= _i2c_remove,

+        = ;     .suspend       = ;      =3D max310x_i2c_suspend,

+        = ;     .resume       =             &nb= sp;           =3D max310x= _i2c_resume,

+        = ;     .id_table      &nbs= p;       =3D max310x_id_table,

+};

+module_i2c_driver(max310x_driver);

+#endif

 

 MODULE_LICENSE("GPL v2");=

MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");

 

--_000_CDD76EB921100341B75E76FF5FC7731F1F14067FSIMTCSMB06napaa_--