Commit 2c837a8a authored by Rama Kiran Kumar Indrakanti's avatar Rama Kiran Kumar Indrakanti Committed by Greg Kroah-Hartman

sc16is7xx: spi interface is added

spi interface for sc16is7xx is added along with Kconfig flag
to enable spi or i2c, thus in a instance we can have either
spi or i2c or both, in sync to the hw.
Signed-off-by: default avatarRama Kiran Kumar Indrakanti <indrakanti_ram@hotmail.com>
Signed-off-by: default avatarJakub Kicinski <kubakici@wp.pl>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 34d2e458
...@@ -1179,15 +1179,42 @@ config SERIAL_SCCNXP_CONSOLE ...@@ -1179,15 +1179,42 @@ config SERIAL_SCCNXP_CONSOLE
help help
Support for console on SCCNXP serial ports. Support for console on SCCNXP serial ports.
config SERIAL_SC16IS7XX_CORE
tristate
config SERIAL_SC16IS7XX config SERIAL_SC16IS7XX
tristate "SC16IS7xx serial support" tristate "SC16IS7xx serial support"
depends on I2C select SERIAL_CORE
select SERIAL_CORE depends on I2C || SPI_MASTER
select REGMAP_I2C if I2C help
help This selects support for SC16IS7xx serial ports.
This selects support for SC16IS7xx serial ports. Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752,
Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752, SC16IS760 and SC16IS762. Select supported buses using options below.
SC16IS760 and SC16IS762.
config SERIAL_SC16IS7XX_I2C
bool "SC16IS7xx for I2C interface"
depends on SERIAL_SC16IS7XX
depends on I2C
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_I2C if I2C
default y
help
Enable SC16IS7xx driver on I2C bus,
If required say y, and say n to i2c if not required,
Enabled by default to support oldconfig.
You must select at least one bus for the driver to be built.
config SERIAL_SC16IS7XX_SPI
bool "SC16IS7xx for spi interface"
depends on SERIAL_SC16IS7XX
depends on SPI_MASTER
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_SPI if SPI_MASTER
help
Enable SC16IS7xx driver on SPI bus,
If required say y, and say n to spi if not required,
This is additional support to exsisting driver.
You must select at least one bus for the driver to be built.
config SERIAL_BFIN_SPORT config SERIAL_BFIN_SPORT
tristate "Blackfin SPORT emulate UART" tristate "Blackfin SPORT emulate UART"
......
...@@ -53,7 +53,7 @@ obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o ...@@ -53,7 +53,7 @@ obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
obj-$(CONFIG_SERIAL_ETRAXFS) += etraxfs-uart.o obj-$(CONFIG_SERIAL_ETRAXFS) += etraxfs-uart.o
obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o
obj-$(CONFIG_SERIAL_SC16IS7XX) += sc16is7xx.o obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o
obj-$(CONFIG_SERIAL_JSM) += jsm/ obj-$(CONFIG_SERIAL_JSM) += jsm/
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#define SC16IS7XX_NAME "sc16is7xx" #define SC16IS7XX_NAME "sc16is7xx"
...@@ -1204,6 +1205,73 @@ static struct regmap_config regcfg = { ...@@ -1204,6 +1205,73 @@ static struct regmap_config regcfg = {
.precious_reg = sc16is7xx_regmap_precious, .precious_reg = sc16is7xx_regmap_precious,
}; };
#ifdef CONFIG_SERIAL_SC16IS7XX_SPI
static int sc16is7xx_spi_probe(struct spi_device *spi)
{
struct sc16is7xx_devtype *devtype;
unsigned long flags = 0;
struct regmap *regmap;
int ret;
/* Setup SPI bus */
spi->bits_per_word = 8;
/* only supports mode 0 on SC16IS762 */
spi->mode = spi->mode ? : SPI_MODE_0;
spi->max_speed_hz = spi->max_speed_hz ? : 15000000;
ret = spi_setup(spi);
if (ret)
return ret;
if (spi->dev.of_node) {
const struct of_device_id *of_id =
of_match_device(sc16is7xx_dt_ids, &spi->dev);
devtype = (struct sc16is7xx_devtype *)of_id->data;
} else {
const struct spi_device_id *id_entry = spi_get_device_id(spi);
devtype = (struct sc16is7xx_devtype *)id_entry->driver_data;
flags = IRQF_TRIGGER_FALLING;
}
regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) |
(devtype->nr_uart - 1);
regmap = devm_regmap_init_spi(spi, &regcfg);
return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq, flags);
}
static int sc16is7xx_spi_remove(struct spi_device *spi)
{
return sc16is7xx_remove(&spi->dev);
}
static const struct spi_device_id sc16is7xx_spi_id_table[] = {
{ "sc16is74x", (kernel_ulong_t)&sc16is74x_devtype, },
{ "sc16is750", (kernel_ulong_t)&sc16is750_devtype, },
{ "sc16is752", (kernel_ulong_t)&sc16is752_devtype, },
{ "sc16is760", (kernel_ulong_t)&sc16is760_devtype, },
{ "sc16is762", (kernel_ulong_t)&sc16is762_devtype, },
{ }
};
MODULE_DEVICE_TABLE(spi, sc16is7xx_spi_id_table);
static struct spi_driver sc16is7xx_spi_uart_driver = {
.driver = {
.name = SC16IS7XX_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(sc16is7xx_dt_ids),
},
.probe = sc16is7xx_spi_probe,
.remove = sc16is7xx_spi_remove,
.id_table = sc16is7xx_spi_id_table,
};
MODULE_ALIAS("spi:sc16is7xx");
#endif
#ifdef CONFIG_SERIAL_SC16IS7XX_I2C
static int sc16is7xx_i2c_probe(struct i2c_client *i2c, static int sc16is7xx_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -1253,8 +1321,43 @@ static struct i2c_driver sc16is7xx_i2c_uart_driver = { ...@@ -1253,8 +1321,43 @@ static struct i2c_driver sc16is7xx_i2c_uart_driver = {
.remove = sc16is7xx_i2c_remove, .remove = sc16is7xx_i2c_remove,
.id_table = sc16is7xx_i2c_id_table, .id_table = sc16is7xx_i2c_id_table,
}; };
module_i2c_driver(sc16is7xx_i2c_uart_driver);
MODULE_ALIAS("i2c:sc16is7xx"); MODULE_ALIAS("i2c:sc16is7xx");
#endif
static int __init sc16is7xx_init(void)
{
int ret = 0;
#ifdef CONFIG_SERIAL_SC16IS7XX_I2C
ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver);
if (ret < 0) {
pr_err("failed to init sc16is7xx i2c --> %d\n", ret);
return ret;
}
#endif
#ifdef CONFIG_SERIAL_SC16IS7XX_SPI
ret = spi_register_driver(&sc16is7xx_spi_uart_driver);
if (ret < 0) {
pr_err("failed to init sc16is7xx spi --> %d\n", ret);
return ret;
}
#endif
return ret;
}
module_init(sc16is7xx_init);
static void __exit sc16is7xx_exit(void)
{
#ifdef CONFIG_SERIAL_SC16IS7XX_I2C
i2c_del_driver(&sc16is7xx_i2c_uart_driver);
#endif
#ifdef CONFIG_SERIAL_SC16IS7XX_SPI
spi_unregister_driver(&sc16is7xx_spi_uart_driver);
#endif
}
module_exit(sc16is7xx_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jon Ringle <jringle@gridpoint.com>"); MODULE_AUTHOR("Jon Ringle <jringle@gridpoint.com>");
......
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