1
2
3
4#include <linux/i2c.h>
5#include <linux/mfd/core.h>
6#include <linux/mfd/tps68470.h>
7#include <linux/platform_device.h>
8#include <linux/regmap.h>
9
10#include "intel_skl_int3472_common.h"
11
12#define DESIGNED_FOR_CHROMEOS 1
13#define DESIGNED_FOR_WINDOWS 2
14
15static const struct mfd_cell tps68470_cros[] = {
16 { .name = "tps68470-gpio" },
17 { .name = "tps68470_pmic_opregion" },
18};
19
20static const struct mfd_cell tps68470_win[] = {
21 { .name = "tps68470-gpio" },
22 { .name = "tps68470-clk" },
23 { .name = "tps68470-regulator" },
24};
25
26static const struct regmap_config tps68470_regmap_config = {
27 .reg_bits = 8,
28 .val_bits = 8,
29 .max_register = TPS68470_REG_MAX,
30};
31
32static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
33{
34 unsigned int version;
35 int ret;
36
37
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
77{
78 struct int3472_cldb cldb = { 0 };
79 int ret;
80
81
82
83
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
98int skl_int3472_tps68470_probe(struct i2c_client *client)
99{
100 struct acpi_device *adev = ACPI_COMPANION(&client->dev);
101 struct regmap *regmap;
102 int device_type;
103 int ret;
104
105 regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
106 if (IS_ERR(regmap)) {
107 dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
108 return PTR_ERR(regmap);
109 }
110
111 i2c_set_clientdata(client, regmap);
112
113 ret = tps68470_chip_init(&client->dev, regmap);
114 if (ret < 0) {
115 dev_err(&client->dev, "TPS68470 init error %d\n", ret);
116 return ret;
117 }
118
119 device_type = skl_int3472_tps68470_calc_type(adev);
120 switch (device_type) {
121 case DESIGNED_FOR_WINDOWS:
122 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
123 tps68470_win, ARRAY_SIZE(tps68470_win),
124 NULL, 0, NULL);
125 break;
126 case DESIGNED_FOR_CHROMEOS:
127 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
128 tps68470_cros, ARRAY_SIZE(tps68470_cros),
129 NULL, 0, NULL);
130 break;
131 default:
132 dev_err(&client->dev, "Failed to add MFD devices\n");
133 return device_type;
134 }
135
136 return ret;
137}
138