1 // SPDX-License-Identifier: GPL-2.0
3 // Register map access API - SPMI support
5 // Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
7 // Based on regmap-i2c.c:
8 // Copyright 2011 Wolfson Microelectronics plc
9 // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
11 #include <linux/regmap.h>
12 #include <linux/spmi.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
16 static int regmap_spmi_base_read(void *context
,
17 const void *reg
, size_t reg_size
,
18 void *val
, size_t val_size
)
23 BUG_ON(reg_size
!= 1);
25 while (val_size
-- && !err
)
26 err
= spmi_register_read(context
, addr
++, val
++);
31 static int regmap_spmi_base_gather_write(void *context
,
32 const void *reg
, size_t reg_size
,
33 const void *val
, size_t val_size
)
39 BUG_ON(reg_size
!= 1);
42 * SPMI defines a more bandwidth-efficient 'Register 0 Write' sequence,
43 * use it when possible.
45 if (addr
== 0 && val_size
) {
46 err
= spmi_register_zero_write(context
, *data
);
56 err
= spmi_register_write(context
, addr
, *data
);
69 static int regmap_spmi_base_write(void *context
, const void *data
,
73 return regmap_spmi_base_gather_write(context
, data
, 1, data
+ 1,
77 static const struct regmap_bus regmap_spmi_base
= {
78 .read
= regmap_spmi_base_read
,
79 .write
= regmap_spmi_base_write
,
80 .gather_write
= regmap_spmi_base_gather_write
,
81 .reg_format_endian_default
= REGMAP_ENDIAN_NATIVE
,
82 .val_format_endian_default
= REGMAP_ENDIAN_NATIVE
,
85 struct regmap
*__regmap_init_spmi_base(struct spmi_device
*sdev
,
86 const struct regmap_config
*config
,
87 struct lock_class_key
*lock_key
,
88 const char *lock_name
)
90 return __regmap_init(&sdev
->dev
, ®map_spmi_base
, sdev
, config
,
93 EXPORT_SYMBOL_GPL(__regmap_init_spmi_base
);
95 struct regmap
*__devm_regmap_init_spmi_base(struct spmi_device
*sdev
,
96 const struct regmap_config
*config
,
97 struct lock_class_key
*lock_key
,
98 const char *lock_name
)
100 return __devm_regmap_init(&sdev
->dev
, ®map_spmi_base
, sdev
, config
,
101 lock_key
, lock_name
);
103 EXPORT_SYMBOL_GPL(__devm_regmap_init_spmi_base
);
105 static int regmap_spmi_ext_read(void *context
,
106 const void *reg
, size_t reg_size
,
107 void *val
, size_t val_size
)
113 BUG_ON(reg_size
!= 2);
118 * Split accesses into two to take advantage of the more
119 * bandwidth-efficient 'Extended Register Read' command when possible
121 while (addr
<= 0xFF && val_size
) {
122 len
= min_t(size_t, val_size
, 16);
124 err
= spmi_ext_register_read(context
, addr
, val
, len
);
134 len
= min_t(size_t, val_size
, 8);
136 err
= spmi_ext_register_readl(context
, addr
, val
, len
);
149 static int regmap_spmi_ext_gather_write(void *context
,
150 const void *reg
, size_t reg_size
,
151 const void *val
, size_t val_size
)
157 BUG_ON(reg_size
!= 2);
161 while (addr
<= 0xFF && val_size
) {
162 len
= min_t(size_t, val_size
, 16);
164 err
= spmi_ext_register_write(context
, addr
, val
, len
);
174 len
= min_t(size_t, val_size
, 8);
176 err
= spmi_ext_register_writel(context
, addr
, val
, len
);
189 static int regmap_spmi_ext_write(void *context
, const void *data
,
193 return regmap_spmi_ext_gather_write(context
, data
, 2, data
+ 2,
197 static const struct regmap_bus regmap_spmi_ext
= {
198 .read
= regmap_spmi_ext_read
,
199 .write
= regmap_spmi_ext_write
,
200 .gather_write
= regmap_spmi_ext_gather_write
,
201 .reg_format_endian_default
= REGMAP_ENDIAN_NATIVE
,
202 .val_format_endian_default
= REGMAP_ENDIAN_NATIVE
,
205 struct regmap
*__regmap_init_spmi_ext(struct spmi_device
*sdev
,
206 const struct regmap_config
*config
,
207 struct lock_class_key
*lock_key
,
208 const char *lock_name
)
210 return __regmap_init(&sdev
->dev
, ®map_spmi_ext
, sdev
, config
,
211 lock_key
, lock_name
);
213 EXPORT_SYMBOL_GPL(__regmap_init_spmi_ext
);
215 struct regmap
*__devm_regmap_init_spmi_ext(struct spmi_device
*sdev
,
216 const struct regmap_config
*config
,
217 struct lock_class_key
*lock_key
,
218 const char *lock_name
)
220 return __devm_regmap_init(&sdev
->dev
, ®map_spmi_ext
, sdev
, config
,
221 lock_key
, lock_name
);
223 EXPORT_SYMBOL_GPL(__devm_regmap_init_spmi_ext
);
225 MODULE_LICENSE("GPL");