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