| 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* SC16IS7xx I2C interface driver */ |
| 3 | |
| 4 | #include <linux/dev_printk.h> |
| 5 | #include <linux/i2c.h> |
| 6 | #include <linux/mod_devicetable.h> |
| 7 | #include <linux/module.h> |
| 8 | #include <linux/regmap.h> |
| 9 | #include <linux/string.h> |
| 10 | |
| 11 | #include "sc16is7xx.h" |
| 12 | |
| 13 | static int sc16is7xx_i2c_probe(struct i2c_client *i2c) |
| 14 | { |
| 15 | const struct sc16is7xx_devtype *devtype; |
| 16 | struct regmap *regmaps[SC16IS7XX_MAX_PORTS]; |
| 17 | struct regmap_config regcfg; |
| 18 | unsigned int i; |
| 19 | |
| 20 | devtype = i2c_get_match_data(client: i2c); |
| 21 | if (!devtype) |
| 22 | return dev_err_probe(dev: &i2c->dev, err: -ENODEV, fmt: "Failed to match device\n" ); |
| 23 | |
| 24 | memcpy(®cfg, &sc16is7xx_regcfg, sizeof(struct regmap_config)); |
| 25 | |
| 26 | for (i = 0; i < devtype->nr_uart; i++) { |
| 27 | regcfg.name = sc16is7xx_regmap_name(port_id: i); |
| 28 | regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(port_id: i); |
| 29 | regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(port_id: i); |
| 30 | regmaps[i] = devm_regmap_init_i2c(i2c, ®cfg); |
| 31 | } |
| 32 | |
| 33 | return sc16is7xx_probe(dev: &i2c->dev, devtype, regmaps, irq: i2c->irq); |
| 34 | } |
| 35 | |
| 36 | static void sc16is7xx_i2c_remove(struct i2c_client *client) |
| 37 | { |
| 38 | sc16is7xx_remove(dev: &client->dev); |
| 39 | } |
| 40 | |
| 41 | static const struct i2c_device_id sc16is7xx_i2c_id_table[] = { |
| 42 | { "sc16is74x" , (kernel_ulong_t)&sc16is74x_devtype, }, |
| 43 | { "sc16is740" , (kernel_ulong_t)&sc16is74x_devtype, }, |
| 44 | { "sc16is741" , (kernel_ulong_t)&sc16is74x_devtype, }, |
| 45 | { "sc16is750" , (kernel_ulong_t)&sc16is750_devtype, }, |
| 46 | { "sc16is752" , (kernel_ulong_t)&sc16is752_devtype, }, |
| 47 | { "sc16is760" , (kernel_ulong_t)&sc16is760_devtype, }, |
| 48 | { "sc16is762" , (kernel_ulong_t)&sc16is762_devtype, }, |
| 49 | { } |
| 50 | }; |
| 51 | MODULE_DEVICE_TABLE(i2c, sc16is7xx_i2c_id_table); |
| 52 | |
| 53 | static struct i2c_driver sc16is7xx_i2c_driver = { |
| 54 | .driver = { |
| 55 | .name = SC16IS7XX_NAME, |
| 56 | .of_match_table = sc16is7xx_dt_ids, |
| 57 | }, |
| 58 | .probe = sc16is7xx_i2c_probe, |
| 59 | .remove = sc16is7xx_i2c_remove, |
| 60 | .id_table = sc16is7xx_i2c_id_table, |
| 61 | }; |
| 62 | |
| 63 | module_i2c_driver(sc16is7xx_i2c_driver); |
| 64 | |
| 65 | MODULE_LICENSE("GPL" ); |
| 66 | MODULE_DESCRIPTION("SC16IS7xx I2C interface driver" ); |
| 67 | MODULE_IMPORT_NS("SERIAL_NXP_SC16IS7XX" ); |
| 68 | |