diff mbox series

[U-Boot,v1,3/5] regmap: Allow providing read/write callbacks through struct regmap_config

Message ID 20190927132221.17892-4-jjhiblot@ti.com
State Superseded
Delegated to: Tom Rini
Headers show
Series regmap: Add a managed API, custom read/write callbacks and support for regmap fields | expand

Commit Message

Jean-Jacques Hiblot Sept. 27, 2019, 1:22 p.m. UTC
Some linux drivers provide their own read/write functions to access data
from/of the regmap. Adding support for it.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
---

 drivers/core/regmap.c | 12 ++++++++++++
 include/regmap.h      | 26 +++++++++++++++++++++++---
 2 files changed, 35 insertions(+), 3 deletions(-)

Comments

Simon Glass Oct. 30, 2019, 1:48 a.m. UTC | #1
Hi Jean-Jacques,

On Fri, 27 Sep 2019 at 07:22, Jean-Jacques Hiblot <jjhiblot@ti.com> wrote:
>
> Some linux drivers provide their own read/write functions to access data
> from/of the regmap. Adding support for it.
>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
> ---
>
>  drivers/core/regmap.c | 12 ++++++++++++
>  include/regmap.h      | 26 +++++++++++++++++++++++---
>  2 files changed, 35 insertions(+), 3 deletions(-)

This increases code size in SPL so should probably be controlled by a Kconfig.

Also I wonder if regmap should become a uclass if we are adding
operations to it?

Regards,
Simon
Jean-Jacques Hiblot Nov. 4, 2019, 4:07 p.m. UTC | #2
On 30/10/2019 02:48, Simon Glass wrote:
> Hi Jean-Jacques,
>
> On Fri, 27 Sep 2019 at 07:22, Jean-Jacques Hiblot <jjhiblot@ti.com> wrote:
>> Some linux drivers provide their own read/write functions to access data
>> from/of the regmap. Adding support for it.
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
>> ---
>>
>>   drivers/core/regmap.c | 12 ++++++++++++
>>   include/regmap.h      | 26 +++++++++++++++++++++++---
>>   2 files changed, 35 insertions(+), 3 deletions(-)
> This increases code size in SPL so should probably be controlled by a Kconfig.
OK.
>
> Also I wonder if regmap should become a uclass if we are adding

I don't see a real value in making a regmap a device. IMO It will just 
make things more complex than needed.

JJ

> operations to it?
>
> Regards,
> Simon
>
diff mbox series

Patch

diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index f69ff6d12f..486eea7bd4 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -31,6 +31,9 @@  static struct regmap *regmap_alloc(int count)
 	if (!map)
 		return NULL;
 	map->range_count = count;
+	map->bus_context = NULL;
+	map->reg_read = NULL;
+	map->reg_write = NULL;
 
 	return map;
 }
@@ -241,6 +244,9 @@  struct regmap *devm_regmap_init(struct udevice *dev,
 	rc = regmap_init_mem(dev_ofnode(dev), mapp);
 	if (rc)
 		return ERR_PTR(rc);
+	(*mapp)->reg_read = config->reg_read;
+	(*mapp)->reg_write = config->reg_write;
+	(*mapp)->bus_context = bus_context;
 
 	devres_add(dev, mapp);
 	return *mapp;
@@ -320,6 +326,9 @@  int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
 	struct regmap_range *range;
 	void *ptr;
 
+	if (map->reg_read)
+		return map->reg_read(map->bus_context, offset, valp);
+
 	if (range_num >= map->range_count) {
 		debug("%s: range index %d larger than range count\n",
 		      __func__, range_num);
@@ -429,6 +438,9 @@  int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset,
 	struct regmap_range *range;
 	void *ptr;
 
+	if (map->reg_write)
+		return map->reg_write(map->bus_context, offset,
+				      *(unsigned int *)val);
 	if (range_num >= map->range_count) {
 		debug("%s: range index %d larger than range count\n",
 		      __func__, range_num);
diff --git a/include/regmap.h b/include/regmap.h
index 63a362d86d..cc0adf568b 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -74,16 +74,36 @@  struct regmap_range {
 };
 
 struct regmap_bus;
-struct regmap_config;
+/**
+ * struct regmap_config - a way of accessing hardware/bus registers
+ *
+ * @reg_read:	  Optional callback that if filled will be used to perform
+ *		  all the reads from the registers. Should only be provided for
+ *		  devices whose read operation cannot be represented as a simple
+ *		  read operation on a bus such as SPI, I2C, etc. Most of the
+ *		  devices do not need this.
+ * @reg_write:	  Same as above for writing.
+ */
+struct regmap_config {
+	int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
+	int (*reg_write)(void *context, unsigned int reg, unsigned int val);
+};
 
 /**
  * struct regmap - a way of accessing hardware/bus registers
  *
  * @range_count:	Number of ranges available within the map
  * @ranges:		Array of ranges
+ * @bus_context:	Data passed to bus-specific callbacks
+ * @reg_read:		Optional callback that if filled will be used to perform
+ *			all the reads from the registers.
+ * @reg_write:		Same as above for writing.
  */
 struct regmap {
 	enum regmap_endianness_t endianness;
+	void *bus_context;
+	int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
+	int (*reg_write)(void *context, unsigned int reg, unsigned int val);
 	int range_count;
 	struct regmap_range ranges[0];
 };
@@ -340,8 +360,8 @@  int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index);
  *
  * @dev: Device that will be interacted with
  * @bus: Bus-specific callbacks to use with device (IGNORED)
- * @bus_context: Data passed to bus-specific callbacks (IGNORED)
- * @config: Configuration for register map (IGNORED)
+ * @bus_context: Data passed to bus-specific callbacks
+ * @config: Configuration for register map
  *
  * The return value will be an ERR_PTR() on error or a valid pointer to
  * a struct regmap.