1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Microchip KSZ9477 series register access through I2C |
4 | * |
5 | * Copyright (C) 2018-2019 Microchip Technology Inc. |
6 | */ |
7 | |
8 | #include <linux/i2c.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> |
11 | #include <linux/regmap.h> |
12 | |
13 | #include "ksz_common.h" |
14 | |
15 | KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0); |
16 | |
17 | static int ksz9477_i2c_probe(struct i2c_client *i2c) |
18 | { |
19 | struct regmap_config rc; |
20 | struct ksz_device *dev; |
21 | int i, ret; |
22 | |
23 | dev = ksz_switch_alloc(base: &i2c->dev, priv: i2c); |
24 | if (!dev) |
25 | return -ENOMEM; |
26 | |
27 | for (i = 0; i < __KSZ_NUM_REGMAPS; i++) { |
28 | rc = ksz9477_regmap_config[i]; |
29 | rc.lock_arg = &dev->regmap_mutex; |
30 | dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc); |
31 | if (IS_ERR(ptr: dev->regmap[i])) { |
32 | return dev_err_probe(dev: &i2c->dev, err: PTR_ERR(ptr: dev->regmap[i]), |
33 | fmt: "Failed to initialize regmap%i\n" , |
34 | ksz9477_regmap_config[i].val_bits); |
35 | } |
36 | } |
37 | |
38 | if (i2c->dev.platform_data) |
39 | dev->pdata = i2c->dev.platform_data; |
40 | |
41 | dev->irq = i2c->irq; |
42 | |
43 | ret = ksz_switch_register(dev); |
44 | |
45 | /* Main DSA driver may not be started yet. */ |
46 | if (ret) |
47 | return ret; |
48 | |
49 | i2c_set_clientdata(client: i2c, data: dev); |
50 | |
51 | return 0; |
52 | } |
53 | |
54 | static void ksz9477_i2c_remove(struct i2c_client *i2c) |
55 | { |
56 | struct ksz_device *dev = i2c_get_clientdata(client: i2c); |
57 | |
58 | if (dev) |
59 | ksz_switch_remove(dev); |
60 | } |
61 | |
62 | static void ksz9477_i2c_shutdown(struct i2c_client *i2c) |
63 | { |
64 | struct ksz_device *dev = i2c_get_clientdata(client: i2c); |
65 | |
66 | if (!dev) |
67 | return; |
68 | |
69 | ksz_switch_shutdown(dev); |
70 | |
71 | i2c_set_clientdata(client: i2c, NULL); |
72 | } |
73 | |
74 | static const struct i2c_device_id ksz9477_i2c_id[] = { |
75 | { "ksz9477-switch" , 0 }, |
76 | {}, |
77 | }; |
78 | |
79 | MODULE_DEVICE_TABLE(i2c, ksz9477_i2c_id); |
80 | |
81 | static const struct of_device_id ksz9477_dt_ids[] = { |
82 | { |
83 | .compatible = "microchip,ksz9477" , |
84 | .data = &ksz_switch_chips[KSZ9477] |
85 | }, |
86 | { |
87 | .compatible = "microchip,ksz9896" , |
88 | .data = &ksz_switch_chips[KSZ9896] |
89 | }, |
90 | { |
91 | .compatible = "microchip,ksz9897" , |
92 | .data = &ksz_switch_chips[KSZ9897] |
93 | }, |
94 | { |
95 | .compatible = "microchip,ksz9893" , |
96 | .data = &ksz_switch_chips[KSZ9893] |
97 | }, |
98 | { |
99 | .compatible = "microchip,ksz9563" , |
100 | .data = &ksz_switch_chips[KSZ9563] |
101 | }, |
102 | { |
103 | .compatible = "microchip,ksz8563" , |
104 | .data = &ksz_switch_chips[KSZ8563] |
105 | }, |
106 | { |
107 | .compatible = "microchip,ksz8567" , |
108 | .data = &ksz_switch_chips[KSZ8567] |
109 | }, |
110 | { |
111 | .compatible = "microchip,ksz9567" , |
112 | .data = &ksz_switch_chips[KSZ9567] |
113 | }, |
114 | {}, |
115 | }; |
116 | MODULE_DEVICE_TABLE(of, ksz9477_dt_ids); |
117 | |
118 | static struct i2c_driver ksz9477_i2c_driver = { |
119 | .driver = { |
120 | .name = "ksz9477-switch" , |
121 | .of_match_table = ksz9477_dt_ids, |
122 | }, |
123 | .probe = ksz9477_i2c_probe, |
124 | .remove = ksz9477_i2c_remove, |
125 | .shutdown = ksz9477_i2c_shutdown, |
126 | .id_table = ksz9477_i2c_id, |
127 | }; |
128 | |
129 | module_i2c_driver(ksz9477_i2c_driver); |
130 | |
131 | MODULE_AUTHOR("Tristram Ha <Tristram.Ha@microchip.com>" ); |
132 | MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch I2C access Driver" ); |
133 | MODULE_LICENSE("GPL v2" ); |
134 | |