linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/3] ARM: Tegra: Device Tree: i2c & wm8903
@ 2011-05-11 23:26 John Bonesio
       [not found] ` <20110511232637.10362.84551.stgit@riker>
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: John Bonesio @ 2011-05-11 23:26 UTC (permalink / raw)
  To: linux-arm-kernel

This is revision 2 of my previous patch series:
     Tegra: Harmony: Device Tree first steps

The following patch series is a step in the direction of getting board specific
devices initialized from a device tree.

This patch set adds intiailization of i2c and the wm8903. The i2c controller is
in the SoC and is initialized statically, but the board specific information is
pulled in from the device tree. The wm8903 is initialized using only the device
tree when using the board-dt.c general Tegra board initialization file.

---

John Bonesio (3):
      ARM: Tegra: Device Tree Support: Update how sdhci devices are initialized
      ARM: Tegra: Device Tree Support: Add i2c devices
      ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree


 arch/arm/boot/dts/tegra-harmony.dts |   37 ++++++++++++++
 arch/arm/boot/dts/tegra250.dtsi     |   37 ++++++++++++++
 arch/arm/mach-tegra/Makefile        |    1 
 arch/arm/mach-tegra/board-dt.c      |   94 ++++-------------------------------
 drivers/i2c/busses/i2c-tegra.c      |   16 ++++++
 sound/soc/codecs/wm8903.c           |   93 +++++++++++++++++++++++++++++++++--
 sound/soc/tegra/Kconfig             |    2 -
 sound/soc/tegra/harmony.c           |    8 +++
 8 files changed, 200 insertions(+), 88 deletions(-)

-- 
- John

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

* [RFC 1/3] ARM: Tegra: Device Tree Support: Update how sdhci devices are initialized
       [not found] ` <20110511232637.10362.84551.stgit@riker>
@ 2011-05-12  4:13   ` Stephen Warren
  0 siblings, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2011-05-12  4:13 UTC (permalink / raw)
  To: linux-arm-kernel

John Bonesio wrote at Wednesday, May 11, 2011 5:27 PM:
> This patch changes how sdhci devices are initialized so that a later patch can
> easily add support for i2c devies.
>...
> diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
>...
> +#include <mach/sdhci.h>
>...
> +#include "gpio-names.h"

I don't think either of those headers are needed any more.

Otherwise, looks good.

-- 
nvpublic

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

* [RFC 2/3] ARM: Tegra: Device Tree Support: Add i2c devices
       [not found] ` <20110511232659.10362.45811.stgit@riker>
@ 2011-05-12  4:34   ` Stephen Warren
  2011-05-12  4:47     ` Grant Likely
  0 siblings, 1 reply; 10+ messages in thread
From: Stephen Warren @ 2011-05-12  4:34 UTC (permalink / raw)
  To: linux-arm-kernel

John Bonesio wrote at Wednesday, May 11, 2011 5:27 PM:
> This patch initializes i2c controller devices in board-dt.c. The i2c controller
> is added to tegra250.dtsi so later on-board i2c devices can be found and
> initialized based on the device tree information.
>...
> diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
>...
> +#include <linux/i2c.h>
> +#include <linux/i2c-tegra.h>

I don't think those headers are needed now the platform data isn't set up here.

> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>...
> @@ -598,6 +609,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>  	i2c_dev->adapter.algo = &tegra_i2c_algo;
>  	i2c_dev->adapter.dev.parent = &pdev->dev;
>  	i2c_dev->adapter.nr = pdev->id;
> +	i2c_dev->adapter.dev.of_node = of_node_get(pdev->dev.of_node);

It seems like users of this of_node (i.e. the probe function) could just
access pdev->dev.of_node directly (since pdev is already passed in)
rather than storing a copy here. At least, sdhci-tegra.c works that way.
Still, this isn't a big deal, I think.

> @@ -605,6 +617,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>  		goto err_free_irq;
>  	}
> 
> +	of_i2c_register_devices(&i2c_dev->adapter);
> +

I would have expected that to be performed inside the core I2C code,
probably inside i2c_add_numbered_adapter? Still, it looks like the
other I2C controllers don't already work that way, so this is probably
more a suggestion for future cleanup than something to be addressed in
this patch.

-- 
nvpublic

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

* [RFC 2/3] ARM: Tegra: Device Tree Support: Add i2c devices
  2011-05-12  4:34   ` [RFC 2/3] ARM: Tegra: Device Tree Support: Add i2c devices Stephen Warren
@ 2011-05-12  4:47     ` Grant Likely
  2011-05-12  5:10       ` Stephen Warren
  0 siblings, 1 reply; 10+ messages in thread
From: Grant Likely @ 2011-05-12  4:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 12, 2011 at 6:34 AM, Stephen Warren <swarren@nvidia.com> wrote:
> John Bonesio wrote at Wednesday, May 11, 2011 5:27 PM:
>> This patch initializes i2c controller devices in board-dt.c. The i2c controller
>> is added to tegra250.dtsi so later on-board i2c devices can be found and
>> initialized based on the device tree information.
>>...
>> diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
>>...
>> +#include <linux/i2c.h>
>> +#include <linux/i2c-tegra.h>
>
> I don't think those headers are needed now the platform data isn't set up here.
>
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>>...
>> @@ -598,6 +609,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>> ? ? ? i2c_dev->adapter.algo = &tegra_i2c_algo;
>> ? ? ? i2c_dev->adapter.dev.parent = &pdev->dev;
>> ? ? ? i2c_dev->adapter.nr = pdev->id;
>> + ? ? i2c_dev->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
>
> It seems like users of this of_node (i.e. the probe function) could just
> access pdev->dev.of_node directly (since pdev is already passed in)
> rather than storing a copy here. At least, sdhci-tegra.c works that way.
> Still, this isn't a big deal, I think.

Actually, using of_node_get() here is the right thing since it
increases the reference count on the of_node.  However, the patch
should also do an of_node_put() in the remove hook, or in the .probe
error path.

>
>> @@ -605,6 +617,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>> ? ? ? ? ? ? ? goto err_free_irq;
>> ? ? ? }
>>
>> + ? ? of_i2c_register_devices(&i2c_dev->adapter);
>> +
>
> I would have expected that to be performed inside the core I2C code,
> probably inside i2c_add_numbered_adapter? Still, it looks like the
> other I2C controllers don't already work that way, so this is probably
> more a suggestion for future cleanup than something to be addressed in
> this patch.

This may move into core code in the future, but for the moment the
drivers need to call it explicitly.

g.

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

* [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree
       [not found] ` <20110511232711.10362.53256.stgit@riker>
@ 2011-05-12  5:01   ` Stephen Warren
  2011-05-12  7:49   ` Mark Brown
  1 sibling, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2011-05-12  5:01 UTC (permalink / raw)
  To: linux-arm-kernel

John Bonesio wrote at Wednesday, May 11, 2011 5:27 PM:
> This patch makes it so the wm8903 is initialized from it's device tree
> node.

> diff --git a/arch/arm/boot/dts/tegra-harmony.dts
> b/arch/arm/boot/dts/tegra-harmony.dts
> index af169aa..05521a5 100644
> --- a/arch/arm/boot/dts/tegra-harmony.dts
> +++ b/arch/arm/boot/dts/tegra-harmony.dts
> @@ -19,6 +19,23 @@
>  	i2c at 7000c000 {
>  		status = "ok";
>  		clock-frequency = <400000>;
> +
> +		codec: wm8903 at 1a {
> +			compatible = "wlf,wm8903";
> +			reg = <0x1a>;
> +			interrupts = < 347 >;
> +			irq-active-low = <0>;
> +			micdet-cfg = <0>;
> +			micdet-delay = <100>;

Nit: Maybe group all the WM8903-specific fields together, rather than
spacing them out and interleaving the gpio-controller/gpio-cells in the
middle of them?

> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			gpio-base = < 224 >;
> +			gpio-num-cfg = < 5 >;

I don't think gpio-num-cfg is required; the codec always exports 5 GPIOs.

> +			/* #define WM8903_GPIO_NO_CONFIG 0x8000 */
> +			gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;
> +		};
>  	};
> 
>  	i2c at 7000c400 {
> diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
> index f52b623..2347201 100644
> --- a/sound/soc/codecs/wm8903.c
> +++ b/sound/soc/codecs/wm8903.c
> @@ -1865,10 +1865,14 @@ static void wm8903_init_gpio(struct snd_soc_codec *codec)
>  	wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
>  	wm8903->gpio_chip.dev = codec->dev;
> 
> -	if (pdata && pdata->gpio_base)
> +	wm8903->gpio_chip.base = -1;
> +	if (pdata && pdata->gpio_base) {
>  		wm8903->gpio_chip.base = pdata->gpio_base;
> -	else
> -		wm8903->gpio_chip.base = -1;
> +	} else if (codec->dev->of_node) {
> +		prop = of_get_property(codec->dev->of_node, "gpio-base", NULL);
> +		if (prop)
> +			wm8903->gpio_chip.base = be32_to_cpup(prop);
> +	}

The above checks for pdata first, then falls back to of_node. However,
The previous i2c-tegra.c patch checks of_node first then falls back to
pdata. It seems like the ordering should be consistent (although
changing the I2C patch might be best, since I imagine checking pdata
first would lead to least compatibility issues)

> @@ -1964,10 +1973,76 @@ static int wm8903_probe(struct snd_soc_codec
> *codec)
>  		WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
> 
>  		wm8903->mic_delay = pdata->micdet_delay;
> +	} else if (codec->dev->of_node) {
> +		bool mic_gpio = false;
> +
> +		prop = of_get_property(codec->dev->of_node, "gpio-num-cfg", NULL);
> +		if (prop)
> +			num_gpios = be32_to_cpup(prop);

Again, I'd just hard-code num_gpios==WM8903_NUM_GPIO in the
loop below, instead of making it configurable, since the HW is fixed.

> +		prop = of_get_property(codec->dev->of_node, "gpio-cfg", NULL);
> +		if (num_gpios && prop) {
> +			for (i = 0; i < num_gpios; i++) {
> +				gpio_cfg = be32_to_cpu(prop[i]);
> +
> +				if (gpio_cfg == WM8903_GPIO_NO_CONFIG)
> +					continue;
> +
> +				snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
> +					      gpio_cfg & 0xffff);
> +
> +				val = (gpio_cfg & WM8903_GP1_FN_MASK)
> +					>> WM8903_GP1_FN_SHIFT;
> +
> +				switch (val) {
> +				case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
> +				case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
> +					mic_gpio = true;
> +					break;
> +				default:
> +					break;
> +				}
> +			}
> +		}
> +
> +		prop = of_get_property(codec->dev->of_node, "interrupts", NULL);
> +		if (prop)
> +			wm8903->irq = be32_to_cpup(prop);
> +
> +		prop = of_get_property(codec->dev->of_node, "micdet-cfg", NULL);
> +		if (prop)
> +			micdet_cfg = be32_to_cpup(prop);
> +
> +		snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, micdet_cfg);
> +
> +		if (micdet_cfg)
> +			snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
> +					    WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
> +
> +		/* If microphone detection is enabled in device tree but
> +		 * detected via IRQ then interrupts can be lost before
> +		 * the machine driver has set up microphone detection
> +		 * IRQs as the IRQs are clear on read.  The detection
> +		 * will be enabled when the machine driver configures.
> +		 */
> +		WARN_ON(!mic_gpio && (micdet_cfg & WM8903_MICDET_ENA));
> +
> +		prop = of_get_property(codec->dev->of_node, "micdet-delay", NULL);
> +		if (prop)
> +			wm8903->mic_delay = be32_to_cpup(prop);
> +

The above chunk duplicates a lot of code in the pdata and of_node paths.

Instead, perhaps it'd be better to do something more like:

if (!pdata && of_node) {
    pdata = kalloc()
    read of_node, convert & write to pdata
}
if (pdata) {
    // existing code to handle pdata
}

That way, the code to handle the pdata is re-used and not duplicated.

> diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
>...
> +#ifdef CONFIG_OF
> +	if ((!of_machine_is_compatible("nvidia,harmony")) &&
> (!machine_is_harmony())) {
> +		dev_err(&pdev->dev, "Not running on Tegra Harmony!\n");
> +		return -ENODEV;
> +	}
> +#else
>  	if (!machine_is_harmony()) {
>  		dev_err(&pdev->dev, "Not running on Tegra Harmony!\n");
>  		return -ENODEV;
>  	}
> +#endif

Is that backwards-compatible if CONFIG_OF is enabled, but a devicetree
wasn't provided, but instead the old-style Harmony machine ID was used?
I note that the board-harmony.c machine description doesn't include a
DT_MACHINE_START listing that compatible value; only board-dt.c does
this, and that has a different ARM machine ID.

-- 
nvpublic

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

* [RFC 2/3] ARM: Tegra: Device Tree Support: Add i2c devices
  2011-05-12  4:47     ` Grant Likely
@ 2011-05-12  5:10       ` Stephen Warren
  0 siblings, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2011-05-12  5:10 UTC (permalink / raw)
  To: linux-arm-kernel

Grant Likely wrote at Wednesday, May 11, 2011 10:47 PM:
> On Thu, May 12, 2011 at 6:34 AM, Stephen Warren <swarren@nvidia.com> wrote:
> > John Bonesio wrote at Wednesday, May 11, 2011 5:27 PM:
> >> This patch initializes i2c controller devices in board-dt.c. The i2c controller
> >> is added to tegra250.dtsi so later on-board i2c devices can be found and
> >> initialized based on the device tree information.
> >>...
> >> @@ -598,6 +609,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
> >> ? ? ? i2c_dev->adapter.algo = &tegra_i2c_algo;
> >> ? ? ? i2c_dev->adapter.dev.parent = &pdev->dev;
> >> ? ? ? i2c_dev->adapter.nr = pdev->id;
> >> + ? ? i2c_dev->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
> >
> > It seems like users of this of_node (i.e. the probe function) could just
> > access pdev->dev.of_node directly (since pdev is already passed in)
> > rather than storing a copy here. At least, sdhci-tegra.c works that way.
> > Still, this isn't a big deal, I think.
> 
> Actually, using of_node_get() here is the right thing since it
> increases the reference count on the of_node.  However, the patch
> should also do an of_node_put() in the remove hook, or in the .probe
> error path.

Ah OK, I was missing that the later all of of_i2c_register_devices()
uses i2c_dev->adapter.dev.of_node; I was thinking that it'd just use
i2c_dev->adapter.dev.parent->of_node directly, in which case we
wouldn't need to copy the pointer, nor increment the refcount.

So, I agree this is OK.

-- 
nvpublic

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

* [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree
       [not found] ` <20110511232711.10362.53256.stgit@riker>
  2011-05-12  5:01   ` [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree Stephen Warren
@ 2011-05-12  7:49   ` Mark Brown
  2011-06-02 16:46     ` Grant Likely
  2011-06-03 16:20     ` Grant Likely
  1 sibling, 2 replies; 10+ messages in thread
From: Mark Brown @ 2011-05-12  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 11, 2011 at 04:27:18PM -0700, John Bonesio wrote:
> This patch makes it so the wm8903 is initialized from it's device tree node.
> 
> Signed-off-by: John Bonesio<bones@secretlab.ca>
> ---
> 
>  arch/arm/boot/dts/tegra-harmony.dts |   17 ++++++
>  sound/soc/codecs/wm8903.c           |   93 +++++++++++++++++++++++++++++++++--

This needs to be sent separately to the relevant mailing lists and
maintainers.  You can't go making substantial changes to drivers without
even telling the maintainers about it - this will apply to any device
tree work you're doing.  In this case one of the maintainers happens to
be me, but even so.

> +			interrupts = < 347 >;
> +			irq-active-low = <0>;
> +			micdet-cfg = <0>;
> +			micdet-delay = <100>;

Some of this looks like chip default, why is it being configured?

> +                       gpio-controller;
> +                       #gpio-cells = <2>;

The fact that this device is a GPIO controller is a physical property of
the device, we shouldn't need to be putting it into the device tree.

> +			gpio-num-cfg = < 5 >;

Similarly here, the device has a fixed number of GPIOs.

> +			/* #define WM8903_GPIO_NO_CONFIG 0x8000 */
> +			gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;

This doesn't seem great for usability.  I'd suggest key/value pairs
rather than an array.

> -	if (pdata && pdata->gpio_base)
> +	wm8903->gpio_chip.base = -1;
> +	if (pdata && pdata->gpio_base) {
>  		wm8903->gpio_chip.base = pdata->gpio_base;
> -	else
> -		wm8903->gpio_chip.base = -1;
> +	} else if (codec->dev->of_node) {
> +		prop = of_get_property(codec->dev->of_node, "gpio-base", NULL);
> +		if (prop)
> +			wm8903->gpio_chip.base = be32_to_cpup(prop);
> +	}

We have to do manual endianness conversions to read from the device
tree?  Oh, well.

> +
> +		prop = of_get_property(codec->dev->of_node, "interrupts", NULL);
> +		if (prop)
> +			wm8903->irq = be32_to_cpup(prop);
> +

We have a standard way of passing the IRQ number to I2C devices, surely
we should make sure that works at the bus level rather than having to
replicate this code everywhere?

> +		prop = of_get_property(codec->dev->of_node, "micdet-cfg", NULL);
> +		if (prop)
> +			micdet_cfg = be32_to_cpup(prop);
> +
> +		snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, micdet_cfg);
> +
> +		if (micdet_cfg)
> +			snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
> +					    WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
> +		
> +		/* If microphone detection is enabled in device tree but
> +		 * detected via IRQ then interrupts can be lost before
> +		 * the machine driver has set up microphone detection
> +		 * IRQs as the IRQs are clear on read.  The detection
> +		 * will be enabled when the machine driver configures.
> +		 */
> +		WARN_ON(!mic_gpio && (micdet_cfg & WM8903_MICDET_ENA));
> +

There's an awful lot of cut'n'paste code for the parsing code from the
platform data code.

>  config SND_TEGRA_SOC_HARMONY
>  	tristate "SoC Audio support for Tegra Harmony reference board"
> -	depends on SND_TEGRA_SOC && MACH_HARMONY && I2C
> +	depends on SND_TEGRA_SOC && (MACH_HARMONY || MACH_TEGRA_DT) && I2C

You've not added anything to the device tree to register the platform
device for the machine and I rather fear this won't apply to current
code.  You should develop against -next.

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

* [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree
  2011-05-12  7:49   ` Mark Brown
@ 2011-06-02 16:46     ` Grant Likely
  2011-06-03  9:06       ` Mark Brown
  2011-06-03 16:20     ` Grant Likely
  1 sibling, 1 reply; 10+ messages in thread
From: Grant Likely @ 2011-06-02 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 12, 2011 at 1:49 AM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, May 11, 2011 at 04:27:18PM -0700, John Bonesio wrote:
>> - ? ? if (pdata && pdata->gpio_base)
>> + ? ? wm8903->gpio_chip.base = -1;
>> + ? ? if (pdata && pdata->gpio_base) {
>> ? ? ? ? ? ? ? wm8903->gpio_chip.base = pdata->gpio_base;
>> - ? ? else
>> - ? ? ? ? ? ? wm8903->gpio_chip.base = -1;
>> + ? ? } else if (codec->dev->of_node) {
>> + ? ? ? ? ? ? prop = of_get_property(codec->dev->of_node, "gpio-base", NULL);
>> + ? ? ? ? ? ? if (prop)
>> + ? ? ? ? ? ? ? ? ? ? wm8903->gpio_chip.base = be32_to_cpup(prop);
>> + ? ? }
>
> We have to do manual endianness conversions to read from the device
> tree? ?Oh, well.

Yeah, it's not great.  I'd really like to have a set of helper
functions that locate and decode the data for the most common types of
properties, but I've not sat down to focus on it and I've not seen a
pattern I'm happy with yet.  It does need to be solved though.  The
issue is I want something that handles fetching the property, error
checking and decoding, all in a consistent way so that it actually
reduces the amount of parsing code required.

Perhaps something like:

/* Not sure about this; in this case the return value is an error code
so that bad properties can be detected */
int dt_decode_cell(struct *property, int index, u32 *out_val);
int dt_decode_string(struct *property, int index, char **out_val);
int dt_decode_number(struct *property, int start, int len, unsigned
long long *out_val);

and perhaps a set of companion functions:
int dt_get_prop_cell(struct *device_node, char *propname, int index,
u32 *out_val);
int dt_get_prop_string(struct *device_node, char *propname, int index,
char **out_val);
int dt_get_prop_number(struct *device_node, char *propname, int start,
int len, unsigned long long *out_val);

The first set would be used when the property pointer has already be
obtained, and multiple datum need to be extracted.  The second would
be most useful when only one value will be extracted from a property.
I'm not totally happy with returning the value via a passed in pointer
though.  Thoughts?

g.

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

* [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree
  2011-06-02 16:46     ` Grant Likely
@ 2011-06-03  9:06       ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2011-06-03  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 02, 2011 at 10:46:18AM -0600, Grant Likely wrote:

> Yeah, it's not great.  I'd really like to have a set of helper
> functions that locate and decode the data for the most common types of
> properties, but I've not sat down to focus on it and I've not seen a
> pattern I'm happy with yet.  It does need to be solved though.  The

Yes, looking at the examples you've got below it looks like you've got a
similar set of issues to the ones that I've been running into trying to
factor the register map access code out of ASoC.

> Perhaps something like:

> /* Not sure about this; in this case the return value is an error code
> so that bad properties can be detected */
> int dt_decode_cell(struct *property, int index, u32 *out_val);
> int dt_decode_string(struct *property, int index, char **out_val);
> int dt_decode_number(struct *property, int start, int len, unsigned
> long long *out_val);

> and perhaps a set of companion functions:
> int dt_get_prop_cell(struct *device_node, char *propname, int index,
> u32 *out_val);
> int dt_get_prop_string(struct *device_node, char *propname, int index,
> char **out_val);
> int dt_get_prop_number(struct *device_node, char *propname, int start,
> int len, unsigned long long *out_val);

> The first set would be used when the property pointer has already be
> obtained, and multiple datum need to be extracted.  The second would
> be most useful when only one value will be extracted from a property.
> I'm not totally happy with returning the value via a passed in pointer
> though.  Thoughts?

Yes, I think this sort of format with the error out of band from the
number is best if a little ugly, and especially the second set is
definitely going to cut down the amount of boiler plate code.  It's a
little painful having to pass a pointer to the result but otherwise the
error handling gets a bit rubbish, especially for the numbers where
there really isn't a sensible invalid value.

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

* [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree
  2011-05-12  7:49   ` Mark Brown
  2011-06-02 16:46     ` Grant Likely
@ 2011-06-03 16:20     ` Grant Likely
  1 sibling, 0 replies; 10+ messages in thread
From: Grant Likely @ 2011-06-03 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 12, 2011 at 1:49 AM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, May 11, 2011 at 04:27:18PM -0700, John Bonesio wrote:
>> This patch makes it so the wm8903 is initialized from it's device tree node.
>>
>> Signed-off-by: John Bonesio<bones@secretlab.ca>
>> ---
>>
>> ?arch/arm/boot/dts/tegra-harmony.dts | ? 17 ++++++
>> ?sound/soc/codecs/wm8903.c ? ? ? ? ? | ? 93 +++++++++++++++++++++++++++++++++--
>
> This needs to be sent separately to the relevant mailing lists and
> maintainers. ?You can't go making substantial changes to drivers without
> even telling the maintainers about it - this will apply to any device
> tree work you're doing. ?In this case one of the maintainers happens to
> be me, but even so.
>
>> + ? ? ? ? ? ? ? ? ? ? interrupts = < 347 >;
>> + ? ? ? ? ? ? ? ? ? ? irq-active-low = <0>;
>> + ? ? ? ? ? ? ? ? ? ? micdet-cfg = <0>;
>> + ? ? ? ? ? ? ? ? ? ? micdet-delay = <100>;
>
> Some of this looks like chip default, why is it being configured?
>
>> + ? ? ? ? ? ? ? ? ? ? ? gpio-controller;
>> + ? ? ? ? ? ? ? ? ? ? ? #gpio-cells = <2>;
>
> The fact that this device is a GPIO controller is a physical property of
> the device, we shouldn't need to be putting it into the device tree.
>
>> + ? ? ? ? ? ? ? ? ? ? gpio-num-cfg = < 5 >;
>
> Similarly here, the device has a fixed number of GPIOs.
>
>> + ? ? ? ? ? ? ? ? ? ? /* #define WM8903_GPIO_NO_CONFIG 0x8000 */
>> + ? ? ? ? ? ? ? ? ? ? gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;
>
> This doesn't seem great for usability. ?I'd suggest key/value pairs
> rather than an array.
>
>> - ? ? if (pdata && pdata->gpio_base)
>> + ? ? wm8903->gpio_chip.base = -1;
>> + ? ? if (pdata && pdata->gpio_base) {
>> ? ? ? ? ? ? ? wm8903->gpio_chip.base = pdata->gpio_base;
>> - ? ? else
>> - ? ? ? ? ? ? wm8903->gpio_chip.base = -1;
>> + ? ? } else if (codec->dev->of_node) {
>> + ? ? ? ? ? ? prop = of_get_property(codec->dev->of_node, "gpio-base", NULL);
>> + ? ? ? ? ? ? if (prop)
>> + ? ? ? ? ? ? ? ? ? ? wm8903->gpio_chip.base = be32_to_cpup(prop);
>> + ? ? }
>
> We have to do manual endianness conversions to read from the device
> tree? ?Oh, well.
>
>> +
>> + ? ? ? ? ? ? prop = of_get_property(codec->dev->of_node, "interrupts", NULL);
>> + ? ? ? ? ? ? if (prop)
>> + ? ? ? ? ? ? ? ? ? ? wm8903->irq = be32_to_cpup(prop);
>> +
>
> We have a standard way of passing the IRQ number to I2C devices, surely
> we should make sure that works at the bus level rather than having to
> replicate this code everywhere?

Yes actually there is.  The code in drivers/of/of_i2c.c already
correctly populates the i2c_client irq from the device tree.  This
hunk can be completely removed.

g.

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

end of thread, other threads:[~2011-06-03 16:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-11 23:26 [RFC 0/3] ARM: Tegra: Device Tree: i2c & wm8903 John Bonesio
     [not found] ` <20110511232637.10362.84551.stgit@riker>
2011-05-12  4:13   ` [RFC 1/3] ARM: Tegra: Device Tree Support: Update how sdhci devices are initialized Stephen Warren
     [not found] ` <20110511232659.10362.45811.stgit@riker>
2011-05-12  4:34   ` [RFC 2/3] ARM: Tegra: Device Tree Support: Add i2c devices Stephen Warren
2011-05-12  4:47     ` Grant Likely
2011-05-12  5:10       ` Stephen Warren
     [not found] ` <20110511232711.10362.53256.stgit@riker>
2011-05-12  5:01   ` [RFC 3/3] ARM:Tegra: Device Tree Support: Initialize from wm8903 the device tree Stephen Warren
2011-05-12  7:49   ` Mark Brown
2011-06-02 16:46     ` Grant Likely
2011-06-03  9:06       ` Mark Brown
2011-06-03 16:20     ` Grant Likely

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).