1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dan Scally <djrscally@gmail.com> */
4 #include <linux/acpi.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>
17 #define DESIGNED_FOR_CHROMEOS 1
18 #define DESIGNED_FOR_WINDOWS 2
20 #define TPS68470_WIN_MFD_CELL_COUNT 3
22 static const struct mfd_cell tps68470_cros
[] = {
23 { .name
= "tps68470-gpio" },
24 { .name
= "tps68470_pmic_opregion" },
27 static const struct regmap_config tps68470_regmap_config
= {
30 .max_register
= TPS68470_REG_MAX
,
33 static int tps68470_chip_init(struct device
*dev
, struct regmap
*regmap
)
38 /* Force software reset */
39 ret
= regmap_write(regmap
, TPS68470_REG_RESET
, TPS68470_REG_RESET_MASK
);
43 ret
= regmap_read(regmap
, TPS68470_REG_REVID
, &version
);
45 dev_err(dev
, "Failed to read revision register: %d\n", ret
);
49 dev_info(dev
, "TPS68470 REVID: 0x%02x\n", version
);
54 /** skl_int3472_tps68470_calc_type: Check what platform a device is designed for
55 * @adev: A pointer to a &struct acpi_device
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:
61 * 1. No CLDB - likely ACPI tables designed for ChromeOS. We
62 * create platform devices for the GPIOs and OpRegion drivers.
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.
68 * 3. Any other value in control_logic_type, we should never have
69 * gotten to this point; fail probe and 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
77 static int skl_int3472_tps68470_calc_type(struct acpi_device
*adev
)
79 struct int3472_cldb cldb
= { 0 };
83 * A CLDB buffer that exists, but which does not match our expectations
84 * should trigger an error so we don't blindly continue.
86 ret
= skl_int3472_fill_cldb(adev
, &cldb
);
87 if (ret
&& ret
!= -ENODEV
)
91 return DESIGNED_FOR_CHROMEOS
;
93 if (cldb
.control_logic_type
!= 2)
96 return DESIGNED_FOR_WINDOWS
;
100 * Return the size of the flexible array member, because we'll need that later
101 * on to pass .pdata_size to cells.
104 skl_int3472_fill_clk_pdata(struct device
*dev
, struct tps68470_clk_platform_data
**clk_pdata
)
106 struct acpi_device
*adev
= ACPI_COMPANION(dev
);
107 struct acpi_device
*consumer
;
108 unsigned int n_consumers
= 0;
109 const char *sensor_name
;
112 for_each_acpi_consumer_dev(adev
, consumer
)
116 dev_err(dev
, "INT3472 seems to have no dependents\n");
120 *clk_pdata
= devm_kzalloc(dev
, struct_size(*clk_pdata
, consumers
, n_consumers
),
125 (*clk_pdata
)->n_consumers
= n_consumers
;
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
));
132 acpi_dev_put(consumer
);
136 (*clk_pdata
)->consumers
[i
].consumer_dev_name
= sensor_name
;
143 static int skl_int3472_tps68470_probe(struct i2c_client
*client
)
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
;
155 n_consumers
= skl_int3472_fill_clk_pdata(&client
->dev
, &clk_pdata
);
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
);
165 i2c_set_clientdata(client
, regmap
);
167 ret
= tps68470_chip_init(&client
->dev
, regmap
);
169 dev_err(&client
->dev
, "TPS68470 init error %d\n", ret
);
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
));
178 return dev_err_probe(&client
->dev
, -ENODEV
, "No board-data found for this model\n");
180 cells
= kcalloc(TPS68470_WIN_MFD_CELL_COUNT
, sizeof(*cells
), GFP_KERNEL
);
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.
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";
198 for (i
= 0; i
< board_data
->n_gpiod_lookups
; i
++)
199 gpiod_add_lookup_table(board_data
->tps68470_gpio_lookup_tables
[i
]);
201 ret
= devm_mfd_add_devices(&client
->dev
, PLATFORM_DEVID_NONE
,
202 cells
, TPS68470_WIN_MFD_CELL_COUNT
,
207 for (i
= 0; i
< board_data
->n_gpiod_lookups
; i
++)
208 gpiod_remove_lookup_table(board_data
->tps68470_gpio_lookup_tables
[i
]);
212 case DESIGNED_FOR_CHROMEOS
:
213 ret
= devm_mfd_add_devices(&client
->dev
, PLATFORM_DEVID_NONE
,
214 tps68470_cros
, ARRAY_SIZE(tps68470_cros
),
218 dev_err(&client
->dev
, "Failed to add MFD devices\n");
223 * No acpi_dev_clear_dependencies() here, since the acpi_gpiochip_add()
224 * for the GPIO cell already does this.
230 static void skl_int3472_tps68470_remove(struct i2c_client
*client
)
232 const struct int3472_tps68470_board_data
*board_data
;
235 board_data
= int3472_tps68470_get_board_data(dev_name(&client
->dev
));
237 for (i
= 0; i
< board_data
->n_gpiod_lookups
; i
++)
238 gpiod_remove_lookup_table(board_data
->tps68470_gpio_lookup_tables
[i
]);
242 static const struct acpi_device_id int3472_device_id
[] = {
246 MODULE_DEVICE_TABLE(acpi
, int3472_device_id
);
248 static struct i2c_driver int3472_tps68470
= {
250 .name
= "int3472-tps68470",
251 .acpi_match_table
= int3472_device_id
,
253 .probe
= skl_int3472_tps68470_probe
,
254 .remove
= skl_int3472_tps68470_remove
,
256 module_i2c_driver(int3472_tps68470
);
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");