Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Microchip KSZ9477 series register access through I2C
0004  *
0005  * Copyright (C) 2018-2019 Microchip Technology Inc.
0006  */
0007 
0008 #include <linux/i2c.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/regmap.h>
0012 
0013 #include "ksz_common.h"
0014 
0015 KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0);
0016 
0017 static int ksz9477_i2c_probe(struct i2c_client *i2c,
0018                  const struct i2c_device_id *i2c_id)
0019 {
0020     struct regmap_config rc;
0021     struct ksz_device *dev;
0022     int i, ret;
0023 
0024     dev = ksz_switch_alloc(&i2c->dev, i2c);
0025     if (!dev)
0026         return -ENOMEM;
0027 
0028     for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) {
0029         rc = ksz9477_regmap_config[i];
0030         rc.lock_arg = &dev->regmap_mutex;
0031         dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc);
0032         if (IS_ERR(dev->regmap[i])) {
0033             ret = PTR_ERR(dev->regmap[i]);
0034             dev_err(&i2c->dev,
0035                 "Failed to initialize regmap%i: %d\n",
0036                 ksz9477_regmap_config[i].val_bits, ret);
0037             return ret;
0038         }
0039     }
0040 
0041     if (i2c->dev.platform_data)
0042         dev->pdata = i2c->dev.platform_data;
0043 
0044     ret = ksz_switch_register(dev);
0045 
0046     /* Main DSA driver may not be started yet. */
0047     if (ret)
0048         return ret;
0049 
0050     i2c_set_clientdata(i2c, dev);
0051 
0052     return 0;
0053 }
0054 
0055 static int ksz9477_i2c_remove(struct i2c_client *i2c)
0056 {
0057     struct ksz_device *dev = i2c_get_clientdata(i2c);
0058 
0059     if (dev)
0060         ksz_switch_remove(dev);
0061 
0062     i2c_set_clientdata(i2c, NULL);
0063 
0064     return 0;
0065 }
0066 
0067 static void ksz9477_i2c_shutdown(struct i2c_client *i2c)
0068 {
0069     struct ksz_device *dev = i2c_get_clientdata(i2c);
0070 
0071     if (!dev)
0072         return;
0073 
0074     if (dev->dev_ops->reset)
0075         dev->dev_ops->reset(dev);
0076 
0077     dsa_switch_shutdown(dev->ds);
0078 
0079     i2c_set_clientdata(i2c, NULL);
0080 }
0081 
0082 static const struct i2c_device_id ksz9477_i2c_id[] = {
0083     { "ksz9477-switch", 0 },
0084     {},
0085 };
0086 
0087 MODULE_DEVICE_TABLE(i2c, ksz9477_i2c_id);
0088 
0089 static const struct of_device_id ksz9477_dt_ids[] = {
0090     {
0091         .compatible = "microchip,ksz9477",
0092         .data = &ksz_switch_chips[KSZ9477]
0093     },
0094     {
0095         .compatible = "microchip,ksz9897",
0096         .data = &ksz_switch_chips[KSZ9897]
0097     },
0098     {
0099         .compatible = "microchip,ksz9893",
0100         .data = &ksz_switch_chips[KSZ9893]
0101     },
0102     {
0103         .compatible = "microchip,ksz9563",
0104         .data = &ksz_switch_chips[KSZ9893]
0105     },
0106     {
0107         .compatible = "microchip,ksz8563",
0108         .data = &ksz_switch_chips[KSZ9893]
0109     },
0110     {
0111         .compatible = "microchip,ksz9567",
0112         .data = &ksz_switch_chips[KSZ9567]
0113     },
0114     {},
0115 };
0116 MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);
0117 
0118 static struct i2c_driver ksz9477_i2c_driver = {
0119     .driver = {
0120         .name   = "ksz9477-switch",
0121         .of_match_table = of_match_ptr(ksz9477_dt_ids),
0122     },
0123     .probe  = ksz9477_i2c_probe,
0124     .remove = ksz9477_i2c_remove,
0125     .shutdown = ksz9477_i2c_shutdown,
0126     .id_table = ksz9477_i2c_id,
0127 };
0128 
0129 module_i2c_driver(ksz9477_i2c_driver);
0130 
0131 MODULE_AUTHOR("Tristram Ha <Tristram.Ha@microchip.com>");
0132 MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch I2C access Driver");
0133 MODULE_LICENSE("GPL v2");