blob: 73a8111aea93822610248026b454b1bd7e7c1f2c [file] [log] [blame]
Mark Brownb83a3132011-05-11 19:59:58 +02001/*
2 * Register map access API
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/slab.h>
14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/err.h>
17
Mark Brownfb2736b2011-07-24 21:30:55 +010018#define CREATE_TRACE_POINTS
19#include <trace/events/regmap.h>
20
Mark Brown93de9122011-07-20 22:35:37 +010021#include "internal.h"
Mark Brownb83a3132011-05-11 19:59:58 +020022
Mark Brown8de2f082011-08-10 17:14:41 +090023bool regmap_writeable(struct regmap *map, unsigned int reg)
24{
25 if (map->max_register && reg > map->max_register)
26 return false;
27
28 if (map->writeable_reg)
29 return map->writeable_reg(map->dev, reg);
30
31 return true;
32}
33
34bool regmap_readable(struct regmap *map, unsigned int reg)
35{
36 if (map->max_register && reg > map->max_register)
37 return false;
38
Wolfram Sang4191f192012-01-30 15:08:16 +010039 if (map->format.format_write)
40 return false;
41
Mark Brown8de2f082011-08-10 17:14:41 +090042 if (map->readable_reg)
43 return map->readable_reg(map->dev, reg);
44
45 return true;
46}
47
48bool regmap_volatile(struct regmap *map, unsigned int reg)
49{
Wolfram Sang4191f192012-01-30 15:08:16 +010050 if (!regmap_readable(map, reg))
Mark Brown8de2f082011-08-10 17:14:41 +090051 return false;
52
53 if (map->volatile_reg)
54 return map->volatile_reg(map->dev, reg);
55
56 return true;
57}
58
59bool regmap_precious(struct regmap *map, unsigned int reg)
60{
Wolfram Sang4191f192012-01-30 15:08:16 +010061 if (!regmap_readable(map, reg))
Mark Brown8de2f082011-08-10 17:14:41 +090062 return false;
63
64 if (map->precious_reg)
65 return map->precious_reg(map->dev, reg);
66
67 return false;
68}
69
Lars-Peter Clausen82cd9962011-11-08 18:37:25 +010070static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
71 unsigned int num)
72{
73 unsigned int i;
74
75 for (i = 0; i < num; i++)
76 if (!regmap_volatile(map, reg + i))
77 return false;
78
79 return true;
80}
81
Wolfram Sang9aa50752012-01-27 16:10:22 +010082static void regmap_format_2_6_write(struct regmap *map,
83 unsigned int reg, unsigned int val)
84{
85 u8 *out = map->work_buf;
86
87 *out = (reg << 6) | val;
88}
89
Mark Brownb83a3132011-05-11 19:59:58 +020090static void regmap_format_4_12_write(struct regmap *map,
91 unsigned int reg, unsigned int val)
92{
93 __be16 *out = map->work_buf;
94 *out = cpu_to_be16((reg << 12) | val);
95}
96
97static void regmap_format_7_9_write(struct regmap *map,
98 unsigned int reg, unsigned int val)
99{
100 __be16 *out = map->work_buf;
101 *out = cpu_to_be16((reg << 9) | val);
102}
103
Lars-Peter Clausen7e5ec632011-11-16 16:28:21 +0100104static void regmap_format_10_14_write(struct regmap *map,
105 unsigned int reg, unsigned int val)
106{
107 u8 *out = map->work_buf;
108
109 out[2] = val;
110 out[1] = (val >> 8) | (reg << 6);
111 out[0] = reg >> 2;
112}
113
Mark Brownb83a3132011-05-11 19:59:58 +0200114static void regmap_format_8(void *buf, unsigned int val)
115{
116 u8 *b = buf;
117
118 b[0] = val;
119}
120
121static void regmap_format_16(void *buf, unsigned int val)
122{
123 __be16 *b = buf;
124
125 b[0] = cpu_to_be16(val);
126}
127
Mark Brown7d5e5252012-02-17 15:58:25 -0800128static void regmap_format_32(void *buf, unsigned int val)
129{
130 __be32 *b = buf;
131
132 b[0] = cpu_to_be32(val);
133}
134
Mark Brownb83a3132011-05-11 19:59:58 +0200135static unsigned int regmap_parse_8(void *buf)
136{
137 u8 *b = buf;
138
139 return b[0];
140}
141
142static unsigned int regmap_parse_16(void *buf)
143{
144 __be16 *b = buf;
145
146 b[0] = be16_to_cpu(b[0]);
147
148 return b[0];
149}
150
Mark Brown7d5e5252012-02-17 15:58:25 -0800151static unsigned int regmap_parse_32(void *buf)
152{
153 __be32 *b = buf;
154
155 b[0] = be32_to_cpu(b[0]);
156
157 return b[0];
158}
159
Mark Brownb83a3132011-05-11 19:59:58 +0200160/**
161 * regmap_init(): Initialise register map
162 *
163 * @dev: Device that will be interacted with
164 * @bus: Bus-specific callbacks to use with device
165 * @config: Configuration for register map
166 *
167 * The return value will be an ERR_PTR() on error or a valid pointer to
168 * a struct regmap. This function should generally not be called
169 * directly, it should be called by bus-specific init functions.
170 */
171struct regmap *regmap_init(struct device *dev,
172 const struct regmap_bus *bus,
173 const struct regmap_config *config)
174{
175 struct regmap *map;
176 int ret = -EINVAL;
177
178 if (!bus || !config)
Lars-Peter Clausenabbb18f2011-11-14 10:40:15 +0100179 goto err;
Mark Brownb83a3132011-05-11 19:59:58 +0200180
181 map = kzalloc(sizeof(*map), GFP_KERNEL);
182 if (map == NULL) {
183 ret = -ENOMEM;
184 goto err;
185 }
186
187 mutex_init(&map->lock);
188 map->format.buf_size = (config->reg_bits + config->val_bits) / 8;
Wolfram Sangc212acc2012-01-28 02:16:41 +0100189 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
Mark Brown82159ba2012-01-18 10:52:25 +0000190 map->format.pad_bytes = config->pad_bits / 8;
Wolfram Sangc212acc2012-01-28 02:16:41 +0100191 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
Mark Brown82159ba2012-01-18 10:52:25 +0000192 map->format.buf_size += map->format.pad_bytes;
Mark Brownb83a3132011-05-11 19:59:58 +0200193 map->dev = dev;
194 map->bus = bus;
Mark Brown2e2ae662011-07-20 22:33:39 +0100195 map->max_register = config->max_register;
196 map->writeable_reg = config->writeable_reg;
197 map->readable_reg = config->readable_reg;
198 map->volatile_reg = config->volatile_reg;
Mark Brown2efe1642011-08-08 15:41:46 +0900199 map->precious_reg = config->precious_reg;
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100200 map->cache_type = config->cache_type;
Mark Brownb83a3132011-05-11 19:59:58 +0200201
Lars-Peter Clausen6f306442011-09-05 20:46:32 +0200202 if (config->read_flag_mask || config->write_flag_mask) {
203 map->read_flag_mask = config->read_flag_mask;
204 map->write_flag_mask = config->write_flag_mask;
205 } else {
206 map->read_flag_mask = bus->read_flag_mask;
207 }
208
Mark Brownb83a3132011-05-11 19:59:58 +0200209 switch (config->reg_bits) {
Wolfram Sang9aa50752012-01-27 16:10:22 +0100210 case 2:
211 switch (config->val_bits) {
212 case 6:
213 map->format.format_write = regmap_format_2_6_write;
214 break;
215 default:
216 goto err_map;
217 }
218 break;
219
Mark Brownb83a3132011-05-11 19:59:58 +0200220 case 4:
221 switch (config->val_bits) {
222 case 12:
223 map->format.format_write = regmap_format_4_12_write;
224 break;
225 default:
226 goto err_map;
227 }
228 break;
229
230 case 7:
231 switch (config->val_bits) {
232 case 9:
233 map->format.format_write = regmap_format_7_9_write;
234 break;
235 default:
236 goto err_map;
237 }
238 break;
239
Lars-Peter Clausen7e5ec632011-11-16 16:28:21 +0100240 case 10:
241 switch (config->val_bits) {
242 case 14:
243 map->format.format_write = regmap_format_10_14_write;
244 break;
245 default:
246 goto err_map;
247 }
248 break;
249
Mark Brownb83a3132011-05-11 19:59:58 +0200250 case 8:
251 map->format.format_reg = regmap_format_8;
252 break;
253
254 case 16:
255 map->format.format_reg = regmap_format_16;
256 break;
257
Mark Brown7d5e5252012-02-17 15:58:25 -0800258 case 32:
259 map->format.format_reg = regmap_format_32;
260 break;
261
Mark Brownb83a3132011-05-11 19:59:58 +0200262 default:
263 goto err_map;
264 }
265
266 switch (config->val_bits) {
267 case 8:
268 map->format.format_val = regmap_format_8;
269 map->format.parse_val = regmap_parse_8;
270 break;
271 case 16:
272 map->format.format_val = regmap_format_16;
273 map->format.parse_val = regmap_parse_16;
274 break;
Mark Brown7d5e5252012-02-17 15:58:25 -0800275 case 32:
276 map->format.format_val = regmap_format_32;
277 map->format.parse_val = regmap_parse_32;
278 break;
Mark Brownb83a3132011-05-11 19:59:58 +0200279 }
280
281 if (!map->format.format_write &&
282 !(map->format.format_reg && map->format.format_val))
283 goto err_map;
284
Mark Brown82159ba2012-01-18 10:52:25 +0000285 map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL);
Mark Brownb83a3132011-05-11 19:59:58 +0200286 if (map->work_buf == NULL) {
287 ret = -ENOMEM;
Mark Brown5204f5e2011-09-05 08:07:47 -0700288 goto err_map;
Mark Brownb83a3132011-05-11 19:59:58 +0200289 }
290
Mark Brown052d2cd2011-11-21 19:05:13 +0000291 regmap_debugfs_init(map);
292
Lars-Peter Clausene5e3b8a2011-11-16 16:28:16 +0100293 ret = regcache_init(map, config);
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100294 if (ret < 0)
Lars-Peter Clausen58072cb2011-11-10 18:15:15 +0100295 goto err_free_workbuf;
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100296
Mark Brownb83a3132011-05-11 19:59:58 +0200297 return map;
298
Lars-Peter Clausen58072cb2011-11-10 18:15:15 +0100299err_free_workbuf:
300 kfree(map->work_buf);
Mark Brownb83a3132011-05-11 19:59:58 +0200301err_map:
302 kfree(map);
303err:
304 return ERR_PTR(ret);
305}
306EXPORT_SYMBOL_GPL(regmap_init);
307
308/**
Mark Brownbf315172011-12-03 17:06:20 +0000309 * regmap_reinit_cache(): Reinitialise the current register cache
310 *
311 * @map: Register map to operate on.
312 * @config: New configuration. Only the cache data will be used.
313 *
314 * Discard any existing register cache for the map and initialize a
315 * new cache. This can be used to restore the cache to defaults or to
316 * update the cache configuration to reflect runtime discovery of the
317 * hardware.
318 */
319int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
320{
321 int ret;
322
323 mutex_lock(&map->lock);
324
325 regcache_exit(map);
Mark Browna24f64a2012-01-26 18:30:16 +0000326 regmap_debugfs_exit(map);
Mark Brownbf315172011-12-03 17:06:20 +0000327
328 map->max_register = config->max_register;
329 map->writeable_reg = config->writeable_reg;
330 map->readable_reg = config->readable_reg;
331 map->volatile_reg = config->volatile_reg;
332 map->precious_reg = config->precious_reg;
333 map->cache_type = config->cache_type;
334
Mark Browna24f64a2012-01-26 18:30:16 +0000335 regmap_debugfs_init(map);
336
Mark Brownbf315172011-12-03 17:06:20 +0000337 ret = regcache_init(map, config);
338
339 mutex_unlock(&map->lock);
340
341 return ret;
342}
343
344/**
Mark Brownb83a3132011-05-11 19:59:58 +0200345 * regmap_exit(): Free a previously allocated register map
346 */
347void regmap_exit(struct regmap *map)
348{
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100349 regcache_exit(map);
Mark Brown31244e32011-07-20 22:56:53 +0100350 regmap_debugfs_exit(map);
Mark Brownb83a3132011-05-11 19:59:58 +0200351 kfree(map->work_buf);
Mark Brownb83a3132011-05-11 19:59:58 +0200352 kfree(map);
353}
354EXPORT_SYMBOL_GPL(regmap_exit);
355
356static int _regmap_raw_write(struct regmap *map, unsigned int reg,
357 const void *val, size_t val_len)
358{
Lars-Peter Clausen6f306442011-09-05 20:46:32 +0200359 u8 *u8 = map->work_buf;
Mark Brownb83a3132011-05-11 19:59:58 +0200360 void *buf;
361 int ret = -ENOTSUPP;
362 size_t len;
Mark Brown73304782011-07-24 11:46:20 +0100363 int i;
364
365 /* Check for unwritable registers before we start */
366 if (map->writeable_reg)
367 for (i = 0; i < val_len / map->format.val_bytes; i++)
368 if (!map->writeable_reg(map->dev, reg + i))
369 return -EINVAL;
Mark Brownb83a3132011-05-11 19:59:58 +0200370
371 map->format.format_reg(map->work_buf, reg);
372
Lars-Peter Clausen6f306442011-09-05 20:46:32 +0200373 u8[0] |= map->write_flag_mask;
374
Mark Brownfb2736b2011-07-24 21:30:55 +0100375 trace_regmap_hw_write_start(map->dev, reg,
376 val_len / map->format.val_bytes);
377
Mark Brown2547e202011-07-20 21:47:22 +0100378 /* If we're doing a single register write we can probably just
379 * send the work_buf directly, otherwise try to do a gather
380 * write.
381 */
Mark Brown82159ba2012-01-18 10:52:25 +0000382 if (val == (map->work_buf + map->format.pad_bytes +
383 map->format.reg_bytes))
Mark Brown2547e202011-07-20 21:47:22 +0100384 ret = map->bus->write(map->dev, map->work_buf,
Mark Brown82159ba2012-01-18 10:52:25 +0000385 map->format.reg_bytes +
386 map->format.pad_bytes +
387 val_len);
Mark Brown2547e202011-07-20 21:47:22 +0100388 else if (map->bus->gather_write)
Mark Brownb83a3132011-05-11 19:59:58 +0200389 ret = map->bus->gather_write(map->dev, map->work_buf,
Mark Brown82159ba2012-01-18 10:52:25 +0000390 map->format.reg_bytes +
391 map->format.pad_bytes,
Mark Brownb83a3132011-05-11 19:59:58 +0200392 val, val_len);
393
Mark Brown2547e202011-07-20 21:47:22 +0100394 /* If that didn't work fall back on linearising by hand. */
Mark Brownb83a3132011-05-11 19:59:58 +0200395 if (ret == -ENOTSUPP) {
Mark Brown82159ba2012-01-18 10:52:25 +0000396 len = map->format.reg_bytes + map->format.pad_bytes + val_len;
397 buf = kzalloc(len, GFP_KERNEL);
Mark Brownb83a3132011-05-11 19:59:58 +0200398 if (!buf)
399 return -ENOMEM;
400
401 memcpy(buf, map->work_buf, map->format.reg_bytes);
Mark Brown82159ba2012-01-18 10:52:25 +0000402 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
403 val, val_len);
Mark Brownb83a3132011-05-11 19:59:58 +0200404 ret = map->bus->write(map->dev, buf, len);
405
406 kfree(buf);
407 }
408
Mark Brownfb2736b2011-07-24 21:30:55 +0100409 trace_regmap_hw_write_done(map->dev, reg,
410 val_len / map->format.val_bytes);
411
Mark Brownb83a3132011-05-11 19:59:58 +0200412 return ret;
413}
414
Dimitris Papastamos4d2dc092011-09-29 10:39:07 +0100415int _regmap_write(struct regmap *map, unsigned int reg,
416 unsigned int val)
Mark Brownb83a3132011-05-11 19:59:58 +0200417{
Mark Brownfb2736b2011-07-24 21:30:55 +0100418 int ret;
Mark Brownb83a3132011-05-11 19:59:58 +0200419 BUG_ON(!map->format.format_write && !map->format.format_val);
420
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100421 if (!map->cache_bypass) {
422 ret = regcache_write(map, reg, val);
423 if (ret != 0)
424 return ret;
Mark Brown8ae0d7e2011-10-26 10:34:22 +0200425 if (map->cache_only) {
426 map->cache_dirty = true;
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100427 return 0;
Mark Brown8ae0d7e2011-10-26 10:34:22 +0200428 }
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100429 }
430
Mark Brownfb2736b2011-07-24 21:30:55 +0100431 trace_regmap_reg_write(map->dev, reg, val);
432
Mark Brownb83a3132011-05-11 19:59:58 +0200433 if (map->format.format_write) {
434 map->format.format_write(map, reg, val);
435
Mark Brownfb2736b2011-07-24 21:30:55 +0100436 trace_regmap_hw_write_start(map->dev, reg, 1);
437
438 ret = map->bus->write(map->dev, map->work_buf,
439 map->format.buf_size);
440
441 trace_regmap_hw_write_done(map->dev, reg, 1);
442
443 return ret;
Mark Brownb83a3132011-05-11 19:59:58 +0200444 } else {
Mark Brown82159ba2012-01-18 10:52:25 +0000445 map->format.format_val(map->work_buf + map->format.reg_bytes
446 + map->format.pad_bytes, val);
Mark Brownb83a3132011-05-11 19:59:58 +0200447 return _regmap_raw_write(map, reg,
Mark Brown82159ba2012-01-18 10:52:25 +0000448 map->work_buf +
449 map->format.reg_bytes +
450 map->format.pad_bytes,
Mark Brownb83a3132011-05-11 19:59:58 +0200451 map->format.val_bytes);
452 }
453}
454
455/**
456 * regmap_write(): Write a value to a single register
457 *
458 * @map: Register map to write to
459 * @reg: Register to write to
460 * @val: Value to be written
461 *
462 * A value of zero will be returned on success, a negative errno will
463 * be returned in error cases.
464 */
465int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
466{
467 int ret;
468
469 mutex_lock(&map->lock);
470
471 ret = _regmap_write(map, reg, val);
472
473 mutex_unlock(&map->lock);
474
475 return ret;
476}
477EXPORT_SYMBOL_GPL(regmap_write);
478
479/**
480 * regmap_raw_write(): Write raw values to one or more registers
481 *
482 * @map: Register map to write to
483 * @reg: Initial register to write to
484 * @val: Block of data to be written, laid out for direct transmission to the
485 * device
486 * @val_len: Length of data pointed to by val.
487 *
488 * This function is intended to be used for things like firmware
489 * download where a large block of data needs to be transferred to the
490 * device. No formatting will be done on the data provided.
491 *
492 * A value of zero will be returned on success, a negative errno will
493 * be returned in error cases.
494 */
495int regmap_raw_write(struct regmap *map, unsigned int reg,
496 const void *val, size_t val_len)
497{
Lars-Peter Clausenc48a9d72011-11-08 18:37:26 +0100498 size_t val_count = val_len / map->format.val_bytes;
Mark Brownb83a3132011-05-11 19:59:58 +0200499 int ret;
500
Lars-Peter Clausenc48a9d72011-11-08 18:37:26 +0100501 WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
502 map->cache_type != REGCACHE_NONE);
Mark Brown04e016a2011-10-09 13:35:43 +0100503
Mark Brownb83a3132011-05-11 19:59:58 +0200504 mutex_lock(&map->lock);
505
506 ret = _regmap_raw_write(map, reg, val, val_len);
507
508 mutex_unlock(&map->lock);
509
510 return ret;
511}
512EXPORT_SYMBOL_GPL(regmap_raw_write);
513
514static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
515 unsigned int val_len)
516{
517 u8 *u8 = map->work_buf;
518 int ret;
519
520 map->format.format_reg(map->work_buf, reg);
521
522 /*
Lars-Peter Clausen6f306442011-09-05 20:46:32 +0200523 * Some buses or devices flag reads by setting the high bits in the
Mark Brownb83a3132011-05-11 19:59:58 +0200524 * register addresss; since it's always the high bits for all
525 * current formats we can do this here rather than in
526 * formatting. This may break if we get interesting formats.
527 */
Lars-Peter Clausen6f306442011-09-05 20:46:32 +0200528 u8[0] |= map->read_flag_mask;
Mark Brownb83a3132011-05-11 19:59:58 +0200529
Mark Brownfb2736b2011-07-24 21:30:55 +0100530 trace_regmap_hw_read_start(map->dev, reg,
531 val_len / map->format.val_bytes);
532
Mark Brown82159ba2012-01-18 10:52:25 +0000533 ret = map->bus->read(map->dev, map->work_buf,
534 map->format.reg_bytes + map->format.pad_bytes,
Mark Brown40c5cc22011-07-24 22:39:12 +0100535 val, val_len);
Mark Brownb83a3132011-05-11 19:59:58 +0200536
Mark Brownfb2736b2011-07-24 21:30:55 +0100537 trace_regmap_hw_read_done(map->dev, reg,
538 val_len / map->format.val_bytes);
539
540 return ret;
Mark Brownb83a3132011-05-11 19:59:58 +0200541}
542
543static int _regmap_read(struct regmap *map, unsigned int reg,
544 unsigned int *val)
545{
546 int ret;
547
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100548 if (!map->cache_bypass) {
549 ret = regcache_read(map, reg, val);
550 if (ret == 0)
551 return 0;
552 }
553
Lars-Peter Clausen19254412011-11-16 16:28:19 +0100554 if (!map->format.parse_val)
555 return -EINVAL;
556
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100557 if (map->cache_only)
558 return -EBUSY;
559
Mark Brownb83a3132011-05-11 19:59:58 +0200560 ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes);
Mark Brownfb2736b2011-07-24 21:30:55 +0100561 if (ret == 0) {
Mark Brownb83a3132011-05-11 19:59:58 +0200562 *val = map->format.parse_val(map->work_buf);
Mark Brownfb2736b2011-07-24 21:30:55 +0100563 trace_regmap_reg_read(map->dev, reg, *val);
564 }
Mark Brownb83a3132011-05-11 19:59:58 +0200565
566 return ret;
567}
568
569/**
570 * regmap_read(): Read a value from a single register
571 *
572 * @map: Register map to write to
573 * @reg: Register to be read from
574 * @val: Pointer to store read value
575 *
576 * A value of zero will be returned on success, a negative errno will
577 * be returned in error cases.
578 */
579int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
580{
581 int ret;
582
583 mutex_lock(&map->lock);
584
585 ret = _regmap_read(map, reg, val);
586
587 mutex_unlock(&map->lock);
588
589 return ret;
590}
591EXPORT_SYMBOL_GPL(regmap_read);
592
593/**
594 * regmap_raw_read(): Read raw data from the device
595 *
596 * @map: Register map to write to
597 * @reg: First register to be read from
598 * @val: Pointer to store read value
599 * @val_len: Size of data to read
600 *
601 * A value of zero will be returned on success, a negative errno will
602 * be returned in error cases.
603 */
604int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
605 size_t val_len)
606{
Lars-Peter Clausen82cd9962011-11-08 18:37:25 +0100607 size_t val_count = val_len / map->format.val_bytes;
Mark Brownb83a3132011-05-11 19:59:58 +0200608 int ret;
609
Lars-Peter Clausen82cd9962011-11-08 18:37:25 +0100610 WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
611 map->cache_type != REGCACHE_NONE);
Mark Brown04e016a2011-10-09 13:35:43 +0100612
Mark Brownb83a3132011-05-11 19:59:58 +0200613 mutex_lock(&map->lock);
614
615 ret = _regmap_raw_read(map, reg, val, val_len);
616
617 mutex_unlock(&map->lock);
618
619 return ret;
620}
621EXPORT_SYMBOL_GPL(regmap_raw_read);
622
623/**
624 * regmap_bulk_read(): Read multiple registers from the device
625 *
626 * @map: Register map to write to
627 * @reg: First register to be read from
628 * @val: Pointer to store read value, in native register size for device
629 * @val_count: Number of registers to read
630 *
631 * A value of zero will be returned on success, a negative errno will
632 * be returned in error cases.
633 */
634int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
635 size_t val_count)
636{
637 int ret, i;
638 size_t val_bytes = map->format.val_bytes;
Lars-Peter Clausen82cd9962011-11-08 18:37:25 +0100639 bool vol = regmap_volatile_range(map, reg, val_count);
Dimitris Papastamos5d1729e2011-09-19 14:34:05 +0100640
Mark Brownb83a3132011-05-11 19:59:58 +0200641 if (!map->format.parse_val)
642 return -EINVAL;
643
Mark Brownde2d8082011-10-10 13:24:52 +0100644 if (vol || map->cache_type == REGCACHE_NONE) {
645 ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
646 if (ret != 0)
647 return ret;
648
649 for (i = 0; i < val_count * val_bytes; i += val_bytes)
650 map->format.parse_val(val + i);
651 } else {
652 for (i = 0; i < val_count; i++) {
653 ret = regmap_read(map, reg + i, val + (i * val_bytes));
654 if (ret != 0)
655 return ret;
656 }
657 }
Mark Brownb83a3132011-05-11 19:59:58 +0200658
659 return 0;
660}
661EXPORT_SYMBOL_GPL(regmap_bulk_read);
662
Mark Brown018690d2011-11-29 20:10:36 +0000663static int _regmap_update_bits(struct regmap *map, unsigned int reg,
664 unsigned int mask, unsigned int val,
665 bool *change)
Mark Brownb83a3132011-05-11 19:59:58 +0200666{
667 int ret;
Mark Brownd91e8db2011-11-18 16:03:50 +0000668 unsigned int tmp, orig;
Mark Brownb83a3132011-05-11 19:59:58 +0200669
670 mutex_lock(&map->lock);
671
Mark Brownd91e8db2011-11-18 16:03:50 +0000672 ret = _regmap_read(map, reg, &orig);
Mark Brownb83a3132011-05-11 19:59:58 +0200673 if (ret != 0)
674 goto out;
675
Mark Brownd91e8db2011-11-18 16:03:50 +0000676 tmp = orig & ~mask;
Mark Brownb83a3132011-05-11 19:59:58 +0200677 tmp |= val & mask;
678
Mark Brown018690d2011-11-29 20:10:36 +0000679 if (tmp != orig) {
Mark Brownd91e8db2011-11-18 16:03:50 +0000680 ret = _regmap_write(map, reg, tmp);
Mark Brown018690d2011-11-29 20:10:36 +0000681 *change = true;
682 } else {
683 *change = false;
684 }
Mark Brownb83a3132011-05-11 19:59:58 +0200685
686out:
687 mutex_unlock(&map->lock);
688
689 return ret;
690}
Mark Brown018690d2011-11-29 20:10:36 +0000691
692/**
693 * regmap_update_bits: Perform a read/modify/write cycle on the register map
694 *
695 * @map: Register map to update
696 * @reg: Register to update
697 * @mask: Bitmask to change
698 * @val: New value for bitmask
699 *
700 * Returns zero for success, a negative number on error.
701 */
702int regmap_update_bits(struct regmap *map, unsigned int reg,
703 unsigned int mask, unsigned int val)
704{
705 bool change;
706 return _regmap_update_bits(map, reg, mask, val, &change);
707}
Mark Brownb83a3132011-05-11 19:59:58 +0200708EXPORT_SYMBOL_GPL(regmap_update_bits);
Mark Brown31244e32011-07-20 22:56:53 +0100709
Mark Brown018690d2011-11-29 20:10:36 +0000710/**
711 * regmap_update_bits_check: Perform a read/modify/write cycle on the
712 * register map and report if updated
713 *
714 * @map: Register map to update
715 * @reg: Register to update
716 * @mask: Bitmask to change
717 * @val: New value for bitmask
718 * @change: Boolean indicating if a write was done
719 *
720 * Returns zero for success, a negative number on error.
721 */
722int regmap_update_bits_check(struct regmap *map, unsigned int reg,
723 unsigned int mask, unsigned int val,
724 bool *change)
725{
726 return _regmap_update_bits(map, reg, mask, val, change);
727}
728EXPORT_SYMBOL_GPL(regmap_update_bits_check);
729
Mark Brown31244e32011-07-20 22:56:53 +0100730static int __init regmap_initcall(void)
731{
732 regmap_debugfs_initcall();
733
734 return 0;
735}
736postcore_initcall(regmap_initcall);