Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / base / regmap / regmap-fsi.c
blob3d2f3cb31d5eb75f3ae5be0085f4da9fa40753d5
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Register map access API - FSI support
4 //
5 // Copyright 2022 IBM Corp
6 //
7 // Author: Eddie James <eajames@linux.ibm.com>
9 #include <linux/fsi.h>
10 #include <linux/module.h>
11 #include <linux/regmap.h>
13 #include "internal.h"
15 static int regmap_fsi32_reg_read(void *context, unsigned int reg, unsigned int *val)
17 u32 v;
18 int ret;
20 ret = fsi_slave_read(context, reg, &v, sizeof(v));
21 if (ret)
22 return ret;
24 *val = v;
25 return 0;
28 static int regmap_fsi32_reg_write(void *context, unsigned int reg, unsigned int val)
30 u32 v = val;
32 return fsi_slave_write(context, reg, &v, sizeof(v));
35 static const struct regmap_bus regmap_fsi32 = {
36 .reg_write = regmap_fsi32_reg_write,
37 .reg_read = regmap_fsi32_reg_read,
40 static int regmap_fsi32le_reg_read(void *context, unsigned int reg, unsigned int *val)
42 __be32 v;
43 int ret;
45 ret = fsi_slave_read(context, reg, &v, sizeof(v));
46 if (ret)
47 return ret;
49 *val = be32_to_cpu(v);
50 return 0;
53 static int regmap_fsi32le_reg_write(void *context, unsigned int reg, unsigned int val)
55 __be32 v = cpu_to_be32(val);
57 return fsi_slave_write(context, reg, &v, sizeof(v));
60 static const struct regmap_bus regmap_fsi32le = {
61 .reg_write = regmap_fsi32le_reg_write,
62 .reg_read = regmap_fsi32le_reg_read,
65 static int regmap_fsi16_reg_read(void *context, unsigned int reg, unsigned int *val)
67 u16 v;
68 int ret;
70 ret = fsi_slave_read(context, reg, &v, sizeof(v));
71 if (ret)
72 return ret;
74 *val = v;
75 return 0;
78 static int regmap_fsi16_reg_write(void *context, unsigned int reg, unsigned int val)
80 u16 v;
82 if (val > 0xffff)
83 return -EINVAL;
85 v = val;
86 return fsi_slave_write(context, reg, &v, sizeof(v));
89 static const struct regmap_bus regmap_fsi16 = {
90 .reg_write = regmap_fsi16_reg_write,
91 .reg_read = regmap_fsi16_reg_read,
94 static int regmap_fsi16le_reg_read(void *context, unsigned int reg, unsigned int *val)
96 __be16 v;
97 int ret;
99 ret = fsi_slave_read(context, reg, &v, sizeof(v));
100 if (ret)
101 return ret;
103 *val = be16_to_cpu(v);
104 return 0;
107 static int regmap_fsi16le_reg_write(void *context, unsigned int reg, unsigned int val)
109 __be16 v;
111 if (val > 0xffff)
112 return -EINVAL;
114 v = cpu_to_be16(val);
115 return fsi_slave_write(context, reg, &v, sizeof(v));
118 static const struct regmap_bus regmap_fsi16le = {
119 .reg_write = regmap_fsi16le_reg_write,
120 .reg_read = regmap_fsi16le_reg_read,
123 static int regmap_fsi8_reg_read(void *context, unsigned int reg, unsigned int *val)
125 u8 v;
126 int ret;
128 ret = fsi_slave_read(context, reg, &v, sizeof(v));
129 if (ret)
130 return ret;
132 *val = v;
133 return 0;
136 static int regmap_fsi8_reg_write(void *context, unsigned int reg, unsigned int val)
138 u8 v;
140 if (val > 0xff)
141 return -EINVAL;
143 v = val;
144 return fsi_slave_write(context, reg, &v, sizeof(v));
147 static const struct regmap_bus regmap_fsi8 = {
148 .reg_write = regmap_fsi8_reg_write,
149 .reg_read = regmap_fsi8_reg_read,
152 static const struct regmap_bus *regmap_get_fsi_bus(struct fsi_device *fsi_dev,
153 const struct regmap_config *config)
155 const struct regmap_bus *bus = NULL;
157 if (config->reg_bits == 8 || config->reg_bits == 16 || config->reg_bits == 32) {
158 switch (config->val_bits) {
159 case 8:
160 bus = &regmap_fsi8;
161 break;
162 case 16:
163 switch (regmap_get_val_endian(&fsi_dev->dev, NULL, config)) {
164 case REGMAP_ENDIAN_LITTLE:
165 #ifdef __LITTLE_ENDIAN
166 case REGMAP_ENDIAN_NATIVE:
167 #endif
168 bus = &regmap_fsi16le;
169 break;
170 case REGMAP_ENDIAN_DEFAULT:
171 case REGMAP_ENDIAN_BIG:
172 #ifdef __BIG_ENDIAN
173 case REGMAP_ENDIAN_NATIVE:
174 #endif
175 bus = &regmap_fsi16;
176 break;
177 default:
178 break;
180 break;
181 case 32:
182 switch (regmap_get_val_endian(&fsi_dev->dev, NULL, config)) {
183 case REGMAP_ENDIAN_LITTLE:
184 #ifdef __LITTLE_ENDIAN
185 case REGMAP_ENDIAN_NATIVE:
186 #endif
187 bus = &regmap_fsi32le;
188 break;
189 case REGMAP_ENDIAN_DEFAULT:
190 case REGMAP_ENDIAN_BIG:
191 #ifdef __BIG_ENDIAN
192 case REGMAP_ENDIAN_NATIVE:
193 #endif
194 bus = &regmap_fsi32;
195 break;
196 default:
197 break;
199 break;
203 return bus ?: ERR_PTR(-EOPNOTSUPP);
206 struct regmap *__regmap_init_fsi(struct fsi_device *fsi_dev, const struct regmap_config *config,
207 struct lock_class_key *lock_key, const char *lock_name)
209 const struct regmap_bus *bus = regmap_get_fsi_bus(fsi_dev, config);
211 if (IS_ERR(bus))
212 return ERR_CAST(bus);
214 return __regmap_init(&fsi_dev->dev, bus, fsi_dev->slave, config, lock_key, lock_name);
216 EXPORT_SYMBOL_GPL(__regmap_init_fsi);
218 struct regmap *__devm_regmap_init_fsi(struct fsi_device *fsi_dev,
219 const struct regmap_config *config,
220 struct lock_class_key *lock_key, const char *lock_name)
222 const struct regmap_bus *bus = regmap_get_fsi_bus(fsi_dev, config);
224 if (IS_ERR(bus))
225 return ERR_CAST(bus);
227 return __devm_regmap_init(&fsi_dev->dev, bus, fsi_dev->slave, config, lock_key, lock_name);
229 EXPORT_SYMBOL_GPL(__devm_regmap_init_fsi);
231 MODULE_LICENSE("GPL");