|
@@ -801,6 +801,95 @@ struct regmap *devm_regmap_init(struct device *dev,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(devm_regmap_init);
|
|
|
|
|
|
+static void regmap_field_init(struct regmap_field *rm_field,
|
|
|
+ struct regmap *regmap, struct reg_field reg_field)
|
|
|
+{
|
|
|
+ int field_bits = reg_field.msb - reg_field.lsb + 1;
|
|
|
+ rm_field->regmap = regmap;
|
|
|
+ rm_field->reg = reg_field.reg;
|
|
|
+ rm_field->shift = reg_field.lsb;
|
|
|
+ rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_field_alloc(): Allocate and initialise a register field
|
|
|
+ * in a register map.
|
|
|
+ *
|
|
|
+ * @dev: Device that will be interacted with
|
|
|
+ * @regmap: regmap bank in which this register field is located.
|
|
|
+ * @reg_field: Register field with in the bank.
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap_field. The regmap_field will be automatically freed
|
|
|
+ * by the device management code.
|
|
|
+ */
|
|
|
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
|
|
|
+ struct regmap *regmap, struct reg_field reg_field)
|
|
|
+{
|
|
|
+ struct regmap_field *rm_field = devm_kzalloc(dev,
|
|
|
+ sizeof(*rm_field), GFP_KERNEL);
|
|
|
+ if (!rm_field)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ regmap_field_init(rm_field, regmap, reg_field);
|
|
|
+
|
|
|
+ return rm_field;
|
|
|
+
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_field_free(): Free register field allocated using
|
|
|
+ * devm_regmap_field_alloc. Usally drivers need not call this function,
|
|
|
+ * as the memory allocated via devm will be freed as per device-driver
|
|
|
+ * life-cyle.
|
|
|
+ *
|
|
|
+ * @dev: Device that will be interacted with
|
|
|
+ * @field: regmap field which should be freed.
|
|
|
+ */
|
|
|
+void devm_regmap_field_free(struct device *dev,
|
|
|
+ struct regmap_field *field)
|
|
|
+{
|
|
|
+ devm_kfree(dev, field);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(devm_regmap_field_free);
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_field_alloc(): Allocate and initialise a register field
|
|
|
+ * in a register map.
|
|
|
+ *
|
|
|
+ * @regmap: regmap bank in which this register field is located.
|
|
|
+ * @reg_field: Register field with in the bank.
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap_field. The regmap_field should be freed by the
|
|
|
+ * user once its finished working with it using regmap_field_free().
|
|
|
+ */
|
|
|
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
|
|
|
+ struct reg_field reg_field)
|
|
|
+{
|
|
|
+ struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
|
|
|
+
|
|
|
+ if (!rm_field)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ regmap_field_init(rm_field, regmap, reg_field);
|
|
|
+
|
|
|
+ return rm_field;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(regmap_field_alloc);
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_field_free(): Free register field allocated using regmap_field_alloc
|
|
|
+ *
|
|
|
+ * @field: regmap field which should be freed.
|
|
|
+ */
|
|
|
+void regmap_field_free(struct regmap_field *field)
|
|
|
+{
|
|
|
+ kfree(field);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(regmap_field_free);
|
|
|
+
|
|
|
/**
|
|
|
* regmap_reinit_cache(): Reinitialise the current register cache
|
|
|
*
|
|
@@ -1249,6 +1338,22 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(regmap_raw_write);
|
|
|
|
|
|
+/**
|
|
|
+ * regmap_field_write(): Write a value to a single register field
|
|
|
+ *
|
|
|
+ * @field: Register field to write to
|
|
|
+ * @val: Value to be written
|
|
|
+ *
|
|
|
+ * A value of zero will be returned on success, a negative errno will
|
|
|
+ * be returned in error cases.
|
|
|
+ */
|
|
|
+int regmap_field_write(struct regmap_field *field, unsigned int val)
|
|
|
+{
|
|
|
+ return regmap_update_bits(field->regmap, field->reg,
|
|
|
+ field->mask, val << field->shift);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(regmap_field_write);
|
|
|
+
|
|
|
/*
|
|
|
* regmap_bulk_write(): Write multiple registers to the device
|
|
|
*
|
|
@@ -1531,6 +1636,31 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(regmap_raw_read);
|
|
|
|
|
|
+/**
|
|
|
+ * regmap_field_read(): Read a value to a single register field
|
|
|
+ *
|
|
|
+ * @field: Register field to read from
|
|
|
+ * @val: Pointer to store read value
|
|
|
+ *
|
|
|
+ * A value of zero will be returned on success, a negative errno will
|
|
|
+ * be returned in error cases.
|
|
|
+ */
|
|
|
+int regmap_field_read(struct regmap_field *field, unsigned int *val)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+ unsigned int reg_val;
|
|
|
+ ret = regmap_read(field->regmap, field->reg, ®_val);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ reg_val &= field->mask;
|
|
|
+ reg_val >>= field->shift;
|
|
|
+ *val = reg_val;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(regmap_field_read);
|
|
|
+
|
|
|
/**
|
|
|
* regmap_bulk_read(): Read multiple registers from the device
|
|
|
*
|