Merge tag 'i2c-for-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[platform/kernel/linux-starfive.git] / drivers / platform / x86 / intel / int3472 / tps68470.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dan Scally <djrscally@gmail.com> */
3
4 #include <linux/acpi.h>
5 #include <linux/i2c.h>
6 #include <linux/kernel.h>
7 #include <linux/mfd/core.h>
8 #include <linux/mfd/tps68470.h>
9 #include <linux/platform_device.h>
10 #include <linux/platform_data/tps68470.h>
11 #include <linux/regmap.h>
12 #include <linux/string.h>
13
14 #include "common.h"
15 #include "tps68470.h"
16
17 #define DESIGNED_FOR_CHROMEOS           1
18 #define DESIGNED_FOR_WINDOWS            2
19
20 #define TPS68470_WIN_MFD_CELL_COUNT     3
21
22 static const struct mfd_cell tps68470_cros[] = {
23         { .name = "tps68470-gpio" },
24         { .name = "tps68470_pmic_opregion" },
25 };
26
27 static const struct regmap_config tps68470_regmap_config = {
28         .reg_bits = 8,
29         .val_bits = 8,
30         .max_register = TPS68470_REG_MAX,
31 };
32
33 static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
34 {
35         unsigned int version;
36         int ret;
37
38         /* Force software reset */
39         ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
40         if (ret)
41                 return ret;
42
43         ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
44         if (ret) {
45                 dev_err(dev, "Failed to read revision register: %d\n", ret);
46                 return ret;
47         }
48
49         dev_info(dev, "TPS68470 REVID: 0x%02x\n", version);
50
51         return 0;
52 }
53
54 /** skl_int3472_tps68470_calc_type: Check what platform a device is designed for
55  * @adev: A pointer to a &struct acpi_device
56  *
57  * Check CLDB buffer against the PMIC's adev. If present, then we check
58  * the value of control_logic_type field and follow one of the
59  * following scenarios:
60  *
61  *      1. No CLDB - likely ACPI tables designed for ChromeOS. We
62  *      create platform devices for the GPIOs and OpRegion drivers.
63  *
64  *      2. CLDB, with control_logic_type = 2 - probably ACPI tables
65  *      made for Windows 2-in-1 platforms. Register pdevs for GPIO,
66  *      Clock and Regulator drivers to bind to.
67  *
68  *      3. Any other value in control_logic_type, we should never have
69  *      gotten to this point; fail probe and return.
70  *
71  * Return:
72  * * 1          Device intended for ChromeOS
73  * * 2          Device intended for Windows
74  * * -EINVAL    Where @adev has an object named CLDB but it does not conform to
75  *              our expectations
76  */
77 static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
78 {
79         struct int3472_cldb cldb = { 0 };
80         int ret;
81
82         /*
83          * A CLDB buffer that exists, but which does not match our expectations
84          * should trigger an error so we don't blindly continue.
85          */
86         ret = skl_int3472_fill_cldb(adev, &cldb);
87         if (ret && ret != -ENODEV)
88                 return ret;
89
90         if (ret)
91                 return DESIGNED_FOR_CHROMEOS;
92
93         if (cldb.control_logic_type != 2)
94                 return -EINVAL;
95
96         return DESIGNED_FOR_WINDOWS;
97 }
98
99 /*
100  * Return the size of the flexible array member, because we'll need that later
101  * on to pass .pdata_size to cells.
102  */
103 static int
104 skl_int3472_fill_clk_pdata(struct device *dev, struct tps68470_clk_platform_data **clk_pdata)
105 {
106         struct acpi_device *adev = ACPI_COMPANION(dev);
107         struct acpi_device *consumer;
108         unsigned int n_consumers = 0;
109         const char *sensor_name;
110         unsigned int i = 0;
111
112         for_each_acpi_consumer_dev(adev, consumer)
113                 n_consumers++;
114
115         if (!n_consumers) {
116                 dev_err(dev, "INT3472 seems to have no dependents\n");
117                 return -ENODEV;
118         }
119
120         *clk_pdata = devm_kzalloc(dev, struct_size(*clk_pdata, consumers, n_consumers),
121                                   GFP_KERNEL);
122         if (!*clk_pdata)
123                 return -ENOMEM;
124
125         (*clk_pdata)->n_consumers = n_consumers;
126         i = 0;
127
128         for_each_acpi_consumer_dev(adev, consumer) {
129                 sensor_name = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
130                                              acpi_dev_name(consumer));
131                 if (!sensor_name)
132                         return -ENOMEM;
133
134                 (*clk_pdata)->consumers[i].consumer_dev_name = sensor_name;
135                 i++;
136         }
137
138         acpi_dev_put(consumer);
139
140         return n_consumers;
141 }
142
143 static int skl_int3472_tps68470_probe(struct i2c_client *client)
144 {
145         struct acpi_device *adev = ACPI_COMPANION(&client->dev);
146         const struct int3472_tps68470_board_data *board_data;
147         struct tps68470_clk_platform_data *clk_pdata;
148         struct mfd_cell *cells;
149         struct regmap *regmap;
150         int n_consumers;
151         int device_type;
152         int ret;
153         int i;
154
155         n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata);
156         if (n_consumers < 0)
157                 return n_consumers;
158
159         regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
160         if (IS_ERR(regmap)) {
161                 dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
162                 return PTR_ERR(regmap);
163         }
164
165         i2c_set_clientdata(client, regmap);
166
167         ret = tps68470_chip_init(&client->dev, regmap);
168         if (ret < 0) {
169                 dev_err(&client->dev, "TPS68470 init error %d\n", ret);
170                 return ret;
171         }
172
173         device_type = skl_int3472_tps68470_calc_type(adev);
174         switch (device_type) {
175         case DESIGNED_FOR_WINDOWS:
176                 board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
177                 if (!board_data)
178                         return dev_err_probe(&client->dev, -ENODEV, "No board-data found for this model\n");
179
180                 cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL);
181                 if (!cells)
182                         return -ENOMEM;
183
184                 /*
185                  * The order of the cells matters here! The clk must be first
186                  * because the regulator depends on it. The gpios must be last,
187                  * acpi_gpiochip_add() calls acpi_dev_clear_dependencies() and
188                  * the clk + regulators must be ready when this happens.
189                  */
190                 cells[0].name = "tps68470-clk";
191                 cells[0].platform_data = clk_pdata;
192                 cells[0].pdata_size = struct_size(clk_pdata, consumers, n_consumers);
193                 cells[1].name = "tps68470-regulator";
194                 cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
195                 cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
196                 cells[2].name = "tps68470-gpio";
197
198                 for (i = 0; i < board_data->n_gpiod_lookups; i++)
199                         gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
200
201                 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
202                                            cells, TPS68470_WIN_MFD_CELL_COUNT,
203                                            NULL, 0, NULL);
204                 kfree(cells);
205
206                 if (ret) {
207                         for (i = 0; i < board_data->n_gpiod_lookups; i++)
208                                 gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
209                 }
210
211                 break;
212         case DESIGNED_FOR_CHROMEOS:
213                 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
214                                            tps68470_cros, ARRAY_SIZE(tps68470_cros),
215                                            NULL, 0, NULL);
216                 break;
217         default:
218                 dev_err(&client->dev, "Failed to add MFD devices\n");
219                 return device_type;
220         }
221
222         /*
223          * No acpi_dev_clear_dependencies() here, since the acpi_gpiochip_add()
224          * for the GPIO cell already does this.
225          */
226
227         return ret;
228 }
229
230 static void skl_int3472_tps68470_remove(struct i2c_client *client)
231 {
232         const struct int3472_tps68470_board_data *board_data;
233         int i;
234
235         board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
236         if (board_data) {
237                 for (i = 0; i < board_data->n_gpiod_lookups; i++)
238                         gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
239         }
240 }
241
242 static const struct acpi_device_id int3472_device_id[] = {
243         { "INT3472", 0 },
244         { }
245 };
246 MODULE_DEVICE_TABLE(acpi, int3472_device_id);
247
248 static struct i2c_driver int3472_tps68470 = {
249         .driver = {
250                 .name = "int3472-tps68470",
251                 .acpi_match_table = int3472_device_id,
252         },
253         .probe_new = skl_int3472_tps68470_probe,
254         .remove = skl_int3472_tps68470_remove,
255 };
256 module_i2c_driver(int3472_tps68470);
257
258 MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
259 MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
260 MODULE_LICENSE("GPL v2");
261 MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");