xref: /linux/drivers/mfd/sec-i2c.c (revision 1cea1b6b2c89ef67ebd09e43d85d7308f86a538c)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2012 Samsung Electronics Co., Ltd
4  *                http://www.samsung.com
5  * Copyright 2025 Linaro Ltd.
6  *
7  * Samsung SxM I2C driver
8  */
9 
10 #include <linux/dev_printk.h>
11 #include <linux/err.h>
12 #include <linux/i2c.h>
13 #include <linux/mfd/samsung/core.h>
14 #include <linux/mfd/samsung/s2mpa01.h>
15 #include <linux/mfd/samsung/s2mps11.h>
16 #include <linux/mfd/samsung/s2mps13.h>
17 #include <linux/mfd/samsung/s2mps14.h>
18 #include <linux/mfd/samsung/s2mps15.h>
19 #include <linux/mfd/samsung/s2mpu02.h>
20 #include <linux/mfd/samsung/s5m8767.h>
21 #include <linux/mod_devicetable.h>
22 #include <linux/module.h>
23 #include <linux/of.h>
24 #include <linux/pm.h>
25 #include <linux/regmap.h>
26 #include "sec-core.h"
27 
28 static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
29 {
30 	switch (reg) {
31 	case S2MPA01_REG_INT1M:
32 	case S2MPA01_REG_INT2M:
33 	case S2MPA01_REG_INT3M:
34 		return false;
35 	default:
36 		return true;
37 	}
38 }
39 
40 static bool s2mps11_volatile(struct device *dev, unsigned int reg)
41 {
42 	switch (reg) {
43 	case S2MPS11_REG_INT1M:
44 	case S2MPS11_REG_INT2M:
45 	case S2MPS11_REG_INT3M:
46 		return false;
47 	default:
48 		return true;
49 	}
50 }
51 
52 static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
53 {
54 	switch (reg) {
55 	case S2MPU02_REG_INT1M:
56 	case S2MPU02_REG_INT2M:
57 	case S2MPU02_REG_INT3M:
58 		return false;
59 	default:
60 		return true;
61 	}
62 }
63 
64 static const struct regmap_config s2dos05_regmap_config = {
65 	.reg_bits = 8,
66 	.val_bits = 8,
67 };
68 
69 static const struct regmap_config s2mpa01_regmap_config = {
70 	.reg_bits = 8,
71 	.val_bits = 8,
72 
73 	.max_register = S2MPA01_REG_LDO_OVCB4,
74 	.volatile_reg = s2mpa01_volatile,
75 	.cache_type = REGCACHE_FLAT,
76 };
77 
78 static const struct regmap_config s2mps11_regmap_config = {
79 	.reg_bits = 8,
80 	.val_bits = 8,
81 
82 	.max_register = S2MPS11_REG_L38CTRL,
83 	.volatile_reg = s2mps11_volatile,
84 	.cache_type = REGCACHE_FLAT,
85 };
86 
87 static const struct regmap_config s2mps13_regmap_config = {
88 	.reg_bits = 8,
89 	.val_bits = 8,
90 
91 	.max_register = S2MPS13_REG_LDODSCH5,
92 	.volatile_reg = s2mps11_volatile,
93 	.cache_type = REGCACHE_FLAT,
94 };
95 
96 static const struct regmap_config s2mps14_regmap_config = {
97 	.reg_bits = 8,
98 	.val_bits = 8,
99 
100 	.max_register = S2MPS14_REG_LDODSCH3,
101 	.volatile_reg = s2mps11_volatile,
102 	.cache_type = REGCACHE_FLAT,
103 };
104 
105 static const struct regmap_config s2mps15_regmap_config = {
106 	.reg_bits = 8,
107 	.val_bits = 8,
108 
109 	.max_register = S2MPS15_REG_LDODSCH4,
110 	.volatile_reg = s2mps11_volatile,
111 	.cache_type = REGCACHE_FLAT,
112 };
113 
114 static const struct regmap_config s2mpu02_regmap_config = {
115 	.reg_bits = 8,
116 	.val_bits = 8,
117 
118 	.max_register = S2MPU02_REG_DVSDATA,
119 	.volatile_reg = s2mpu02_volatile,
120 	.cache_type = REGCACHE_FLAT,
121 };
122 
123 static const struct regmap_config s2mpu05_regmap_config = {
124 	.reg_bits = 8,
125 	.val_bits = 8,
126 };
127 
128 static const struct regmap_config s5m8767_regmap_config = {
129 	.reg_bits = 8,
130 	.val_bits = 8,
131 
132 	.max_register = S5M8767_REG_LDO28CTRL,
133 	.volatile_reg = s2mps11_volatile,
134 	.cache_type = REGCACHE_FLAT,
135 };
136 
137 static int sec_pmic_i2c_probe(struct i2c_client *client)
138 {
139 	const struct regmap_config *regmap;
140 	unsigned long device_type;
141 	struct regmap *regmap_pmic;
142 
143 	device_type = (unsigned long)of_device_get_match_data(&client->dev);
144 
145 	switch (device_type) {
146 	case S2DOS05:
147 		regmap = &s2dos05_regmap_config;
148 		break;
149 	case S2MPA01:
150 		regmap = &s2mpa01_regmap_config;
151 		break;
152 	case S2MPS11X:
153 		regmap = &s2mps11_regmap_config;
154 		break;
155 	case S2MPS13X:
156 		regmap = &s2mps13_regmap_config;
157 		break;
158 	case S2MPS14X:
159 		regmap = &s2mps14_regmap_config;
160 		break;
161 	case S2MPS15X:
162 		regmap = &s2mps15_regmap_config;
163 		break;
164 	case S2MPU02:
165 		regmap = &s2mpu02_regmap_config;
166 		break;
167 	case S2MPU05:
168 		regmap = &s2mpu05_regmap_config;
169 		break;
170 	case S5M8767X:
171 		regmap = &s5m8767_regmap_config;
172 		break;
173 	default:
174 		return dev_err_probe(&client->dev, -ENODEV,
175 				     "Unsupported device type %lu\n",
176 				     device_type);
177 	}
178 
179 	regmap_pmic = devm_regmap_init_i2c(client, regmap);
180 	if (IS_ERR(regmap_pmic))
181 		return dev_err_probe(&client->dev, PTR_ERR(regmap_pmic),
182 				     "regmap init failed\n");
183 
184 	return sec_pmic_probe(&client->dev, device_type, client->irq,
185 			      regmap_pmic, client);
186 }
187 
188 static void sec_pmic_i2c_shutdown(struct i2c_client *i2c)
189 {
190 	sec_pmic_shutdown(&i2c->dev);
191 }
192 
193 static const struct of_device_id sec_pmic_i2c_of_match[] = {
194 	{
195 		.compatible = "samsung,s2dos05",
196 		.data = (void *)S2DOS05,
197 	}, {
198 		.compatible = "samsung,s2mpa01-pmic",
199 		.data = (void *)S2MPA01,
200 	}, {
201 		.compatible = "samsung,s2mps11-pmic",
202 		.data = (void *)S2MPS11X,
203 	}, {
204 		.compatible = "samsung,s2mps13-pmic",
205 		.data = (void *)S2MPS13X,
206 	}, {
207 		.compatible = "samsung,s2mps14-pmic",
208 		.data = (void *)S2MPS14X,
209 	}, {
210 		.compatible = "samsung,s2mps15-pmic",
211 		.data = (void *)S2MPS15X,
212 	}, {
213 		.compatible = "samsung,s2mpu02-pmic",
214 		.data = (void *)S2MPU02,
215 	}, {
216 		.compatible = "samsung,s2mpu05-pmic",
217 		.data = (void *)S2MPU05,
218 	}, {
219 		.compatible = "samsung,s5m8767-pmic",
220 		.data = (void *)S5M8767X,
221 	},
222 	{ },
223 };
224 MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match);
225 
226 static struct i2c_driver sec_pmic_i2c_driver = {
227 	.driver = {
228 		.name = "sec-pmic-i2c",
229 		.pm = pm_sleep_ptr(&sec_pmic_pm_ops),
230 		.of_match_table = sec_pmic_i2c_of_match,
231 	},
232 	.probe = sec_pmic_i2c_probe,
233 	.shutdown = sec_pmic_i2c_shutdown,
234 };
235 module_i2c_driver(sec_pmic_i2c_driver);
236 
237 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
238 MODULE_DESCRIPTION("I2C driver for the Samsung S5M");
239 MODULE_LICENSE("GPL");
240