]>
Commit | Line | Data |
---|---|---|
3abee457 MW |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* | |
3 | * Simple MFD - I2C | |
4 | * | |
c753ea31 LJ |
5 | * Author(s): |
6 | * Michael Walle <[email protected]> | |
7 | * Lee Jones <[email protected]> | |
8 | * | |
3abee457 MW |
9 | * This driver creates a single register map with the intention for it to be |
10 | * shared by all sub-devices. Children can use their parent's device structure | |
11 | * (dev.parent) in order to reference it. | |
12 | * | |
13 | * Once the register map has been successfully initialised, any sub-devices | |
c753ea31 LJ |
14 | * represented by child nodes in Device Tree or via the MFD cells in this file |
15 | * will be subsequently registered. | |
3abee457 MW |
16 | */ |
17 | ||
18 | #include <linux/i2c.h> | |
19 | #include <linux/kernel.h> | |
c753ea31 | 20 | #include <linux/mfd/core.h> |
3abee457 MW |
21 | #include <linux/module.h> |
22 | #include <linux/of_platform.h> | |
23 | #include <linux/regmap.h> | |
24 | ||
c753ea31 LJ |
25 | #include "simple-mfd-i2c.h" |
26 | ||
27 | static const struct regmap_config regmap_config_8r_8v = { | |
3abee457 MW |
28 | .reg_bits = 8, |
29 | .val_bits = 8, | |
30 | }; | |
31 | ||
32 | static int simple_mfd_i2c_probe(struct i2c_client *i2c) | |
33 | { | |
c753ea31 LJ |
34 | const struct simple_mfd_data *simple_mfd_data; |
35 | const struct regmap_config *regmap_config; | |
3abee457 | 36 | struct regmap *regmap; |
c753ea31 LJ |
37 | int ret; |
38 | ||
39 | simple_mfd_data = device_get_match_data(&i2c->dev); | |
3abee457 | 40 | |
c753ea31 LJ |
41 | /* If no regmap_config is specified, use the default 8reg and 8val bits */ |
42 | if (!simple_mfd_data || !simple_mfd_data->regmap_config) | |
43 | regmap_config = ®map_config_8r_8v; | |
44 | else | |
45 | regmap_config = simple_mfd_data->regmap_config; | |
3abee457 | 46 | |
c753ea31 | 47 | regmap = devm_regmap_init_i2c(i2c, regmap_config); |
3abee457 MW |
48 | if (IS_ERR(regmap)) |
49 | return PTR_ERR(regmap); | |
50 | ||
81435ed2 | 51 | /* If no MFD cells are specified, register using the DT child nodes instead */ |
c753ea31 LJ |
52 | if (!simple_mfd_data || !simple_mfd_data->mfd_cell) |
53 | return devm_of_platform_populate(&i2c->dev); | |
54 | ||
55 | ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, | |
56 | simple_mfd_data->mfd_cell, | |
57 | simple_mfd_data->mfd_cell_size, | |
58 | NULL, 0, NULL); | |
59 | if (ret) | |
60 | dev_err(&i2c->dev, "Failed to add child devices\n"); | |
61 | ||
62 | return ret; | |
3abee457 MW |
63 | } |
64 | ||
5913eb45 AF |
65 | static const struct mfd_cell sy7636a_cells[] = { |
66 | { .name = "sy7636a-regulator", }, | |
67 | { .name = "sy7636a-temperature", }, | |
68 | }; | |
69 | ||
70 | static const struct simple_mfd_data silergy_sy7636a = { | |
71 | .mfd_cell = sy7636a_cells, | |
72 | .mfd_cell_size = ARRAY_SIZE(sy7636a_cells), | |
73 | }; | |
74 | ||
49f661ba NS |
75 | static const struct mfd_cell max5970_cells[] = { |
76 | { .name = "max5970-regulator", }, | |
77 | { .name = "max5970-iio", }, | |
78 | { .name = "max5970-led", }, | |
0742c2a6 PR |
79 | }; |
80 | ||
49f661ba NS |
81 | static const struct simple_mfd_data maxim_max5970 = { |
82 | .mfd_cell = max5970_cells, | |
83 | .mfd_cell_size = ARRAY_SIZE(max5970_cells), | |
0742c2a6 PR |
84 | }; |
85 | ||
3abee457 | 86 | static const struct of_device_id simple_mfd_i2c_of_match[] = { |
a538ad22 | 87 | { .compatible = "kontron,sl28cpld" }, |
5913eb45 | 88 | { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, |
49f661ba NS |
89 | { .compatible = "maxim,max5970", .data = &maxim_max5970}, |
90 | { .compatible = "maxim,max5978", .data = &maxim_max5970}, | |
3abee457 MW |
91 | {} |
92 | }; | |
93 | MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); | |
94 | ||
95 | static struct i2c_driver simple_mfd_i2c_driver = { | |
9816d859 | 96 | .probe = simple_mfd_i2c_probe, |
3abee457 MW |
97 | .driver = { |
98 | .name = "simple-mfd-i2c", | |
99 | .of_match_table = simple_mfd_i2c_of_match, | |
100 | }, | |
101 | }; | |
102 | module_i2c_driver(simple_mfd_i2c_driver); | |
103 | ||
104 | MODULE_AUTHOR("Michael Walle <[email protected]>"); | |
105 | MODULE_DESCRIPTION("Simple MFD - I2C driver"); | |
106 | MODULE_LICENSE("GPL v2"); |