aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-06-30 07:40:03 -0400
committerMark Brown <broonie@linaro.org>2013-06-30 07:40:03 -0400
commit7bc8c4c37aea74332b16ffb5412a8ad355d508ce (patch)
treeca37bdf59d25c68fe97a3894184aba79c4f1aa87 /drivers/base
parentad4f496b445eac30bb6ddc72599bf6dd73529cd2 (diff)
parent539fde59ebc615bcb9af373af8947e866dc072c7 (diff)
Merge remote-tracking branch 'regmap/topic/field' into regmap-next
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h8
-rw-r--r--drivers/base/regmap/regmap.c130
2 files changed, 138 insertions, 0 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index ae23d8391aa0..29c83160ca29 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -176,6 +176,14 @@ struct regmap_range_node {
176 unsigned int window_len; 176 unsigned int window_len;
177}; 177};
178 178
179struct regmap_field {
180 struct regmap *regmap;
181 unsigned int mask;
182 /* lsb */
183 unsigned int shift;
184 unsigned int reg;
185};
186
179#ifdef CONFIG_DEBUG_FS 187#ifdef CONFIG_DEBUG_FS
180extern void regmap_debugfs_initcall(void); 188extern void regmap_debugfs_initcall(void);
181extern void regmap_debugfs_init(struct regmap *map, const char *name); 189extern void regmap_debugfs_init(struct regmap *map, const char *name);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ed152e3d2d88..95920583e31e 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -807,6 +807,95 @@ struct regmap *devm_regmap_init(struct device *dev,
807} 807}
808EXPORT_SYMBOL_GPL(devm_regmap_init); 808EXPORT_SYMBOL_GPL(devm_regmap_init);
809 809
810static void regmap_field_init(struct regmap_field *rm_field,
811 struct regmap *regmap, struct reg_field reg_field)
812{
813 int field_bits = reg_field.msb - reg_field.lsb + 1;
814 rm_field->regmap = regmap;
815 rm_field->reg = reg_field.reg;
816 rm_field->shift = reg_field.lsb;
817 rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
818}
819
820/**
821 * devm_regmap_field_alloc(): Allocate and initialise a register field
822 * in a register map.
823 *
824 * @dev: Device that will be interacted with
825 * @regmap: regmap bank in which this register field is located.
826 * @reg_field: Register field with in the bank.
827 *
828 * The return value will be an ERR_PTR() on error or a valid pointer
829 * to a struct regmap_field. The regmap_field will be automatically freed
830 * by the device management code.
831 */
832struct regmap_field *devm_regmap_field_alloc(struct device *dev,
833 struct regmap *regmap, struct reg_field reg_field)
834{
835 struct regmap_field *rm_field = devm_kzalloc(dev,
836 sizeof(*rm_field), GFP_KERNEL);
837 if (!rm_field)
838 return ERR_PTR(-ENOMEM);
839
840 regmap_field_init(rm_field, regmap, reg_field);
841
842 return rm_field;
843
844}
845EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
846
847/**
848 * devm_regmap_field_free(): Free register field allocated using
849 * devm_regmap_field_alloc. Usally drivers need not call this function,
850 * as the memory allocated via devm will be freed as per device-driver
851 * life-cyle.
852 *
853 * @dev: Device that will be interacted with
854 * @field: regmap field which should be freed.
855 */
856void devm_regmap_field_free(struct device *dev,
857 struct regmap_field *field)
858{
859 devm_kfree(dev, field);
860}
861EXPORT_SYMBOL_GPL(devm_regmap_field_free);
862
863/**
864 * regmap_field_alloc(): Allocate and initialise a register field
865 * in a register map.
866 *
867 * @regmap: regmap bank in which this register field is located.
868 * @reg_field: Register field with in the bank.
869 *
870 * The return value will be an ERR_PTR() on error or a valid pointer
871 * to a struct regmap_field. The regmap_field should be freed by the
872 * user once its finished working with it using regmap_field_free().
873 */
874struct regmap_field *regmap_field_alloc(struct regmap *regmap,
875 struct reg_field reg_field)
876{
877 struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
878
879 if (!rm_field)
880 return ERR_PTR(-ENOMEM);
881
882 regmap_field_init(rm_field, regmap, reg_field);
883
884 return rm_field;
885}
886EXPORT_SYMBOL_GPL(regmap_field_alloc);
887
888/**
889 * regmap_field_free(): Free register field allocated using regmap_field_alloc
890 *
891 * @field: regmap field which should be freed.
892 */
893void regmap_field_free(struct regmap_field *field)
894{
895 kfree(field);
896}
897EXPORT_SYMBOL_GPL(regmap_field_free);
898
810/** 899/**
811 * regmap_reinit_cache(): Reinitialise the current register cache 900 * regmap_reinit_cache(): Reinitialise the current register cache
812 * 901 *
@@ -1255,6 +1344,22 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
1255} 1344}
1256EXPORT_SYMBOL_GPL(regmap_raw_write); 1345EXPORT_SYMBOL_GPL(regmap_raw_write);
1257 1346
1347/**
1348 * regmap_field_write(): Write a value to a single register field
1349 *
1350 * @field: Register field to write to
1351 * @val: Value to be written
1352 *
1353 * A value of zero will be returned on success, a negative errno will
1354 * be returned in error cases.
1355 */
1356int regmap_field_write(struct regmap_field *field, unsigned int val)
1357{
1358 return regmap_update_bits(field->regmap, field->reg,
1359 field->mask, val << field->shift);
1360}
1361EXPORT_SYMBOL_GPL(regmap_field_write);
1362
1258/* 1363/*
1259 * regmap_bulk_write(): Write multiple registers to the device 1364 * regmap_bulk_write(): Write multiple registers to the device
1260 * 1365 *
@@ -1538,6 +1643,31 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
1538EXPORT_SYMBOL_GPL(regmap_raw_read); 1643EXPORT_SYMBOL_GPL(regmap_raw_read);
1539 1644
1540/** 1645/**
1646 * regmap_field_read(): Read a value to a single register field
1647 *
1648 * @field: Register field to read from
1649 * @val: Pointer to store read value
1650 *
1651 * A value of zero will be returned on success, a negative errno will
1652 * be returned in error cases.
1653 */
1654int regmap_field_read(struct regmap_field *field, unsigned int *val)
1655{
1656 int ret;
1657 unsigned int reg_val;
1658 ret = regmap_read(field->regmap, field->reg, &reg_val);
1659 if (ret != 0)
1660 return ret;
1661
1662 reg_val &= field->mask;
1663 reg_val >>= field->shift;
1664 *val = reg_val;
1665
1666 return ret;
1667}
1668EXPORT_SYMBOL_GPL(regmap_field_read);
1669
1670/**
1541 * regmap_bulk_read(): Read multiple registers from the device 1671 * regmap_bulk_read(): Read multiple registers from the device
1542 * 1672 *
1543 * @map: Register map to write to 1673 * @map: Register map to write to