]>
Commit | Line | Data |
---|---|---|
1802d0be | 1 | // SPDX-License-Identifier: GPL-2.0-only |
be4e119f JB |
2 | /* |
3 | * Copyright (C) 2017 Pengutronix, Juergen Borleis <kernel@pengutronix.de> | |
be4e119f JB |
4 | */ |
5 | #include <linux/kernel.h> | |
6 | #include <linux/module.h> | |
7 | #include <linux/i2c.h> | |
8 | #include <linux/of.h> | |
9 | ||
10 | #include "lan9303.h" | |
11 | ||
12 | struct lan9303_i2c { | |
13 | struct i2c_client *device; | |
14 | struct lan9303 chip; | |
15 | }; | |
16 | ||
17 | static const struct regmap_config lan9303_i2c_regmap_config = { | |
18 | .reg_bits = 8, | |
19 | .val_bits = 32, | |
20 | .reg_stride = 1, | |
21 | .can_multi_write = true, | |
22 | .max_register = 0x0ff, /* address bits 0..1 are not used */ | |
23 | .reg_format_endian = REGMAP_ENDIAN_LITTLE, | |
24 | ||
25 | .volatile_table = &lan9303_register_set, | |
26 | .wr_table = &lan9303_register_set, | |
27 | .rd_table = &lan9303_register_set, | |
28 | ||
29 | .cache_type = REGCACHE_NONE, | |
30 | }; | |
31 | ||
32 | static int lan9303_i2c_probe(struct i2c_client *client, | |
33 | const struct i2c_device_id *id) | |
34 | { | |
35 | struct lan9303_i2c *sw_dev; | |
36 | int ret; | |
37 | ||
38 | sw_dev = devm_kzalloc(&client->dev, sizeof(struct lan9303_i2c), | |
39 | GFP_KERNEL); | |
40 | if (!sw_dev) | |
41 | return -ENOMEM; | |
42 | ||
43 | sw_dev->chip.regmap = devm_regmap_init_i2c(client, | |
92f25caf | 44 | &lan9303_i2c_regmap_config); |
be4e119f JB |
45 | if (IS_ERR(sw_dev->chip.regmap)) { |
46 | ret = PTR_ERR(sw_dev->chip.regmap); | |
47 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | |
48 | ret); | |
49 | return ret; | |
50 | } | |
51 | ||
52 | /* link forward and backward */ | |
53 | sw_dev->device = client; | |
54 | i2c_set_clientdata(client, sw_dev); | |
55 | sw_dev->chip.dev = &client->dev; | |
56 | ||
2c340898 EH |
57 | sw_dev->chip.ops = &lan9303_indirect_phy_ops; |
58 | ||
be4e119f JB |
59 | ret = lan9303_probe(&sw_dev->chip, client->dev.of_node); |
60 | if (ret != 0) | |
61 | return ret; | |
62 | ||
63 | dev_info(&client->dev, "LAN9303 I2C driver loaded successfully\n"); | |
64 | ||
65 | return 0; | |
66 | } | |
67 | ||
68 | static int lan9303_i2c_remove(struct i2c_client *client) | |
69 | { | |
70 | struct lan9303_i2c *sw_dev; | |
71 | ||
72 | sw_dev = i2c_get_clientdata(client); | |
73 | if (!sw_dev) | |
74 | return -ENODEV; | |
75 | ||
76 | return lan9303_remove(&sw_dev->chip); | |
77 | } | |
78 | ||
79 | /*-------------------------------------------------------------------------*/ | |
80 | ||
81 | static const struct i2c_device_id lan9303_i2c_id[] = { | |
82 | { "lan9303", 0 }, | |
83 | { /* sentinel */ } | |
84 | }; | |
85 | MODULE_DEVICE_TABLE(i2c, lan9303_i2c_id); | |
86 | ||
87 | static const struct of_device_id lan9303_i2c_of_match[] = { | |
88 | { .compatible = "smsc,lan9303-i2c", }, | |
89 | { /* sentinel */ }, | |
90 | }; | |
91 | MODULE_DEVICE_TABLE(of, lan9303_i2c_of_match); | |
92 | ||
93 | static struct i2c_driver lan9303_i2c_driver = { | |
94 | .driver = { | |
95 | .name = "LAN9303_I2C", | |
96 | .of_match_table = of_match_ptr(lan9303_i2c_of_match), | |
97 | }, | |
98 | .probe = lan9303_i2c_probe, | |
99 | .remove = lan9303_i2c_remove, | |
100 | .id_table = lan9303_i2c_id, | |
101 | }; | |
102 | module_i2c_driver(lan9303_i2c_driver); | |
103 | ||
104 | MODULE_AUTHOR("Juergen Borleis <kernel@pengutronix.de>"); | |
105 | MODULE_DESCRIPTION("Driver for SMSC/Microchip LAN9303 three port ethernet switch in I2C managed mode"); | |
106 | MODULE_LICENSE("GPL v2"); |