.. | .. |
---|
1 | | -/* |
---|
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 | | - */ |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
| 2 | +// |
---|
| 3 | +// Register map access API |
---|
| 4 | +// |
---|
| 5 | +// Copyright 2011 Wolfson Microelectronics plc |
---|
| 6 | +// |
---|
| 7 | +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
---|
12 | 8 | |
---|
13 | 9 | #include <linux/device.h> |
---|
14 | 10 | #include <linux/slab.h> |
---|
15 | 11 | #include <linux/export.h> |
---|
16 | 12 | #include <linux/mutex.h> |
---|
17 | 13 | #include <linux/err.h> |
---|
18 | | -#include <linux/of.h> |
---|
| 14 | +#include <linux/property.h> |
---|
19 | 15 | #include <linux/rbtree.h> |
---|
20 | 16 | #include <linux/sched.h> |
---|
21 | 17 | #include <linux/delay.h> |
---|
.. | .. |
---|
35 | 31 | * register I/O on a specific device. |
---|
36 | 32 | */ |
---|
37 | 33 | #undef LOG_DEVICE |
---|
| 34 | + |
---|
| 35 | +#ifdef LOG_DEVICE |
---|
| 36 | +static inline bool regmap_should_log(struct regmap *map) |
---|
| 37 | +{ |
---|
| 38 | + return (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0); |
---|
| 39 | +} |
---|
| 40 | +#else |
---|
| 41 | +static inline bool regmap_should_log(struct regmap *map) { return false; } |
---|
| 42 | +#endif |
---|
| 43 | + |
---|
38 | 44 | |
---|
39 | 45 | static int _regmap_update_bits(struct regmap *map, unsigned int reg, |
---|
40 | 46 | unsigned int mask, unsigned int val, |
---|
.. | .. |
---|
169 | 175 | return false; |
---|
170 | 176 | } |
---|
171 | 177 | |
---|
| 178 | +bool regmap_writeable_noinc(struct regmap *map, unsigned int reg) |
---|
| 179 | +{ |
---|
| 180 | + if (map->writeable_noinc_reg) |
---|
| 181 | + return map->writeable_noinc_reg(map->dev, reg); |
---|
| 182 | + |
---|
| 183 | + if (map->wr_noinc_table) |
---|
| 184 | + return regmap_check_range_table(map, reg, map->wr_noinc_table); |
---|
| 185 | + |
---|
| 186 | + return true; |
---|
| 187 | +} |
---|
| 188 | + |
---|
172 | 189 | bool regmap_readable_noinc(struct regmap *map, unsigned int reg) |
---|
173 | 190 | { |
---|
174 | 191 | if (map->readable_noinc_reg) |
---|
.. | .. |
---|
191 | 208 | |
---|
192 | 209 | return true; |
---|
193 | 210 | } |
---|
| 211 | + |
---|
| 212 | +static void regmap_format_12_20_write(struct regmap *map, |
---|
| 213 | + unsigned int reg, unsigned int val) |
---|
| 214 | +{ |
---|
| 215 | + u8 *out = map->work_buf; |
---|
| 216 | + |
---|
| 217 | + out[0] = reg >> 4; |
---|
| 218 | + out[1] = (reg << 4) | (val >> 16); |
---|
| 219 | + out[2] = val >> 8; |
---|
| 220 | + out[3] = val; |
---|
| 221 | +} |
---|
| 222 | + |
---|
194 | 223 | |
---|
195 | 224 | static void regmap_format_2_6_write(struct regmap *map, |
---|
196 | 225 | unsigned int reg, unsigned int val) |
---|
.. | .. |
---|
564 | 593 | kfree(map->selector_work_buf); |
---|
565 | 594 | } |
---|
566 | 595 | |
---|
| 596 | +static int regmap_set_name(struct regmap *map, const struct regmap_config *config) |
---|
| 597 | +{ |
---|
| 598 | + if (config->name) { |
---|
| 599 | + const char *name = kstrdup_const(config->name, GFP_KERNEL); |
---|
| 600 | + |
---|
| 601 | + if (!name) |
---|
| 602 | + return -ENOMEM; |
---|
| 603 | + |
---|
| 604 | + kfree_const(map->name); |
---|
| 605 | + map->name = name; |
---|
| 606 | + } |
---|
| 607 | + |
---|
| 608 | + return 0; |
---|
| 609 | +} |
---|
| 610 | + |
---|
567 | 611 | int regmap_attach_dev(struct device *dev, struct regmap *map, |
---|
568 | 612 | const struct regmap_config *config) |
---|
569 | 613 | { |
---|
570 | 614 | struct regmap **m; |
---|
| 615 | + int ret; |
---|
571 | 616 | |
---|
572 | 617 | map->dev = dev; |
---|
573 | 618 | |
---|
574 | | - regmap_debugfs_init(map, config->name); |
---|
| 619 | + ret = regmap_set_name(map, config); |
---|
| 620 | + if (ret) |
---|
| 621 | + return ret; |
---|
| 622 | + |
---|
| 623 | + regmap_debugfs_exit(map); |
---|
| 624 | + regmap_debugfs_init(map); |
---|
575 | 625 | |
---|
576 | 626 | /* Add a devres resource for dev_get_regmap() */ |
---|
577 | 627 | m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); |
---|
.. | .. |
---|
614 | 664 | const struct regmap_bus *bus, |
---|
615 | 665 | const struct regmap_config *config) |
---|
616 | 666 | { |
---|
617 | | - struct device_node *np; |
---|
| 667 | + struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL; |
---|
618 | 668 | enum regmap_endian endian; |
---|
619 | 669 | |
---|
620 | 670 | /* Retrieve the endianness specification from the regmap config */ |
---|
.. | .. |
---|
624 | 674 | if (endian != REGMAP_ENDIAN_DEFAULT) |
---|
625 | 675 | return endian; |
---|
626 | 676 | |
---|
627 | | - /* If the dev and dev->of_node exist try to get endianness from DT */ |
---|
628 | | - if (dev && dev->of_node) { |
---|
629 | | - np = dev->of_node; |
---|
| 677 | + /* If the firmware node exist try to get endianness from it */ |
---|
| 678 | + if (fwnode_property_read_bool(fwnode, "big-endian")) |
---|
| 679 | + endian = REGMAP_ENDIAN_BIG; |
---|
| 680 | + else if (fwnode_property_read_bool(fwnode, "little-endian")) |
---|
| 681 | + endian = REGMAP_ENDIAN_LITTLE; |
---|
| 682 | + else if (fwnode_property_read_bool(fwnode, "native-endian")) |
---|
| 683 | + endian = REGMAP_ENDIAN_NATIVE; |
---|
630 | 684 | |
---|
631 | | - /* Parse the device's DT node for an endianness specification */ |
---|
632 | | - if (of_property_read_bool(np, "big-endian")) |
---|
633 | | - endian = REGMAP_ENDIAN_BIG; |
---|
634 | | - else if (of_property_read_bool(np, "little-endian")) |
---|
635 | | - endian = REGMAP_ENDIAN_LITTLE; |
---|
636 | | - else if (of_property_read_bool(np, "native-endian")) |
---|
637 | | - endian = REGMAP_ENDIAN_NATIVE; |
---|
638 | | - |
---|
639 | | - /* If the endianness was specified in DT, use that */ |
---|
640 | | - if (endian != REGMAP_ENDIAN_DEFAULT) |
---|
641 | | - return endian; |
---|
642 | | - } |
---|
| 685 | + /* If the endianness was specified in fwnode, use that */ |
---|
| 686 | + if (endian != REGMAP_ENDIAN_DEFAULT) |
---|
| 687 | + return endian; |
---|
643 | 688 | |
---|
644 | 689 | /* Retrieve the endianness specification from the bus config */ |
---|
645 | 690 | if (bus && bus->val_format_endian_default) |
---|
.. | .. |
---|
675 | 720 | goto err; |
---|
676 | 721 | } |
---|
677 | 722 | |
---|
678 | | - if (config->name) { |
---|
679 | | - map->name = kstrdup_const(config->name, GFP_KERNEL); |
---|
680 | | - if (!map->name) { |
---|
681 | | - ret = -ENOMEM; |
---|
682 | | - goto err_map; |
---|
683 | | - } |
---|
684 | | - } |
---|
| 723 | + ret = regmap_set_name(map, config); |
---|
| 724 | + if (ret) |
---|
| 725 | + goto err_map; |
---|
| 726 | + |
---|
| 727 | + ret = -EINVAL; /* Later error paths rely on this */ |
---|
685 | 728 | |
---|
686 | 729 | if (config->disable_locking) { |
---|
687 | 730 | map->lock = map->unlock = regmap_lock_unlock_none; |
---|
| 731 | + map->can_sleep = config->can_sleep; |
---|
688 | 732 | regmap_debugfs_disable(map); |
---|
689 | 733 | } else if (config->lock && config->unlock) { |
---|
690 | 734 | map->lock = config->lock; |
---|
691 | 735 | map->unlock = config->unlock; |
---|
692 | 736 | map->lock_arg = config->lock_arg; |
---|
| 737 | + map->can_sleep = config->can_sleep; |
---|
693 | 738 | } else if (config->use_hwlock) { |
---|
694 | 739 | map->hwlock = hwspin_lock_request_specific(config->hwlock_id); |
---|
695 | 740 | if (!map->hwlock) { |
---|
.. | .. |
---|
725 | 770 | mutex_init(&map->mutex); |
---|
726 | 771 | map->lock = regmap_lock_mutex; |
---|
727 | 772 | map->unlock = regmap_unlock_mutex; |
---|
| 773 | + map->can_sleep = true; |
---|
728 | 774 | lockdep_set_class_and_name(&map->mutex, |
---|
729 | 775 | lock_key, lock_name); |
---|
730 | 776 | } |
---|
.. | .. |
---|
754 | 800 | map->reg_stride_order = ilog2(map->reg_stride); |
---|
755 | 801 | else |
---|
756 | 802 | map->reg_stride_order = -1; |
---|
757 | | - map->use_single_read = config->use_single_rw || !bus || !bus->read; |
---|
758 | | - map->use_single_write = config->use_single_rw || !bus || !bus->write; |
---|
| 803 | + map->use_single_read = config->use_single_read || !bus || !bus->read; |
---|
| 804 | + map->use_single_write = config->use_single_write || !bus || !bus->write; |
---|
759 | 805 | map->can_multi_write = config->can_multi_write && bus && bus->write; |
---|
760 | 806 | if (bus) { |
---|
761 | 807 | map->max_raw_read = bus->max_raw_read; |
---|
.. | .. |
---|
769 | 815 | map->rd_table = config->rd_table; |
---|
770 | 816 | map->volatile_table = config->volatile_table; |
---|
771 | 817 | map->precious_table = config->precious_table; |
---|
| 818 | + map->wr_noinc_table = config->wr_noinc_table; |
---|
772 | 819 | map->rd_noinc_table = config->rd_noinc_table; |
---|
773 | 820 | map->writeable_reg = config->writeable_reg; |
---|
774 | 821 | map->readable_reg = config->readable_reg; |
---|
775 | 822 | map->volatile_reg = config->volatile_reg; |
---|
776 | 823 | map->precious_reg = config->precious_reg; |
---|
| 824 | + map->writeable_noinc_reg = config->writeable_noinc_reg; |
---|
777 | 825 | map->readable_noinc_reg = config->readable_noinc_reg; |
---|
778 | 826 | map->cache_type = config->cache_type; |
---|
779 | 827 | |
---|
.. | .. |
---|
800 | 848 | } else if (!bus->read || !bus->write) { |
---|
801 | 849 | map->reg_read = _regmap_bus_reg_read; |
---|
802 | 850 | map->reg_write = _regmap_bus_reg_write; |
---|
| 851 | + map->reg_update_bits = bus->reg_update_bits; |
---|
803 | 852 | |
---|
804 | 853 | map->defer_caching = false; |
---|
805 | 854 | goto skip_format_initialization; |
---|
.. | .. |
---|
846 | 895 | switch (config->val_bits) { |
---|
847 | 896 | case 14: |
---|
848 | 897 | map->format.format_write = regmap_format_10_14_write; |
---|
| 898 | + break; |
---|
| 899 | + default: |
---|
| 900 | + goto err_hwlock; |
---|
| 901 | + } |
---|
| 902 | + break; |
---|
| 903 | + |
---|
| 904 | + case 12: |
---|
| 905 | + switch (config->val_bits) { |
---|
| 906 | + case 20: |
---|
| 907 | + map->format.format_write = regmap_format_12_20_write; |
---|
849 | 908 | break; |
---|
850 | 909 | default: |
---|
851 | 910 | goto err_hwlock; |
---|
.. | .. |
---|
1122 | 1181 | if (ret != 0) |
---|
1123 | 1182 | goto err_regcache; |
---|
1124 | 1183 | } else { |
---|
1125 | | - regmap_debugfs_init(map, config->name); |
---|
| 1184 | + regmap_debugfs_init(map); |
---|
1126 | 1185 | } |
---|
1127 | 1186 | |
---|
1128 | 1187 | return map; |
---|
.. | .. |
---|
1212 | 1271 | } |
---|
1213 | 1272 | EXPORT_SYMBOL_GPL(devm_regmap_field_alloc); |
---|
1214 | 1273 | |
---|
| 1274 | + |
---|
| 1275 | +/** |
---|
| 1276 | + * regmap_field_bulk_alloc() - Allocate and initialise a bulk register field. |
---|
| 1277 | + * |
---|
| 1278 | + * @regmap: regmap bank in which this register field is located. |
---|
| 1279 | + * @rm_field: regmap register fields within the bank. |
---|
| 1280 | + * @reg_field: Register fields within the bank. |
---|
| 1281 | + * @num_fields: Number of register fields. |
---|
| 1282 | + * |
---|
| 1283 | + * The return value will be an -ENOMEM on error or zero for success. |
---|
| 1284 | + * Newly allocated regmap_fields should be freed by calling |
---|
| 1285 | + * regmap_field_bulk_free() |
---|
| 1286 | + */ |
---|
| 1287 | +int regmap_field_bulk_alloc(struct regmap *regmap, |
---|
| 1288 | + struct regmap_field **rm_field, |
---|
| 1289 | + struct reg_field *reg_field, |
---|
| 1290 | + int num_fields) |
---|
| 1291 | +{ |
---|
| 1292 | + struct regmap_field *rf; |
---|
| 1293 | + int i; |
---|
| 1294 | + |
---|
| 1295 | + rf = kcalloc(num_fields, sizeof(*rf), GFP_KERNEL); |
---|
| 1296 | + if (!rf) |
---|
| 1297 | + return -ENOMEM; |
---|
| 1298 | + |
---|
| 1299 | + for (i = 0; i < num_fields; i++) { |
---|
| 1300 | + regmap_field_init(&rf[i], regmap, reg_field[i]); |
---|
| 1301 | + rm_field[i] = &rf[i]; |
---|
| 1302 | + } |
---|
| 1303 | + |
---|
| 1304 | + return 0; |
---|
| 1305 | +} |
---|
| 1306 | +EXPORT_SYMBOL_GPL(regmap_field_bulk_alloc); |
---|
| 1307 | + |
---|
| 1308 | +/** |
---|
| 1309 | + * devm_regmap_field_bulk_alloc() - Allocate and initialise a bulk register |
---|
| 1310 | + * fields. |
---|
| 1311 | + * |
---|
| 1312 | + * @dev: Device that will be interacted with |
---|
| 1313 | + * @regmap: regmap bank in which this register field is located. |
---|
| 1314 | + * @rm_field: regmap register fields within the bank. |
---|
| 1315 | + * @reg_field: Register fields within the bank. |
---|
| 1316 | + * @num_fields: Number of register fields. |
---|
| 1317 | + * |
---|
| 1318 | + * The return value will be an -ENOMEM on error or zero for success. |
---|
| 1319 | + * Newly allocated regmap_fields will be automatically freed by the |
---|
| 1320 | + * device management code. |
---|
| 1321 | + */ |
---|
| 1322 | +int devm_regmap_field_bulk_alloc(struct device *dev, |
---|
| 1323 | + struct regmap *regmap, |
---|
| 1324 | + struct regmap_field **rm_field, |
---|
| 1325 | + struct reg_field *reg_field, |
---|
| 1326 | + int num_fields) |
---|
| 1327 | +{ |
---|
| 1328 | + struct regmap_field *rf; |
---|
| 1329 | + int i; |
---|
| 1330 | + |
---|
| 1331 | + rf = devm_kcalloc(dev, num_fields, sizeof(*rf), GFP_KERNEL); |
---|
| 1332 | + if (!rf) |
---|
| 1333 | + return -ENOMEM; |
---|
| 1334 | + |
---|
| 1335 | + for (i = 0; i < num_fields; i++) { |
---|
| 1336 | + regmap_field_init(&rf[i], regmap, reg_field[i]); |
---|
| 1337 | + rm_field[i] = &rf[i]; |
---|
| 1338 | + } |
---|
| 1339 | + |
---|
| 1340 | + return 0; |
---|
| 1341 | +} |
---|
| 1342 | +EXPORT_SYMBOL_GPL(devm_regmap_field_bulk_alloc); |
---|
| 1343 | + |
---|
| 1344 | +/** |
---|
| 1345 | + * regmap_field_bulk_free() - Free register field allocated using |
---|
| 1346 | + * regmap_field_bulk_alloc. |
---|
| 1347 | + * |
---|
| 1348 | + * @field: regmap fields which should be freed. |
---|
| 1349 | + */ |
---|
| 1350 | +void regmap_field_bulk_free(struct regmap_field *field) |
---|
| 1351 | +{ |
---|
| 1352 | + kfree(field); |
---|
| 1353 | +} |
---|
| 1354 | +EXPORT_SYMBOL_GPL(regmap_field_bulk_free); |
---|
| 1355 | + |
---|
| 1356 | +/** |
---|
| 1357 | + * devm_regmap_field_bulk_free() - Free a bulk register field allocated using |
---|
| 1358 | + * devm_regmap_field_bulk_alloc. |
---|
| 1359 | + * |
---|
| 1360 | + * @dev: Device that will be interacted with |
---|
| 1361 | + * @field: regmap field which should be freed. |
---|
| 1362 | + * |
---|
| 1363 | + * Free register field allocated using devm_regmap_field_bulk_alloc(). Usually |
---|
| 1364 | + * drivers need not call this function, as the memory allocated via devm |
---|
| 1365 | + * will be freed as per device-driver life-cycle. |
---|
| 1366 | + */ |
---|
| 1367 | +void devm_regmap_field_bulk_free(struct device *dev, |
---|
| 1368 | + struct regmap_field *field) |
---|
| 1369 | +{ |
---|
| 1370 | + devm_kfree(dev, field); |
---|
| 1371 | +} |
---|
| 1372 | +EXPORT_SYMBOL_GPL(devm_regmap_field_bulk_free); |
---|
| 1373 | + |
---|
1215 | 1374 | /** |
---|
1216 | 1375 | * devm_regmap_field_free() - Free a register field allocated using |
---|
1217 | 1376 | * devm_regmap_field_alloc. |
---|
.. | .. |
---|
1282 | 1441 | */ |
---|
1283 | 1442 | int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) |
---|
1284 | 1443 | { |
---|
| 1444 | + int ret; |
---|
| 1445 | + |
---|
1285 | 1446 | regcache_exit(map); |
---|
1286 | 1447 | regmap_debugfs_exit(map); |
---|
1287 | 1448 | |
---|
.. | .. |
---|
1290 | 1451 | map->readable_reg = config->readable_reg; |
---|
1291 | 1452 | map->volatile_reg = config->volatile_reg; |
---|
1292 | 1453 | map->precious_reg = config->precious_reg; |
---|
| 1454 | + map->writeable_noinc_reg = config->writeable_noinc_reg; |
---|
1293 | 1455 | map->readable_noinc_reg = config->readable_noinc_reg; |
---|
1294 | 1456 | map->cache_type = config->cache_type; |
---|
1295 | 1457 | |
---|
1296 | | - regmap_debugfs_init(map, config->name); |
---|
| 1458 | + ret = regmap_set_name(map, config); |
---|
| 1459 | + if (ret) |
---|
| 1460 | + return ret; |
---|
| 1461 | + |
---|
| 1462 | + regmap_debugfs_init(map); |
---|
1297 | 1463 | |
---|
1298 | 1464 | map->cache_bypass = false; |
---|
1299 | 1465 | map->cache_only = false; |
---|
.. | .. |
---|
1327 | 1493 | } |
---|
1328 | 1494 | if (map->hwlock) |
---|
1329 | 1495 | hwspin_lock_free(map->hwlock); |
---|
| 1496 | + if (map->lock == regmap_lock_mutex) |
---|
| 1497 | + mutex_destroy(&map->mutex); |
---|
1330 | 1498 | kfree_const(map->name); |
---|
1331 | 1499 | kfree(map->patch); |
---|
1332 | 1500 | kfree(map); |
---|
.. | .. |
---|
1448 | 1616 | } |
---|
1449 | 1617 | |
---|
1450 | 1618 | static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, |
---|
1451 | | - const void *val, size_t val_len) |
---|
| 1619 | + const void *val, size_t val_len, bool noinc) |
---|
1452 | 1620 | { |
---|
1453 | 1621 | struct regmap_range_node *range; |
---|
1454 | 1622 | unsigned long flags; |
---|
.. | .. |
---|
1461 | 1629 | |
---|
1462 | 1630 | WARN_ON(!map->bus); |
---|
1463 | 1631 | |
---|
1464 | | - /* Check for unwritable registers before we start */ |
---|
1465 | | - if (map->writeable_reg) |
---|
1466 | | - for (i = 0; i < val_len / map->format.val_bytes; i++) |
---|
1467 | | - if (!map->writeable_reg(map->dev, |
---|
1468 | | - reg + regmap_get_offset(map, i))) |
---|
| 1632 | + /* Check for unwritable or noinc registers in range |
---|
| 1633 | + * before we start |
---|
| 1634 | + */ |
---|
| 1635 | + if (!regmap_writeable_noinc(map, reg)) { |
---|
| 1636 | + for (i = 0; i < val_len / map->format.val_bytes; i++) { |
---|
| 1637 | + unsigned int element = |
---|
| 1638 | + reg + regmap_get_offset(map, i); |
---|
| 1639 | + if (!regmap_writeable(map, element) || |
---|
| 1640 | + regmap_writeable_noinc(map, element)) |
---|
1469 | 1641 | return -EINVAL; |
---|
| 1642 | + } |
---|
| 1643 | + } |
---|
1470 | 1644 | |
---|
1471 | 1645 | if (!map->cache_bypass && map->format.parse_val) { |
---|
1472 | 1646 | unsigned int ival; |
---|
.. | .. |
---|
1501 | 1675 | win_residue, val_len / map->format.val_bytes); |
---|
1502 | 1676 | ret = _regmap_raw_write_impl(map, reg, val, |
---|
1503 | 1677 | win_residue * |
---|
1504 | | - map->format.val_bytes); |
---|
| 1678 | + map->format.val_bytes, noinc); |
---|
1505 | 1679 | if (ret != 0) |
---|
1506 | 1680 | return ret; |
---|
1507 | 1681 | |
---|
.. | .. |
---|
1515 | 1689 | win_residue = range->window_len - win_offset; |
---|
1516 | 1690 | } |
---|
1517 | 1691 | |
---|
1518 | | - ret = _regmap_select_page(map, ®, range, val_num); |
---|
| 1692 | + ret = _regmap_select_page(map, ®, range, noinc ? 1 : val_num); |
---|
1519 | 1693 | if (ret != 0) |
---|
1520 | 1694 | return ret; |
---|
1521 | 1695 | } |
---|
.. | .. |
---|
1723 | 1897 | map->work_buf + |
---|
1724 | 1898 | map->format.reg_bytes + |
---|
1725 | 1899 | map->format.pad_bytes, |
---|
1726 | | - map->format.val_bytes); |
---|
| 1900 | + map->format.val_bytes, |
---|
| 1901 | + false); |
---|
1727 | 1902 | } |
---|
1728 | 1903 | |
---|
1729 | 1904 | static inline void *_regmap_map_get_context(struct regmap *map) |
---|
.. | .. |
---|
1750 | 1925 | } |
---|
1751 | 1926 | } |
---|
1752 | 1927 | |
---|
1753 | | -#ifdef LOG_DEVICE |
---|
1754 | | - if (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0) |
---|
| 1928 | + if (regmap_should_log(map)) |
---|
1755 | 1929 | dev_info(map->dev, "%x <= %x\n", reg, val); |
---|
1756 | | -#endif |
---|
1757 | 1930 | |
---|
1758 | 1931 | trace_regmap_reg_write(map, reg, val); |
---|
1759 | 1932 | |
---|
.. | .. |
---|
1819 | 1992 | EXPORT_SYMBOL_GPL(regmap_write_async); |
---|
1820 | 1993 | |
---|
1821 | 1994 | int _regmap_raw_write(struct regmap *map, unsigned int reg, |
---|
1822 | | - const void *val, size_t val_len) |
---|
| 1995 | + const void *val, size_t val_len, bool noinc) |
---|
1823 | 1996 | { |
---|
1824 | 1997 | size_t val_bytes = map->format.val_bytes; |
---|
1825 | 1998 | size_t val_count = val_len / val_bytes; |
---|
.. | .. |
---|
1840 | 2013 | |
---|
1841 | 2014 | /* Write as many bytes as possible with chunk_size */ |
---|
1842 | 2015 | for (i = 0; i < chunk_count; i++) { |
---|
1843 | | - ret = _regmap_raw_write_impl(map, reg, val, chunk_bytes); |
---|
| 2016 | + ret = _regmap_raw_write_impl(map, reg, val, chunk_bytes, noinc); |
---|
1844 | 2017 | if (ret) |
---|
1845 | 2018 | return ret; |
---|
1846 | 2019 | |
---|
.. | .. |
---|
1851 | 2024 | |
---|
1852 | 2025 | /* Write remaining bytes */ |
---|
1853 | 2026 | if (val_len) |
---|
1854 | | - ret = _regmap_raw_write_impl(map, reg, val, val_len); |
---|
| 2027 | + ret = _regmap_raw_write_impl(map, reg, val, val_len, noinc); |
---|
1855 | 2028 | |
---|
1856 | 2029 | return ret; |
---|
1857 | 2030 | } |
---|
.. | .. |
---|
1884 | 2057 | |
---|
1885 | 2058 | map->lock(map->lock_arg); |
---|
1886 | 2059 | |
---|
1887 | | - ret = _regmap_raw_write(map, reg, val, val_len); |
---|
| 2060 | + ret = _regmap_raw_write(map, reg, val, val_len, false); |
---|
1888 | 2061 | |
---|
1889 | 2062 | map->unlock(map->lock_arg); |
---|
1890 | 2063 | |
---|
1891 | 2064 | return ret; |
---|
1892 | 2065 | } |
---|
1893 | 2066 | EXPORT_SYMBOL_GPL(regmap_raw_write); |
---|
| 2067 | + |
---|
| 2068 | +/** |
---|
| 2069 | + * regmap_noinc_write(): Write data from a register without incrementing the |
---|
| 2070 | + * register number |
---|
| 2071 | + * |
---|
| 2072 | + * @map: Register map to write to |
---|
| 2073 | + * @reg: Register to write to |
---|
| 2074 | + * @val: Pointer to data buffer |
---|
| 2075 | + * @val_len: Length of output buffer in bytes. |
---|
| 2076 | + * |
---|
| 2077 | + * The regmap API usually assumes that bulk bus write operations will write a |
---|
| 2078 | + * range of registers. Some devices have certain registers for which a write |
---|
| 2079 | + * operation can write to an internal FIFO. |
---|
| 2080 | + * |
---|
| 2081 | + * The target register must be volatile but registers after it can be |
---|
| 2082 | + * completely unrelated cacheable registers. |
---|
| 2083 | + * |
---|
| 2084 | + * This will attempt multiple writes as required to write val_len bytes. |
---|
| 2085 | + * |
---|
| 2086 | + * A value of zero will be returned on success, a negative errno will be |
---|
| 2087 | + * returned in error cases. |
---|
| 2088 | + */ |
---|
| 2089 | +int regmap_noinc_write(struct regmap *map, unsigned int reg, |
---|
| 2090 | + const void *val, size_t val_len) |
---|
| 2091 | +{ |
---|
| 2092 | + size_t write_len; |
---|
| 2093 | + int ret; |
---|
| 2094 | + |
---|
| 2095 | + if (!map->bus) |
---|
| 2096 | + return -EINVAL; |
---|
| 2097 | + if (!map->bus->write) |
---|
| 2098 | + return -ENOTSUPP; |
---|
| 2099 | + if (val_len % map->format.val_bytes) |
---|
| 2100 | + return -EINVAL; |
---|
| 2101 | + if (!IS_ALIGNED(reg, map->reg_stride)) |
---|
| 2102 | + return -EINVAL; |
---|
| 2103 | + if (val_len == 0) |
---|
| 2104 | + return -EINVAL; |
---|
| 2105 | + |
---|
| 2106 | + map->lock(map->lock_arg); |
---|
| 2107 | + |
---|
| 2108 | + if (!regmap_volatile(map, reg) || !regmap_writeable_noinc(map, reg)) { |
---|
| 2109 | + ret = -EINVAL; |
---|
| 2110 | + goto out_unlock; |
---|
| 2111 | + } |
---|
| 2112 | + |
---|
| 2113 | + while (val_len) { |
---|
| 2114 | + if (map->max_raw_write && map->max_raw_write < val_len) |
---|
| 2115 | + write_len = map->max_raw_write; |
---|
| 2116 | + else |
---|
| 2117 | + write_len = val_len; |
---|
| 2118 | + ret = _regmap_raw_write(map, reg, val, write_len, true); |
---|
| 2119 | + if (ret) |
---|
| 2120 | + goto out_unlock; |
---|
| 2121 | + val = ((u8 *)val) + write_len; |
---|
| 2122 | + val_len -= write_len; |
---|
| 2123 | + } |
---|
| 2124 | + |
---|
| 2125 | +out_unlock: |
---|
| 2126 | + map->unlock(map->lock_arg); |
---|
| 2127 | + return ret; |
---|
| 2128 | +} |
---|
| 2129 | +EXPORT_SYMBOL_GPL(regmap_noinc_write); |
---|
1894 | 2130 | |
---|
1895 | 2131 | /** |
---|
1896 | 2132 | * regmap_field_update_bits_base() - Perform a read/modify/write cycle a |
---|
.. | .. |
---|
1936 | 2172 | * A value of zero will be returned on success, a negative errno will |
---|
1937 | 2173 | * be returned in error cases. |
---|
1938 | 2174 | */ |
---|
1939 | | -int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id, |
---|
| 2175 | +int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id, |
---|
1940 | 2176 | unsigned int mask, unsigned int val, |
---|
1941 | 2177 | bool *change, bool async, bool force) |
---|
1942 | 2178 | { |
---|
.. | .. |
---|
2147 | 2383 | if (ret != 0) |
---|
2148 | 2384 | return ret; |
---|
2149 | 2385 | |
---|
2150 | | - if (regs[i].delay_us) |
---|
2151 | | - udelay(regs[i].delay_us); |
---|
| 2386 | + if (regs[i].delay_us) { |
---|
| 2387 | + if (map->can_sleep) |
---|
| 2388 | + fsleep(regs[i].delay_us); |
---|
| 2389 | + else |
---|
| 2390 | + udelay(regs[i].delay_us); |
---|
| 2391 | + } |
---|
2152 | 2392 | |
---|
2153 | 2393 | base += n; |
---|
2154 | 2394 | n = 0; |
---|
.. | .. |
---|
2184 | 2424 | if (ret != 0) |
---|
2185 | 2425 | return ret; |
---|
2186 | 2426 | |
---|
2187 | | - if (regs[i].delay_us) |
---|
2188 | | - udelay(regs[i].delay_us); |
---|
| 2427 | + if (regs[i].delay_us) { |
---|
| 2428 | + if (map->can_sleep) |
---|
| 2429 | + fsleep(regs[i].delay_us); |
---|
| 2430 | + else |
---|
| 2431 | + udelay(regs[i].delay_us); |
---|
| 2432 | + } |
---|
2189 | 2433 | } |
---|
2190 | 2434 | return 0; |
---|
2191 | 2435 | } |
---|
.. | .. |
---|
2356 | 2600 | |
---|
2357 | 2601 | map->async = true; |
---|
2358 | 2602 | |
---|
2359 | | - ret = _regmap_raw_write(map, reg, val, val_len); |
---|
| 2603 | + ret = _regmap_raw_write(map, reg, val, val_len, false); |
---|
2360 | 2604 | |
---|
2361 | 2605 | map->async = false; |
---|
2362 | 2606 | |
---|
.. | .. |
---|
2445 | 2689 | |
---|
2446 | 2690 | ret = map->reg_read(context, reg, val); |
---|
2447 | 2691 | if (ret == 0) { |
---|
2448 | | -#ifdef LOG_DEVICE |
---|
2449 | | - if (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0) |
---|
| 2692 | + if (regmap_should_log(map)) |
---|
2450 | 2693 | dev_info(map->dev, "%x => %x\n", reg, *val); |
---|
2451 | | -#endif |
---|
2452 | 2694 | |
---|
2453 | 2695 | trace_regmap_reg_read(map, reg, *val); |
---|
2454 | 2696 | |
---|
.. | .. |
---|
2844 | 3086 | } |
---|
2845 | 3087 | EXPORT_SYMBOL_GPL(regmap_update_bits_base); |
---|
2846 | 3088 | |
---|
| 3089 | +/** |
---|
| 3090 | + * regmap_test_bits() - Check if all specified bits are set in a register. |
---|
| 3091 | + * |
---|
| 3092 | + * @map: Register map to operate on |
---|
| 3093 | + * @reg: Register to read from |
---|
| 3094 | + * @bits: Bits to test |
---|
| 3095 | + * |
---|
| 3096 | + * Returns 0 if at least one of the tested bits is not set, 1 if all tested |
---|
| 3097 | + * bits are set and a negative error number if the underlying regmap_read() |
---|
| 3098 | + * fails. |
---|
| 3099 | + */ |
---|
| 3100 | +int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) |
---|
| 3101 | +{ |
---|
| 3102 | + unsigned int val, ret; |
---|
| 3103 | + |
---|
| 3104 | + ret = regmap_read(map, reg, &val); |
---|
| 3105 | + if (ret) |
---|
| 3106 | + return ret; |
---|
| 3107 | + |
---|
| 3108 | + return (val & bits) == bits; |
---|
| 3109 | +} |
---|
| 3110 | +EXPORT_SYMBOL_GPL(regmap_test_bits); |
---|
| 3111 | + |
---|
2847 | 3112 | void regmap_async_complete_cb(struct regmap_async *async, int ret) |
---|
2848 | 3113 | { |
---|
2849 | 3114 | struct regmap *map = async->map; |
---|