File Index
Files and directories
Sign in
FILE

sec-i2c.c

File preview with syntax highlighting.

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