xref: /linux/drivers/mfd/sec-i2c.c (revision 69352bd52b2667e5c6e8ebb14143528c28f5e37d)
1680ef579SAndré Draszik // SPDX-License-Identifier: GPL-2.0+
2680ef579SAndré Draszik /*
3680ef579SAndré Draszik  * Copyright 2012 Samsung Electronics Co., Ltd
4680ef579SAndré Draszik  *                http://www.samsung.com
5680ef579SAndré Draszik  * Copyright 2025 Linaro Ltd.
6680ef579SAndré Draszik  *
7680ef579SAndré Draszik  * Samsung SxM I2C driver
8680ef579SAndré Draszik  */
9680ef579SAndré Draszik 
10680ef579SAndré Draszik #include <linux/dev_printk.h>
11680ef579SAndré Draszik #include <linux/err.h>
12680ef579SAndré Draszik #include <linux/i2c.h>
13680ef579SAndré Draszik #include <linux/mfd/samsung/core.h>
14680ef579SAndré Draszik #include <linux/mfd/samsung/s2mpa01.h>
15680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps11.h>
16680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps13.h>
17680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps14.h>
18680ef579SAndré Draszik #include <linux/mfd/samsung/s2mps15.h>
19680ef579SAndré Draszik #include <linux/mfd/samsung/s2mpu02.h>
20680ef579SAndré Draszik #include <linux/mfd/samsung/s5m8767.h>
21680ef579SAndré Draszik #include <linux/mod_devicetable.h>
22680ef579SAndré Draszik #include <linux/module.h>
23680ef579SAndré Draszik #include <linux/pm.h>
24aaaeae7eSAndré Draszik #include <linux/property.h>
25680ef579SAndré Draszik #include <linux/regmap.h>
26680ef579SAndré Draszik #include "sec-core.h"
27680ef579SAndré Draszik 
28aaaeae7eSAndré Draszik struct sec_pmic_i2c_platform_data {
29aaaeae7eSAndré Draszik 	const struct regmap_config *regmap_cfg;
30adf91d9eSAndré Draszik 	int device_type;
31aaaeae7eSAndré Draszik };
32aaaeae7eSAndré Draszik 
33680ef579SAndré Draszik static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
34680ef579SAndré Draszik {
35680ef579SAndré Draszik 	switch (reg) {
36680ef579SAndré Draszik 	case S2MPA01_REG_INT1M:
37680ef579SAndré Draszik 	case S2MPA01_REG_INT2M:
38680ef579SAndré Draszik 	case S2MPA01_REG_INT3M:
39680ef579SAndré Draszik 		return false;
40680ef579SAndré Draszik 	default:
41680ef579SAndré Draszik 		return true;
42680ef579SAndré Draszik 	}
43680ef579SAndré Draszik }
44680ef579SAndré Draszik 
45680ef579SAndré Draszik static bool s2mps11_volatile(struct device *dev, unsigned int reg)
46680ef579SAndré Draszik {
47680ef579SAndré Draszik 	switch (reg) {
48680ef579SAndré Draszik 	case S2MPS11_REG_INT1M:
49680ef579SAndré Draszik 	case S2MPS11_REG_INT2M:
50680ef579SAndré Draszik 	case S2MPS11_REG_INT3M:
51680ef579SAndré Draszik 		return false;
52680ef579SAndré Draszik 	default:
53680ef579SAndré Draszik 		return true;
54680ef579SAndré Draszik 	}
55680ef579SAndré Draszik }
56680ef579SAndré Draszik 
57680ef579SAndré Draszik static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
58680ef579SAndré Draszik {
59680ef579SAndré Draszik 	switch (reg) {
60680ef579SAndré Draszik 	case S2MPU02_REG_INT1M:
61680ef579SAndré Draszik 	case S2MPU02_REG_INT2M:
62680ef579SAndré Draszik 	case S2MPU02_REG_INT3M:
63680ef579SAndré Draszik 		return false;
64680ef579SAndré Draszik 	default:
65680ef579SAndré Draszik 		return true;
66680ef579SAndré Draszik 	}
67680ef579SAndré Draszik }
68680ef579SAndré Draszik 
691cea1b6bSAndré Draszik static const struct regmap_config s2dos05_regmap_config = {
70680ef579SAndré Draszik 	.reg_bits = 8,
71680ef579SAndré Draszik 	.val_bits = 8,
72680ef579SAndré Draszik };
73680ef579SAndré Draszik 
74680ef579SAndré Draszik static const struct regmap_config s2mpa01_regmap_config = {
75680ef579SAndré Draszik 	.reg_bits = 8,
76680ef579SAndré Draszik 	.val_bits = 8,
77680ef579SAndré Draszik 
78680ef579SAndré Draszik 	.max_register = S2MPA01_REG_LDO_OVCB4,
79680ef579SAndré Draszik 	.volatile_reg = s2mpa01_volatile,
80680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
81680ef579SAndré Draszik };
82680ef579SAndré Draszik 
83680ef579SAndré Draszik static const struct regmap_config s2mps11_regmap_config = {
84680ef579SAndré Draszik 	.reg_bits = 8,
85680ef579SAndré Draszik 	.val_bits = 8,
86680ef579SAndré Draszik 
87680ef579SAndré Draszik 	.max_register = S2MPS11_REG_L38CTRL,
88680ef579SAndré Draszik 	.volatile_reg = s2mps11_volatile,
89680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
90680ef579SAndré Draszik };
91680ef579SAndré Draszik 
92680ef579SAndré Draszik static const struct regmap_config s2mps13_regmap_config = {
93680ef579SAndré Draszik 	.reg_bits = 8,
94680ef579SAndré Draszik 	.val_bits = 8,
95680ef579SAndré Draszik 
96680ef579SAndré Draszik 	.max_register = S2MPS13_REG_LDODSCH5,
97680ef579SAndré Draszik 	.volatile_reg = s2mps11_volatile,
98680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
99680ef579SAndré Draszik };
100680ef579SAndré Draszik 
101680ef579SAndré Draszik static const struct regmap_config s2mps14_regmap_config = {
102680ef579SAndré Draszik 	.reg_bits = 8,
103680ef579SAndré Draszik 	.val_bits = 8,
104680ef579SAndré Draszik 
105680ef579SAndré Draszik 	.max_register = S2MPS14_REG_LDODSCH3,
106680ef579SAndré Draszik 	.volatile_reg = s2mps11_volatile,
107680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
108680ef579SAndré Draszik };
109680ef579SAndré Draszik 
110680ef579SAndré Draszik static const struct regmap_config s2mps15_regmap_config = {
111680ef579SAndré Draszik 	.reg_bits = 8,
112680ef579SAndré Draszik 	.val_bits = 8,
113680ef579SAndré Draszik 
114680ef579SAndré Draszik 	.max_register = S2MPS15_REG_LDODSCH4,
115680ef579SAndré Draszik 	.volatile_reg = s2mps11_volatile,
116680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
117680ef579SAndré Draszik };
118680ef579SAndré Draszik 
119680ef579SAndré Draszik static const struct regmap_config s2mpu02_regmap_config = {
120680ef579SAndré Draszik 	.reg_bits = 8,
121680ef579SAndré Draszik 	.val_bits = 8,
122680ef579SAndré Draszik 
123680ef579SAndré Draszik 	.max_register = S2MPU02_REG_DVSDATA,
124680ef579SAndré Draszik 	.volatile_reg = s2mpu02_volatile,
125680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
126680ef579SAndré Draszik };
127680ef579SAndré Draszik 
1281cea1b6bSAndré Draszik static const struct regmap_config s2mpu05_regmap_config = {
1291cea1b6bSAndré Draszik 	.reg_bits = 8,
1301cea1b6bSAndré Draszik 	.val_bits = 8,
1311cea1b6bSAndré Draszik };
1321cea1b6bSAndré Draszik 
133680ef579SAndré Draszik static const struct regmap_config s5m8767_regmap_config = {
134680ef579SAndré Draszik 	.reg_bits = 8,
135680ef579SAndré Draszik 	.val_bits = 8,
136680ef579SAndré Draszik 
137680ef579SAndré Draszik 	.max_register = S5M8767_REG_LDO28CTRL,
138680ef579SAndré Draszik 	.volatile_reg = s2mps11_volatile,
139680ef579SAndré Draszik 	.cache_type = REGCACHE_FLAT,
140680ef579SAndré Draszik };
141680ef579SAndré Draszik 
142680ef579SAndré Draszik static int sec_pmic_i2c_probe(struct i2c_client *client)
143680ef579SAndré Draszik {
144aaaeae7eSAndré Draszik 	const struct sec_pmic_i2c_platform_data *pdata;
145680ef579SAndré Draszik 	struct regmap *regmap_pmic;
146680ef579SAndré Draszik 
147aaaeae7eSAndré Draszik 	pdata = device_get_match_data(&client->dev);
148aaaeae7eSAndré Draszik 	if (!pdata)
1491cea1b6bSAndré Draszik 		return dev_err_probe(&client->dev, -ENODEV,
150aaaeae7eSAndré Draszik 				     "Unsupported device type\n");
151680ef579SAndré Draszik 
152aaaeae7eSAndré Draszik 	regmap_pmic = devm_regmap_init_i2c(client, pdata->regmap_cfg);
153176a3068SAndré Draszik 	if (IS_ERR(regmap_pmic))
154176a3068SAndré Draszik 		return dev_err_probe(&client->dev, PTR_ERR(regmap_pmic),
155176a3068SAndré Draszik 				     "regmap init failed\n");
156680ef579SAndré Draszik 
157aaaeae7eSAndré Draszik 	return sec_pmic_probe(&client->dev, pdata->device_type, client->irq,
158680ef579SAndré Draszik 			      regmap_pmic, client);
159680ef579SAndré Draszik }
160680ef579SAndré Draszik 
161680ef579SAndré Draszik static void sec_pmic_i2c_shutdown(struct i2c_client *i2c)
162680ef579SAndré Draszik {
163680ef579SAndré Draszik 	sec_pmic_shutdown(&i2c->dev);
164680ef579SAndré Draszik }
165680ef579SAndré Draszik 
166aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2dos05_data = {
167aaaeae7eSAndré Draszik 	.regmap_cfg = &s2dos05_regmap_config,
168aaaeae7eSAndré Draszik 	.device_type = S2DOS05
169aaaeae7eSAndré Draszik };
170aaaeae7eSAndré Draszik 
171aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mpa01_data = {
172aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mpa01_regmap_config,
173aaaeae7eSAndré Draszik 	.device_type = S2MPA01,
174aaaeae7eSAndré Draszik };
175aaaeae7eSAndré Draszik 
176aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps11_data = {
177aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mps11_regmap_config,
178aaaeae7eSAndré Draszik 	.device_type = S2MPS11X,
179aaaeae7eSAndré Draszik };
180aaaeae7eSAndré Draszik 
181aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps13_data = {
182aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mps13_regmap_config,
183aaaeae7eSAndré Draszik 	.device_type = S2MPS13X,
184aaaeae7eSAndré Draszik };
185aaaeae7eSAndré Draszik 
186aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps14_data = {
187aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mps14_regmap_config,
188aaaeae7eSAndré Draszik 	.device_type = S2MPS14X,
189aaaeae7eSAndré Draszik };
190aaaeae7eSAndré Draszik 
191aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mps15_data = {
192aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mps15_regmap_config,
193aaaeae7eSAndré Draszik 	.device_type = S2MPS15X,
194aaaeae7eSAndré Draszik };
195aaaeae7eSAndré Draszik 
196aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mpu02_data = {
197aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mpu02_regmap_config,
198aaaeae7eSAndré Draszik 	.device_type = S2MPU02,
199aaaeae7eSAndré Draszik };
200aaaeae7eSAndré Draszik 
201aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s2mpu05_data = {
202aaaeae7eSAndré Draszik 	.regmap_cfg = &s2mpu05_regmap_config,
203aaaeae7eSAndré Draszik 	.device_type = S2MPU05,
204aaaeae7eSAndré Draszik };
205aaaeae7eSAndré Draszik 
206aaaeae7eSAndré Draszik static const struct sec_pmic_i2c_platform_data s5m8767_data = {
207aaaeae7eSAndré Draszik 	.regmap_cfg = &s5m8767_regmap_config,
208aaaeae7eSAndré Draszik 	.device_type = S5M8767X,
209aaaeae7eSAndré Draszik };
210aaaeae7eSAndré Draszik 
211680ef579SAndré Draszik static const struct of_device_id sec_pmic_i2c_of_match[] = {
212aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2dos05", .data = &s2dos05_data, },
213aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mpa01-pmic", .data = &s2mpa01_data, },
214aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mps11-pmic", .data = &s2mps11_data, },
215aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mps13-pmic", .data = &s2mps13_data, },
216aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mps14-pmic", .data = &s2mps14_data, },
217aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mps15-pmic", .data = &s2mps15_data, },
218aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mpu02-pmic", .data = &s2mpu02_data, },
219aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s2mpu05-pmic", .data = &s2mpu05_data, },
220aaaeae7eSAndré Draszik 	{ .compatible = "samsung,s5m8767-pmic", .data = &s5m8767_data, },
221680ef579SAndré Draszik 	{ },
222680ef579SAndré Draszik };
223680ef579SAndré Draszik MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match);
224680ef579SAndré Draszik 
225680ef579SAndré Draszik static struct i2c_driver sec_pmic_i2c_driver = {
226680ef579SAndré Draszik 	.driver = {
227680ef579SAndré Draszik 		.name = "sec-pmic-i2c",
228680ef579SAndré Draszik 		.pm = pm_sleep_ptr(&sec_pmic_pm_ops),
229680ef579SAndré Draszik 		.of_match_table = sec_pmic_i2c_of_match,
230680ef579SAndré Draszik 	},
231680ef579SAndré Draszik 	.probe = sec_pmic_i2c_probe,
232680ef579SAndré Draszik 	.shutdown = sec_pmic_i2c_shutdown,
233680ef579SAndré Draszik };
234680ef579SAndré Draszik module_i2c_driver(sec_pmic_i2c_driver);
235680ef579SAndré Draszik 
236680ef579SAndré Draszik MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
237*217c445cSAndré Draszik MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>");
238680ef579SAndré Draszik MODULE_DESCRIPTION("I2C driver for the Samsung S5M");
239680ef579SAndré Draszik MODULE_LICENSE("GPL");
240