On Thu, Jan 17, 2019 at 10:36 AM Sergio Paracuellos <sergio.paracuel...@gmail.com> wrote: > > On Thu, Jan 17, 2019 at 4:24 AM <tristram...@microchip.com> wrote: > > > > From: Tristram Ha <tristram...@microchip.com> > > > > Add KSZ9477 I2C driver support. The code ksz9477.c and ksz_common.c are > > used together to generate the I2C driver. > > > > Signed-off-by: Tristram Ha <tristram...@microchip.com> > > --- > > drivers/net/dsa/microchip/Kconfig | 7 ++ > > drivers/net/dsa/microchip/Makefile | 1 + > > drivers/net/dsa/microchip/ksz9477_i2c.c | 120 > > ++++++++++++++++++++++++++++++++ > > 3 files changed, 128 insertions(+) > > create mode 100644 drivers/net/dsa/microchip/ksz9477_i2c.c > > > > diff --git a/drivers/net/dsa/microchip/Kconfig > > b/drivers/net/dsa/microchip/Kconfig > > index 385b93f..1798755 100644 > > --- a/drivers/net/dsa/microchip/Kconfig > > +++ b/drivers/net/dsa/microchip/Kconfig > > @@ -9,6 +9,13 @@ menuconfig NET_DSA_MICROCHIP_KSZ9477 > > help > > This driver adds support for Microchip KSZ9477 switch chips. > > > > +config NET_DSA_MICROCHIP_KSZ9477_I2C > > + tristate "KSZ9477 series I2C connected switch driver" > > + depends on NET_DSA_MICROCHIP_KSZ9477 && I2C > > + select REGMAP_I2C > > + help > > + Select to enable support for registering switches configured > > through I2C. > > + > > config NET_DSA_MICROCHIP_KSZ9477_SPI > > tristate "KSZ9477 series SPI connected switch driver" > > depends on NET_DSA_MICROCHIP_KSZ9477 && SPI > > diff --git a/drivers/net/dsa/microchip/Makefile > > b/drivers/net/dsa/microchip/Makefile > > index 3142c18..dbcc5db 100644 > > --- a/drivers/net/dsa/microchip/Makefile > > +++ b/drivers/net/dsa/microchip/Makefile > > @@ -1,3 +1,4 @@ > > obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON) += ksz_common.o > > obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477) += ksz9477.o > > +obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C) += ksz9477_i2c.o > > obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI) += ksz9477_spi.o > > diff --git a/drivers/net/dsa/microchip/ksz9477_i2c.c > > b/drivers/net/dsa/microchip/ksz9477_i2c.c > > new file mode 100644 > > index 0000000..d8720ff > > --- /dev/null > > +++ b/drivers/net/dsa/microchip/ksz9477_i2c.c > > @@ -0,0 +1,120 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Microchip KSZ9477 series register access through I2C > > + * > > + * Copyright (C) 2018-2019 Microchip Technology Inc. > > + */ > > + > > +#include <linux/kernel.h> > > +#include <linux/module.h> > > +#include <linux/i2c.h> > > + > > +#include "ksz_priv.h" > > + > > +#define REG_SIZE 0x8000 > > + > > +#define I2C_REGMAP_VAL 8 > > +#define I2C_REGMAP_REG 16 > > + > > +#define KSZ_REGMAP_COMMON(n, width) \ > > +{ \ > > + .name = n, \ > > + .max_register = REG_SIZE - (width), \ > > + .reg_bits = I2C_REGMAP_REG, \ > > + .val_bits = I2C_REGMAP_VAL * (width), \ > > + .reg_stride = (width), \ > > + .reg_format_endian = REGMAP_ENDIAN_BIG, \ > > + .val_format_endian = REGMAP_ENDIAN_BIG, \ > > +} > > + > > +static const struct regmap_config ksz9477_regmap_cfg[] = { > > + KSZ_REGMAP_COMMON("8", 1), > > + KSZ_REGMAP_COMMON("16", 2), > > + KSZ_REGMAP_COMMON("32", 4), > > +}; > > + > > +static int ksz9477_i2c_probe(struct i2c_client *i2c, > > + const struct i2c_device_id *i2c_id) > > +{ > > + struct ksz_device *dev; > > + int i; > > + int ret; > > + > > + dev = ksz_switch_alloc(&i2c->dev); > > + if (!dev) > > + return -ENOMEM; > > + > > + for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_cfg); i++) { > > + dev->regmap[i] = devm_regmap_init_i2c(i2c, > > + > > &ksz9477_regmap_cfg[i]); > > + if (IS_ERR(dev->regmap[i])) { > > + ret = PTR_ERR(dev->regmap[i]); > > + dev_err(&i2c->dev, "Failed to initialize regmap: > > %d\n", > > + ret); > > + return ret; > > + } > > + } > > + > > + if (i2c->dev.platform_data) > > + dev->pdata = i2c->dev.platform_data; > > + > > + ret = ksz9477_switch_register(dev); > > + > > + /* Main DSA driver may not be started yet. */ > > + if (ret) > > + return ret; > > + > > + i2c_set_clientdata(i2c, dev); > > + > > + return 0; > > +} > > + > > +static int ksz9477_i2c_remove(struct i2c_client *i2c) > > +{ > > + struct ksz_device *dev = i2c_get_clientdata(i2c); > > + > > + if (dev) > > + ksz_switch_remove(dev); > > + > > + return 0; > > +} > > + > > +static void ksz9477_i2c_shutdown(struct i2c_client *i2c) > > +{ > > + struct ksz_device *dev = i2c_get_clientdata(i2c); > > + > > + if (dev && dev->dev_ops->shutdown) > > + dev->dev_ops->shutdown(dev); > > +} > > + > > +static const struct i2c_device_id ksz9477_i2c_id[] = { > > + { "ksz9477-switch", 0 }, > > + {}, > > +}; > > + > > +MODULE_DEVICE_TABLE(i2c, ksz9477_i2c_id); > > + > > +static const struct of_device_id ksz9477_dt_ids[] = { > > + { .compatible = "microchip,ksz9477" }, > > + { .compatible = "microchip,ksz9897" }, > > + {}, > > +}; > > +MODULE_DEVICE_TABLE(of, ksz9477_dt_ids); > > + > > +static struct i2c_driver ksz9477_i2c_driver = { > > + .driver = { > > + .name = "ksz9477-switch", > > + .owner = THIS_MODULE, > > + .of_match_table = of_match_ptr(ksz9477_dt_ids), > > + }, > > + .probe = ksz9477_i2c_probe, > > + .remove = ksz9477_i2c_remove, > > + .shutdown = ksz9477_i2c_shutdown, > > + .id_table = ksz9477_i2c_id, > > +}; > > + > > +module_i2c_driver(ksz9477_i2c_driver); > > + > > +MODULE_AUTHOR("Tristram Ha <tristram...@microchip.com>"); > > +MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch I2C Driver"); > > +MODULE_LICENSE("GPL v2"); > > -- > > 1.9.1 > > > I have to make use of the microchip regs_bin utility and one extra > patch to provide access to switch registers through > /sys/bus/i2c/devices/0-005f/registers file because I need to configure > master direct mode with sgmii which is not supported yet by this > driver but the i2c interface using regmap as it is here works for me. > So you can add my: > > Tested-by: Sergio Paracuellos <sergio.paracuel...@gmail.com> > > Best regards, > Sergio Paracuellos
I forgot to mention that I have tested this on KSZ9897S switch. Best regards, Sergio Paracuellos