linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver
@ 2013-08-30  4:31 Kuninori Morimoto
  2013-08-30  4:33 ` [PATCH 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
                   ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-08-30  4:31 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel


Hi Mark

These patches add new regmap_filelds API on kernel.
                                   ~
and use it on Renesas sound driver instead of original method.
It can care about multi port register offset via regmap.

0xAAAA + 0x40    -- port 0 --
                    regX
                    regY
                    regZ
0xAAAA + 0x80    -- port 1 --
                    regX
                    regY
                    regZ

This case, current API needs 2 (= port) x 3 (= regX/Y/Z) regmap_fileld,
but this new API can care about all port via 3 regmap_filelds with port ID.

I'm not sure that regmap_filelds is good naming or not.
Please let me know if you have good naming idea.

These are based on below branchs
 regmap/for-next + asoc/for-next

Kuninori Morimoto (4):
      regmap: add regmap_field_update_bits()
      regmap: Add regmap_fields APIs
      ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove
      ASoC: rsnd: use regmap instead of original register mapping method

 drivers/base/regmap/internal.h |    3 +
 drivers/base/regmap/regmap.c   |  117 +++++++++++++++++
 include/linux/regmap.h         |   14 +++
 sound/soc/sh/rcar/core.c       |   45 -------
 sound/soc/sh/rcar/gen.c        |  270 +++++++++++++++++++++++++---------------
 5 files changed, 307 insertions(+), 142 deletions(-)


Best regards
---
Kuninori Morimoto

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/4] regmap: add regmap_field_update_bits()
  2013-08-30  4:31 [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
@ 2013-08-30  4:33 ` Kuninori Morimoto
  2013-08-30  4:34 ` [PATCH 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-08-30  4:33 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current regmap_field is supporting read/write functions.
This patch adds new update_bits function for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/base/regmap/regmap.c |   20 ++++++++++++++++++++
 include/linux/regmap.h       |    2 ++
 2 files changed, 22 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e0d0c7d..7ae90d8 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1360,6 +1360,26 @@ int regmap_field_write(struct regmap_field *field, unsigned int val)
 }
 EXPORT_SYMBOL_GPL(regmap_field_write);
 
+/**
+ * regmap_field_update_bits():	Perform a read/modify/write cycle
+ *                              on the register field
+ *
+ * @field: Register field to write to
+ * @mask: Bitmask to change
+ * @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_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val)
+{
+	mask = (mask << field->shift) & field->mask;
+
+	return regmap_update_bits(field->regmap, field->reg,
+				  mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 75981d0..1425c91 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -446,6 +446,8 @@ void devm_regmap_field_free(struct device *dev,	struct regmap_field *field);
 
 int regmap_field_read(struct regmap_field *field, unsigned int *val);
 int regmap_field_write(struct regmap_field *field, unsigned int val);
+int regmap_field_update_bits(struct regmap_field *field,
+			     unsigned int mask, unsigned int val);
 
 /**
  * Description of an IRQ for the generic regmap irq_chip.
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/4] regmap: Add regmap_fields APIs
  2013-08-30  4:31 [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
  2013-08-30  4:33 ` [PATCH 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
@ 2013-08-30  4:34 ` Kuninori Morimoto
  2013-09-02  2:36   ` Kuninori Morimoto
  2013-08-30  4:34 ` [PATCH 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-08-30  4:34 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current Linux kernel is supporting regmap_field method
and it is very useful feature.
It needs one regmap_filed for one register access.

OTOH, there is multi port device which
has many same registers in the market.
The difference for each port register access is
only its address offset.

Current API needs many regmap_field for such device,
but it is not good.
This patch adds new regmap_fileds API which can care
about multi port/offset access via regmap.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/base/regmap/internal.h |    3 ++
 drivers/base/regmap/regmap.c   |   97 ++++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h         |   12 +++++
 3 files changed, 112 insertions(+)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 29c8316..ba22cc7 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -182,6 +182,9 @@ struct regmap_field {
 	/* lsb */
 	unsigned int shift;
 	unsigned int reg;
+
+	unsigned int id_size;
+	unsigned int id_offset;
 };
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7ae90d8..677e559 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -815,6 +815,8 @@ static void regmap_field_init(struct regmap_field *rm_field,
 	rm_field->reg = reg_field.reg;
 	rm_field->shift = reg_field.lsb;
 	rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+	rm_field->id_size = reg_field.id_size;
+	rm_field->id_offset = reg_field.id_offset;
 }
 
 /**
@@ -1380,6 +1382,68 @@ int regmap_field_update_bits(struct regmap_field *field, unsigned int mask, unsi
 }
 EXPORT_SYMBOL_GPL(regmap_field_write);
 
+/**
+ * regmap_fields_write(): Write a value to a single register field with port ID
+ *
+ * @field: Register field to write to
+ * @id: port ID
+ * @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_fields_write(struct regmap_field *field, unsigned int id,
+			unsigned int val)
+{
+	if (id >= field->id_size)
+		return -EINVAL;
+
+	return regmap_update_bits(field->regmap,
+				  field->reg + (field->id_offset * id),
+				  field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
+/**
+ * regmap_fields_update_bits():	Perform a read/modify/write cycle
+ *                              on the register field
+ *
+ * @field: Register field to write to
+ * @id: port ID
+ * @mask: Bitmask to change
+ * @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_fields_update_bits(struct regmap_field *field,  unsigned int id,
+			      unsigned int mask, unsigned int val)
+{
+	if (id >= field->id_size)
+		return -EINVAL;
+
+	mask = (mask << field->shift) & field->mask;
+
+	return regmap_update_bits(field->regmap,
+				  field->reg + (field->id_offset * id),
+				  mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
+/**
+ * regmap_fields_enable(): query fields access
+ *
+ * @field: Query Register field
+ *
+ * A non-zero will be returned when fields access enable,
+ * a zero will be returned in single field.
+ */
+int regmap_fields_enable(struct regmap_field *field)
+{
+	return field->id_size && field->id_offset;
+}
+EXPORT_SYMBOL_GPL(regmap_fields_enable);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
@@ -1688,6 +1752,39 @@ int regmap_field_read(struct regmap_field *field, unsigned int *val)
 EXPORT_SYMBOL_GPL(regmap_field_read);
 
 /**
+ * regmap_fields_read(): Read a value to a single register field with port ID
+ *
+ * @field: Register field to read from
+ * @id: port ID
+ * @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_fields_read(struct regmap_field *field, unsigned int id,
+		       unsigned int *val)
+{
+	int ret;
+	unsigned int reg_val;
+
+	if (id >= field->id_size)
+		return -EINVAL;
+
+	ret = regmap_read(field->regmap,
+			  field->reg + (field->id_offset * id),
+			  &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
  *
  * @map: Register map to write to
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 1425c91..d329f50 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -423,11 +423,15 @@ bool regmap_reg_in_ranges(unsigned int reg,
  * @reg: Offset of the register within the regmap bank
  * @lsb: lsb of the register field.
  * @reg: msb of the register field.
+ * @id_size: port size if it has some ports
+ * @id_offset: address offset for each ports
  */
 struct reg_field {
 	unsigned int reg;
 	unsigned int lsb;
 	unsigned int msb;
+	unsigned int id_size;
+	unsigned int id_offset;
 };
 
 #define REG_FIELD(_reg, _lsb, _msb) {		\
@@ -449,6 +453,14 @@ int regmap_field_write(struct regmap_field *field, unsigned int val);
 int regmap_field_update_bits(struct regmap_field *field,
 			     unsigned int mask, unsigned int val);
 
+int regmap_fields_write(struct regmap_field *field, unsigned int id,
+			unsigned int val);
+int regmap_fields_read(struct regmap_field *field, unsigned int id,
+		       unsigned int *val);
+int regmap_fields_enable(struct regmap_field *field);
+int regmap_fields_update_bits(struct regmap_field *field,  unsigned int id,
+			      unsigned int mask, unsigned int val);
+
 /**
  * Description of an IRQ for the generic regmap irq_chip.
  *
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove
  2013-08-30  4:31 [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
  2013-08-30  4:33 ` [PATCH 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
  2013-08-30  4:34 ` [PATCH 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
@ 2013-08-30  4:34 ` Kuninori Morimoto
  2013-08-30  4:35 ` [PATCH 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
  2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
  4 siblings, 0 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-08-30  4:34 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current rsnd_gen_ops didn't care about .probe and .remove
functions, but it was not good sense.
This patch tidyup it

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/gen.c |   41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index babb203..331fc55 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -11,6 +11,11 @@
 #include "rsnd.h"
 
 struct rsnd_gen_ops {
+	int (*probe)(struct platform_device *pdev,
+		     struct rcar_snd_info *info,
+		     struct rsnd_priv *priv);
+	void (*remove)(struct platform_device *pdev,
+		      struct rsnd_priv *priv);
 	int (*path_init)(struct rsnd_priv *priv,
 			 struct rsnd_dai *rdai,
 			 struct rsnd_dai_stream *io);
@@ -98,11 +103,6 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
 	return ret;
 }
 
-static struct rsnd_gen_ops rsnd_gen1_ops = {
-	.path_init	= rsnd_gen1_path_init,
-	.path_exit	= rsnd_gen1_path_exit,
-};
-
 #define RSND_GEN1_REG_MAP(g, s, i, oi, oa)				\
 	do {								\
 		(g)->reg_map[RSND_REG_##i].index  = RSND_GEN1_##s;	\
@@ -163,7 +163,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	    IS_ERR(gen->base[RSND_GEN1_SSI]))
 		return -ENODEV;
 
-	gen->ops = &rsnd_gen1_ops;
 	rsnd_gen1_reg_map_init(gen);
 
 	dev_dbg(dev, "Gen1 device probed\n");
@@ -183,6 +182,13 @@ static void rsnd_gen1_remove(struct platform_device *pdev,
 {
 }
 
+static struct rsnd_gen_ops rsnd_gen1_ops = {
+	.probe		= rsnd_gen1_probe,
+	.remove		= rsnd_gen1_remove,
+	.path_init	= rsnd_gen1_path_init,
+	.path_exit	= rsnd_gen1_path_exit,
+};
+
 /*
  *		Gen
  */
@@ -251,6 +257,14 @@ int rsnd_gen_probe(struct platform_device *pdev,
 		return -ENOMEM;
 	}
 
+	if (rsnd_is_gen1(priv))
+		gen->ops = &rsnd_gen1_ops;
+
+	if (!gen->ops) {
+		dev_err(dev, "unknown generation R-Car sound device\n");
+		return -ENODEV;
+	}
+
 	priv->gen = gen;
 
 	/*
@@ -261,20 +275,13 @@ int rsnd_gen_probe(struct platform_device *pdev,
 	for (i = 0; i < RSND_REG_MAX; i++)
 		gen->reg_map[i].index = -1;
 
-	/*
-	 *	init each module
-	 */
-	if (rsnd_is_gen1(priv))
-		return rsnd_gen1_probe(pdev, info, priv);
-
-	dev_err(dev, "unknown generation R-Car sound device\n");
-
-	return -ENODEV;
+	return gen->ops->probe(pdev, info, priv);
 }
 
 void rsnd_gen_remove(struct platform_device *pdev,
 		     struct rsnd_priv *priv)
 {
-	if (rsnd_is_gen1(priv))
-		rsnd_gen1_remove(pdev, priv);
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	gen->ops->remove(pdev, priv);
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/4] ASoC: rsnd: use regmap instead of original register mapping method
  2013-08-30  4:31 [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
                   ` (2 preceding siblings ...)
  2013-08-30  4:34 ` [PATCH 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
@ 2013-08-30  4:35 ` Kuninori Morimoto
  2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
  4 siblings, 0 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-08-30  4:35 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current Linux kernel is supporting regmap/regmap_field,
and, it is good match for Renesas Sound Gen1/Gen2 register mapping.
This patch uses regmap instead of original method for register access

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/core.c |   45 ---------
 sound/soc/sh/rcar/gen.c  |  233 ++++++++++++++++++++++++++++++----------------
 2 files changed, 151 insertions(+), 127 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index a357060..fc83f0f 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -106,51 +106,6 @@
 	(!(priv->info->func) ? -ENODEV :		\
 	 priv->info->func(param))
 
-
-/*
- *	basic function
- */
-u32 rsnd_read(struct rsnd_priv *priv,
-	      struct rsnd_mod *mod, enum rsnd_reg reg)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-
-	BUG_ON(!base);
-
-	return ioread32(base);
-}
-
-void rsnd_write(struct rsnd_priv *priv,
-		struct rsnd_mod *mod,
-		enum rsnd_reg reg, u32 data)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-	struct device *dev = rsnd_priv_to_dev(priv);
-
-	BUG_ON(!base);
-
-	dev_dbg(dev, "w %p : %08x\n", base, data);
-
-	iowrite32(data, base);
-}
-
-void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
-	       enum rsnd_reg reg, u32 mask, u32 data)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	u32 val;
-
-	BUG_ON(!base);
-
-	val = ioread32(base);
-	val &= ~mask;
-	val |= data & mask;
-	iowrite32(val, base);
-
-	dev_dbg(dev, "s %p : %08x\n", base, val);
-}
-
 /*
  *	rsnd_mod functions
  */
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 331fc55..b245584 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -24,21 +24,112 @@ struct rsnd_gen_ops {
 			 struct rsnd_dai_stream *io);
 };
 
-struct rsnd_gen_reg_map {
-	int index;	/* -1 : not supported */
-	u32 offset_id;	/* offset of ssi0, ssi1, ssi2... */
-	u32 offset_adr;	/* offset of SSICR, SSISR, ... */
-};
-
 struct rsnd_gen {
 	void __iomem *base[RSND_BASE_MAX];
 
-	struct rsnd_gen_reg_map reg_map[RSND_REG_MAX];
 	struct rsnd_gen_ops *ops;
+
+	struct regmap *regmap;
+	struct regmap_field *regs[RSND_REG_MAX];
 };
 
 #define rsnd_priv_to_gen(p)	((struct rsnd_gen *)(p)->gen)
 
+#define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size)	\
+	[id] = {							\
+		.reg = (unsigned int)gen->base[reg_id] + offset,	\
+		.lsb = 0,						\
+		.msb = 31,						\
+		.id_size = _id_size,					\
+		.id_offset = _id_offset,				\
+	}
+
+#define RSND_SINGLE_REG(gen, reg, id, offset)				\
+	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 0)
+
+#define RSND_MULTI_REG(gen, reg, id, offset, _id_offset)		\
+	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
+
+/*
+ *		basic function
+ */
+static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
+{
+	struct rsnd_priv *priv = context;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 *data = (u32 *)_data;
+	u32 val = data[1];
+	void __iomem *reg = (void *)data[0];
+
+	iowrite32(val, reg);
+
+	dev_dbg(dev, "w %p : %08x\n", reg, val);
+
+	return 0;
+}
+
+static int rsnd_regmap_read32(void *context,
+			      const void *_data, size_t reg_size,
+			      void *_val, size_t val_size)
+{
+	struct rsnd_priv *priv = context;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 *data = (u32 *)_data;
+	u32 *val = (u32 *)_val;
+	void __iomem *reg = (void *)data[0];
+
+	*val = ioread32(reg);
+
+	dev_dbg(dev, "r %p : %08x\n", reg, *val);
+
+	return 0;
+}
+
+static struct regmap_bus rsnd_regmap_bus = {
+	.write				= rsnd_regmap_write32,
+	.read				= rsnd_regmap_read32,
+	.reg_format_endian_default	= REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default	= REGMAP_ENDIAN_NATIVE,
+};
+
+u32 rsnd_read(struct rsnd_priv *priv,
+	      struct rsnd_mod *mod, enum rsnd_reg reg)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+	u32 val;
+
+	if (regmap_fields_enable(gen->regs[reg]))
+		regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
+	else
+		regmap_field_read(gen->regs[reg], &val);
+
+	return val;
+}
+
+void rsnd_write(struct rsnd_priv *priv,
+		struct rsnd_mod *mod,
+		enum rsnd_reg reg, u32 data)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	if (regmap_fields_enable(gen->regs[reg]))
+		regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
+	else
+		regmap_field_write(gen->regs[reg], data);
+}
+
+void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
+	       enum rsnd_reg reg, u32 mask, u32 data)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	if (regmap_fields_enable(gen->regs[reg]))
+		regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
+					  mask, data);
+	else
+		regmap_field_update_bits(gen->regs[reg], mask, data);
+}
+
 /*
  *		Gen2
  *		will be filled in the future
@@ -103,39 +194,56 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
 	return ret;
 }
 
-#define RSND_GEN1_REG_MAP(g, s, i, oi, oa)				\
-	do {								\
-		(g)->reg_map[RSND_REG_##i].index  = RSND_GEN1_##s;	\
-		(g)->reg_map[RSND_REG_##i].offset_id = oi;		\
-		(g)->reg_map[RSND_REG_##i].offset_adr = oa;		\
-	} while (0)
-
-static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen)
+static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
 {
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_ROUTE_SEL,	0x0,	0x00);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL0,	0x0,	0x08);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL1,	0x0,	0x0c);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL2,	0x0,	0x10);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_CTRL,	0x0,	0xc0);
-	RSND_GEN1_REG_MAP(gen, SRU,	SSI_MODE0,	0x0,	0xD0);
-	RSND_GEN1_REG_MAP(gen, SRU,	SSI_MODE1,	0x0,	0xD4);
-	RSND_GEN1_REG_MAP(gen, SRU,	BUSIF_MODE,	0x4,	0x20);
-	RSND_GEN1_REG_MAP(gen, SRU,	BUSIF_ADINR,	0x40,	0x214);
-
-	RSND_GEN1_REG_MAP(gen, ADG,	BRRA,		0x0,	0x00);
-	RSND_GEN1_REG_MAP(gen, ADG,	BRRB,		0x0,	0x04);
-	RSND_GEN1_REG_MAP(gen, ADG,	SSICKR,		0x0,	0x08);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL0,	0x0,	0x0c);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL1,	0x0,	0x10);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL3,	0x0,	0x18);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL4,	0x0,	0x1c);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL5,	0x0,	0x20);
-
-	RSND_GEN1_REG_MAP(gen, SSI,	SSICR,		0x40,	0x00);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSISR,		0x40,	0x04);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSITDR,		0x40,	0x08);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSIRDR,		0x40,	0x0c);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSIWSR,		0x40,	0x20);
+	int i;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	struct regmap_config regc;
+	struct reg_field regf[RSND_REG_MAX] = {
+		RSND_SINGLE_REG(gen, SRU,	SRC_ROUTE_SEL,	0x00),
+		RSND_SINGLE_REG(gen, SRU,	SRC_TMG_SEL0,	0x08),
+		RSND_SINGLE_REG(gen, SRU,	SRC_TMG_SEL1,	0x0c),
+		RSND_SINGLE_REG(gen, SRU,	SRC_TMG_SEL2,	0x10),
+		RSND_SINGLE_REG(gen, SRU,	SRC_CTRL,	0xc0),
+		RSND_SINGLE_REG(gen, SRU,	SSI_MODE0,	0xD0),
+		RSND_SINGLE_REG(gen, SRU,	SSI_MODE1,	0xD4),
+		RSND_MULTI_REG(gen,  SRU,	BUSIF_MODE,	0x20,	0x4),
+		RSND_MULTI_REG(gen,  SRU,	BUSIF_ADINR,	0x214,	0x40),
+
+		RSND_SINGLE_REG(gen, ADG,	BRRA,		0x00),
+		RSND_SINGLE_REG(gen, ADG,	BRRB,		0x04),
+		RSND_SINGLE_REG(gen, ADG,	SSICKR,		0x08),
+		RSND_SINGLE_REG(gen, ADG,	AUDIO_CLK_SEL0,	0x0c),
+		RSND_SINGLE_REG(gen, ADG,	AUDIO_CLK_SEL1,	0x10),
+		RSND_SINGLE_REG(gen, ADG,	AUDIO_CLK_SEL3,	0x18),
+		RSND_SINGLE_REG(gen, ADG,	AUDIO_CLK_SEL4,	0x1c),
+		RSND_SINGLE_REG(gen, ADG,	AUDIO_CLK_SEL5,	0x20),
+
+		RSND_MULTI_REG(gen,  SSI,	SSICR,		0x00,	0x40),
+		RSND_MULTI_REG(gen,  SSI,	SSISR,		0x04,	0x40),
+		RSND_MULTI_REG(gen,  SSI,	SSITDR,		0x08,	0x40),
+		RSND_MULTI_REG(gen,  SSI,	SSIRDR,		0x0c,	0x40),
+		RSND_MULTI_REG(gen,  SSI,	SSIWSR,		0x20,	0x40),
+	};
+
+	memset(&regc, 0, sizeof(regc));
+	regc.reg_bits = 32;
+	regc.val_bits = 32;
+
+	gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
+	if (IS_ERR(gen->regmap)) {
+		dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
+		return PTR_ERR(gen->regmap);
+	}
+
+	for (i = 0; i < RSND_REG_MAX; i++) {
+		gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
+		if (IS_ERR(gen->regs[i]))
+			return PTR_ERR(gen->regs[i]);
+
+	}
+
+	return 0;
 }
 
 static int rsnd_gen1_probe(struct platform_device *pdev,
@@ -147,6 +255,7 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	struct resource *sru_res;
 	struct resource *adg_res;
 	struct resource *ssi_res;
+	int ret;
 
 	/*
 	 * map address
@@ -163,7 +272,9 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	    IS_ERR(gen->base[RSND_GEN1_SSI]))
 		return -ENODEV;
 
-	rsnd_gen1_reg_map_init(gen);
+	ret = rsnd_gen1_regmap_init(priv, gen);
+	if (ret < 0)
+		return ret;
 
 	dev_dbg(dev, "Gen1 device probed\n");
 	dev_dbg(dev, "SRU : %08x => %p\n",	sru_res->start,
@@ -210,46 +321,12 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv,
 	return gen->ops->path_exit(priv, rdai, io);
 }
 
-void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
-			       struct rsnd_mod *mod,
-			       enum rsnd_reg reg)
-{
-	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	int index;
-	u32 offset_id, offset_adr;
-
-	if (reg >= RSND_REG_MAX) {
-		dev_err(dev, "rsnd_reg reg error\n");
-		return NULL;
-	}
-
-	index		= gen->reg_map[reg].index;
-	offset_id	= gen->reg_map[reg].offset_id;
-	offset_adr	= gen->reg_map[reg].offset_adr;
-
-	if (index < 0) {
-		dev_err(dev, "unsupported reg access %d\n", reg);
-		return NULL;
-	}
-
-	if (offset_id && mod)
-		offset_id *= rsnd_mod_id(mod);
-
-	/*
-	 * index/offset were set on gen1/gen2
-	 */
-
-	return gen->base[index] + offset_id + offset_adr;
-}
-
 int rsnd_gen_probe(struct platform_device *pdev,
 		   struct rcar_snd_info *info,
 		   struct rsnd_priv *priv)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct rsnd_gen *gen;
-	int i;
 
 	gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
 	if (!gen) {
@@ -267,14 +344,6 @@ int rsnd_gen_probe(struct platform_device *pdev,
 
 	priv->gen = gen;
 
-	/*
-	 * see
-	 *	rsnd_reg_get()
-	 *	rsnd_gen_probe()
-	 */
-	for (i = 0; i < RSND_REG_MAX; i++)
-		gen->reg_map[i].index = -1;
-
 	return gen->ops->probe(pdev, info, priv);
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 2/4] regmap: Add regmap_fields APIs
  2013-08-30  4:34 ` [PATCH 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
@ 2013-09-02  2:36   ` Kuninori Morimoto
  0 siblings, 0 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-02  2:36 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel


Hi

> Current Linux kernel is supporting regmap_field method
> and it is very useful feature.
> It needs one regmap_filed for one register access.
> 
> OTOH, there is multi port device which
> has many same registers in the market.
> The difference for each port register access is
> only its address offset.
> 
> Current API needs many regmap_field for such device,
> but it is not good.
> This patch adds new regmap_fileds API which can care
> about multi port/offset access via regmap.
> 
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

I noticed that this series didin't care EXPORT_SYMBOL_GPL() name
(many same names)
Please give me v2 chance

Best regards
---
Kuninori Morimoto

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver
  2013-08-30  4:31 [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
                   ` (3 preceding siblings ...)
  2013-08-30  4:35 ` [PATCH 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
@ 2013-09-02  3:24 ` Kuninori Morimoto
  2013-09-02  3:24   ` [PATCH v2 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
                     ` (3 more replies)
  4 siblings, 4 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-02  3:24 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel


Hi Mark

These patches are v2 of new regmap_filelds API on kernel.
                                         ~
It can care about multi port register offset via regmap.
 
0xAAAA + 0x40    -- port 0 --
                    regX
                    regY
                    regZ
0xAAAA + 0x80    -- port 1 --
                    regX
                    regY
                    regZ

This case, current API needs 2 (= port) x 3 (= regX/Y/Z) regmap_fileld,
but this new API can care about all port via 3 regmap_filelds with port ID.

I'm not sure that regmap_filelds is good naming or not.
Please let me know if you have good naming idea.

The difference between v1 <-> v2 is EXPORT_SYMBOL_GPL() naming
on regmap_filelds

these are based on below branchs
 regmap/for-next + asoc/for-next




Kuninori Morimoto (4):
      regmap: add regmap_field_update_bits()
      regmap: Add regmap_fields APIs
      ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove
      ASoC: rsnd: use regmap instead of original register mapping method

 drivers/base/regmap/internal.h |    3 +
 drivers/base/regmap/regmap.c   |  117 +++++++++++++++++
 include/linux/regmap.h         |   14 +++
 sound/soc/sh/rcar/core.c       |   45 -------
 sound/soc/sh/rcar/gen.c        |  270 +++++++++++++++++++++++++---------------
 5 files changed, 307 insertions(+), 142 deletions(-)


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v2 1/4] regmap: add regmap_field_update_bits()
  2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
@ 2013-09-02  3:24   ` Kuninori Morimoto
  2013-09-03 11:20     ` Mark Brown
  2013-09-02  3:30   ` [PATCH v2 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-02  3:24 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current regmap_field is supporting read/write functions.
This patch adds new update_bits function for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

 - fixup EXPORT_SYMBOL_GPL() naming

 drivers/base/regmap/regmap.c |   20 ++++++++++++++++++++
 include/linux/regmap.h       |    2 ++
 2 files changed, 22 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7d689a1..285afa7 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1369,6 +1369,26 @@ int regmap_field_write(struct regmap_field *field, unsigned int val)
 }
 EXPORT_SYMBOL_GPL(regmap_field_write);
 
+/**
+ * regmap_field_update_bits():	Perform a read/modify/write cycle
+ *                              on the register field
+ *
+ * @field: Register field to write to
+ * @mask: Bitmask to change
+ * @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_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val)
+{
+	mask = (mask << field->shift) & field->mask;
+
+	return regmap_update_bits(field->regmap, field->reg,
+				  mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_update_bits);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index a10380b..4c8c20a 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -448,6 +448,8 @@ void devm_regmap_field_free(struct device *dev,	struct regmap_field *field);
 
 int regmap_field_read(struct regmap_field *field, unsigned int *val);
 int regmap_field_write(struct regmap_field *field, unsigned int val);
+int regmap_field_update_bits(struct regmap_field *field,
+			     unsigned int mask, unsigned int val);
 
 /**
  * Description of an IRQ for the generic regmap irq_chip.
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 2/4] regmap: Add regmap_fields APIs
  2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
  2013-09-02  3:24   ` [PATCH v2 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
@ 2013-09-02  3:30   ` Kuninori Morimoto
  2013-09-17 12:48     ` Mark Brown
  2013-09-02  3:31   ` [PATCH v2 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
  2013-09-02  3:32   ` [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
  3 siblings, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-02  3:30 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current Linux kernel is supporting regmap_field method
and it is very useful feature.
It needs one regmap_filed for one register access.

OTOH, there is multi port device which
has many same registers in the market.
The difference for each register access is
only its address offset.

Current API needs many regmap_field for such device,
but it is not good.
This patch adds new regmap_fileds API which can care
about multi port/offset access via regmap.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

 - fixup EXPORT_SYMBOL_GPL() naming

 drivers/base/regmap/internal.h |    3 ++
 drivers/base/regmap/regmap.c   |   97 ++++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h         |   12 +++++
 3 files changed, 112 insertions(+)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 57f7778..9010614 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -179,6 +179,9 @@ struct regmap_field {
 	/* lsb */
 	unsigned int shift;
 	unsigned int reg;
+
+	unsigned int id_size;
+	unsigned int id_offset;
 };
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 285afa7..7cb2e9f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -821,6 +821,8 @@ static void regmap_field_init(struct regmap_field *rm_field,
 	rm_field->reg = reg_field.reg;
 	rm_field->shift = reg_field.lsb;
 	rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+	rm_field->id_size = reg_field.id_size;
+	rm_field->id_offset = reg_field.id_offset;
 }
 
 /**
@@ -1389,6 +1391,68 @@ int regmap_field_update_bits(struct regmap_field *field, unsigned int mask, unsi
 }
 EXPORT_SYMBOL_GPL(regmap_field_update_bits);
 
+/**
+ * regmap_fields_write(): Write a value to a single register field with port ID
+ *
+ * @field: Register field to write to
+ * @id: port ID
+ * @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_fields_write(struct regmap_field *field, unsigned int id,
+			unsigned int val)
+{
+	if (id >= field->id_size)
+		return -EINVAL;
+
+	return regmap_update_bits(field->regmap,
+				  field->reg + (field->id_offset * id),
+				  field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_fields_write);
+
+/**
+ * regmap_fields_update_bits():	Perform a read/modify/write cycle
+ *                              on the register field
+ *
+ * @field: Register field to write to
+ * @id: port ID
+ * @mask: Bitmask to change
+ * @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_fields_update_bits(struct regmap_field *field,  unsigned int id,
+			      unsigned int mask, unsigned int val)
+{
+	if (id >= field->id_size)
+		return -EINVAL;
+
+	mask = (mask << field->shift) & field->mask;
+
+	return regmap_update_bits(field->regmap,
+				  field->reg + (field->id_offset * id),
+				  mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_fields_update_bits);
+
+/**
+ * regmap_fields_enable(): query fields access
+ *
+ * @field: Query Register field
+ *
+ * A non-zero will be returned when fields access enable,
+ * a zero will be returned in single field.
+ */
+int regmap_fields_enable(struct regmap_field *field)
+{
+	return field->id_size && field->id_offset;
+}
+EXPORT_SYMBOL_GPL(regmap_fields_enable);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
@@ -1697,6 +1761,39 @@ int regmap_field_read(struct regmap_field *field, unsigned int *val)
 EXPORT_SYMBOL_GPL(regmap_field_read);
 
 /**
+ * regmap_fields_read(): Read a value to a single register field with port ID
+ *
+ * @field: Register field to read from
+ * @id: port ID
+ * @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_fields_read(struct regmap_field *field, unsigned int id,
+		       unsigned int *val)
+{
+	int ret;
+	unsigned int reg_val;
+
+	if (id >= field->id_size)
+		return -EINVAL;
+
+	ret = regmap_read(field->regmap,
+			  field->reg + (field->id_offset * id),
+			  &reg_val);
+	if (ret != 0)
+		return ret;
+
+	reg_val &= field->mask;
+	reg_val >>= field->shift;
+	*val = reg_val;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_fields_read);
+
+/**
  * regmap_bulk_read(): Read multiple registers from the device
  *
  * @map: Register map to write to
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 4c8c20a..b43d2e3 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -425,11 +425,15 @@ bool regmap_reg_in_ranges(unsigned int reg,
  * @reg: Offset of the register within the regmap bank
  * @lsb: lsb of the register field.
  * @reg: msb of the register field.
+ * @id_size: port size if it has some ports
+ * @id_offset: address offset for each ports
  */
 struct reg_field {
 	unsigned int reg;
 	unsigned int lsb;
 	unsigned int msb;
+	unsigned int id_size;
+	unsigned int id_offset;
 };
 
 #define REG_FIELD(_reg, _lsb, _msb) {		\
@@ -451,6 +455,14 @@ int regmap_field_write(struct regmap_field *field, unsigned int val);
 int regmap_field_update_bits(struct regmap_field *field,
 			     unsigned int mask, unsigned int val);
 
+int regmap_fields_write(struct regmap_field *field, unsigned int id,
+			unsigned int val);
+int regmap_fields_read(struct regmap_field *field, unsigned int id,
+		       unsigned int *val);
+int regmap_fields_enable(struct regmap_field *field);
+int regmap_fields_update_bits(struct regmap_field *field,  unsigned int id,
+			      unsigned int mask, unsigned int val);
+
 /**
  * Description of an IRQ for the generic regmap irq_chip.
  *
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove
  2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
  2013-09-02  3:24   ` [PATCH v2 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
  2013-09-02  3:30   ` [PATCH v2 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
@ 2013-09-02  3:31   ` Kuninori Morimoto
  2013-09-17 12:58     ` Mark Brown
  2013-09-02  3:32   ` [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
  3 siblings, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-02  3:31 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current rsnd_gen_ops didn't care about .probe and .remove
functions, but it was not good sense.
This patch tidyup it

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

 - no change

 sound/soc/sh/rcar/gen.c |   41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index babb203..331fc55 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -11,6 +11,11 @@
 #include "rsnd.h"
 
 struct rsnd_gen_ops {
+	int (*probe)(struct platform_device *pdev,
+		     struct rcar_snd_info *info,
+		     struct rsnd_priv *priv);
+	void (*remove)(struct platform_device *pdev,
+		      struct rsnd_priv *priv);
 	int (*path_init)(struct rsnd_priv *priv,
 			 struct rsnd_dai *rdai,
 			 struct rsnd_dai_stream *io);
@@ -98,11 +103,6 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
 	return ret;
 }
 
-static struct rsnd_gen_ops rsnd_gen1_ops = {
-	.path_init	= rsnd_gen1_path_init,
-	.path_exit	= rsnd_gen1_path_exit,
-};
-
 #define RSND_GEN1_REG_MAP(g, s, i, oi, oa)				\
 	do {								\
 		(g)->reg_map[RSND_REG_##i].index  = RSND_GEN1_##s;	\
@@ -163,7 +163,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	    IS_ERR(gen->base[RSND_GEN1_SSI]))
 		return -ENODEV;
 
-	gen->ops = &rsnd_gen1_ops;
 	rsnd_gen1_reg_map_init(gen);
 
 	dev_dbg(dev, "Gen1 device probed\n");
@@ -183,6 +182,13 @@ static void rsnd_gen1_remove(struct platform_device *pdev,
 {
 }
 
+static struct rsnd_gen_ops rsnd_gen1_ops = {
+	.probe		= rsnd_gen1_probe,
+	.remove		= rsnd_gen1_remove,
+	.path_init	= rsnd_gen1_path_init,
+	.path_exit	= rsnd_gen1_path_exit,
+};
+
 /*
  *		Gen
  */
@@ -251,6 +257,14 @@ int rsnd_gen_probe(struct platform_device *pdev,
 		return -ENOMEM;
 	}
 
+	if (rsnd_is_gen1(priv))
+		gen->ops = &rsnd_gen1_ops;
+
+	if (!gen->ops) {
+		dev_err(dev, "unknown generation R-Car sound device\n");
+		return -ENODEV;
+	}
+
 	priv->gen = gen;
 
 	/*
@@ -261,20 +275,13 @@ int rsnd_gen_probe(struct platform_device *pdev,
 	for (i = 0; i < RSND_REG_MAX; i++)
 		gen->reg_map[i].index = -1;
 
-	/*
-	 *	init each module
-	 */
-	if (rsnd_is_gen1(priv))
-		return rsnd_gen1_probe(pdev, info, priv);
-
-	dev_err(dev, "unknown generation R-Car sound device\n");
-
-	return -ENODEV;
+	return gen->ops->probe(pdev, info, priv);
 }
 
 void rsnd_gen_remove(struct platform_device *pdev,
 		     struct rsnd_priv *priv)
 {
-	if (rsnd_is_gen1(priv))
-		rsnd_gen1_remove(pdev, priv);
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	gen->ops->remove(pdev, priv);
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method
  2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
                     ` (2 preceding siblings ...)
  2013-09-02  3:31   ` [PATCH v2 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
@ 2013-09-02  3:32   ` Kuninori Morimoto
  2013-09-17 13:04     ` Mark Brown
  3 siblings, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-02  3:32 UTC (permalink / raw)
  To: Mark Brown, Greg Kroah-Hartman
  Cc: Linux-ALSA, Liam Girdwood, Kuninori Morimoto, Simon, linux-kernel

Current Linux kernel is supporting regmap/regmap_field,
and, it is good match for Renesas Sound Gen1/Gen2 register mapping.
This patch uses regmap instead of original method for register access

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

 - exchange macro naming (RSND_GEN1_S_REG/RSND_GEN1_M_REG)

 sound/soc/sh/rcar/core.c |   45 ---------
 sound/soc/sh/rcar/gen.c  |  231 ++++++++++++++++++++++++++++++----------------
 2 files changed, 150 insertions(+), 126 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index a357060..fc83f0f 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -106,51 +106,6 @@
 	(!(priv->info->func) ? -ENODEV :		\
 	 priv->info->func(param))
 
-
-/*
- *	basic function
- */
-u32 rsnd_read(struct rsnd_priv *priv,
-	      struct rsnd_mod *mod, enum rsnd_reg reg)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-
-	BUG_ON(!base);
-
-	return ioread32(base);
-}
-
-void rsnd_write(struct rsnd_priv *priv,
-		struct rsnd_mod *mod,
-		enum rsnd_reg reg, u32 data)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-	struct device *dev = rsnd_priv_to_dev(priv);
-
-	BUG_ON(!base);
-
-	dev_dbg(dev, "w %p : %08x\n", base, data);
-
-	iowrite32(data, base);
-}
-
-void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
-	       enum rsnd_reg reg, u32 mask, u32 data)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	u32 val;
-
-	BUG_ON(!base);
-
-	val = ioread32(base);
-	val &= ~mask;
-	val |= data & mask;
-	iowrite32(val, base);
-
-	dev_dbg(dev, "s %p : %08x\n", base, val);
-}
-
 /*
  *	rsnd_mod functions
  */
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 331fc55..9a55fdf 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -24,21 +24,106 @@ struct rsnd_gen_ops {
 			 struct rsnd_dai_stream *io);
 };
 
-struct rsnd_gen_reg_map {
-	int index;	/* -1 : not supported */
-	u32 offset_id;	/* offset of ssi0, ssi1, ssi2... */
-	u32 offset_adr;	/* offset of SSICR, SSISR, ... */
-};
-
 struct rsnd_gen {
 	void __iomem *base[RSND_BASE_MAX];
 
-	struct rsnd_gen_reg_map reg_map[RSND_REG_MAX];
 	struct rsnd_gen_ops *ops;
+
+	struct regmap *regmap;
+	struct regmap_field *regs[RSND_REG_MAX];
 };
 
 #define rsnd_priv_to_gen(p)	((struct rsnd_gen *)(p)->gen)
 
+#define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size)	\
+	[id] = {							\
+		.reg = (unsigned int)gen->base[reg_id] + offset,	\
+		.lsb = 0,						\
+		.msb = 31,						\
+		.id_size = _id_size,					\
+		.id_offset = _id_offset,				\
+	}
+
+/*
+ *		basic function
+ */
+static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
+{
+	struct rsnd_priv *priv = context;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 *data = (u32 *)_data;
+	u32 val = data[1];
+	void __iomem *reg = (void *)data[0];
+
+	iowrite32(val, reg);
+
+	dev_dbg(dev, "w %p : %08x\n", reg, val);
+
+	return 0;
+}
+
+static int rsnd_regmap_read32(void *context,
+			      const void *_data, size_t reg_size,
+			      void *_val, size_t val_size)
+{
+	struct rsnd_priv *priv = context;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 *data = (u32 *)_data;
+	u32 *val = (u32 *)_val;
+	void __iomem *reg = (void *)data[0];
+
+	*val = ioread32(reg);
+
+	dev_dbg(dev, "r %p : %08x\n", reg, *val);
+
+	return 0;
+}
+
+static struct regmap_bus rsnd_regmap_bus = {
+	.write				= rsnd_regmap_write32,
+	.read				= rsnd_regmap_read32,
+	.reg_format_endian_default	= REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default	= REGMAP_ENDIAN_NATIVE,
+};
+
+u32 rsnd_read(struct rsnd_priv *priv,
+	      struct rsnd_mod *mod, enum rsnd_reg reg)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+	u32 val;
+
+	if (regmap_fields_enable(gen->regs[reg]))
+		regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
+	else
+		regmap_field_read(gen->regs[reg], &val);
+
+	return val;
+}
+
+void rsnd_write(struct rsnd_priv *priv,
+		struct rsnd_mod *mod,
+		enum rsnd_reg reg, u32 data)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	if (regmap_fields_enable(gen->regs[reg]))
+		regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
+	else
+		regmap_field_write(gen->regs[reg], data);
+}
+
+void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
+	       enum rsnd_reg reg, u32 mask, u32 data)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	if (regmap_fields_enable(gen->regs[reg]))
+		regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
+					  mask, data);
+	else
+		regmap_field_update_bits(gen->regs[reg], mask, data);
+}
+
 /*
  *		Gen2
  *		will be filled in the future
@@ -103,39 +188,62 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
 	return ret;
 }
 
-#define RSND_GEN1_REG_MAP(g, s, i, oi, oa)				\
-	do {								\
-		(g)->reg_map[RSND_REG_##i].index  = RSND_GEN1_##s;	\
-		(g)->reg_map[RSND_REG_##i].offset_id = oi;		\
-		(g)->reg_map[RSND_REG_##i].offset_adr = oa;		\
-	} while (0)
+#define RSND_GEN1_S_REG(gen, reg, id, offset)				\
+	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 0)
 
-static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen)
+#define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset)		\
+	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
+
+static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
 {
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_ROUTE_SEL,	0x0,	0x00);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL0,	0x0,	0x08);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL1,	0x0,	0x0c);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL2,	0x0,	0x10);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_CTRL,	0x0,	0xc0);
-	RSND_GEN1_REG_MAP(gen, SRU,	SSI_MODE0,	0x0,	0xD0);
-	RSND_GEN1_REG_MAP(gen, SRU,	SSI_MODE1,	0x0,	0xD4);
-	RSND_GEN1_REG_MAP(gen, SRU,	BUSIF_MODE,	0x4,	0x20);
-	RSND_GEN1_REG_MAP(gen, SRU,	BUSIF_ADINR,	0x40,	0x214);
-
-	RSND_GEN1_REG_MAP(gen, ADG,	BRRA,		0x0,	0x00);
-	RSND_GEN1_REG_MAP(gen, ADG,	BRRB,		0x0,	0x04);
-	RSND_GEN1_REG_MAP(gen, ADG,	SSICKR,		0x0,	0x08);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL0,	0x0,	0x0c);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL1,	0x0,	0x10);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL3,	0x0,	0x18);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL4,	0x0,	0x1c);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL5,	0x0,	0x20);
-
-	RSND_GEN1_REG_MAP(gen, SSI,	SSICR,		0x40,	0x00);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSISR,		0x40,	0x04);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSITDR,		0x40,	0x08);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSIRDR,		0x40,	0x0c);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSIWSR,		0x40,	0x20);
+	int i;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	struct regmap_config regc;
+	struct reg_field regf[RSND_REG_MAX] = {
+		RSND_GEN1_S_REG(gen, SRU,	SRC_ROUTE_SEL,	0x00),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL0,	0x08),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL1,	0x0c),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL2,	0x10),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_CTRL,	0xc0),
+		RSND_GEN1_S_REG(gen, SRU,	SSI_MODE0,	0xD0),
+		RSND_GEN1_S_REG(gen, SRU,	SSI_MODE1,	0xD4),
+		RSND_GEN1_M_REG(gen,  SRU,	BUSIF_MODE,	0x20,	0x4),
+		RSND_GEN1_M_REG(gen,  SRU,	BUSIF_ADINR,	0x214,	0x40),
+
+		RSND_GEN1_S_REG(gen, ADG,	BRRA,		0x00),
+		RSND_GEN1_S_REG(gen, ADG,	BRRB,		0x04),
+		RSND_GEN1_S_REG(gen, ADG,	SSICKR,		0x08),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL0,	0x0c),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL1,	0x10),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL3,	0x18),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL4,	0x1c),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL5,	0x20),
+
+		RSND_GEN1_M_REG(gen,  SSI,	SSICR,		0x00,	0x40),
+		RSND_GEN1_M_REG(gen,  SSI,	SSISR,		0x04,	0x40),
+		RSND_GEN1_M_REG(gen,  SSI,	SSITDR,		0x08,	0x40),
+		RSND_GEN1_M_REG(gen,  SSI,	SSIRDR,		0x0c,	0x40),
+		RSND_GEN1_M_REG(gen,  SSI,	SSIWSR,		0x20,	0x40),
+	};
+
+	memset(&regc, 0, sizeof(regc));
+	regc.reg_bits = 32;
+	regc.val_bits = 32;
+
+	gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
+	if (IS_ERR(gen->regmap)) {
+		dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
+		return PTR_ERR(gen->regmap);
+	}
+
+	for (i = 0; i < RSND_REG_MAX; i++) {
+		gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
+		if (IS_ERR(gen->regs[i]))
+			return PTR_ERR(gen->regs[i]);
+
+	}
+
+	return 0;
 }
 
 static int rsnd_gen1_probe(struct platform_device *pdev,
@@ -147,6 +255,7 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	struct resource *sru_res;
 	struct resource *adg_res;
 	struct resource *ssi_res;
+	int ret;
 
 	/*
 	 * map address
@@ -163,7 +272,9 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	    IS_ERR(gen->base[RSND_GEN1_SSI]))
 		return -ENODEV;
 
-	rsnd_gen1_reg_map_init(gen);
+	ret = rsnd_gen1_regmap_init(priv, gen);
+	if (ret < 0)
+		return ret;
 
 	dev_dbg(dev, "Gen1 device probed\n");
 	dev_dbg(dev, "SRU : %08x => %p\n",	sru_res->start,
@@ -210,46 +321,12 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv,
 	return gen->ops->path_exit(priv, rdai, io);
 }
 
-void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
-			       struct rsnd_mod *mod,
-			       enum rsnd_reg reg)
-{
-	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	int index;
-	u32 offset_id, offset_adr;
-
-	if (reg >= RSND_REG_MAX) {
-		dev_err(dev, "rsnd_reg reg error\n");
-		return NULL;
-	}
-
-	index		= gen->reg_map[reg].index;
-	offset_id	= gen->reg_map[reg].offset_id;
-	offset_adr	= gen->reg_map[reg].offset_adr;
-
-	if (index < 0) {
-		dev_err(dev, "unsupported reg access %d\n", reg);
-		return NULL;
-	}
-
-	if (offset_id && mod)
-		offset_id *= rsnd_mod_id(mod);
-
-	/*
-	 * index/offset were set on gen1/gen2
-	 */
-
-	return gen->base[index] + offset_id + offset_adr;
-}
-
 int rsnd_gen_probe(struct platform_device *pdev,
 		   struct rcar_snd_info *info,
 		   struct rsnd_priv *priv)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct rsnd_gen *gen;
-	int i;
 
 	gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
 	if (!gen) {
@@ -267,14 +344,6 @@ int rsnd_gen_probe(struct platform_device *pdev,
 
 	priv->gen = gen;
 
-	/*
-	 * see
-	 *	rsnd_reg_get()
-	 *	rsnd_gen_probe()
-	 */
-	for (i = 0; i < RSND_REG_MAX; i++)
-		gen->reg_map[i].index = -1;
-
 	return gen->ops->probe(pdev, info, priv);
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 1/4] regmap: add regmap_field_update_bits()
  2013-09-02  3:24   ` [PATCH v2 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
@ 2013-09-03 11:20     ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2013-09-03 11:20 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 195 bytes --]

On Sun, Sep 01, 2013 at 08:24:50PM -0700, Kuninori Morimoto wrote:
> Current regmap_field is supporting read/write functions.
> This patch adds new update_bits function for it.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 2/4] regmap: Add regmap_fields APIs
  2013-09-02  3:30   ` [PATCH v2 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
@ 2013-09-17 12:48     ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2013-09-17 12:48 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 823 bytes --]

On Sun, Sep 01, 2013 at 08:30:50PM -0700, Kuninori Morimoto wrote:
> Current Linux kernel is supporting regmap_field method
> and it is very useful feature.
> It needs one regmap_filed for one register access.

Applied, thanks.  I did make one update:

> + * A non-zero will be returned when fields access enable,
> + * a zero will be returned in single field.
> + */
> +int regmap_fields_enable(struct regmap_field *field)
> +{
> +	return field->id_size && field->id_offset;
> +}
> +EXPORT_SYMBOL_GPL(regmap_fields_enable);

This seems like it should be something like _is_present() - the name
makes me think it will turn something on, not check that something is
there.  I removed it since it's not used by the following patches and I
didn't notice earlier when I initially looked at the patches during the
merge window.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove
  2013-09-02  3:31   ` [PATCH v2 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
@ 2013-09-17 12:58     ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2013-09-17 12:58 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 208 bytes --]

On Sun, Sep 01, 2013 at 08:31:16PM -0700, Kuninori Morimoto wrote:
> Current rsnd_gen_ops didn't care about .probe and .remove
> functions, but it was not good sense.
> This patch tidyup it

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method
  2013-09-02  3:32   ` [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
@ 2013-09-17 13:04     ` Mark Brown
  2013-09-17 13:23       ` Kuninori Morimoto
  0 siblings, 1 reply; 21+ messages in thread
From: Mark Brown @ 2013-09-17 13:04 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 742 bytes --]

On Sun, Sep 01, 2013 at 08:32:45PM -0700, Kuninori Morimoto wrote:

> +void rsnd_write(struct rsnd_priv *priv,
> +		struct rsnd_mod *mod,
> +		enum rsnd_reg reg, u32 data)
> +{
> +	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
> +
> +	if (regmap_fields_enable(gen->regs[reg]))
> +		regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
> +	else
> +		regmap_field_write(gen->regs[reg], data);
> +}

Ah, sorry - I see you are actually using fields_enable().  I must've
searched for the wrong thing.  However looking at this I'm not sure that
this is a good use anyway, it seems like the caller should know if the
register it is writing to is in one of the repeated blocks.  Can you
provide a bit more detail as to what's going on here?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method
  2013-09-17 13:04     ` Mark Brown
@ 2013-09-17 13:23       ` Kuninori Morimoto
  2013-09-17 13:35         ` Mark Brown
  0 siblings, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-17 13:23 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel


Dear Mark

> > +void rsnd_write(struct rsnd_priv *priv,
> > +		struct rsnd_mod *mod,
> > +		enum rsnd_reg reg, u32 data)
> > +{
> > +	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
> > +
> > +	if (regmap_fields_enable(gen->regs[reg]))
> > +		regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
> > +	else
> > +		regmap_field_write(gen->regs[reg], data);
> > +}
> 
> Ah, sorry - I see you are actually using fields_enable().  I must've
> searched for the wrong thing.  However looking at this I'm not sure that
> this is a good use anyway, it seems like the caller should know if the
> register it is writing to is in one of the repeated blocks.  Can you
> provide a bit more detail as to what's going on here?

Hmm...
rsnd_write/read() care about it (block/non-block),
and caller don't care it, is nice point of this function...

For example, SSI device have many ports (0-8),
but ADG is only 1 device.
On this driver, all devices are using rsnd_write/read() to
access register.

I can re-check it, but it will be next week
Thank you

Best regards
--
Kuninori Morimoto
 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method
  2013-09-17 13:23       ` Kuninori Morimoto
@ 2013-09-17 13:35         ` Mark Brown
  2013-09-24  6:10           ` [PATCH v3 0/2] " Kuninori Morimoto
  0 siblings, 1 reply; 21+ messages in thread
From: Mark Brown @ 2013-09-17 13:35 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 359 bytes --]

On Tue, Sep 17, 2013 at 10:23:58PM +0900, Kuninori Morimoto wrote:

> For example, SSI device have many ports (0-8),
> but ADG is only 1 device.
> On this driver, all devices are using rsnd_write/read() to
> access register.

OK, this sounds like the module should have this information - ie check
something in the module structure rather than asking regmap.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 0/2] ASoC: rsnd: use regmap instead of original register mapping method
  2013-09-17 13:35         ` Mark Brown
@ 2013-09-24  6:10           ` Kuninori Morimoto
  2013-09-24  6:12             ` [PATCH 1/2] ASoC: rsnd: remove rsnd_priv_read/write/bset() Kuninori Morimoto
  2013-09-24  6:12             ` [PATCH 2/2] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
  0 siblings, 2 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-24  6:10 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel


Hi Mark Brown wrote:

> > For example, SSI device have many ports (0-8),
> > but ADG is only 1 device.
> > On this driver, all devices are using rsnd_write/read() to
> > access register.
> 
> OK, this sounds like the module should have this information - ie check
> something in the module structure rather than asking regmap.

OK, new patch uses only "fields" access by using offset = 0.
then, un-needed rsnd_priv_read/write/bset() are removed by 1st patch.

Kuninori Morimoto (2):
      ASoC: rsnd: remove rsnd_priv_read/write/bset()
      ASoC: rsnd: use regmap instead of original register mapping method

 sound/soc/sh/rcar/adg.c  |   10 ++-
 sound/soc/sh/rcar/core.c |   45 ----------
 sound/soc/sh/rcar/gen.c  |  224 +++++++++++++++++++++++++++++-----------------
 sound/soc/sh/rcar/rsnd.h |    4 -
 4 files changed, 150 insertions(+), 133 deletions(-)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/2] ASoC: rsnd: remove rsnd_priv_read/write/bset()
  2013-09-24  6:10           ` [PATCH v3 0/2] " Kuninori Morimoto
@ 2013-09-24  6:12             ` Kuninori Morimoto
  2013-09-24 18:53               ` Mark Brown
  2013-09-24  6:12             ` [PATCH 2/2] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
  1 sibling, 1 reply; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-24  6:12 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

adg.c only used rsnd_priv_read/write/bset()
which is the only user of NULL mod.
but, it can be removed.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/adg.c  |   10 +++++++---
 sound/soc/sh/rcar/rsnd.h |    4 ----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index d80deb7..ad9ceb9 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -22,6 +22,7 @@ struct rsnd_adg {
 
 	int rate_of_441khz_div_6;
 	int rate_of_48khz_div_6;
+	u32 ckr;
 };
 
 #define for_each_rsnd_clk(pos, adg, i)		\
@@ -116,6 +117,11 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
 
 found_clock:
 
+	/* see rsnd_adg_ssi_clk_init() */
+	rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);
+	rsnd_mod_write(mod, BRRA,  0x00000002); /* 1/6 */
+	rsnd_mod_write(mod, BRRB,  0x00000002); /* 1/6 */
+
 	/*
 	 * This "mod" = "ssi" here.
 	 * we can get "ssi id" from mod
@@ -182,9 +188,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
 		}
 	}
 
-	rsnd_priv_bset(priv, SSICKR, 0x00FF0000, ckr);
-	rsnd_priv_write(priv, BRRA,  0x00000002); /* 1/6 */
-	rsnd_priv_write(priv, BRRB,  0x00000002); /* 1/6 */
+	adg->ckr = ckr;
 }
 
 int rsnd_adg_probe(struct platform_device *pdev,
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 9cc6986..3868aaf 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -78,10 +78,6 @@ struct rsnd_dai_stream;
 #define rsnd_mod_bset(m, r, s, d) \
 	rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
 
-#define rsnd_priv_read(p, r)		rsnd_read(p, NULL, RSND_REG_##r)
-#define rsnd_priv_write(p, r, d)	rsnd_write(p, NULL, RSND_REG_##r, d)
-#define rsnd_priv_bset(p, r, s, d)	rsnd_bset(p, NULL, RSND_REG_##r, s, d)
-
 u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
 void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
 		enum rsnd_reg reg, u32 data);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/2] ASoC: rsnd: use regmap instead of original register mapping method
  2013-09-24  6:10           ` [PATCH v3 0/2] " Kuninori Morimoto
  2013-09-24  6:12             ` [PATCH 1/2] ASoC: rsnd: remove rsnd_priv_read/write/bset() Kuninori Morimoto
@ 2013-09-24  6:12             ` Kuninori Morimoto
  1 sibling, 0 replies; 21+ messages in thread
From: Kuninori Morimoto @ 2013-09-24  6:12 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

Current Linux kernel is supporting regmap/regmap_field,
and, it is good match for Renesas Sound Gen1/Gen2 register mapping.
This patch uses regmap instead of original method for register access

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/core.c |   45 ----------
 sound/soc/sh/rcar/gen.c  |  224 +++++++++++++++++++++++++++++-----------------
 2 files changed, 143 insertions(+), 126 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index a357060..fc83f0f 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -106,51 +106,6 @@
 	(!(priv->info->func) ? -ENODEV :		\
 	 priv->info->func(param))
 
-
-/*
- *	basic function
- */
-u32 rsnd_read(struct rsnd_priv *priv,
-	      struct rsnd_mod *mod, enum rsnd_reg reg)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-
-	BUG_ON(!base);
-
-	return ioread32(base);
-}
-
-void rsnd_write(struct rsnd_priv *priv,
-		struct rsnd_mod *mod,
-		enum rsnd_reg reg, u32 data)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-	struct device *dev = rsnd_priv_to_dev(priv);
-
-	BUG_ON(!base);
-
-	dev_dbg(dev, "w %p : %08x\n", base, data);
-
-	iowrite32(data, base);
-}
-
-void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
-	       enum rsnd_reg reg, u32 mask, u32 data)
-{
-	void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	u32 val;
-
-	BUG_ON(!base);
-
-	val = ioread32(base);
-	val &= ~mask;
-	val |= data & mask;
-	iowrite32(val, base);
-
-	dev_dbg(dev, "s %p : %08x\n", base, val);
-}
-
 /*
  *	rsnd_mod functions
  */
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 331fc55..61212ee 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -24,21 +24,97 @@ struct rsnd_gen_ops {
 			 struct rsnd_dai_stream *io);
 };
 
-struct rsnd_gen_reg_map {
-	int index;	/* -1 : not supported */
-	u32 offset_id;	/* offset of ssi0, ssi1, ssi2... */
-	u32 offset_adr;	/* offset of SSICR, SSISR, ... */
-};
-
 struct rsnd_gen {
 	void __iomem *base[RSND_BASE_MAX];
 
-	struct rsnd_gen_reg_map reg_map[RSND_REG_MAX];
 	struct rsnd_gen_ops *ops;
+
+	struct regmap *regmap;
+	struct regmap_field *regs[RSND_REG_MAX];
 };
 
 #define rsnd_priv_to_gen(p)	((struct rsnd_gen *)(p)->gen)
 
+#define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size)	\
+	[id] = {							\
+		.reg = (unsigned int)gen->base[reg_id] + offset,	\
+		.lsb = 0,						\
+		.msb = 31,						\
+		.id_size = _id_size,					\
+		.id_offset = _id_offset,				\
+	}
+
+/*
+ *		basic function
+ */
+static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
+{
+	struct rsnd_priv *priv = context;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 *data = (u32 *)_data;
+	u32 val = data[1];
+	void __iomem *reg = (void *)data[0];
+
+	iowrite32(val, reg);
+
+	dev_dbg(dev, "w %p : %08x\n", reg, val);
+
+	return 0;
+}
+
+static int rsnd_regmap_read32(void *context,
+			      const void *_data, size_t reg_size,
+			      void *_val, size_t val_size)
+{
+	struct rsnd_priv *priv = context;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	u32 *data = (u32 *)_data;
+	u32 *val = (u32 *)_val;
+	void __iomem *reg = (void *)data[0];
+
+	*val = ioread32(reg);
+
+	dev_dbg(dev, "r %p : %08x\n", reg, *val);
+
+	return 0;
+}
+
+static struct regmap_bus rsnd_regmap_bus = {
+	.write				= rsnd_regmap_write32,
+	.read				= rsnd_regmap_read32,
+	.reg_format_endian_default	= REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default	= REGMAP_ENDIAN_NATIVE,
+};
+
+u32 rsnd_read(struct rsnd_priv *priv,
+	      struct rsnd_mod *mod, enum rsnd_reg reg)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+	u32 val;
+
+	regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
+
+	return val;
+}
+
+void rsnd_write(struct rsnd_priv *priv,
+		struct rsnd_mod *mod,
+		enum rsnd_reg reg, u32 data)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
+}
+
+void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
+	       enum rsnd_reg reg, u32 mask, u32 data)
+{
+	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+
+	regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
+				  mask, data);
+}
+
 /*
  *		Gen2
  *		will be filled in the future
@@ -103,39 +179,64 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
 	return ret;
 }
 
-#define RSND_GEN1_REG_MAP(g, s, i, oi, oa)				\
-	do {								\
-		(g)->reg_map[RSND_REG_##i].index  = RSND_GEN1_##s;	\
-		(g)->reg_map[RSND_REG_##i].offset_id = oi;		\
-		(g)->reg_map[RSND_REG_##i].offset_adr = oa;		\
-	} while (0)
+/* single address mapping */
+#define RSND_GEN1_S_REG(gen, reg, id, offset)	\
+	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9)
 
-static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen)
+/* multi address mapping */
+#define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset)	\
+	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
+
+static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
 {
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_ROUTE_SEL,	0x0,	0x00);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL0,	0x0,	0x08);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL1,	0x0,	0x0c);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_TMG_SEL2,	0x0,	0x10);
-	RSND_GEN1_REG_MAP(gen, SRU,	SRC_CTRL,	0x0,	0xc0);
-	RSND_GEN1_REG_MAP(gen, SRU,	SSI_MODE0,	0x0,	0xD0);
-	RSND_GEN1_REG_MAP(gen, SRU,	SSI_MODE1,	0x0,	0xD4);
-	RSND_GEN1_REG_MAP(gen, SRU,	BUSIF_MODE,	0x4,	0x20);
-	RSND_GEN1_REG_MAP(gen, SRU,	BUSIF_ADINR,	0x40,	0x214);
-
-	RSND_GEN1_REG_MAP(gen, ADG,	BRRA,		0x0,	0x00);
-	RSND_GEN1_REG_MAP(gen, ADG,	BRRB,		0x0,	0x04);
-	RSND_GEN1_REG_MAP(gen, ADG,	SSICKR,		0x0,	0x08);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL0,	0x0,	0x0c);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL1,	0x0,	0x10);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL3,	0x0,	0x18);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL4,	0x0,	0x1c);
-	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL5,	0x0,	0x20);
-
-	RSND_GEN1_REG_MAP(gen, SSI,	SSICR,		0x40,	0x00);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSISR,		0x40,	0x04);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSITDR,		0x40,	0x08);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSIRDR,		0x40,	0x0c);
-	RSND_GEN1_REG_MAP(gen, SSI,	SSIWSR,		0x40,	0x20);
+	int i;
+	struct device *dev = rsnd_priv_to_dev(priv);
+	struct regmap_config regc;
+	struct reg_field regf[RSND_REG_MAX] = {
+		RSND_GEN1_S_REG(gen, SRU,	SRC_ROUTE_SEL,	0x00),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL0,	0x08),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL1,	0x0c),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL2,	0x10),
+		RSND_GEN1_S_REG(gen, SRU,	SRC_CTRL,	0xc0),
+		RSND_GEN1_S_REG(gen, SRU,	SSI_MODE0,	0xD0),
+		RSND_GEN1_S_REG(gen, SRU,	SSI_MODE1,	0xD4),
+		RSND_GEN1_M_REG(gen, SRU,	BUSIF_MODE,	0x20,	0x4),
+		RSND_GEN1_M_REG(gen, SRU,	BUSIF_ADINR,	0x214,	0x40),
+
+		RSND_GEN1_S_REG(gen, ADG,	BRRA,		0x00),
+		RSND_GEN1_S_REG(gen, ADG,	BRRB,		0x04),
+		RSND_GEN1_S_REG(gen, ADG,	SSICKR,		0x08),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL0,	0x0c),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL1,	0x10),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL3,	0x18),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL4,	0x1c),
+		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL5,	0x20),
+
+		RSND_GEN1_M_REG(gen, SSI,	SSICR,		0x00,	0x40),
+		RSND_GEN1_M_REG(gen, SSI,	SSISR,		0x04,	0x40),
+		RSND_GEN1_M_REG(gen, SSI,	SSITDR,		0x08,	0x40),
+		RSND_GEN1_M_REG(gen, SSI,	SSIRDR,		0x0c,	0x40),
+		RSND_GEN1_M_REG(gen, SSI,	SSIWSR,		0x20,	0x40),
+	};
+
+	memset(&regc, 0, sizeof(regc));
+	regc.reg_bits = 32;
+	regc.val_bits = 32;
+
+	gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
+	if (IS_ERR(gen->regmap)) {
+		dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
+		return PTR_ERR(gen->regmap);
+	}
+
+	for (i = 0; i < RSND_REG_MAX; i++) {
+		gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
+		if (IS_ERR(gen->regs[i]))
+			return PTR_ERR(gen->regs[i]);
+
+	}
+
+	return 0;
 }
 
 static int rsnd_gen1_probe(struct platform_device *pdev,
@@ -147,6 +248,7 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	struct resource *sru_res;
 	struct resource *adg_res;
 	struct resource *ssi_res;
+	int ret;
 
 	/*
 	 * map address
@@ -163,7 +265,9 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	    IS_ERR(gen->base[RSND_GEN1_SSI]))
 		return -ENODEV;
 
-	rsnd_gen1_reg_map_init(gen);
+	ret = rsnd_gen1_regmap_init(priv, gen);
+	if (ret < 0)
+		return ret;
 
 	dev_dbg(dev, "Gen1 device probed\n");
 	dev_dbg(dev, "SRU : %08x => %p\n",	sru_res->start,
@@ -210,46 +314,12 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv,
 	return gen->ops->path_exit(priv, rdai, io);
 }
 
-void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
-			       struct rsnd_mod *mod,
-			       enum rsnd_reg reg)
-{
-	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
-	struct device *dev = rsnd_priv_to_dev(priv);
-	int index;
-	u32 offset_id, offset_adr;
-
-	if (reg >= RSND_REG_MAX) {
-		dev_err(dev, "rsnd_reg reg error\n");
-		return NULL;
-	}
-
-	index		= gen->reg_map[reg].index;
-	offset_id	= gen->reg_map[reg].offset_id;
-	offset_adr	= gen->reg_map[reg].offset_adr;
-
-	if (index < 0) {
-		dev_err(dev, "unsupported reg access %d\n", reg);
-		return NULL;
-	}
-
-	if (offset_id && mod)
-		offset_id *= rsnd_mod_id(mod);
-
-	/*
-	 * index/offset were set on gen1/gen2
-	 */
-
-	return gen->base[index] + offset_id + offset_adr;
-}
-
 int rsnd_gen_probe(struct platform_device *pdev,
 		   struct rcar_snd_info *info,
 		   struct rsnd_priv *priv)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct rsnd_gen *gen;
-	int i;
 
 	gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
 	if (!gen) {
@@ -267,14 +337,6 @@ int rsnd_gen_probe(struct platform_device *pdev,
 
 	priv->gen = gen;
 
-	/*
-	 * see
-	 *	rsnd_reg_get()
-	 *	rsnd_gen_probe()
-	 */
-	for (i = 0; i < RSND_REG_MAX; i++)
-		gen->reg_map[i].index = -1;
-
 	return gen->ops->probe(pdev, info, priv);
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/2] ASoC: rsnd: remove rsnd_priv_read/write/bset()
  2013-09-24  6:12             ` [PATCH 1/2] ASoC: rsnd: remove rsnd_priv_read/write/bset() Kuninori Morimoto
@ 2013-09-24 18:53               ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2013-09-24 18:53 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Greg Kroah-Hartman, Linux-ALSA, Liam Girdwood, Kuninori Morimoto,
	Simon, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 200 bytes --]

On Mon, Sep 23, 2013 at 11:12:17PM -0700, Kuninori Morimoto wrote:
> adg.c only used rsnd_priv_read/write/bset()
> which is the only user of NULL mod.
> but, it can be removed.

Applied both, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2013-09-24 18:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-30  4:31 [PATCH 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
2013-08-30  4:33 ` [PATCH 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
2013-08-30  4:34 ` [PATCH 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
2013-09-02  2:36   ` Kuninori Morimoto
2013-08-30  4:34 ` [PATCH 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
2013-08-30  4:35 ` [PATCH 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
2013-09-02  3:24 ` [PATCH v2 0/4] add regmap_filelds and use it on Renesas Sound driver Kuninori Morimoto
2013-09-02  3:24   ` [PATCH v2 1/4] regmap: add regmap_field_update_bits() Kuninori Morimoto
2013-09-03 11:20     ` Mark Brown
2013-09-02  3:30   ` [PATCH v2 2/4] regmap: Add regmap_fields APIs Kuninori Morimoto
2013-09-17 12:48     ` Mark Brown
2013-09-02  3:31   ` [PATCH v2 3/4] ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove Kuninori Morimoto
2013-09-17 12:58     ` Mark Brown
2013-09-02  3:32   ` [PATCH v2 4/4] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto
2013-09-17 13:04     ` Mark Brown
2013-09-17 13:23       ` Kuninori Morimoto
2013-09-17 13:35         ` Mark Brown
2013-09-24  6:10           ` [PATCH v3 0/2] " Kuninori Morimoto
2013-09-24  6:12             ` [PATCH 1/2] ASoC: rsnd: remove rsnd_priv_read/write/bset() Kuninori Morimoto
2013-09-24 18:53               ` Mark Brown
2013-09-24  6:12             ` [PATCH 2/2] ASoC: rsnd: use regmap instead of original register mapping method Kuninori Morimoto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).