0001
0002
0003
0004 #include <linux/i2c.h>
0005 #include <linux/kernel.h>
0006 #include <linux/mfd/core.h>
0007 #include <linux/mfd/tps68470.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/platform_data/tps68470.h>
0010 #include <linux/regmap.h>
0011 #include <linux/string.h>
0012
0013 #include "common.h"
0014 #include "tps68470.h"
0015
0016 #define DESIGNED_FOR_CHROMEOS 1
0017 #define DESIGNED_FOR_WINDOWS 2
0018
0019 #define TPS68470_WIN_MFD_CELL_COUNT 3
0020
0021 static const struct mfd_cell tps68470_cros[] = {
0022 { .name = "tps68470-gpio" },
0023 { .name = "tps68470_pmic_opregion" },
0024 };
0025
0026 static const struct regmap_config tps68470_regmap_config = {
0027 .reg_bits = 8,
0028 .val_bits = 8,
0029 .max_register = TPS68470_REG_MAX,
0030 };
0031
0032 static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
0033 {
0034 unsigned int version;
0035 int ret;
0036
0037
0038 ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
0039 if (ret)
0040 return ret;
0041
0042 ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
0043 if (ret) {
0044 dev_err(dev, "Failed to read revision register: %d\n", ret);
0045 return ret;
0046 }
0047
0048 dev_info(dev, "TPS68470 REVID: 0x%02x\n", version);
0049
0050 return 0;
0051 }
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
0077 {
0078 struct int3472_cldb cldb = { 0 };
0079 int ret;
0080
0081
0082
0083
0084
0085 ret = skl_int3472_fill_cldb(adev, &cldb);
0086 if (ret && ret != -ENODEV)
0087 return ret;
0088
0089 if (ret)
0090 return DESIGNED_FOR_CHROMEOS;
0091
0092 if (cldb.control_logic_type != 2)
0093 return -EINVAL;
0094
0095 return DESIGNED_FOR_WINDOWS;
0096 }
0097
0098 static int skl_int3472_tps68470_probe(struct i2c_client *client)
0099 {
0100 struct acpi_device *adev = ACPI_COMPANION(&client->dev);
0101 const struct int3472_tps68470_board_data *board_data;
0102 struct tps68470_clk_platform_data clk_pdata = {};
0103 struct mfd_cell *cells;
0104 struct regmap *regmap;
0105 int device_type;
0106 int ret;
0107
0108 ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
0109 &clk_pdata.consumer_dev_name);
0110 if (ret)
0111 return ret;
0112
0113 regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
0114 if (IS_ERR(regmap)) {
0115 dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
0116 return PTR_ERR(regmap);
0117 }
0118
0119 i2c_set_clientdata(client, regmap);
0120
0121 ret = tps68470_chip_init(&client->dev, regmap);
0122 if (ret < 0) {
0123 dev_err(&client->dev, "TPS68470 init error %d\n", ret);
0124 return ret;
0125 }
0126
0127 device_type = skl_int3472_tps68470_calc_type(adev);
0128 switch (device_type) {
0129 case DESIGNED_FOR_WINDOWS:
0130 board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
0131 if (!board_data)
0132 return dev_err_probe(&client->dev, -ENODEV, "No board-data found for this model\n");
0133
0134 cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL);
0135 if (!cells)
0136 return -ENOMEM;
0137
0138
0139
0140
0141
0142
0143
0144 cells[0].name = "tps68470-clk";
0145 cells[0].platform_data = &clk_pdata;
0146 cells[0].pdata_size = sizeof(clk_pdata);
0147 cells[1].name = "tps68470-regulator";
0148 cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
0149 cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
0150 cells[2].name = "tps68470-gpio";
0151
0152 gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_table);
0153
0154 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
0155 cells, TPS68470_WIN_MFD_CELL_COUNT,
0156 NULL, 0, NULL);
0157 kfree(cells);
0158
0159 if (ret)
0160 gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
0161
0162 break;
0163 case DESIGNED_FOR_CHROMEOS:
0164 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
0165 tps68470_cros, ARRAY_SIZE(tps68470_cros),
0166 NULL, 0, NULL);
0167 break;
0168 default:
0169 dev_err(&client->dev, "Failed to add MFD devices\n");
0170 return device_type;
0171 }
0172
0173
0174
0175
0176
0177
0178 return ret;
0179 }
0180
0181 static int skl_int3472_tps68470_remove(struct i2c_client *client)
0182 {
0183 const struct int3472_tps68470_board_data *board_data;
0184
0185 board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
0186 if (board_data)
0187 gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
0188
0189 return 0;
0190 }
0191
0192 static const struct acpi_device_id int3472_device_id[] = {
0193 { "INT3472", 0 },
0194 { }
0195 };
0196 MODULE_DEVICE_TABLE(acpi, int3472_device_id);
0197
0198 static struct i2c_driver int3472_tps68470 = {
0199 .driver = {
0200 .name = "int3472-tps68470",
0201 .acpi_match_table = int3472_device_id,
0202 },
0203 .probe_new = skl_int3472_tps68470_probe,
0204 .remove = skl_int3472_tps68470_remove,
0205 };
0206 module_i2c_driver(int3472_tps68470);
0207
0208 MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
0209 MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
0210 MODULE_LICENSE("GPL v2");
0211 MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");