Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH] arm64: dts: rockchip: fix the memory size of PX5 Evaluation board
From: Heiko Stuebner @ 2017-04-07 21:15 UTC (permalink / raw)
  To: Andy Yan
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1491553169-21106-1-git-send-email-andy.yan-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Am Freitag, 7. April 2017, 16:19:29 CEST schrieb Andy Yan:
> Commit 122682b2abb6 ("arm64: dts: rockchip: Add PX5 Evaluation board")
> sets the memory size to 2 GB, but this board only has 1 GB DRAM, so change
> it to the correct value here.
> 
> Signed-off-by: Andy Yan <andy.yan-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

I've added a
Fixes: 122682b2abb6 ("arm64: dts: rockchip: Add PX5 Evaluation board")

and applied it for 4.12


Thanks
Heiko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Applied "ASoC: Add support for Maxim Integrated MAX98927 Amplifier" to the asoc tree
From: Ryan Lee @ 2017-04-07 21:29 UTC (permalink / raw)
  To: Mark Brown
  Cc: Liam Girdwood, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	Kuninori Morimoto, Arnd Bergmann,
	ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	lars-Qo5EllUWu/uELgA04lAiVw, bardliao-Rasf1IRRPZFBDgjK7y7TUQ,
	nh6z-fFIq/eER6g8, KCHSU0-KrzQf0k3Iz9BDgjK7y7TUQ, Axel Lin,
	romain.perier-ZGY8ohtN/8qB+jHODAdFcQ, Srinivas Kandagatla,
	oder_chiou-Rasf1IRRPZFBDgjK7y7TUQ,
	Paul.Handrigan-jGc1dHjMKG3QT0dZR+AlfA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Dylan Reid
In-Reply-To: <E1cwCZ1-0001o4-Q5@debutante>

I appreciate for your effort in MAX98927 driver upstream. I will take
follow up if there's any update.

On Thu, Apr 6, 2017 at 11:55 AM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> The patch
>
>    ASoC: Add support for Maxim Integrated MAX98927 Amplifier
>
> has been applied to the asoc tree at
>
>    git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
>
> All being well this means that it will be integrated into the linux-next
> tree (usually sometime in the next 24 hours) and sent to Linus during
> the next merge window (or sooner if it is a bug fix), however if
> problems are discovered then the patch may be dropped or reverted.
>
> You may get further e-mails resulting from automated or manual testing
> and review of the tree, please engage with people reporting problems and
> send followup patches addressing any issues that are reported if needed.
>
> If any updates are required or you are submitting further changes they
> should be sent as incremental updates against current git, existing
> patches will not be replaced.
>
> Please add any relevant lists and maintainers to the CCs when replying
> to this mail.
>
> Thanks,
> Mark
>
> From 7c0c2000716e64151b3c0c62026c18f31537ebe9 Mon Sep 17 00:00:00 2001
> From: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> Date: Tue, 4 Apr 2017 02:23:08 +0900
> Subject: [PATCH] ASoC: Add support for Maxim Integrated MAX98927 Amplifier
>
> Signed-off-by: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
>  .../devicetree/bindings/sound/max98925.txt         |  22 -
>  .../devicetree/bindings/sound/max98926.txt         |  32 -
>  .../devicetree/bindings/sound/max9892x.txt         |  41 +
>  sound/soc/codecs/Kconfig                           |   5 +
>  sound/soc/codecs/Makefile                          |   2 +
>  sound/soc/codecs/max98927.c                        | 841 +++++++++++++++++++++
>  sound/soc/codecs/max98927.h                        | 272 +++++++
>  7 files changed, 1161 insertions(+), 54 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/sound/max98925.txt
>  delete mode 100644 Documentation/devicetree/bindings/sound/max98926.txt
>  create mode 100644 Documentation/devicetree/bindings/sound/max9892x.txt
>  create mode 100644 sound/soc/codecs/max98927.c
>  create mode 100644 sound/soc/codecs/max98927.h
>
> diff --git a/Documentation/devicetree/bindings/sound/max98925.txt b/Documentation/devicetree/bindings/sound/max98925.txt
> deleted file mode 100644
> index 27be63e2aa0d..000000000000
> --- a/Documentation/devicetree/bindings/sound/max98925.txt
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -max98925 audio CODEC
> -
> -This device supports I2C.
> -
> -Required properties:
> -
> -  - compatible : "maxim,max98925"
> -
> -  - vmon-slot-no : slot number used to send voltage information
> -
> -  - imon-slot-no : slot number used to send current information
> -
> -  - reg : the I2C address of the device for I2C
> -
> -Example:
> -
> -codec: max98925@1a {
> -       compatible = "maxim,max98925";
> -       vmon-slot-no = <0>;
> -       imon-slot-no = <2>;
> -       reg = <0x1a>;
> -};
> diff --git a/Documentation/devicetree/bindings/sound/max98926.txt b/Documentation/devicetree/bindings/sound/max98926.txt
> deleted file mode 100644
> index 0b7f4e4d5f9a..000000000000
> --- a/Documentation/devicetree/bindings/sound/max98926.txt
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -max98926 audio CODEC
> -
> -This device supports I2C.
> -
> -Required properties:
> -
> -  - compatible : "maxim,max98926"
> -
> -  - vmon-slot-no : slot number used to send voltage information
> -                   or in inteleave mode this will be used as
> -                   interleave slot.
> -
> -  - imon-slot-no : slot number used to send current information
> -
> -  - interleave-mode : When using two MAX98926 in a system it is
> -                      possible to create ADC data that that will
> -                      overflow the frame size. Digital Audio Interleave
> -                      mode provides a means to output VMON and IMON data
> -                      from two devices on a single DOUT line when running
> -                      smaller frames sizes such as 32 BCLKS per LRCLK or
> -                      48 BCLKS per LRCLK.
> -
> -  - reg : the I2C address of the device for I2C
> -
> -Example:
> -
> -codec: max98926@1a {
> -   compatible = "maxim,max98926";
> -   vmon-slot-no = <0>;
> -   imon-slot-no = <2>;
> -   reg = <0x1a>;
> -};
> diff --git a/Documentation/devicetree/bindings/sound/max9892x.txt b/Documentation/devicetree/bindings/sound/max9892x.txt
> new file mode 100644
> index 000000000000..f6171591ddc6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/max9892x.txt
> @@ -0,0 +1,41 @@
> +Maxim Integrated MAX98925/MAX98926/MAX98927 Speaker Amplifier
> +
> +This device supports I2C.
> +
> +Required properties:
> +
> +  - compatible : should be one of the following
> +    - "maxim,max98925"
> +    - "maxim,max98926"
> +    - "maxim,max98927"
> +
> +  - vmon-slot-no : slot number used to send voltage information
> +                   or in inteleave mode this will be used as
> +                   interleave slot.
> +                   MAX98925/MAX98926 slot range : 0 ~ 30,  Default : 0
> +                   MAX98927 slot range : 0 ~ 15,  Default : 0
> +
> +  - imon-slot-no : slot number used to send current information
> +                   MAX98925/MAX98926 slot range : 0 ~ 30,  Default : 0
> +                   MAX98927 slot range : 0 ~ 15,  Default : 0
> +
> +  - interleave-mode : When using two MAX9892X in a system it is
> +                   possible to create ADC data that that will
> +                   overflow the frame size. Digital Audio Interleave
> +                   mode provides a means to output VMON and IMON data
> +                   from two devices on a single DOUT line when running
> +                   smaller frames sizes such as 32 BCLKS per LRCLK or
> +                   48 BCLKS per LRCLK.
> +                   Range : 0 (off), 1 (on),  Default : 0
> +
> +  - reg : the I2C address of the device for I2C
> +
> +Example:
> +
> +codec: max98927@3a {
> +   compatible = "maxim,max98927";
> +   vmon-slot-no = <0>;
> +   imon-slot-no = <1>;
> +   interleave-mode = <0>;
> +   reg = <0x3a>;
> +};
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 9e1718a8cb1c..65e31ab88280 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -89,6 +89,7 @@ config SND_SOC_ALL_CODECS
>         select SND_SOC_MAX9867 if I2C
>         select SND_SOC_MAX98925 if I2C
>         select SND_SOC_MAX98926 if I2C
> +       select SND_SOC_MAX98927 if I2C
>         select SND_SOC_MAX9850 if I2C
>         select SND_SOC_MAX9860 if I2C
>         select SND_SOC_MAX9768 if I2C
> @@ -585,6 +586,10 @@ config SND_SOC_MAX98925
>  config SND_SOC_MAX98926
>         tristate
>
> +config SND_SOC_MAX98927
> +       tristate "Maxim Integrated MAX98927 Speaker Amplifier"
> +       depends on I2C
> +
>  config SND_SOC_MAX9850
>         tristate
>
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index 7e1dad79610b..64656c43200c 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -84,6 +84,7 @@ snd-soc-max98371-objs := max98371.o
>  snd-soc-max9867-objs := max9867.o
>  snd-soc-max98925-objs := max98925.o
>  snd-soc-max98926-objs := max98926.o
> +snd-soc-max98927-objs := max98927.o
>  snd-soc-max9850-objs := max9850.o
>  snd-soc-max9860-objs := max9860.o
>  snd-soc-mc13783-objs := mc13783.o
> @@ -312,6 +313,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A)     += snd-soc-max98357a.o
>  obj-$(CONFIG_SND_SOC_MAX9867)  += snd-soc-max9867.o
>  obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
>  obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
> +obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
>  obj-$(CONFIG_SND_SOC_MAX9850)  += snd-soc-max9850.o
>  obj-$(CONFIG_SND_SOC_MAX9860)  += snd-soc-max9860.o
>  obj-$(CONFIG_SND_SOC_MC13783)  += snd-soc-mc13783.o
> diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
> new file mode 100644
> index 000000000000..b5ee29499e16
> --- /dev/null
> +++ b/sound/soc/codecs/max98927.c
> @@ -0,0 +1,841 @@
> +/*
> + * max98927.c  --  MAX98927 ALSA Soc Audio driver
> + *
> + * Copyright (C) 2016 Maxim Integrated Products
> + * Author: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> + *
> + *  This program is free software; you can redistribute  it and/or modify it
> + *  under  the terms of  the GNU General  Public License as published by the
> + *  Free Software Foundation;  either version 2 of the  License, or (at your
> + *  option) any later version.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/cdev.h>
> +#include <sound/pcm.h>
> +#include <sound/pcm_params.h>
> +#include <sound/soc.h>
> +#include <linux/gpio.h>
> +#include <linux/of_gpio.h>
> +#include <sound/tlv.h>
> +#include "max98927.h"
> +
> +static struct reg_default max98927_reg[] = {
> +       {MAX98927_R0001_INT_RAW1,  0x00},
> +       {MAX98927_R0002_INT_RAW2,  0x00},
> +       {MAX98927_R0003_INT_RAW3,  0x00},
> +       {MAX98927_R0004_INT_STATE1,  0x00},
> +       {MAX98927_R0005_INT_STATE2,  0x00},
> +       {MAX98927_R0006_INT_STATE3,  0x00},
> +       {MAX98927_R0007_INT_FLAG1,  0x00},
> +       {MAX98927_R0008_INT_FLAG2,  0x00},
> +       {MAX98927_R0009_INT_FLAG3,  0x00},
> +       {MAX98927_R000A_INT_EN1,  0x00},
> +       {MAX98927_R000B_INT_EN2,  0x00},
> +       {MAX98927_R000C_INT_EN3,  0x00},
> +       {MAX98927_R000D_INT_FLAG_CLR1,  0x00},
> +       {MAX98927_R000E_INT_FLAG_CLR2,  0x00},
> +       {MAX98927_R000F_INT_FLAG_CLR3,  0x00},
> +       {MAX98927_R0010_IRQ_CTRL,  0x00},
> +       {MAX98927_R0011_CLK_MON,  0x00},
> +       {MAX98927_R0012_WDOG_CTRL,  0x00},
> +       {MAX98927_R0013_WDOG_RST,  0x00},
> +       {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH,  0x00},
> +       {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH,  0x00},
> +       {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS,  0x00},
> +       {MAX98927_R0017_PIN_CFG,  0x55},
> +       {MAX98927_R0018_PCM_RX_EN_A,  0x00},
> +       {MAX98927_R0019_PCM_RX_EN_B,  0x00},
> +       {MAX98927_R001A_PCM_TX_EN_A,  0x00},
> +       {MAX98927_R001B_PCM_TX_EN_B,  0x00},
> +       {MAX98927_R001C_PCM_TX_HIZ_CTRL_A,  0x00},
> +       {MAX98927_R001D_PCM_TX_HIZ_CTRL_B,  0x00},
> +       {MAX98927_R001E_PCM_TX_CH_SRC_A,  0x00},
> +       {MAX98927_R001F_PCM_TX_CH_SRC_B,  0x00},
> +       {MAX98927_R0020_PCM_MODE_CFG,  0x40},
> +       {MAX98927_R0021_PCM_MASTER_MODE,  0x00},
> +       {MAX98927_R0022_PCM_CLK_SETUP,  0x22},
> +       {MAX98927_R0023_PCM_SR_SETUP1,  0x00},
> +       {MAX98927_R0024_PCM_SR_SETUP2,  0x00},
> +       {MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,  0x00},
> +       {MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,  0x00},
> +       {MAX98927_R0027_ICC_RX_EN_A,  0x00},
> +       {MAX98927_R0028_ICC_RX_EN_B,  0x00},
> +       {MAX98927_R002B_ICC_TX_EN_A,  0x00},
> +       {MAX98927_R002C_ICC_TX_EN_B,  0x00},
> +       {MAX98927_R002E_ICC_HIZ_MANUAL_MODE,  0x00},
> +       {MAX98927_R002F_ICC_TX_HIZ_EN_A,  0x00},
> +       {MAX98927_R0030_ICC_TX_HIZ_EN_B,  0x00},
> +       {MAX98927_R0031_ICC_LNK_EN,  0x00},
> +       {MAX98927_R0032_PDM_TX_EN,  0x00},
> +       {MAX98927_R0033_PDM_TX_HIZ_CTRL,  0x00},
> +       {MAX98927_R0034_PDM_TX_CTRL,  0x00},
> +       {MAX98927_R0035_PDM_RX_CTRL,  0x00},
> +       {MAX98927_R0036_AMP_VOL_CTRL,  0x00},
> +       {MAX98927_R0037_AMP_DSP_CFG,  0x02},
> +       {MAX98927_R0038_TONE_GEN_DC_CFG,  0x00},
> +       {MAX98927_R0039_DRE_CTRL,  0x01},
> +       {MAX98927_R003A_AMP_EN,  0x00},
> +       {MAX98927_R003B_SPK_SRC_SEL,  0x00},
> +       {MAX98927_R003C_SPK_GAIN,  0x00},
> +       {MAX98927_R003D_SSM_CFG,  0x01},
> +       {MAX98927_R003E_MEAS_EN,  0x00},
> +       {MAX98927_R003F_MEAS_DSP_CFG,  0x04},
> +       {MAX98927_R0040_BOOST_CTRL0,  0x00},
> +       {MAX98927_R0041_BOOST_CTRL3,  0x00},
> +       {MAX98927_R0042_BOOST_CTRL1,  0x00},
> +       {MAX98927_R0043_MEAS_ADC_CFG,  0x00},
> +       {MAX98927_R0044_MEAS_ADC_BASE_MSB,  0x00},
> +       {MAX98927_R0045_MEAS_ADC_BASE_LSB,  0x00},
> +       {MAX98927_R0046_ADC_CH0_DIVIDE,  0x00},
> +       {MAX98927_R0047_ADC_CH1_DIVIDE,  0x00},
> +       {MAX98927_R0048_ADC_CH2_DIVIDE,  0x00},
> +       {MAX98927_R0049_ADC_CH0_FILT_CFG,  0x00},
> +       {MAX98927_R004A_ADC_CH1_FILT_CFG,  0x00},
> +       {MAX98927_R004B_ADC_CH2_FILT_CFG,  0x00},
> +       {MAX98927_R004C_MEAS_ADC_CH0_READ,  0x00},
> +       {MAX98927_R004D_MEAS_ADC_CH1_READ,  0x00},
> +       {MAX98927_R004E_MEAS_ADC_CH2_READ,  0x00},
> +       {MAX98927_R0051_BROWNOUT_STATUS,  0x00},
> +       {MAX98927_R0052_BROWNOUT_EN,  0x00},
> +       {MAX98927_R0053_BROWNOUT_INFINITE_HOLD,  0x00},
> +       {MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR,  0x00},
> +       {MAX98927_R0055_BROWNOUT_LVL_HOLD,  0x00},
> +       {MAX98927_R005A_BROWNOUT_LVL1_THRESH,  0x00},
> +       {MAX98927_R005B_BROWNOUT_LVL2_THRESH,  0x00},
> +       {MAX98927_R005C_BROWNOUT_LVL3_THRESH,  0x00},
> +       {MAX98927_R005D_BROWNOUT_LVL4_THRESH,  0x00},
> +       {MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS,  0x00},
> +       {MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL,  0x00},
> +       {MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL,  0x00},
> +       {MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE,  0x00},
> +       {MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT,  0x00},
> +       {MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1,  0x00},
> +       {MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2,  0x00},
> +       {MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3,  0x00},
> +       {MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT,  0x00},
> +       {MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1,  0x00},
> +       {MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2,  0x00},
> +       {MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3,  0x00},
> +       {MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT,  0x00},
> +       {MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1,  0x00},
> +       {MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2,  0x00},
> +       {MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3,  0x00},
> +       {MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT,  0x00},
> +       {MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,  0x00},
> +       {MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2,  0x00},
> +       {MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3,  0x00},
> +       {MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,  0x00},
> +       {MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY,  0x00},
> +       {MAX98927_R0084_ENV_TRACK_REL_RATE,  0x00},
> +       {MAX98927_R0085_ENV_TRACK_HOLD_RATE,  0x00},
> +       {MAX98927_R0086_ENV_TRACK_CTRL,  0x00},
> +       {MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,  0x00},
> +       {MAX98927_R00FF_GLOBAL_SHDN,  0x00},
> +       {MAX98927_R0100_SOFT_RESET,  0x00},
> +       {MAX98927_R01FF_REV_ID,  0x40},
> +};
> +
> +static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
> +{
> +       struct snd_soc_codec *codec = codec_dai->codec;
> +       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +       unsigned int mode = 0;
> +       unsigned int format = 0;
> +       unsigned int invert = 0;
> +
> +       dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
> +
> +       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> +       case SND_SOC_DAIFMT_CBS_CFS:
> +               mode = MAX98927_PCM_MASTER_MODE_SLAVE;
> +               break;
> +       case SND_SOC_DAIFMT_CBM_CFM:
> +               max98927->master = true;
> +               mode = MAX98927_PCM_MASTER_MODE_MASTER;
> +               break;
> +       default:
> +               dev_err(codec->dev, "DAI clock mode unsupported");
> +               return -EINVAL;
> +       }
> +
> +       regmap_update_bits(max98927->regmap,
> +               MAX98927_R0021_PCM_MASTER_MODE,
> +               MAX98927_PCM_MASTER_MODE_MASK,
> +               mode);
> +
> +       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> +       case SND_SOC_DAIFMT_NB_NF:
> +               break;
> +       case SND_SOC_DAIFMT_IB_NF:
> +               invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
> +               break;
> +       default:
> +               dev_err(codec->dev, "DAI invert mode unsupported");
> +               return -EINVAL;
> +       }
> +
> +       regmap_update_bits(max98927->regmap,
> +               MAX98927_R0020_PCM_MODE_CFG,
> +               MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE,
> +               invert);
> +
> +       /* interface format */
> +       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> +       case SND_SOC_DAIFMT_I2S:
> +               max98927->iface |= SND_SOC_DAIFMT_I2S;
> +               format = MAX98927_PCM_FORMAT_I2S;
> +               break;
> +       case SND_SOC_DAIFMT_LEFT_J:
> +               max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
> +               format = MAX98927_PCM_FORMAT_LJ;
> +               break;
> +       case SND_SOC_DAIFMT_PDM:
> +               max98927->iface |= SND_SOC_DAIFMT_PDM;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       /* pcm channel configuration */
> +       if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0018_PCM_RX_EN_A,
> +                       MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
> +                       MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN);
> +
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0020_PCM_MODE_CFG,
> +                       MAX98927_PCM_MODE_CFG_FORMAT_MASK,
> +                       format << MAX98927_PCM_MODE_CFG_FORMAT_SHIFT);
> +
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R003B_SPK_SRC_SEL,
> +                       MAX98927_SPK_SRC_MASK, 0);
> +
> +       } else
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0018_PCM_RX_EN_A,
> +                       MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
> +
> +       /* pdm channel configuration */
> +       if (max98927->iface & SND_SOC_DAIFMT_PDM) {
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0035_PDM_RX_CTRL,
> +                       MAX98927_PDM_RX_EN_MASK, 1);
> +
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R003B_SPK_SRC_SEL,
> +                       MAX98927_SPK_SRC_MASK, 3);
> +       } else
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0035_PDM_RX_CTRL,
> +                       MAX98927_PDM_RX_EN_MASK, 0);
> +       return 0;
> +}
> +
> +/* codec MCLK rate in master mode */
> +static const int rate_table[] = {
> +       5644800, 6000000, 6144000, 6500000,
> +       9600000, 11289600, 12000000, 12288000,
> +       13000000, 19200000,
> +};
> +
> +static int max98927_set_clock(struct max98927_priv *max98927,
> +       struct snd_pcm_hw_params *params)
> +{
> +       struct snd_soc_codec *codec = max98927->codec;
> +       /* BCLK/LRCLK ratio calculation */
> +       int blr_clk_ratio = params_channels(params) * max98927->ch_size;
> +       int value;
> +
> +       if (max98927->master) {
> +               int i;
> +               /* match rate to closest value */
> +               for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
> +                       if (rate_table[i] >= max98927->sysclk)
> +                               break;
> +               }
> +               if (i == ARRAY_SIZE(rate_table)) {
> +                       dev_err(codec->dev, "failed to find proper clock rate.\n");
> +                       return -EINVAL;
> +               }
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0021_PCM_MASTER_MODE,
> +                       MAX98927_PCM_MASTER_MODE_MCLK_MASK,
> +                       i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
> +       }
> +
> +       switch (blr_clk_ratio) {
> +       case 32:
> +               value = 2;
> +               break;
> +       case 48:
> +               value = 3;
> +               break;
> +       case 64:
> +               value = 4;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +       regmap_update_bits(max98927->regmap,
> +               MAX98927_R0022_PCM_CLK_SETUP,
> +               MAX98927_PCM_CLK_SETUP_BSEL_MASK,
> +               value);
> +       return 0;
> +}
> +
> +static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
> +       struct snd_pcm_hw_params *params,
> +       struct snd_soc_dai *dai)
> +{
> +       struct snd_soc_codec *codec = dai->codec;
> +       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +       unsigned int sampling_rate = 0;
> +       unsigned int chan_sz = 0;
> +
> +       /* pcm mode configuration */
> +       switch (snd_pcm_format_width(params_format(params))) {
> +       case 16:
> +               chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
> +               break;
> +       case 24:
> +               chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
> +               break;
> +       case 32:
> +               chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
> +               break;
> +       default:
> +               dev_err(codec->dev, "format unsupported %d",
> +                       params_format(params));
> +               goto err;
> +       }
> +
> +       max98927->ch_size = snd_pcm_format_width(params_format(params));
> +
> +       regmap_update_bits(max98927->regmap,
> +               MAX98927_R0020_PCM_MODE_CFG,
> +               MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
> +
> +       dev_dbg(codec->dev, "format supported %d",
> +               params_format(params));
> +
> +       /* sampling rate configuration */
> +       switch (params_rate(params)) {
> +       case 8000:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_8000;
> +               break;
> +       case 11025:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_11025;
> +               break;
> +       case 12000:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_12000;
> +               break;
> +       case 16000:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_16000;
> +               break;
> +       case 22050:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_22050;
> +               break;
> +       case 24000:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_24000;
> +               break;
> +       case 32000:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_32000;
> +               break;
> +       case 44100:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_44100;
> +               break;
> +       case 48000:
> +               sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
> +               break;
> +       default:
> +               dev_err(codec->dev, "rate %d not supported\n",
> +                       params_rate(params));
> +               goto err;
> +       }
> +       /* set DAI_SR to correct LRCLK frequency */
> +       regmap_update_bits(max98927->regmap,
> +               MAX98927_R0023_PCM_SR_SETUP1,
> +               MAX98927_PCM_SR_SET1_SR_MASK,
> +               sampling_rate);
> +       regmap_update_bits(max98927->regmap,
> +               MAX98927_R0024_PCM_SR_SETUP2,
> +               MAX98927_PCM_SR_SET2_SR_MASK,
> +               sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
> +
> +       /* set sampling rate of IV */
> +       if (max98927->interleave_mode &&
> +           sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0024_PCM_SR_SETUP2,
> +                       MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
> +                       sampling_rate - 3);
> +       else
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R0024_PCM_SR_SETUP2,
> +                       MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
> +                       sampling_rate);
> +       return max98927_set_clock(max98927, params);
> +err:
> +       return -EINVAL;
> +}
> +
> +#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
> +
> +#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
> +       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
> +
> +static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
> +       int clk_id, unsigned int freq, int dir)
> +{
> +       struct snd_soc_codec *codec = dai->codec;
> +       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> +       max98927->sysclk = freq;
> +       return 0;
> +}
> +
> +static const struct snd_soc_dai_ops max98927_dai_ops = {
> +       .set_sysclk = max98927_dai_set_sysclk,
> +       .set_fmt = max98927_dai_set_fmt,
> +       .hw_params = max98927_dai_hw_params,
> +};
> +
> +static int max98927_dac_event(struct snd_soc_dapm_widget *w,
> +       struct snd_kcontrol *kcontrol, int event)
> +{
> +       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
> +       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> +       switch (event) {
> +       case SND_SOC_DAPM_POST_PMU:
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R003A_AMP_EN,
> +                       MAX98927_AMP_EN_MASK, 1);
> +               /* enable VMON and IMON */
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R003E_MEAS_EN,
> +                       MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
> +                       MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R00FF_GLOBAL_SHDN,
> +                       MAX98927_GLOBAL_EN_MASK, 1);
> +               break;
> +       case SND_SOC_DAPM_POST_PMD:
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R00FF_GLOBAL_SHDN,
> +                       MAX98927_GLOBAL_EN_MASK, 0);
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R003A_AMP_EN,
> +                       MAX98927_AMP_EN_MASK, 0);
> +               /* disable VMON and IMON */
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R003E_MEAS_EN,
> +                       MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
> +               break;
> +       default:
> +               return 0;
> +       }
> +       return 0;
> +}
> +
> +static const char * const max98927_switch_text[] = {
> +       "Left", "Right", "LeftRight"};
> +
> +static const struct soc_enum dai_sel_enum =
> +       SOC_ENUM_SINGLE(MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
> +               MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
> +               3, max98927_switch_text);
> +
> +static const struct snd_kcontrol_new max98927_dai_controls =
> +       SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
> +
> +static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
> +       SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
> +       SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
> +               0, 0, max98927_dac_event,
> +               SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
> +       SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
> +               &max98927_dai_controls),
> +       SND_SOC_DAPM_OUTPUT("BE_OUT"),
> +};
> +
> +static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
> +static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
> +
> +static bool max98927_readable_register(struct device *dev, unsigned int reg)
> +{
> +       switch (reg) {
> +       case MAX98927_R0001_INT_RAW1 ... MAX98927_R0028_ICC_RX_EN_B:
> +       case MAX98927_R002B_ICC_TX_EN_A ... MAX98927_R002C_ICC_TX_EN_B:
> +       case MAX98927_R002E_ICC_HIZ_MANUAL_MODE
> +               ... MAX98927_R004E_MEAS_ADC_CH2_READ:
> +       case MAX98927_R0051_BROWNOUT_STATUS
> +               ... MAX98927_R0055_BROWNOUT_LVL_HOLD:
> +       case MAX98927_R005A_BROWNOUT_LVL1_THRESH
> +               ... MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE:
> +       case MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT
> +               ... MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
> +       case MAX98927_R00FF_GLOBAL_SHDN:
> +       case MAX98927_R0100_SOFT_RESET:
> +       case MAX98927_R01FF_REV_ID:
> +               return true;
> +       default:
> +               return false;
> +       }
> +};
> +
> +static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
> +{
> +       switch (reg) {
> +       case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
> +               return true;
> +       default:
> +               return false;
> +       }
> +}
> +
> +static const char * const max98927_boost_voltage_text[] = {
> +       "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
> +       "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
> +       "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
> +       "9.5V", "9.625V", "9.75V", "9.875V", "10V"
> +};
> +
> +static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
> +               MAX98927_R0040_BOOST_CTRL0, 0,
> +               max98927_boost_voltage_text);
> +
> +static const char * const max98927_current_limit_text[] = {
> +       "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
> +       "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
> +       "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
> +       "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
> +};
> +
> +static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
> +               MAX98927_R0042_BOOST_CTRL1, 1,
> +               max98927_current_limit_text);
> +
> +static const struct snd_kcontrol_new max98927_snd_controls[] = {
> +       SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
> +               0, 6, 0,
> +               max98927_spk_tlv),
> +       SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
> +               0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
> +               max98927_digital_tlv),
> +       SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
> +               MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
> +       SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
> +               MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
> +       SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
> +               MAX98927_DRE_EN_SHIFT, 1, 0),
> +       SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
> +               MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
> +       SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
> +       SOC_ENUM("Current Limit", max98927_current_limit),
> +};
> +
> +static const struct snd_soc_dapm_route max98927_audio_map[] = {
> +       {"Amp Enable", NULL, "DAI_OUT"},
> +       {"DAI Sel Mux", "Left", "Amp Enable"},
> +       {"DAI Sel Mux", "Right", "Amp Enable"},
> +       {"DAI Sel Mux", "LeftRight", "Amp Enable"},
> +       {"BE_OUT", NULL, "DAI Sel Mux"},
> +};
> +
> +static struct snd_soc_dai_driver max98927_dai[] = {
> +       {
> +               .name = "max98927-aif1",
> +               .playback = {
> +                       .stream_name = "HiFi Playback",
> +                       .channels_min = 1,
> +                       .channels_max = 2,
> +                       .rates = MAX98927_RATES,
> +                       .formats = MAX98927_FORMATS,
> +               },
> +               .capture = {
> +                       .stream_name = "HiFi Capture",
> +                       .channels_min = 1,
> +                       .channels_max = 2,
> +                       .rates = MAX98927_RATES,
> +                       .formats = MAX98927_FORMATS,
> +               },
> +               .ops = &max98927_dai_ops,
> +       }
> +};
> +
> +static int max98927_probe(struct snd_soc_codec *codec)
> +{
> +       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> +       max98927->codec = codec;
> +       codec->control_data = max98927->regmap;
> +       codec->cache_bypass = 1;
> +
> +       /* Software Reset */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
> +
> +       /* IV default slot configuration */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
> +               0xFF);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
> +               0xFF);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
> +               0x80);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
> +               0x1);
> +       /* Set inital volume (+13dB) */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0036_AMP_VOL_CTRL,
> +               0x38);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R003C_SPK_GAIN,
> +               0x05);
> +       /* Enable DC blocker */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0037_AMP_DSP_CFG,
> +               0x03);
> +       /* Enable IMON VMON DC blocker */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R003F_MEAS_DSP_CFG,
> +               0xF7);
> +       /* Boost Output Voltage & Current limit */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0040_BOOST_CTRL0,
> +               0x1C);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0042_BOOST_CTRL1,
> +               0x3E);
> +       /* Measurement ADC config */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0043_MEAS_ADC_CFG,
> +               0x04);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0044_MEAS_ADC_BASE_MSB,
> +               0x00);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0045_MEAS_ADC_BASE_LSB,
> +               0x24);
> +       /* Brownout Level */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
> +               0x06);
> +       /* Envelope Tracking configuration */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
> +               0x08);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0086_ENV_TRACK_CTRL,
> +               0x01);
> +       regmap_write(max98927->regmap,
> +               MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
> +               0x10);
> +
> +       /* voltage, current slot configuration */
> +       regmap_write(max98927->regmap,
> +               MAX98927_R001E_PCM_TX_CH_SRC_A,
> +               (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
> +               max98927->v_l_slot)&0xFF);
> +
> +       if (max98927->v_l_slot < 8) {
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
> +                       1 << max98927->v_l_slot, 0);
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001A_PCM_TX_EN_A,
> +                       1 << max98927->v_l_slot,
> +                       1 << max98927->v_l_slot);
> +       } else {
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
> +                       1 << (max98927->v_l_slot - 8), 0);
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001B_PCM_TX_EN_B,
> +                       1 << (max98927->v_l_slot - 8),
> +                       1 << (max98927->v_l_slot - 8));
> +       }
> +
> +       if (max98927->i_l_slot < 8) {
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
> +                       1 << max98927->i_l_slot, 0);
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001A_PCM_TX_EN_A,
> +                       1 << max98927->i_l_slot,
> +                       1 << max98927->i_l_slot);
> +       } else {
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
> +                       1 << (max98927->i_l_slot - 8), 0);
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001B_PCM_TX_EN_B,
> +                       1 << (max98927->i_l_slot - 8),
> +                       1 << (max98927->i_l_slot - 8));
> +       }
> +
> +       /* Set interleave mode */
> +       if (max98927->interleave_mode)
> +               regmap_update_bits(max98927->regmap,
> +                       MAX98927_R001F_PCM_TX_CH_SRC_B,
> +                       MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
> +                       MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
> +       return 0;
> +}
> +
> +static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
> +       .probe = max98927_probe,
> +       .component_driver = {
> +               .controls = max98927_snd_controls,
> +               .num_controls = ARRAY_SIZE(max98927_snd_controls),
> +               .dapm_widgets = max98927_dapm_widgets,
> +               .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
> +               .dapm_routes = max98927_audio_map,
> +               .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
> +       },
> +};
> +
> +static const struct regmap_config max98927_regmap = {
> +       .reg_bits         = 16,
> +       .val_bits         = 8,
> +       .max_register     = MAX98927_R01FF_REV_ID,
> +       .reg_defaults     = max98927_reg,
> +       .num_reg_defaults = ARRAY_SIZE(max98927_reg),
> +       .readable_reg     = max98927_readable_register,
> +       .volatile_reg     = max98927_volatile_reg,
> +       .cache_type       = REGCACHE_RBTREE,
> +};
> +
> +static void max98927_slot_config(struct i2c_client *i2c,
> +       struct max98927_priv *max98927)
> +{
> +       int value;
> +
> +       if (!of_property_read_u32(i2c->dev.of_node,
> +               "vmon-slot-no", &value))
> +               max98927->v_l_slot = value & 0xF;
> +       else
> +               max98927->v_l_slot = 0;
> +       if (!of_property_read_u32(i2c->dev.of_node,
> +               "imon-slot-no", &value))
> +               max98927->i_l_slot = value & 0xF;
> +       else
> +               max98927->i_l_slot = 1;
> +}
> +
> +static int max98927_i2c_probe(struct i2c_client *i2c,
> +       const struct i2c_device_id *id)
> +{
> +
> +       int ret = 0, value;
> +       int reg = 0;
> +       struct max98927_priv *max98927 = NULL;
> +
> +       max98927 = devm_kzalloc(&i2c->dev,
> +               sizeof(*max98927), GFP_KERNEL);
> +
> +       if (!max98927) {
> +               ret = -ENOMEM;
> +               return ret;
> +       }
> +       i2c_set_clientdata(i2c, max98927);
> +
> +       /* update interleave mode info */
> +       if (!of_property_read_u32(i2c->dev.of_node,
> +               "interleave_mode", &value)) {
> +               if (value > 0)
> +                       max98927->interleave_mode = 1;
> +               else
> +                       max98927->interleave_mode = 0;
> +       } else
> +               max98927->interleave_mode = 0;
> +
> +       /* regmap initialization */
> +       max98927->regmap
> +               = devm_regmap_init_i2c(i2c, &max98927_regmap);
> +       if (IS_ERR(max98927->regmap)) {
> +               ret = PTR_ERR(max98927->regmap);
> +               dev_err(&i2c->dev,
> +                       "Failed to allocate regmap: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /* Check Revision ID */
> +       ret = regmap_read(max98927->regmap,
> +               MAX98927_R01FF_REV_ID, &reg);
> +       if (ret < 0) {
> +               dev_err(&i2c->dev,
> +                       "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
> +               return ret;
> +       }
> +       dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
> +
> +       /* voltage/current slot configuration */
> +       max98927_slot_config(i2c, max98927);
> +
> +       /* codec registeration */
> +       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
> +               max98927_dai, ARRAY_SIZE(max98927_dai));
> +       if (ret < 0)
> +               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
> +
> +       return ret;
> +}
> +
> +static int max98927_i2c_remove(struct i2c_client *client)
> +{
> +       snd_soc_unregister_codec(&client->dev);
> +       return 0;
> +}
> +
> +static const struct i2c_device_id max98927_i2c_id[] = {
> +       { "max98927", 0},
> +       { },
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
> +
> +#if defined(CONFIG_OF)
> +static const struct of_device_id max98927_of_match[] = {
> +       { .compatible = "maxim,max98927", },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, max98927_of_match);
> +#endif
> +
> +#ifdef CONFIG_ACPI
> +static const struct acpi_device_id max98927_acpi_match[] = {
> +       { "MX98927", 0 },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
> +#endif
> +
> +static struct i2c_driver max98927_i2c_driver = {
> +       .driver = {
> +               .name = "max98927",
> +               .of_match_table = of_match_ptr(max98927_of_match),
> +               .acpi_match_table = ACPI_PTR(max98927_acpi_match),
> +               .pm = NULL,
> +       },
> +       .probe  = max98927_i2c_probe,
> +       .remove = max98927_i2c_remove,
> +       .id_table = max98927_i2c_id,
> +};
> +
> +module_i2c_driver(max98927_i2c_driver)
> +
> +MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
> +MODULE_AUTHOR("Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
> new file mode 100644
> index 000000000000..ece6a608cbe1
> --- /dev/null
> +++ b/sound/soc/codecs/max98927.h
> @@ -0,0 +1,272 @@
> +/*
> + * max98927.h  --  MAX98927 ALSA Soc Audio driver
> + *
> + * Copyright 2013-15 Maxim Integrated Products
> + * Author: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> + *
> + *  This program is free software; you can redistribute  it and/or modify it
> + *  under  the terms of  the GNU General  Public License as published by the
> + *  Free Software Foundation;  either version 2 of the  License, or (at your
> + *  option) any later version.
> + *
> + */
> +#ifndef _MAX98927_H
> +#define _MAX98927_H
> +
> +/* Register Values */
> +#define MAX98927_R0001_INT_RAW1 0x0001
> +#define MAX98927_R0002_INT_RAW2 0x0002
> +#define MAX98927_R0003_INT_RAW3 0x0003
> +#define MAX98927_R0004_INT_STATE1 0x0004
> +#define MAX98927_R0005_INT_STATE2 0x0005
> +#define MAX98927_R0006_INT_STATE3 0x0006
> +#define MAX98927_R0007_INT_FLAG1 0x0007
> +#define MAX98927_R0008_INT_FLAG2 0x0008
> +#define MAX98927_R0009_INT_FLAG3 0x0009
> +#define MAX98927_R000A_INT_EN1 0x000A
> +#define MAX98927_R000B_INT_EN2 0x000B
> +#define MAX98927_R000C_INT_EN3 0x000C
> +#define MAX98927_R000D_INT_FLAG_CLR1   0x000D
> +#define MAX98927_R000E_INT_FLAG_CLR2   0x000E
> +#define MAX98927_R000F_INT_FLAG_CLR3   0x000F
> +#define MAX98927_R0010_IRQ_CTRL 0x0010
> +#define MAX98927_R0011_CLK_MON 0x0011
> +#define MAX98927_R0012_WDOG_CTRL 0x0012
> +#define MAX98927_R0013_WDOG_RST 0x0013
> +#define MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH 0x0014
> +#define MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH 0x0015
> +#define MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS 0x0016
> +#define MAX98927_R0017_PIN_CFG 0x0017
> +#define MAX98927_R0018_PCM_RX_EN_A 0x0018
> +#define MAX98927_R0019_PCM_RX_EN_B 0x0019
> +#define MAX98927_R001A_PCM_TX_EN_A 0x001A
> +#define MAX98927_R001B_PCM_TX_EN_B 0x001B
> +#define MAX98927_R001C_PCM_TX_HIZ_CTRL_A 0x001C
> +#define MAX98927_R001D_PCM_TX_HIZ_CTRL_B 0x001D
> +#define MAX98927_R001E_PCM_TX_CH_SRC_A 0x001E
> +#define MAX98927_R001F_PCM_TX_CH_SRC_B 0x001F
> +#define MAX98927_R0020_PCM_MODE_CFG 0x0020
> +#define MAX98927_R0021_PCM_MASTER_MODE 0x0021
> +#define MAX98927_R0022_PCM_CLK_SETUP 0x0022
> +#define MAX98927_R0023_PCM_SR_SETUP1 0x0023
> +#define MAX98927_R0024_PCM_SR_SETUP2   0x0024
> +#define MAX98927_R0025_PCM_TO_SPK_MONOMIX_A 0x0025
> +#define MAX98927_R0026_PCM_TO_SPK_MONOMIX_B 0x0026
> +#define MAX98927_R0027_ICC_RX_EN_A 0x0027
> +#define MAX98927_R0028_ICC_RX_EN_B 0x0028
> +#define MAX98927_R002B_ICC_TX_EN_A 0x002B
> +#define MAX98927_R002C_ICC_TX_EN_B 0x002C
> +#define MAX98927_R002E_ICC_HIZ_MANUAL_MODE 0x002E
> +#define MAX98927_R002F_ICC_TX_HIZ_EN_A 0x002F
> +#define MAX98927_R0030_ICC_TX_HIZ_EN_B 0x0030
> +#define MAX98927_R0031_ICC_LNK_EN 0x0031
> +#define MAX98927_R0032_PDM_TX_EN 0x0032
> +#define MAX98927_R0033_PDM_TX_HIZ_CTRL 0x0033
> +#define MAX98927_R0034_PDM_TX_CTRL 0x0034
> +#define MAX98927_R0035_PDM_RX_CTRL 0x0035
> +#define MAX98927_R0036_AMP_VOL_CTRL 0x0036
> +#define MAX98927_R0037_AMP_DSP_CFG 0x0037
> +#define MAX98927_R0038_TONE_GEN_DC_CFG 0x0038
> +#define MAX98927_R0039_DRE_CTRL 0x0039
> +#define MAX98927_R003A_AMP_EN 0x003A
> +#define MAX98927_R003B_SPK_SRC_SEL 0x003B
> +#define MAX98927_R003C_SPK_GAIN 0x003C
> +#define MAX98927_R003D_SSM_CFG 0x003D
> +#define MAX98927_R003E_MEAS_EN 0x003E
> +#define MAX98927_R003F_MEAS_DSP_CFG 0x003F
> +#define MAX98927_R0040_BOOST_CTRL0 0x0040
> +#define MAX98927_R0041_BOOST_CTRL3 0x0041
> +#define MAX98927_R0042_BOOST_CTRL1 0x0042
> +#define MAX98927_R0043_MEAS_ADC_CFG 0x0043
> +#define MAX98927_R0044_MEAS_ADC_BASE_MSB 0x0044
> +#define MAX98927_R0045_MEAS_ADC_BASE_LSB 0x0045
> +#define MAX98927_R0046_ADC_CH0_DIVIDE 0x0046
> +#define MAX98927_R0047_ADC_CH1_DIVIDE 0x0047
> +#define MAX98927_R0048_ADC_CH2_DIVIDE 0x0048
> +#define MAX98927_R0049_ADC_CH0_FILT_CFG 0x0049
> +#define MAX98927_R004A_ADC_CH1_FILT_CFG 0x004A
> +#define MAX98927_R004B_ADC_CH2_FILT_CFG 0x004B
> +#define MAX98927_R004C_MEAS_ADC_CH0_READ 0x004C
> +#define MAX98927_R004D_MEAS_ADC_CH1_READ 0x004D
> +#define MAX98927_R004E_MEAS_ADC_CH2_READ 0x004E
> +#define MAX98927_R0051_BROWNOUT_STATUS 0x0051
> +#define MAX98927_R0052_BROWNOUT_EN 0x0052
> +#define MAX98927_R0053_BROWNOUT_INFINITE_HOLD 0x0053
> +#define MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR 0x0054
> +#define MAX98927_R0055_BROWNOUT_LVL_HOLD 0x0055
> +#define MAX98927_R005A_BROWNOUT_LVL1_THRESH 0x005A
> +#define MAX98927_R005B_BROWNOUT_LVL2_THRESH 0x005B
> +#define MAX98927_R005C_BROWNOUT_LVL3_THRESH 0x005C
> +#define MAX98927_R005D_BROWNOUT_LVL4_THRESH 0x005D
> +#define MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS 0x005E
> +#define MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL 0x005F
> +#define MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL 0x0060
> +#define MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE 0x0061
> +#define MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT 0x0072
> +#define MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1 0x0073
> +#define MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2 0x0074
> +#define MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3 0x0075
> +#define MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT 0x0076
> +#define MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1 0x0077
> +#define MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2 0x0078
> +#define MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3 0x0079
> +#define MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT 0x007A
> +#define MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1 0x007B
> +#define MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2 0x007C
> +#define MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3 0x007D
> +#define MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT 0x007E
> +#define MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1 0x007F
> +#define MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2 0x0080
> +#define MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3 0x0081
> +#define MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM 0x0082
> +#define MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY 0x0083
> +#define MAX98927_R0084_ENV_TRACK_REL_RATE 0x0084
> +#define MAX98927_R0085_ENV_TRACK_HOLD_RATE 0x0085
> +#define MAX98927_R0086_ENV_TRACK_CTRL 0x0086
> +#define MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ 0x0087
> +#define MAX98927_R00FF_GLOBAL_SHDN 0x00FF
> +#define MAX98927_R0100_SOFT_RESET 0x0100
> +#define MAX98927_R01FF_REV_ID 0x01FF
> +
> +/* MAX98927_R0018_PCM_RX_EN_A */
> +#define MAX98927_PCM_RX_CH0_EN (0x1 << 0)
> +#define MAX98927_PCM_RX_CH1_EN (0x1 << 1)
> +#define MAX98927_PCM_RX_CH2_EN (0x1 << 2)
> +#define MAX98927_PCM_RX_CH3_EN (0x1 << 3)
> +#define MAX98927_PCM_RX_CH4_EN (0x1 << 4)
> +#define MAX98927_PCM_RX_CH5_EN (0x1 << 5)
> +#define MAX98927_PCM_RX_CH6_EN (0x1 << 6)
> +#define MAX98927_PCM_RX_CH7_EN (0x1 << 7)
> +
> +/* MAX98927_R001A_PCM_TX_EN_A */
> +#define MAX98927_PCM_TX_CH0_EN (0x1 << 0)
> +#define MAX98927_PCM_TX_CH1_EN (0x1 << 1)
> +#define MAX98927_PCM_TX_CH2_EN (0x1 << 2)
> +#define MAX98927_PCM_TX_CH3_EN (0x1 << 3)
> +#define MAX98927_PCM_TX_CH4_EN (0x1 << 4)
> +#define MAX98927_PCM_TX_CH5_EN (0x1 << 5)
> +#define MAX98927_PCM_TX_CH6_EN (0x1 << 6)
> +#define MAX98927_PCM_TX_CH7_EN (0x1 << 7)
> +
> +/* MAX98927_R001E_PCM_TX_CH_SRC_A */
> +#define MAX98927_PCM_TX_CH_SRC_A_V_SHIFT (0)
> +#define MAX98927_PCM_TX_CH_SRC_A_I_SHIFT (4)
> +
> +/* MAX98927_R001F_PCM_TX_CH_SRC_B */
> +#define MAX98927_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 5)
> +
> +/* MAX98927_R0020_PCM_MODE_CFG */
> +#define MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE (0x1 << 2)
> +#define MAX98927_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3)
> +#define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
> +#define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
> +#define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
> +
> +#define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
> +#define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
> +#define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
> +#define MAX98927_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6)
> +
> +/* MAX98927_R0021_PCM_MASTER_MODE */
> +#define MAX98927_PCM_MASTER_MODE_MASK (0x3 << 0)
> +#define MAX98927_PCM_MASTER_MODE_SLAVE (0x0 << 0)
> +#define MAX98927_PCM_MASTER_MODE_MASTER (0x3 << 0)
> +
> +#define MAX98927_PCM_MASTER_MODE_MCLK_MASK (0xF << 2)
> +#define MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT (2)
> +
> +/* MAX98927_R0022_PCM_CLK_SETUP */
> +#define MAX98927_PCM_CLK_SETUP_BSEL_MASK (0xF << 0)
> +
> +/* MAX98927_R0023_PCM_SR_SETUP1 */
> +#define MAX98927_PCM_SR_SET1_SR_MASK (0xF << 0)
> +
> +#define MAX98927_PCM_SR_SET1_SR_8000 (0x0 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_11025 (0x1 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_12000 (0x2 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_16000 (0x3 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_22050 (0x4 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_24000 (0x5 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_32000 (0x6 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_44100 (0x7 << 0)
> +#define MAX98927_PCM_SR_SET1_SR_48000 (0x8 << 0)
> +
> +/* MAX98927_R0024_PCM_SR_SETUP2 */
> +#define MAX98927_PCM_SR_SET2_SR_MASK (0xF << 4)
> +#define MAX98927_PCM_SR_SET2_SR_SHIFT (4)
> +#define MAX98927_PCM_SR_SET2_IVADC_SR_MASK (0xf << 0)
> +
> +/* MAX98927_R0025_PCM_TO_SPK_MONOMIX_A */
> +#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6)
> +#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT (6)
> +
> +/* MAX98927_R0035_PDM_RX_CTRL */
> +#define MAX98927_PDM_RX_EN_MASK (0x1 << 0)
> +
> +/* MAX98927_R0036_AMP_VOL_CTRL */
> +#define MAX98927_AMP_VOL_SEL (0x1 << 7)
> +#define MAX98927_AMP_VOL_SEL_WIDTH (1)
> +#define MAX98927_AMP_VOL_SEL_SHIFT (7)
> +#define MAX98927_AMP_VOL_MASK (0x7f << 0)
> +#define MAX98927_AMP_VOL_WIDTH (7)
> +#define MAX98927_AMP_VOL_SHIFT (0)
> +
> +/* MAX98927_R0037_AMP_DSP_CFG */
> +#define MAX98927_AMP_DSP_CFG_DCBLK_EN (0x1 << 0)
> +#define MAX98927_AMP_DSP_CFG_DITH_EN (0x1 << 1)
> +#define MAX98927_AMP_DSP_CFG_RMP_BYPASS (0x1 << 4)
> +#define MAX98927_AMP_DSP_CFG_DAC_INV (0x1 << 5)
> +#define MAX98927_AMP_DSP_CFG_RMP_SHIFT (4)
> +
> +/* MAX98927_R0039_DRE_CTRL */
> +#define MAX98927_DRE_CTRL_DRE_EN       (0x1 << 0)
> +#define MAX98927_DRE_EN_SHIFT 0x1
> +
> +/* MAX98927_R003A_AMP_EN */
> +#define MAX98927_AMP_EN_MASK (0x1 << 0)
> +
> +/* MAX98927_R003B_SPK_SRC_SEL */
> +#define MAX98927_SPK_SRC_MASK (0x3 << 0)
> +
> +/* MAX98927_R003C_SPK_GAIN */
> +#define MAX98927_SPK_PCM_GAIN_MASK (0x7 << 0)
> +#define MAX98927_SPK_PDM_GAIN_MASK (0x7 << 4)
> +#define MAX98927_SPK_GAIN_WIDTH (3)
> +
> +/* MAX98927_R003E_MEAS_EN */
> +#define MAX98927_MEAS_V_EN (0x1 << 0)
> +#define MAX98927_MEAS_I_EN (0x1 << 1)
> +
> +/* MAX98927_R0040_BOOST_CTRL0 */
> +#define MAX98927_BOOST_CTRL0_VOUT_MASK (0x1f << 0)
> +#define MAX98927_BOOST_CTRL0_PVDD_MASK (0x1 << 7)
> +#define MAX98927_BOOST_CTRL0_PVDD_EN_SHIFT (7)
> +
> +/* MAX98927_R0052_BROWNOUT_EN */
> +#define MAX98927_BROWNOUT_BDE_EN (0x1 << 0)
> +#define MAX98927_BROWNOUT_AMP_EN (0x1 << 1)
> +#define MAX98927_BROWNOUT_DSP_EN (0x1 << 2)
> +#define MAX98927_BROWNOUT_DSP_SHIFT (2)
> +
> +/* MAX98927_R0100_SOFT_RESET */
> +#define MAX98927_SOFT_RESET (0x1 << 0)
> +
> +/* MAX98927_R00FF_GLOBAL_SHDN */
> +#define MAX98927_GLOBAL_EN_MASK (0x1 << 0)
> +
> +struct max98927_priv {
> +       struct regmap *regmap;
> +       struct snd_soc_codec *codec;
> +       struct max98927_pdata *pdata;
> +       unsigned int spk_gain;
> +       unsigned int sysclk;
> +       unsigned int v_l_slot;
> +       unsigned int i_l_slot;
> +       bool interleave_mode;
> +       unsigned int ch_size;
> +       unsigned int rate;
> +       unsigned int iface;
> +       unsigned int master;
> +       unsigned int digital_gain;
> +};
> +#endif
> --
> 2.11.0
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 2/8] v4l: fwnode: Support generic fwnode for parsing standardised properties
From: Sakari Ailus @ 2017-04-07 21:30 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Sakari Ailus, linux-media, linux-acpi, devicetree
In-Reply-To: <20170407103633.GD4192@valkosipuli.retiisi.org.uk>

On Fri, Apr 07, 2017 at 01:36:34PM +0300, Sakari Ailus wrote:
...
> > > +	if (is_of_node(fwn)) {
> > > +		if (of_node_cmp(to_of_node(fwn)->name, "ports") == 0)
> > > +			fwn = fwnode_get_next_parent(fwn);
> > > +	} else {
> > > +		/* The "ports" node is always there in ACPI. */

This comment is actually wrong and does not reflect the current
implementation anymore. I'll fix that as well.

> > > +		fwn = fwnode_get_next_parent(fwn);
> > > +	}

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply

* Re: Device Tree Binding for Intel FPGA Video and Image Processing Suite
From: Rob Herring @ 2017-04-07 21:53 UTC (permalink / raw)
  To: Ong, Hean Loong; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1491460951.2483.2.camel-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

On Thu, Apr 6, 2017 at 1:42 AM, Ong, Hean Loong
<hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
> Hi Rob,
>
> Any comments on the patch?

Yes, the same ones I provided 5 months ago to you. Repeated below.

>
> BR
>
> Hean Loong
>
> On Tue, 2017-04-04 at 03:57 +0000, Ong, Hean Loong wrote:
>> Hi Rob,
>>
>> Apologies for the mistake. Below are the bindings
>>
>> From 23a9e274bb517b8e232c5aa4cf9737de1644b708 Mon Sep 17 00:00:00
>> 2001
>> From: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>> Date: Thu, 30 Mar 2017 17:59:37 +0800
>> Subject: [PATCHv0] Intel FPGA Video and Image Processing Suite device
>> tree binding

This is still not how you email patches. The easiest way is git-send-email.

>>         Device tree binding for Intel FPGA Video and Image
>>         Processing Suite. The binding involved would be generated
>>         from the Altera (Intel) Qsys system. The bindings would
>>         set the max width, max height, buts per pixel and memory
>>         port width. The device tree binding only supports the Intel
>>         Arria10 devkit and its variants. Vendor name retained as
>>         altr.

There should be no indentation here.

>>
>> Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>> ---
>>  .../devicetree/bindings/gpu/altr,vip-fb2.txt       |   24
>> ++++++++++++++++++++

bindings/display/. This is not a GPU.

>>  1 files changed, 24 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/gpu/altr,vip-
>> fb2.txt
>>
>> diff --git a/Documentation/devicetree/bindings/gpu/altr,vip-fb2.txt
>> b/Documentation/devicetree/bindings/gpu/altr,vip-fb2.txt
>> new file mode 100644
>> index 0000000..9ba3209
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpu/altr,vip-fb2.txt
>> @@ -0,0 +1,24 @@
>> +Intel Video and Image Processing(VIP) Frame Buffer II bindings
>> +
>> +Supported hardware:  Arria 10 and above with display port IP
>> +
>> +Required properties:
>> +- compatible: "altr,vip-frame-buffer-2.0"
>> +- reg: Physical base address and length of the framebuffer
>> controller's
>> +  registers.

>> +- max-width: The width of the framebuffer in pixels.
>> +- max-height: The height of the framebuffer in pixels.
>> +- bits-per-symbol: only "8" is currently supported

Why do these need to be in DT?

>> +- mem-port-width = the bus width of the avalon master port on the
>> frame reader

Still needs a vendor prefix.

>> +
>> +Example:
>> +
>> +dp_0_frame_buf: vip@0x100000280 {

display-controller@100000280

>> +       compatible = "altr,vip-frame-buffer-2.0";
>> +       reg = <0x00000001 0x00000280 0x00000040>;
>> +       altr,max-width = <1280>;
>> +       altr,max-height = <720>;
>> +       altr,bits-per-symbol = <8>;
>> +       altr,mem-port-width = <128>;
>> +};
>> +
>> --
>> 1.7.1
>>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 1/3 RESEND] clocksource: Augment bindings for Faraday timer
From: Linus Walleij @ 2017-04-07 21:55 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linus Walleij

It turns out that the Cortina Gemini timer block is just a
standard IP block from Faraday Technology named FTTMR010.

In order to make things clear and understandable, we rename the
bindings with a Faraday compatible as primary and the Cortina
gemini as a more specific case.

For the plain Faraday timer we require two clock references,
while the Gemini can keep it's syscon lookup pattern.

Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../bindings/timer/cortina,gemini-timer.txt        | 22 ---------------
 .../devicetree/bindings/timer/faraday,fttmr010.txt | 33 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 22 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt
 create mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.txt

diff --git a/Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt b/Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt
deleted file mode 100644
index 16ea1d3b2e9e..000000000000
--- a/Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Cortina Systems Gemini timer
-
-This timer is embedded in the Cortina Systems Gemini SoCs.
-
-Required properties:
-
-- compatible : Must be "cortina,gemini-timer"
-- reg : Should contain registers location and length
-- interrupts : Should contain the three timer interrupts with
-  flags for rising edge
-- syscon : a phandle to the global Gemini system controller
-
-Example:
-
-timer@43000000 {
-	compatible = "cortina,gemini-timer";
-	reg = <0x43000000 0x1000>;
-	interrupts = <14 IRQ_TYPE_EDGE_RISING>, /* Timer 1 */
-		   <15 IRQ_TYPE_EDGE_RISING>, /* Timer 2 */
-		   <16 IRQ_TYPE_EDGE_RISING>; /* Timer 3 */
-	syscon = <&syscon>;
-};
diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
new file mode 100644
index 000000000000..b73ca6cd07f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
@@ -0,0 +1,33 @@
+Faraday Technology timer
+
+This timer is a generic IP block from Faraday Technology, embedded in the
+Cortina Systems Gemini SoCs and other designs.
+
+Required properties:
+
+- compatible : Must be one of
+  "faraday,fttmr010"
+  "cortina,gemini-timer"
+- reg : Should contain registers location and length
+- interrupts : Should contain the three timer interrupts usually with
+  flags for falling edge
+
+Optionally required properties:
+
+- clocks : a clock to provide the tick rate for "faraday,fttmr010"
+- clock-names : should be "EXTCLK" and "PCLK" for the external tick timer
+  and peripheral clock respectively, for "faraday,fttmr010"
+- syscon : a phandle to the global Gemini system controller if the compatible
+  type is "cortina,gemini-timer"
+
+Example:
+
+timer@43000000 {
+	compatible = "faraday,fttmr010";
+	reg = <0x43000000 0x1000>;
+	interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */
+		   <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */
+		   <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */
+	clocks = <&extclk>, <&pclk>;
+	clock-names = "EXTCLK", "PCLK";
+};
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 1/3] mfd: cros-ec: Add functions to read mapped memory
From: Moritz Fischer @ 2017-04-07 22:00 UTC (permalink / raw)
  To: linux-hwmon
  Cc: moritz.fischer, linux-kernel, devicetree, lee.jones, olof, linux,
	jdelvare, robh+dt, mark.rutland, Moritz Fischer

From: Moritz Fischer <mdf@kernel.org>

The ChromeOS EC has mapped memory regions where things like temperature
sensors and fan speed are stored. Provide access to those from the
cros-ec mfd device.

Signed-off-by: Moritz Fischer <mdf@kernel.org>
---
 drivers/platform/chrome/cros_ec_proto.c | 55 +++++++++++++++++++++++++++++++++
 include/linux/mfd/cros_ec.h             | 39 +++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index ed5dee7..28063de 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -494,3 +494,58 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev)
 		return get_keyboard_state_event(ec_dev);
 }
 EXPORT_SYMBOL(cros_ec_get_next_event);
+
+static int __cros_ec_read_mapped_mem(struct cros_ec_device *ec, uint8_t offset,
+				     void *buf, size_t size)
+{
+	int ret;
+	struct ec_params_read_memmap *params;
+	struct cros_ec_command *msg;
+
+	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), size), GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	msg->version = 0;
+	msg->command = EC_CMD_READ_MEMMAP;
+	msg->insize = size;
+	msg->outsize = sizeof(*params);
+
+	params = (struct ec_params_read_memmap *)msg->data;
+	params->offset = offset;
+	params->size = size;
+
+	ret = cros_ec_cmd_xfer(ec, msg);
+	if (ret < 0 || msg->result != EC_RES_SUCCESS) {
+		dev_warn(ec->dev, "cannot read mapped reg: %d/%d\n",
+			 ret, msg->result);
+		goto out_free;
+	}
+
+	memcpy(buf, msg->data, size);
+
+out_free:
+	kfree(msg);
+	return ret;
+}
+
+int cros_ec_read_mapped_mem32(struct cros_ec_device *ec, const uint8_t offset,
+			      uint32_t *data)
+{
+	return __cros_ec_read_mapped_mem(ec, offset, data, sizeof(*data));
+}
+EXPORT_SYMBOL_GPL(cros_ec_read_mapped_mem32);
+
+int cros_ec_read_mapped_mem16(struct cros_ec_device *ec, const uint8_t offset,
+			      uint16_t *data)
+{
+	return __cros_ec_read_mapped_mem(ec, offset, data, sizeof(*data));
+}
+EXPORT_SYMBOL_GPL(cros_ec_read_mapped_mem16);
+
+int cros_ec_read_mapped_mem8(struct cros_ec_device *ec, const uint8_t offset,
+			     uint8_t *data)
+{
+	return __cros_ec_read_mapped_mem(ec, offset, data, sizeof(*data));
+}
+EXPORT_SYMBOL_GPL(cros_ec_read_mapped_mem8);
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index b3d04de..c2de878 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -190,6 +190,45 @@ struct cros_ec_dev {
 };
 
 /**
+ * cros_ec_read_mapped_mem8 - Read mapped memory in the ChromeOS EC
+ *
+ * This can be called by drivers to access the mapped memory in the EC
+ *
+ * @ec_dev: Device to read from
+ * @offset: Offset to read
+ * @data: Return data
+ * @return: 0 if Ok, -ve on error
+ */
+int cros_ec_read_mapped_mem8(struct cros_ec_device *ec, const uint8_t offset,
+			     uint8_t *data);
+
+/**
+ * cros_ec_read_mapped_mem16 - Read mapped memory in the ChromeOS EC
+ *
+ * This can be called by drivers to access the mapped memory in the EC
+ *
+ * @ec_dev: Device to read from
+ * @offset: Offset to read
+ * @data: Return data
+ * @return: 0 if Ok, -ve on error
+ */
+int cros_ec_read_mapped_mem16(struct cros_ec_device *ec, const uint8_t offset,
+			      uint16_t *data);
+
+/**
+ * cros_ec_read_mapped_mem32 - Read mapped memory in the ChromeOS EC
+ *
+ * This can be called by drivers to access the mapped memory in the EC
+ *
+ * @ec_dev: Device to read from
+ * @offset: Offset to read
+ * @data: Return data
+ * @return: 0 if Ok, -ve on error
+ */
+int cros_ec_read_mapped_mem32(struct cros_ec_device *ec, const uint8_t offset,
+			      uint32_t *data);
+
+/**
  * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device
  *
  * This can be called by drivers to handle a suspend event.
-- 
2.7.4


^ permalink raw reply related

* [PATCH 2/3] dt-bindings: hwmon: Add bindings for Google Chromium EC HWMON
From: Moritz Fischer @ 2017-04-07 22:00 UTC (permalink / raw)
  To: linux-hwmon-u79uwXL29TY76Z2rM5mHXA
  Cc: moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-0h96xk9xTtrk1uMJSBkQmQ, jdelvare-IBi9RG/b67k,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	Moritz Fischer
In-Reply-To: <1491602410-31518-1-git-send-email-moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w@public.gmane.org>

From: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Add bindings for the Chromium EC HWMON. The Chromium EC HWMON
allows monitoring of temperature sensors and fans attached to the
EC.

Signed-off-by: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 .../devicetree/bindings/hwmon/cros-ec-hwmon.txt    | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/cros-ec-hwmon.txt

diff --git a/Documentation/devicetree/bindings/hwmon/cros-ec-hwmon.txt b/Documentation/devicetree/bindings/hwmon/cros-ec-hwmon.txt
new file mode 100644
index 0000000..4c94869
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/cros-ec-hwmon.txt
@@ -0,0 +1,25 @@
+Chromium Embedded Controller EC temperature and fan control
+-----------------------------------------------------------
+
+Google's Chromium EC HWMON is a hwmon implemented byimplemented by the Chromium EC
+firmware attached to the Embedded Controller (EC) and controlled via a host-command
+interface.
+
+An EC HWMON node should be only found as a sub-node of the EC node (see
+Documentation/devicetree/bindings/mfd/cros-ec.txt).
+
+Required properties:
+- compatible: Must contain "google,cros-ec-hwmon"
+
+Example:
+	embedded-controller@1e {
+		reg = <0x1e>;
+		compatible = "google,cros-ec-i2c";
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&gpio0>;
+
+		hwmon {
+			compatible = "google,cros-ec-hwmon";
+		};
+};
+
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 3/3] hwmon: cros-ec-hwmon: Add Chromium-EC HWMON driver
From: Moritz Fischer @ 2017-04-07 22:00 UTC (permalink / raw)
  To: linux-hwmon-u79uwXL29TY76Z2rM5mHXA
  Cc: moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-0h96xk9xTtrk1uMJSBkQmQ, jdelvare-IBi9RG/b67k,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	Moritz Fischer
In-Reply-To: <1491602410-31518-1-git-send-email-moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w@public.gmane.org>

From: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

This adds a hwmon driver for the Chromium EC's fans
and temperature sensors.

Signed-off-by: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---

This one still needs some work, but I figured some early feedback might not hurt.
Specifically I was wondering if using the devm_hwmon_register_with_info() is
preferable to the devm_hwmon_register_with_groups().

The EC has a bunch of additional features such as setting thermal limits etc,
which I'd still like to add but I figured I'll get some feedback on what I got so far.

Thanks,

Moritz

---
 drivers/hwmon/Kconfig         |   8 ++
 drivers/hwmon/Makefile        |   1 +
 drivers/hwmon/cros-ec-hwmon.c | 244 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/hwmon/cros-ec-hwmon.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0649d53f3..3b9155f 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1254,6 +1254,14 @@ config SENSORS_PCF8591
 	  These devices are hard to detect and rarely found on mainstream
 	  hardware.  If unsure, say N.
 
+config SENSORS_CROS_EC
+	tristate "ChromeOS EC hwmon"
+	depends on MFD_CROS_EC
+	help
+	  If you say yes here you get hwmon support that will expose the
+	  ChromeOS internal sensors for fanspeed and temperature to the
+	  Linux hwmon subsystem.
+
 source drivers/hwmon/pmbus/Kconfig
 
 config SENSORS_PWM_FAN
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 5509edf..e59b5da 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -134,6 +134,7 @@ obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_POWR1220)  += powr1220.o
+obj-$(CONFIG_SENSORS_CROS_EC)   += cros-ec-hwmon.o
 obj-$(CONFIG_SENSORS_PWM_FAN)	+= pwm-fan.o
 obj-$(CONFIG_SENSORS_S3C)	+= s3c-hwmon.o
 obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
diff --git a/drivers/hwmon/cros-ec-hwmon.c b/drivers/hwmon/cros-ec-hwmon.c
new file mode 100644
index 0000000..29d8b06
--- /dev/null
+++ b/drivers/hwmon/cros-ec-hwmon.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2017, National Instruments Corp.
+ *
+ * Chromium EC Fan speed and temperature sensor driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/of_platform.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/bitops.h>
+#include <linux/mfd/cros_ec.h>
+
+struct cros_ec_hwmon_priv {
+	struct cros_ec_device *ec;
+	struct device *hwmon_dev;
+
+	struct attribute **attrs;
+
+	struct attribute_group attr_group;
+	const struct attribute_group *groups[2];
+};
+
+#define KELVIN_TO_MILLICELSIUS(x) (((x) - 273) * 1000)
+
+static int __cros_ec_hwmon_probe_fans(struct cros_ec_hwmon_priv *priv)
+{
+	int err, idx;
+	uint16_t data;
+
+	for (idx = 0; idx < EC_FAN_SPEED_ENTRIES; idx++) {
+		err = cros_ec_read_mapped_mem16(priv->ec,
+					       EC_MEMMAP_FAN + 2 * idx,
+					       &data);
+		if (err)
+			return err;
+
+		if (data == EC_FAN_SPEED_NOT_PRESENT)
+			break;
+	}
+
+	return idx;
+}
+
+static int __cros_ec_hwmon_probe_temps(struct cros_ec_hwmon_priv *priv)
+{
+	uint8_t data;
+	int err, idx;
+
+	err = cros_ec_read_mapped_mem8(priv->ec, EC_MEMMAP_THERMAL_VERSION,
+				       &data);
+
+	/* if we have a read error, or EC_MEMMAP_THERMAL_VERSION is not set,
+	 * most likely we don't have temperature sensors ...
+	 */
+	if (err || !data)
+		return 0;
+
+	for (idx = 0; idx < EC_TEMP_SENSOR_ENTRIES; idx++) {
+		err = cros_ec_read_mapped_mem8(priv->ec,
+					       EC_MEMMAP_TEMP_SENSOR + idx,
+					       &data);
+		if (err)
+			return idx;
+
+		/* this assumes that they're all good up to idx */
+		switch (data) {
+		case EC_TEMP_SENSOR_NOT_PRESENT:
+		case EC_TEMP_SENSOR_ERROR:
+		case EC_TEMP_SENSOR_NOT_POWERED:
+		case EC_TEMP_SENSOR_NOT_CALIBRATED:
+			return idx;
+		default:
+			continue;
+		};
+	}
+
+	return idx;
+}
+
+static ssize_t cros_ec_hwmon_read_fan_rpm(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
+{
+	uint16_t data;
+	int err;
+	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+
+	err = cros_ec_read_mapped_mem16(priv->ec,
+					EC_MEMMAP_FAN + 2 * sattr->index,
+					&data);
+	if (err)
+		return err;
+
+	return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t cros_ec_hwmon_read_temp(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
+{
+	uint8_t data;
+	int err, tmp;
+
+	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+
+	err = cros_ec_read_mapped_mem8(priv->ec,
+				       EC_MEMMAP_TEMP_SENSOR + 1 * sattr->index,
+				       &data);
+	if (err)
+		return err;
+
+	switch (data) {
+	case EC_TEMP_SENSOR_NOT_PRESENT:
+	case EC_TEMP_SENSOR_ERROR:
+	case EC_TEMP_SENSOR_NOT_POWERED:
+	case EC_TEMP_SENSOR_NOT_CALIBRATED:
+		dev_info(priv->ec->dev, "Failure: result=%d\n", data);
+		return -EIO;
+	}
+
+	/* make sure we don't overflow when adding offset*/
+	tmp = data + EC_TEMP_SENSOR_OFFSET;
+
+	return sprintf(buf, "%d\n", KELVIN_TO_MILLICELSIUS(tmp));
+}
+
+static int cros_ec_hwmon_probe(struct platform_device *pdev)
+{
+	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
+	struct cros_ec_hwmon_priv *ec_hwmon;
+	struct sensor_device_attribute *attr;
+	int num_fans, num_temps, i;
+
+	ec_hwmon = devm_kzalloc(&pdev->dev, sizeof(*ec_hwmon), GFP_KERNEL);
+	if (!ec_hwmon)
+		return -ENOMEM;
+	ec_hwmon->ec = ec;
+
+	num_fans = __cros_ec_hwmon_probe_fans(ec_hwmon);
+	if (num_fans < 0)
+		return num_fans;
+
+	num_temps = __cros_ec_hwmon_probe_temps(ec_hwmon);
+	if (num_fans < 0)
+		return num_temps;
+
+	ec_hwmon->attrs = devm_kzalloc(&pdev->dev,
+				       sizeof(*ec_hwmon->attrs) *
+				       (num_fans + num_temps + 1),
+				       GFP_KERNEL);
+	if (!ec_hwmon->attrs)
+		return -ENOMEM;
+
+	for (i = 0; i < num_fans; i++) {
+		attr = devm_kzalloc(&pdev->dev, sizeof(*attr), GFP_KERNEL);
+		if (!attr)
+			return -ENOMEM;
+		sysfs_attr_init(&attr->dev_attr.attr);
+		attr->dev_attr.attr.name = devm_kasprintf(&pdev->dev,
+							  GFP_KERNEL,
+							  "fan%d_input",
+							  i);
+		if (!attr->dev_attr.attr.name)
+			return -ENOMEM;
+
+		attr->dev_attr.show = cros_ec_hwmon_read_fan_rpm;
+		attr->dev_attr.attr.mode = S_IRUGO;
+		attr->index = i;
+		ec_hwmon->attrs[i] = &attr->dev_attr.attr;
+
+	}
+
+	for (i = 0; i < num_temps; i++) {
+		attr = devm_kzalloc(&pdev->dev, sizeof(*attr), GFP_KERNEL);
+		if (!attr)
+			return -ENOMEM;
+		sysfs_attr_init(&attr->dev_attr.attr);
+		attr->dev_attr.attr.name = devm_kasprintf(&pdev->dev,
+							  GFP_KERNEL,
+							  "temp%d_input",
+							  i);
+		if (!attr->dev_attr.attr.name)
+			return -ENOMEM;
+
+		attr->dev_attr.show = cros_ec_hwmon_read_temp;
+		attr->dev_attr.attr.mode = S_IRUGO;
+		attr->index = i;
+		ec_hwmon->attrs[i + num_fans] = &attr->dev_attr.attr;
+
+	}
+
+	ec_hwmon->attr_group.attrs = ec_hwmon->attrs;
+	ec_hwmon->groups[0] = &ec_hwmon->attr_group;
+
+	ec_hwmon->hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
+		    "ec_hwmon", ec_hwmon, ec_hwmon->groups);
+
+	if (IS_ERR(ec_hwmon->hwmon_dev))
+		return PTR_ERR(ec_hwmon->hwmon_dev);
+
+	platform_set_drvdata(pdev, ec_hwmon);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id cros_ec_hwmon_of_match[] = {
+	{ .compatible = "google,cros-ec-hwmon" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, cros_ec_hwmon_of_match);
+#endif
+
+static struct platform_driver cros_ec_hwmon_driver = {
+	.probe = cros_ec_hwmon_probe,
+	.driver = {
+		.name = "cros-ec-hwmon",
+		.of_match_table = of_match_ptr(cros_ec_hwmon_of_match),
+	},
+};
+module_platform_driver(cros_ec_hwmon_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ChromeOS EC Hardware Monitor driver");
+MODULE_ALIAS("platform:cros-ec-hwmon");
+MODULE_AUTHOR("Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>");
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH 1/3 RESEND] clocksource: Augment bindings for Faraday timer
From: Rob Herring @ 2017-04-07 22:01 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Lezcano, Thomas Gleixner,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20170407215513.25706-1-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Fri, Apr 7, 2017 at 4:55 PM, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> It turns out that the Cortina Gemini timer block is just a
> standard IP block from Faraday Technology named FTTMR010.
>
> In order to make things clear and understandable, we rename the
> bindings with a Faraday compatible as primary and the Cortina
> gemini as a more specific case.
>
> For the plain Faraday timer we require two clock references,
> while the Gemini can keep it's syscon lookup pattern.
>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  .../bindings/timer/cortina,gemini-timer.txt        | 22 ---------------
>  .../devicetree/bindings/timer/faraday,fttmr010.txt | 33 ++++++++++++++++++++++
>  2 files changed, 33 insertions(+), 22 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.txt

Does the -M option not work here?

In any case,

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/3 RESEND] clocksource: Augment bindings for Faraday timer
From: Daniel Lezcano @ 2017-04-07 22:03 UTC (permalink / raw)
  To: Rob Herring, Linus Walleij
  Cc: Thomas Gleixner, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <CAL_JsqJ6HWRiU2iQtJapRLwuWdUM6KCgYfseJzMtie-xG_UKxw@mail.gmail.com>

On 08/04/2017 00:01, Rob Herring wrote:
> On Fri, Apr 7, 2017 at 4:55 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>> It turns out that the Cortina Gemini timer block is just a
>> standard IP block from Faraday Technology named FTTMR010.
>>
>> In order to make things clear and understandable, we rename the
>> bindings with a Faraday compatible as primary and the Cortina
>> gemini as a more specific case.
>>
>> For the plain Faraday timer we require two clock references,
>> while the Gemini can keep it's syscon lookup pattern.
>>
>> Cc: devicetree@vger.kernel.org
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>> ---
>>  .../bindings/timer/cortina,gemini-timer.txt        | 22 ---------------
>>  .../devicetree/bindings/timer/faraday,fttmr010.txt | 33 ++++++++++++++++++++++
>>  2 files changed, 33 insertions(+), 22 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt
>>  create mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
> 
> Does the -M option not work here?
> 
> In any case,
> 
> Acked-by: Rob Herring <robh@kernel.org>

Thanks.


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* Re: [PATCH 1/3 RESEND] clocksource: Augment bindings for Faraday timer
From: Daniel Lezcano @ 2017-04-07 22:03 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Gleixner, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170407215513.25706-1-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Fri, Apr 07, 2017 at 11:55:13PM +0200, Linus Walleij wrote:
> It turns out that the Cortina Gemini timer block is just a
> standard IP block from Faraday Technology named FTTMR010.
> 
> In order to make things clear and understandable, we rename the
> bindings with a Faraday compatible as primary and the Cortina
> gemini as a more specific case.
> 
> For the plain Faraday timer we require two clock references,
> while the Gemini can keep it's syscon lookup pattern.
> 
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---

Series applied.

Thanks.

  -- Daniel
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 3/8] v4l: async: Add fwnode match support
From: Sakari Ailus @ 2017-04-07 22:08 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sakari Ailus, linux-media-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <3116679.V91IAuC66O@avalon>

On Fri, Apr 07, 2017 at 01:47:11PM +0300, Laurent Pinchart wrote:
> Hi Sakari,
> 
> On Friday 07 Apr 2017 13:45:09 Sakari Ailus wrote:
> > On Fri, Apr 07, 2017 at 01:04:47PM +0300, Laurent Pinchart wrote:
> > > > @@ -58,6 +60,9 @@ struct v4l2_async_subdev {
> > > >  			const struct device_node *node;
> > > >  		} of;
> > > >  		struct {
> > > > +			struct fwnode_handle *fwn;
> > > 
> > > Shouldn't this be const ?
> > 
> > I thought the same, but a lot of functions that operate on fwnode_handle
> > take a non-const argument. I attempted changing that, but it starts a
> > cascade of unavoidable changes elsewhere. That's not very well suitable for
> > this patchset.
> 
> fwnode is young, we should try to fix it instead of propagating issues :-)

I'm not arguing this would be how I'd prefer things to be. Adding a
dependency to another kernel framework would mean postponing the set. This
can well be fixed later on as well.

-- 
Sakari Ailus
e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org	XMPP: sailus-PCDdDYkjdNMDXYZnReoRVg@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/3 RESEND] clocksource: Augment bindings for Faraday timer
From: Daniel Lezcano @ 2017-04-07 22:08 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Thomas Gleixner,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAL_JsqJ6HWRiU2iQtJapRLwuWdUM6KCgYfseJzMtie-xG_UKxw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Fri, Apr 07, 2017 at 05:01:53PM -0500, Rob Herring wrote:
> On Fri, Apr 7, 2017 at 4:55 PM, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> > It turns out that the Cortina Gemini timer block is just a
> > standard IP block from Faraday Technology named FTTMR010.
> >
> > In order to make things clear and understandable, we rename the
> > bindings with a Faraday compatible as primary and the Cortina
> > gemini as a more specific case.
> >
> > For the plain Faraday timer we require two clock references,
> > while the Gemini can keep it's syscon lookup pattern.
> >
> > Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > ---
> >  .../bindings/timer/cortina,gemini-timer.txt        | 22 ---------------
> >  .../devicetree/bindings/timer/faraday,fttmr010.txt | 33 ++++++++++++++++++++++
> >  2 files changed, 33 insertions(+), 22 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/timer/cortina,gemini-timer.txt
> >  create mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
> 
> Does the -M option not work here?
> 
> In any case,
> 
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Thanks.


-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 4/8] v4l: async: Provide interoperability between OF and fwnode matching
From: Sakari Ailus @ 2017-04-07 22:10 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Sakari Ailus, linux-media, linux-acpi, devicetree
In-Reply-To: <4169138.83VydnvH0Q@avalon>

Hi Laurent,

On Fri, Apr 07, 2017 at 01:07:48PM +0300, Laurent Pinchart wrote:
> Hi Sakari,
> 
> Thank you for the patch.
> 
> On Thursday 06 Apr 2017 16:12:06 Sakari Ailus wrote:
> > OF and fwnode support are separated in V4L2 and individual drivers may
> > implement one of them. Sub-devices do not match with a notifier
> > expecting sub-devices with fwnodes, nor the other way around.
> 
> Shouldn't we instead convert all drivers to fwnode matching ? What's missing 
> after the mass conversion in patch 5/8 ?

A lot of drivers use the OF frame work and thus do not deal with fwnodes
directly. I haven't entirely converted them to use the fwnode API since
making additional, unnecessary changes increases the likelihood of errors.

> 
> > Fix this by checking for sub-device's of_node field in fwnode match and
> > fwnode field in OF match.
> > 
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-async.c | 26 +++++++++++++++++++++++---
> >  include/media/v4l2-async.h           |  2 +-
> >  2 files changed, 24 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-async.c
> > b/drivers/media/v4l2-core/v4l2-async.c index 384ad5e..7f5d804 100644
> > --- a/drivers/media/v4l2-core/v4l2-async.c
> > +++ b/drivers/media/v4l2-core/v4l2-async.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/list.h>
> >  #include <linux/module.h>
> >  #include <linux/mutex.h>
> > +#include <linux/of.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/slab.h>
> >  #include <linux/types.h>
> > @@ -40,15 +41,34 @@ static bool match_devname(struct v4l2_subdev *sd,
> >  	return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
> >  }
> > 
> > +static bool fwnode_cmp(struct fwnode_handle *one,
> > +		       struct fwnode_handle *theother)
> > +{
> > +	if (!one || !theother)
> > +		return false;
> > +
> > +	if (one->type != theother->type)
> > +		return false;
> > +
> > +	if (is_of_node(one))
> > +		return !of_node_cmp(of_node_full_name(to_of_node(one)),
> > +				    of_node_full_name(to_of_node(theother)));
> > +	else
> > +		return one == theother;
> > +}
> > +
> >  static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
> > {
> > -	return !of_node_cmp(of_node_full_name(sd->of_node),
> > -			    of_node_full_name(asd->match.of.node));
> > +	return fwnode_cmp(sd->of_node ?
> > +			  of_fwnode_handle(sd->of_node) : sd->fwnode,
> > +			  of_fwnode_handle(asd->match.of.node));
> >  }
> > 
> >  static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev
> > *asd)
> >  {
> > -	return sd->fwnode == asd->match.fwnode.fwn;
> > +	return fwnode_cmp(sd->of_node ?
> > +			  of_fwnode_handle(sd->of_node) : sd->fwnode,
> > +					   asd->match.fwnode.fwn);
> >  }
> > 
> >  static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev
> > *asd) diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> > index 8f552d2..df8b682 100644
> > --- a/include/media/v4l2-async.h
> > +++ b/include/media/v4l2-async.h
> > @@ -57,7 +57,7 @@ struct v4l2_async_subdev {
> >  	enum v4l2_async_match_type match_type;
> >  	union {
> >  		struct {
> > -			const struct device_node *node;
> > +			struct device_node *node;
> 
> That seems to be a bit of a hack :-( I'd rather make everything const and cast 
> to non-const pointers explicitly where the API requires us to. Or, better, add 
> a to_of_node_const() function.

I'll see what I can do to the matter, but if you don't mind, I'll base it on
this patchset.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply

* Re: [PATCH v2 5/8] v4l: Switch from V4L2 OF not V4L2 fwnode API
From: Sakari Ailus @ 2017-04-07 22:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sakari Ailus, linux-media-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	mika.westerberg-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <1895617.xparv3opoe@avalon>

Hi Laurent,

On Fri, Apr 07, 2017 at 02:09:16PM +0300, Laurent Pinchart wrote:
> Hi Sakari,
> 
> On Friday 07 Apr 2017 13:58:06 Sakari Ailus wrote:
> > On Fri, Apr 07, 2017 at 01:32:54PM +0300, Laurent Pinchart wrote:
> > > On Thursday 06 Apr 2017 16:12:07 Sakari Ailus wrote:
> > > > Switch users of the v4l2_of_ APIs to the more generic v4l2_fwnode_ APIs.
> > > > 
> > > > Existing OF matching continues to be supported. omap3isp and smiapp
> > > > drivers are converted to fwnode matching as well.
> > > > 
> > > > Signed-off-by: Sakari Ailus <sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> > > > Acked-by: Benoit Parrot <bparrot-l0cyMroinI0@public.gmane.org> # i2c/ov2569.c,
> > > > am437x/am437x-vpfe.c and ti-vpe/cal.c ---
> > > > 
> > > >  drivers/media/i2c/Kconfig                      |  9 ++++
> > > >  drivers/media/i2c/adv7604.c                    |  7 +--
> > > >  drivers/media/i2c/mt9v032.c                    |  7 +--
> > > >  drivers/media/i2c/ov2659.c                     |  8 +--
> > > >  drivers/media/i2c/s5c73m3/s5c73m3-core.c       |  7 +--
> > > >  drivers/media/i2c/s5k5baf.c                    |  6 +--
> > > >  drivers/media/i2c/smiapp/Kconfig               |  1 +
> > > >  drivers/media/i2c/smiapp/smiapp-core.c         | 29 ++++++-----
> > > >  drivers/media/i2c/tc358743.c                   | 11 ++--
> > > >  drivers/media/i2c/tvp514x.c                    |  6 +--
> > > >  drivers/media/i2c/tvp5150.c                    |  7 +--
> > > >  drivers/media/i2c/tvp7002.c                    |  6 +--
> > > >  drivers/media/platform/Kconfig                 |  3 ++
> > > >  drivers/media/platform/am437x/Kconfig          |  1 +
> > > >  drivers/media/platform/am437x/am437x-vpfe.c    |  8 +--
> > > >  drivers/media/platform/atmel/Kconfig           |  1 +
> > > >  drivers/media/platform/atmel/atmel-isc.c       |  8 +--
> > > >  drivers/media/platform/exynos4-is/Kconfig      |  2 +
> > > >  drivers/media/platform/exynos4-is/media-dev.c  |  6 +--
> > > >  drivers/media/platform/exynos4-is/mipi-csis.c  |  6 +--
> > > >  drivers/media/platform/omap3isp/isp.c          | 71  +++++++++---------
> > > >  drivers/media/platform/pxa_camera.c            |  7 +--
> > > >  drivers/media/platform/rcar-vin/Kconfig        |  1 +
> > > >  drivers/media/platform/rcar-vin/rcar-core.c    |  6 +--
> > > >  drivers/media/platform/soc_camera/Kconfig      |  1 +
> > > >  drivers/media/platform/soc_camera/atmel-isi.c  |  7 +--
> > > >  drivers/media/platform/soc_camera/soc_camera.c |  3 +-
> > > >  drivers/media/platform/ti-vpe/cal.c            | 11 ++--
> > > >  drivers/media/platform/xilinx/Kconfig          |  1 +
> > > >  drivers/media/platform/xilinx/xilinx-vipp.c    | 59  +++++++++---------
> > > >  include/media/v4l2-fwnode.h                    |  4 +-
> > > >  31 files changed, 176 insertions(+), 134 deletions(-)
> > > > 
> > > > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > > > index cee1dae..6b2423a 100644
> > > > --- a/drivers/media/i2c/Kconfig
> > > > +++ b/drivers/media/i2c/Kconfig
> > > > @@ -210,6 +210,7 @@ config VIDEO_ADV7604
> > > > 
> > > >  	depends on GPIOLIB || COMPILE_TEST
> > > >  	select HDMI
> > > >  	select MEDIA_CEC_EDID
> > > > 
> > > > +	select V4L2_FWNODE
> > > 
> > > What happens when building the driver on a platform that includes neither
> > > OF nor ACPI support ?
> > 
> > You need either in practice, also for the V4L2 fwnode to be meaningful.
> > 
> > Do you have something in particular in mind?
> 
> I will obviously need either OF or ACPI to use the fwnode API, but some 
> drivers still support platform data (either on non-OF embedded systems, or 
> when the I2C device is part of a PCI card for instance). Compile-testing is 
> also a use case I'm concerned about.

Ah, so essentially compiling a driver using V4L2 fwnode with both ACPI and
OF disabled? I don't know if there are such drivers right now but that's a
good point in general.

> 
> [snip]
> 
> > > > diff --git a/drivers/media/platform/omap3isp/isp.c
> > > > b/drivers/media/platform/omap3isp/isp.c index 084ecf4a..95850b9 100644
> > > > --- a/drivers/media/platform/omap3isp/isp.c
> > > > +++ b/drivers/media/platform/omap3isp/isp.c
> > > 
> > > [snip]
> > > 
> > > > @@ -2024,43 +2025,42 @@ enum isp_of_phy {
> > > >  	ISP_OF_PHY_CSIPHY2,
> > > >  };
> > > > 
> > > > -static int isp_of_parse_node(struct device *dev, struct device_node
> > > > *node,
> > > > -			     struct isp_async_subdev *isd)
> > > > +static int isp_fwnode_parse(struct device *dev, struct fwnode_handle
> > > > *fwn,
> > > > +			    struct isp_async_subdev *isd)
> > > >  {
> > > >  	struct isp_bus_cfg *buscfg = &isd->bus;
> > > > -	struct v4l2_of_endpoint vep;
> > > > +	struct v4l2_fwnode_endpoint vfwn;
> > > 
> > > vfwn is confusing to me, I think the variable name should show that it
> > > refers to an endpoint.
> > 
> > How about adding ep to tell it's an endpoint?
> 
> I'd name is vep or endpoint.

I'll use "vep". "fwnode" for struct fwnode_handle pointers, it is an
established practice elsewhere.

> 
> > > >  	unsigned int i;
> > > >  	int ret;
> > > > 
> > > > -	ret = v4l2_of_parse_endpoint(node, &vep);
> > > > +	ret = v4l2_fwnode_endpoint_parse(fwn, &vfwn);
> > > >  	if (ret)
> > > >  		return ret;
> > > > 
> > > > -	dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name,
> > > > -		vep.base.port);
> > > > +	dev_dbg(dev, "interface %u\n", vfwn.base.port);
> > > 
> > > Is there no way to keep the node name in the error message ?
> > 
> > There's no generic fwnode means to do something similar currently, possibly
> > because I understand ACPI doesn't do that. One could check whether the node
> > is an OF node and then use the full_name field but I wonder if it's worth
> > it.
> 
> My ACPI knowledge is limited, but don't ACPI nodes have 4 character names that 
> can be combined in a string to create a full path ?

There is something, yes, but the ACPI framework currently has no such
functionality. I believe it could be implemented though. Cc Mika.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org	XMPP: sailus-PCDdDYkjdNMDXYZnReoRVg@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 6/8] v4l: media/drv-intf/soc_mediabus.h: include dependent header file
From: Sakari Ailus @ 2017-04-07 22:56 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Sakari Ailus, linux-media, linux-acpi, devicetree
In-Reply-To: <2155093.Y2052RbRLf@avalon>

Hi Laurent,

On Fri, Apr 07, 2017 at 01:01:29PM +0300, Laurent Pinchart wrote:
> Hi Sakari,
> 
> Thank you for the patch.
> 
> On Thursday 06 Apr 2017 16:12:08 Sakari Ailus wrote:
> > media/drv-intf/soc_mediabus.h does depend on struct v4l2_mbus_config which
> > is defined in media/v4l2-mediabus.h. Include it.
> > 
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> 
> Was this provided indirectly before, through v4l2-of.h perhaps ? If so, 
> shouldn't this patch be moved before 5/8 ? Apart from that,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

I tried compiling with and without this patch and see no difference. I could
miss something but the more likely case is that the reason why I wrote this
patch has ceased to exist. I'll drop it from the set, at least for now.

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply

* Re: [PATCH v2 1/2] arm64: dts: rk3399: add support for firefly-rk3399 board
From: Heiko Stuebner @ 2017-04-07 23:01 UTC (permalink / raw)
  To: Kever Yang, Will Deacon
  Cc: linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Jianqun Xu, Liang Chen,
	Brian Norris, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andy Yan,
	Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Mark Rutland, Catalin Marinas, Matthias Brugger
In-Reply-To: <1491384800-22412-1-git-send-email-kever.yang-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Hi Kever,

Am Mittwoch, 5. April 2017, 17:33:19 CEST schrieb Kever Yang:
> Firefly-rk3399 is a bord from T-Firefly, you can find detail about
> it here:
> http://en.t-firefly.com/en/firenow/Firefly_RK3399/
> 
> This patch add basic node for the board and make it able to bring
> up.
> 
> Peripheral works:
> - usb hub which connect to ehci controller;
> - UART2 debug
> - eMMC
> - PCIe
> 
> Not work:
> - USB 3.0 HOST, type-C port
> - sdio, sd-card
> 
> Not test for other peripheral:
> - HDMI
> - Ethernet
> - OPTICAL
> - WiFi/BT
> - MIPI CSI/DSI
> - IR
> - EDP/DP
> 
> Signed-off-by: Kever Yang <kever.yang-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

[...]

> +	vdd_log: vdd-log {
> +		compatible = "pwm-regulator";
> +		pwms = <&pwm2 0 25000 1>;
> +		regulator-name = "vdd_log";
> +		regulator-min-microvolt = <800000>;
> +		regulator-max-microvolt = <1400000>;
> +		regulator-always-on;
> +		regulator-boot-on;
> +
> +		/* for rockchip boot on */
> +		rockchip,pwm_id= <2>;
> +		rockchip,pwm_voltage = <1000000>;

Vendor-kernel stuff, needs to be dropped

[...]

> +&i2c0 {
> +	status = "okay";
> +	i2c-scl-rising-time-ns = <168>;
> +	i2c-scl-falling-time-ns = <4>;
> +	clock-frequency = <400000>;
> +
> +	vdd_cpu_b: pmic@40 {
> +		compatible = "silergy,syr827";
> +		reg = <0x40>;
> +		vin-supply = <&vcc5v0_sys>;
> +		regulator-compatible = "fan53555-reg";
> +		regulator-name = "vdd_cpu_b";
> +		regulator-min-microvolt = <712500>;
> +		regulator-max-microvolt = <1500000>;
> +		regulator-ramp-delay = <1000>;
> +		vsel-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;

non-mainline property

> +		fcs,suspend-voltage-selector = <0>;
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-initial-state = <3>;

non-mainline property

> +			regulator-state-mem {

indentation is wrong

> +			regulator-off-in-suspend;
> +		};
> +	};
> +
> +	vdd_gpu: syr828@41 {
> +		compatible = "silergy,syr828";
> +		reg = <0x41>;
> +		vin-supply = <&vcc5v0_sys>;
> +		regulator-compatible = "fan53555-reg";
> +		regulator-name = "vdd_gpu";
> +		regulator-min-microvolt = <712500>;
> +		regulator-max-microvolt = <1500000>;
> +		regulator-ramp-delay = <1000>;
> +		fcs,suspend-voltage-selector = <1>;
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-initial-state = <3>;

non-mainline property

> +			regulator-state-mem {

indentation is wrong

> +			regulator-off-in-suspend;
> +		};
> +	};
> +
> +	rk808: pmic@1b {
> +		compatible = "rockchip,rk808";
> +		reg = <0x1b>;
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pmic_int_l>;
> +		rockchip,system-power-controller;

system-power-controller without the "rockchip,"?

> +		wakeup-source;
> +		#clock-cells = <1>;
> +		clock-output-names = "xin32k", "rk808-clkout2";

[...]

> +&i2c1 {
> +	status = "okay";
> +	i2c-scl-rising-time-ns = <300>;
> +	i2c-scl-falling-time-ns = <15>;
> +
> +	gsl3673: gsl3673@40 {

gsl3673: touchscreen@40

> +		compatible = "GSL,GSL3673";

compatible lowercase?

> +		reg = <0x40>;
> +		screen_max_x = <1536>;
> +		screen_max_y = <2048>;
> +		irq_gpio_number = <&gpio1 RK_PC4 IRQ_TYPE_LEVEL_LOW>;
> +		rst_gpio_number = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
> +	};
> +
> +	rt5640: rt5640@1c {
> +		#sound-dai-cells = <0>;
> +		compatible = "realtek,rt5640";
> +		reg = <0x1c>;
> +		clocks = <&cru SCLK_I2S_8CH_OUT>;
> +		clock-names = "mclk";
> +		realtek,in1-differential;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&rt5640_hpcon>;

> +		hp-con-gpio = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
> +		io-channels = <&saradc 4>;
> +		hp-det-adc-value = <500>;

these last 3 properties are not contained in the rt5640 binding
document on linux-next-20170407 .

> +	};
> +};
> +
> +&i2c3 {
> +	status = "okay";
> +	i2c-scl-rising-time-ns = <450>;
> +	i2c-scl-falling-time-ns = <15>;
> +};
> +
> +&i2c4 {
> +	status = "okay";
> +	i2c-scl-rising-time-ns = <600>;
> +	i2c-scl-falling-time-ns = <20>;
> +
> +	fusb0: fusb30x@22 {

fusb0: usb-typec@22 or so

Also that device is not in mainline yet, so has no approved binding
so should not be included right now.

> +		compatible = "fairchild,fusb302";
> +		reg = <0x22>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&fusb0_int>;
> +		int-n-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;
> +		vbus-5v-gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_HIGH>;
> +		status = "okay";
> +	};
> +
> +	mpu6500@68 {

accelerometer@68

> +		status = "okay";
> +		compatible = "invensense,mpu6500";
> +		reg = <0x68>;
> +		irq-gpio = <&gpio1 RK_PC6 IRQ_TYPE_EDGE_RISING>;
> +		mpu-int_config = <0x10>;
> +		mpu-level_shifter = <0>;
> +		mpu-orientation = <0 1 0 1 0 0 0 0 1>;
> +		orientation-x= <1>;
> +		orientation-y= <0>;
> +		orientation-z= <0>;
> +		mpu-debug = <1>;
> +	};
> +};
> +

[...]

> +&u2phy0 {
> +	status = "okay";
> +	extcon = <&fusb0>;

see comment for fusb302

> +
> +	u2phy0_otg: otg-port {
> +		status = "okay";
> +	};
> +
> +	u2phy0_host: host-port {
> +		phy-supply = <&vcc5v0_host>;
> +		status = "okay";
> +	};
> +};
> +


Heiko

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 7/8] docs-rst: media: Switch documentation to V4L2 fwnode API
From: Sakari Ailus @ 2017-04-07 23:02 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Sakari Ailus, linux-media, linux-acpi, devicetree
In-Reply-To: <1640047.4eZCzTnCCW@avalon>

Hi Laurent,

On Fri, Apr 07, 2017 at 12:59:01PM +0300, Laurent Pinchart wrote:
> Hi Sakari,
> 
> Thank you for the patch.
> 
> On Thursday 06 Apr 2017 16:12:09 Sakari Ailus wrote:
> > Instead of including the V4L2 OF header in ReST documentation, use the
> > V4L2 fwnode header instead.
> > 
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  Documentation/media/kapi/v4l2-core.rst   | 2 +-
> >  Documentation/media/kapi/v4l2-fwnode.rst | 3 +++
> >  Documentation/media/kapi/v4l2-of.rst     | 3 ---
> >  3 files changed, 4 insertions(+), 4 deletions(-)
> >  create mode 100644 Documentation/media/kapi/v4l2-fwnode.rst
> >  delete mode 100644 Documentation/media/kapi/v4l2-of.rst
> > 
> > diff --git a/Documentation/media/kapi/v4l2-core.rst
> > b/Documentation/media/kapi/v4l2-core.rst index e967715..1bc8a14 100644
> > --- a/Documentation/media/kapi/v4l2-core.rst
> > +++ b/Documentation/media/kapi/v4l2-core.rst
> > @@ -19,7 +19,7 @@ Video2Linux devices
> >      v4l2-mc
> >      v4l2-mediabus
> >      v4l2-mem2mem
> > -    v4l2-of
> > +    v4l2-fwnode
> 
> I wonder whether we should keep this alphabetically sorted.

It's not fully sorted at the moment --- see tuner / common below. It'd be
good if it was though. I'll add a patch for that.

> 
> Apart from that,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Thanks!

> 
> >      v4l2-rect
> >      v4l2-tuner
> >      v4l2-common
> > diff --git a/Documentation/media/kapi/v4l2-fwnode.rst
> > b/Documentation/media/kapi/v4l2-fwnode.rst new file mode 100644
> > index 0000000..6c8bccd
> > --- /dev/null
> > +++ b/Documentation/media/kapi/v4l2-fwnode.rst
> > @@ -0,0 +1,3 @@
> > +V4L2 fwnode kAPI
> > +^^^^^^^^^^^^^^^^
> > +.. kernel-doc:: include/media/v4l2-fwnode.h
> > diff --git a/Documentation/media/kapi/v4l2-of.rst
> > b/Documentation/media/kapi/v4l2-of.rst deleted file mode 100644
> > index 1ddf76b..0000000
> > --- a/Documentation/media/kapi/v4l2-of.rst
> > +++ /dev/null
> > @@ -1,3 +0,0 @@
> > -V4L2 Open Firmware kAPI
> > -^^^^^^^^^^^^^^^^^^^^^^^
> > -.. kernel-doc:: include/media/v4l2-of.h
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply

* Re: [PATCH V10 06/12] of: device: Fix overflow of coherent_dma_mask
From: Frank Rowand @ 2017-04-07 23:10 UTC (permalink / raw)
  To: Sricharan R, robin.murphy, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt, devicetree,
	linux-kernel, sudeep.holla, rjw, lenb, catalin.marinas, arnd,
	linux-arch, gregkh
In-Reply-To: <58E5E7B7.1050400@gmail.com>

On 04/06/17 00:01, Frank Rowand wrote:
> On 04/04/17 03:18, Sricharan R wrote:
>> Size of the dma-range is calculated as coherent_dma_mask + 1
>> and passed to arch_setup_dma_ops further. It overflows when
>> the coherent_dma_mask is set for full 64 bits 0xFFFFFFFFFFFFFFFF,
>> resulting in size getting passed as 0 wrongly. Fix this by
>> passsing in max(mask, mask + 1). Note that in this case
>> when the mask is set to full 64bits, we will be passing the mask
>> itself to arch_setup_dma_ops instead of the size. The real fix
>> for this should be to make arch_setup_dma_ops receive the
>> mask and handle it, to be done in the future.
>>
>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>> ---
>>  drivers/of/device.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index c17c19d..c2ae6bb 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>>  	ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
>>  	if (ret < 0) {
>>  		dma_addr = offset = 0;
>> -		size = dev->coherent_dma_mask + 1;
>> +		size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);

NACK withdrawn below.

However, I would prefer a change to this line for readability. Using max() results
in the correct result, but obscures the reason behind the algorithm, where the
intent is to avoid an overflow.  How about something like:

	size = (dev->coherent_dma_mask == 0xffffffffffffffffULL)
		? 0xffffffffffffffffULL : dev->coherent_dma_mask + 1;


>>  	} else {
>>  		offset = PFN_DOWN(paddr - dma_addr);
>>  		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
>>
> 
> NACK.
> 
> Passing an invalid size to arch_setup_dma_ops() is only part of the problem.
> size is also used in of_dma_configure() before calling arch_setup_dma_ops():
> 
>         dev->coherent_dma_mask = min(dev->coherent_dma_mask,
>                                      DMA_BIT_MASK(ilog2(dma_addr + size)));
>         *dev->dma_mask = min((*dev->dma_mask),
>                              DMA_BIT_MASK(ilog2(dma_addr + size)));
> 
> which would be incorrect for size == 0xffffffffffffffffULL when
> dma_addr != 0.  So the proposed fix really is not papering over

  ^^^^^^^^^^^^^  This is the flaw in my objection.  When in the
(ret < 0) path, dma_addr is set to zero.  So my worry about dma_addr != 0
is baseless.

I withdraw my NACK because my analysis was flawed.

-Frank

> the base problem very well.
> 
> I agree that the proper solution involves passing a mask instead
> of a size to arch_setup_dma_ops().
> 
> -Frank
> 


^ permalink raw reply

* Re: [PATCH V10 06/12] of: device: Fix overflow of coherent_dma_mask
From: Frank Rowand @ 2017-04-07 23:13 UTC (permalink / raw)
  To: Robin Murphy, Sricharan R, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt, devicetree,
	linux-kernel, sudeep.holla, rjw, lenb, catalin.marinas, arnd,
	linux-arch, gregkh
In-Reply-To: <b38312b0-268b-ed86-a5b3-886f86ea13f5@arm.com>

On 04/07/17 07:46, Robin Murphy wrote:
> On 06/04/17 20:34, Frank Rowand wrote:
>> On 04/06/17 04:01, Sricharan R wrote:
>>> Hi Frank,
>>>
>>> On 4/6/2017 12:31 PM, Frank Rowand wrote:
>>>> On 04/04/17 03:18, Sricharan R wrote:
>>>>> Size of the dma-range is calculated as coherent_dma_mask + 1
>>>>> and passed to arch_setup_dma_ops further. It overflows when
>>>>> the coherent_dma_mask is set for full 64 bits 0xFFFFFFFFFFFFFFFF,
>>>>> resulting in size getting passed as 0 wrongly. Fix this by
>>>>> passsing in max(mask, mask + 1). Note that in this case
>>>>> when the mask is set to full 64bits, we will be passing the mask
>>>>> itself to arch_setup_dma_ops instead of the size. The real fix
>>>>> for this should be to make arch_setup_dma_ops receive the
>>>>> mask and handle it, to be done in the future.
>>>>>
>>>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>>>> ---
>>>>>  drivers/of/device.c | 2 +-
>>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>>>>> index c17c19d..c2ae6bb 100644
>>>>> --- a/drivers/of/device.c
>>>>> +++ b/drivers/of/device.c
>>>>> @@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>>>>>      ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
>>>>>      if (ret < 0) {
>>>>>          dma_addr = offset = 0;
>>>>> -        size = dev->coherent_dma_mask + 1;
>>>>> +        size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>>>>>      } else {
>>>>>          offset = PFN_DOWN(paddr - dma_addr);
>>>>>          dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
>>>>>
>>>>
>>>> NACK.
>>>>
>>>> Passing an invalid size to arch_setup_dma_ops() is only part of the problem.
>>>> size is also used in of_dma_configure() before calling arch_setup_dma_ops():
>>>>
>>>>         dev->coherent_dma_mask = min(dev->coherent_dma_mask,
>>>>                                      DMA_BIT_MASK(ilog2(dma_addr + size)));
>>>>         *dev->dma_mask = min((*dev->dma_mask),
>>>>                              DMA_BIT_MASK(ilog2(dma_addr + size)));
>>>>
>>>> which would be incorrect for size == 0xffffffffffffffffULL when
>>>> dma_addr != 0.  So the proposed fix really is not papering over
>>>> the base problem very well.
>>>>
>>>
>>> Ok, but with your fix for of_dma_get_range and the above fix,
>>> dma_addr will be '0' when size = 0xffffffffffffffffULL,
>>> but DMA_BIT_MASK(ilog2(dma_addr + size)) would be wrong though,
>>> making coherent_dma_mask to be smaller 0x7fffffffffffffffULL.
>>
>> Yes, that was my point.  Setting size to 0x7fffffffffffffffULL
>> affects several places.  Another potential location (based only
>> on the function header comment, not from reading the code) is
>> iommu_dma_init_domain().  The header comment says:
>>
>>     * @base and @size should be exact multiples of IOMMU page granularity to
>>     * avoid rounding surprises.
> 
> That is really only referring to the fact that some of the work done
> therein involves truncation to PFNs, so anyone passing in non-exact
> values expecting them to round a particular way may get things off by a
> page one way or the other. It's not going to have much practical
> significance for real devices (in particular since size is used more as
> a sanity check than any kind of actual limit there).
> 
>> I have not read enough context to really understand of_dma_configure(), but
>> it seems there is yet another issue in how the error return case from
>> of_dma_get_range() is handled (with the existing code, as well as if
>> my patch gets accepted).  An error return value can mean _either_
>> there is no dma-ranges property _or_ "an other problem occurred".  Should
>> the "an other problem occurred" case be handled by defaulting size to
>> a value based on dev->coherent_dma_mask (the current case) or should the
>> attempt to set up the DMA configuration just fail?
> 
> There is indeed a lot wrong with of_dma_configure() and
> arch_setup_dma_ops(), but fixing those is beyond the scope of this
> series. This is just working around a latent bug in the one specific
> case where a value is *not* derived from DT. Any DT which worked before
> still works; any DT which made of_dma_configure() go wrong before still
> makes of_dma_configure() go wrong exactly the same.
> 
> Whilst it's not ideal, since a DMA mask basically represents the maximum
> size of address that that particular device can be given, I can't see it
> making any practical difference for a full 64-bit DMA mask to be trimmed
> down to 63 bits upon re-probing - no system is likely to have that many
> physical address bits anyway, and I don't think any IOMMUs support that
> large an IOVA space either, so as long as it's still big enough to cover
> "everything", it'll be OK.
> 
> Of course, whether DMA_BIT_MASK(ilog2(dma_addr + size)) is the right
> thing to do in the first place is yet another matter, as there are
> plenty of cases where it results in something which can't reach the
> given range at all, but again, this isn't the place. Much as I'm keen to
> get the behaviour of of_dma_configure() sorted out properly, it doesn't
> seem reasonable that that should suddenly block this
> almost-entirely-orthogonal series that various other work has been
> waiting on for some time now. The WIP patch I have for
> arch_setup_dma_ops() already touches 3 architectures and 4 other
> subsystems...

In a reply to my original NACK email, I just now retracted the NACK,
but with a requested change for readability.

I buy your analysis and argument here.  The patch will improve things
a little, but it will be good to revisit of_dma_configure() in the
future to further clean things up.

-Frank

> 
> Robin.
> 
>>
>>>
>>> Regards,
>>>  Sricharan
>>>
>>>> I agree that the proper solution involves passing a mask instead
>>>> of a size to arch_setup_dma_ops().
>>>>
>>>
>>
> 
> 

^ permalink raw reply

* Re: [PATCH] of: change fixup of dma-ranges size to error
From: Frank Rowand @ 2017-04-07 23:26 UTC (permalink / raw)
  To: Rob Herring, Robin Murphy, Sricharan
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAL_Jsq+8PoR5ikPbTbHgd-8rkGFmvorLrS9hHpmkVynkh69e-A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 04/07/17 10:09, Rob Herring wrote:
> + Robin, Sricharan
> 
> On Fri, Apr 7, 2017 at 12:18 AM, Frank Rowand <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> On 04/06/17 15:41, Rob Herring wrote:
>>> On Thu, Apr 6, 2017 at 1:37 PM, Frank Rowand <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>>> On 04/06/17 07:03, Rob Herring wrote:
>>>>> On Thu, Apr 6, 2017 at 1:18 AM,  <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>>>>> From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>>>>>>
>>>>>> of_dma_get_range() has workaround code to fixup a device tree that
>>>>>> incorrectly specified a mask instead of a size for property
>>>>>> dma-ranges.  That device tree was fixed a year ago in v4.6, so
>>>>>> the workaround is no longer needed.  Leave a data validation
>>>>>> check in place, but no longer do the fixup.  Move the check
>>>>>> one level deeper in the call stack so that other possible users
>>>>>> of dma-ranges will also be protected.
>>>>>>
>>>>>> The fix to the device tree was in
>>>>>> commit c91cb9123cdd ("dtb: amd: Fix DMA ranges in device tree").
>>>>>
>>>>> NACK.
>>>>> This was by design. You can't represent a size of 2^64 or 2^32.
>>>>
>>>> I agree that being unable to represent a size of 2^32 in a u32 and
>>>> a size of 2^64 in a u64 is the underlying issue.
>>>>
>>>> But the code to convert a mask to a size is _not_ design, it is a
>>>> hack that temporarily worked around a device tree that did not follow
>>>> the dma-ranges binding in the ePAPR.
>>>
>>> Since when is (2^64 - 1) not a size. It's a perfectly valid size in
>>
>> I did not say (2^64 -1) is not a size.
>>
>> I said that the existing code has a hack that converts what is perceived
>> to be a mask into a size.  The existing code is:
>>
>> @@ 110,21 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>>                 size = dev->coherent_dma_mask + 1;
>>         } else {
>>                 offset = PFN_DOWN(paddr - dma_addr);
>>
>>                 /*
>>                  * Add a work around to treat the size as mask + 1 in case
>>                  * it is defined in DT as a mask.
>>                  */
>>                 if (size & 1) {
>>                         dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
>>                                  size);
>>                         size = size + 1;
>>                 }
>>
>>                 if (!size) {
>>                         dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
>>                         return;
>>                 }
>>                 dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
>>         }
>>
>> Note the comment that says "in case it is defined in DT as a mask."
>>
>> And as you stated in a review comment is 2015: "Also, we need a WARN
>> here so DTs get fixed."
> 
> Indeed. I agree that "let me put a mask in the DT so Linux (at some
> version) works" is wrong. I still think (2^32 - 1) and (2^64 - 1)
> should be allowed to avoid growing #size-cells and because
> #size-cells=3 doesn't work.
> 
>>> DT. And there's probably not a system in the world that needs access
>>> to that last byte. Is it completely accurate description if we
>>> subtract off 1? No, but it is still a valid range (so would be
>>> subtracting 12345).
>>>
>>>> That device tree was corrected a year ago to provide a size instead of
>>>> a mask.
>>>
>>> You are letting Linux implementation details influence your DT
>>> thinking. DT is much more flexible in that it supports a base address
>>> and size (and multiple of them) while Linux can only deal with a
>>> single address mask. If Linux dealt with base + size, then we wouldn't
>>
>> No.  of_dma_get_range() returns two addresses and a size from the
>> dma-ranges property, just as it is defined in the spec.
>>
>> of_dma_configure() then interprets an odd size as meaning that the
>> device tree incorrectly contains a mask, and then converts that mask
>> to a size by adding one to it.  Linux is _still_ using address and
>> size at this point.  It does _not_ convert this size into a mask,
>> but instead passes size on into arch_setup_dma_ops().
> 
> It doesn't really matter where in the implementation, but at some
> point we end up with only a mask in Linux was my point.
> 
>> The proposed patch is to quit accepting a mask as valid data in
>> dma-ranges.
>>
>>
>>> be having this conversation. As long as Linux only deals with masks,
>>> we're going to have to have some sort of work-around to deal with
>>> them.
>>>
>>>>> Well, technically you can for the latter, but then you have to grow
>>>>> #size-cells to 2 for an otherwise all 32-bit system which seems kind
>>>>> of pointless and wasteful. You could further restrict this to only
>>>>> allow ~0 and not just any case with bit 0 set.
>>>>>
>>>>> I'm pretty sure AMD is not the only system. There were 32-bit systems too.
>>>>
>>>> I examined all instances of property dma-ranges in in tree dts files in
>>>> Linux 4.11-rc1.  There are none that incorrectly specify mask instead of
>>>> size.
>>>
>>> Okay, but there are ones for ranges at least. See ecx-2000.dts.
>>
>> The patch does not impact the ranges property.  It only impacts the
>> dma-ranges property.
> 
> Yes, I know. I'm only pointing out we have other cases of size=~0 to
> avoid growing #size-cells.
> 
>>>> #size-cells only changes to 2 for the dma-ranges property and the ranges
>>>> property when size is 2^32, so that is a very small amount of space.
>>>>
>>>> The patch does not allow for a size of 2^64.  If a system requires a
>>>> size of 2^64 then the type of size needs to increase to be larger
>>>> than a u64.  If you would like for the code to be defensive and
>>>> detect a device tree providing a size of 2^64 then I can add a
>>>> check to of_dma_get_range() to return -EINVAL if #size-cells > 2.
>>>> When that error triggers, the type of size can be changed.
>>>
>>> #size-cells > 2 is completely broken for anything but PCI. I doubt it
>>
>> Yes, that is what I said.  The current code does not support #size-cells > 2
>> for dma-ranges.
> 
> It's not just dma-ranges. It's everywhere with reg and ranges and any
> code that parses those too. If someone needs to truly specify sizes of
> 2^64 in DT (for reg, ranges, or dma-ranges), they are SOL.
> 
>> #size-cells > 2 for dma-ranges will lead to a problem in
>> of_dma_get_range(), which stuffs the value of the size into a u64.
>> Clearly, a 3 cell size will not fit into a u64.
>>
>>
>>> is easily fixed without some special casing (i.e. a different hack)
>>> until we have 128-bit support. I hope to retire before we need to
>>> support that.
>>>
>>> Rob
>>>
>>
>> Can we get back to the basic premise of the proposed patch?
>>
>> The current code in of_dma_configure() contains a hack that allows the
>> dma-ranges property to specify a mask instead of a size.  The binding
>> in the specification allows a size and does not allow a mask.
>>
>> The hack was added to account for one or more dts files that did not
>> follow the specification.  In the mail list discussion of the hack
>> you said "Also, we need a WARN here so DTs get fixed."
>>
>> The hack was first present in Linux 4.1.  The only in-tree dts that
>> incorrectly contained a mask instead of a size in dma-ranges was
>> arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi
>>
>> That .dtsi was fixed by
>> commit c91cb9123cdd ("dtb: amd: Fix DMA ranges in device tree")
>> The fix was present in Linux 4.6, May 15, 2016.
>>
>> I would like to remove the hack.  I think that enough time has
>> elapsed to allow this change.
> 
> If we have no cases of what I'm concerned about, then removing it is
> fine. Is this a dependency for iommu series? Doesn't look like it to
> me.

This patch is a replacement for patch 03/12 in the iommu series.  I
think that patch 03/12 of the iommu series could be dropped and my
patch could be applied independently of the iommu series.

There is likely a conflict between my patch and patch 06/12 of the
iommu series because in my patch the first line of the patch chunk
of drivers/of/device.c includes a line that is changed in 06/12
of the iommu series.  If this is the case then the iommu series
should take precedence over my patch (and I should subsequently
fixup my patch).

-Frank

> 
> Rob
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* 3786 devicetree
From: nkosuta-f+iqBESB6gc @ 2017-04-08  0:54 UTC (permalink / raw)
  To: devicetree

[-- Attachment #1: 2310022.zip --]
[-- Type: application/zip, Size: 159 bytes --]

^ permalink raw reply

* [PATCH] ARM: dts: stm32f7: add STM32f769I & stm32f746 discovery board support
From: Vikas Manocha @ 2017-04-08  1:12 UTC (permalink / raw)
  To: alexandre.torgue-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o
  Cc: Vikas Manocha,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list, Mark Rutland, Maxime Coquelin,
	Rob Herring, Russell King

Stm32f769I & stm32f746 are MCUs of stm32f7 family. Here are the major
spces of the two boards:

stm32f769I discovery board:
	- Cortex-M7 core @216MHz
	- 2MB mcu internal flash
	- 512KB internal sram
	- 16MB sdram memory
	- 64MB qspi flash memory
	- 4 inch wvga LCD-TFT Display

stm32f746 discovery board:
	- Cortex-M7 core @216MHz
	- 1MB mcu internal flash
	- 320KB internal sram
	- 8MB sdram memory
	- 16MB qspi flash memory
	- 4.3 inch 480x272 LCD-TFT display

Signed-off-by: Vikas Manocha <vikas.manocha-qxv4g6HH51o@public.gmane.org>
---
 arch/arm/boot/dts/Makefile            |   2 +
 arch/arm/boot/dts/stm32f746-disco.dts | 101 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/stm32f746.dtsi      |   2 +-
 arch/arm/boot/dts/stm32f769-disco.dts | 101 ++++++++++++++++++++++++++++++++++
 4 files changed, 205 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/stm32f746-disco.dts
 create mode 100644 arch/arm/boot/dts/stm32f769-disco.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0118084..a119f74 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -763,6 +763,8 @@ dtb-$(CONFIG_ARCH_STI) += \
 dtb-$(CONFIG_ARCH_STM32)+= \
 	stm32f429-disco.dtb \
 	stm32f469-disco.dtb \
+	stm32f746-disco.dtb \
+	stm32f769-disco.dtb \
 	stm32429i-eval.dtb \
 	stm32746g-eval.dtb
 dtb-$(CONFIG_MACH_SUN4I) += \
diff --git a/arch/arm/boot/dts/stm32f746-disco.dts b/arch/arm/boot/dts/stm32f746-disco.dts
new file mode 100644
index 0000000..c0e313f
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f746-disco.dts
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017 - Vikas MANOCHA <vikas.manocha-qxv4g6HH51o@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32f746.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "STMicroelectronics STM32F746-DISCO board";
+	compatible = "st,stm32f746-disco", "st,stm32f746";
+
+	chosen {
+		bootargs = "root=/dev/ram";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		reg = <0xC0000000 0x800000>;
+	};
+
+	aliases {
+		serial0 = &usart1;
+	};
+
+};
+
+&clk_hse {
+	clock-frequency = <25000000>;
+};
+
+&pinctrl {
+	usart1_pins: usart1@0	{
+		pins1 {
+			pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+				bias-disable;
+				drive-push-pull;
+				slew-rate = <2>;
+		};
+		pins2 {
+			pinmux = <STM32F746_PB7_FUNC_USART1_RX>;
+			bias-disable;
+		};
+	};
+
+	qspi_pins: qspi@0 {
+		pins {
+			pinmux = <STM32F746_PB2_FUNC_QUADSPI_CLK>,
+			       <STM32F746_PB6_FUNC_QUADSPI_BK1_NCS>,
+			       <STM32F746_PD11_FUNC_QUADSPI_BK1_IO0>,
+			       <STM32F746_PD12_FUNC_QUADSPI_BK1_IO1>,
+			       <STM32F746_PD13_FUNC_QUADSPI_BK1_IO3>,
+			       <STM32F746_PE2_FUNC_QUADSPI_BK1_IO2>;
+			slew-rate = <2>;
+		};
+	};
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
index f321ffe..826700f 100644
--- a/arch/arm/boot/dts/stm32f746.dtsi
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -178,7 +178,7 @@
 			interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
 		};
 
-		pin-controller {
+		pinctrl: pin-controller {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stm32f746-pinctrl";
diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts
new file mode 100644
index 0000000..5f8558e
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f769-disco.dts
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017 - Vikas MANOCHA <vikas.manocha-qxv4g6HH51o@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32f746.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "STMicroelectronics STM32F769-DISCO board";
+	compatible = "st,stm32f769-disco", "st,stm32f7";
+
+	chosen {
+		bootargs = "root=/dev/ram";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		reg = <0xC0000000 0x1000000>;
+	};
+
+	aliases {
+		serial0 = &usart1;
+	};
+
+};
+
+&clk_hse {
+	clock-frequency = <25000000>;
+};
+
+&pinctrl {
+	usart1_pins: usart1@0	{
+		pins1 {
+			pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+				bias-disable;
+				drive-push-pull;
+				slew-rate = <2>;
+		};
+		pins2 {
+			pinmux = <STM32F746_PA10_FUNC_USART1_RX>;
+			bias-disable;
+		};
+	};
+
+	qspi_pins: qspi@0 {
+		pins {
+			pinmux = <STM32F746_PB2_FUNC_QUADSPI_CLK>,
+			       <STM32F746_PB6_FUNC_QUADSPI_BK1_NCS>,
+			       <STM32F746_PC9_FUNC_QUADSPI_BK1_IO0>,
+			       <STM32F746_PC10_FUNC_QUADSPI_BK1_IO1>,
+			       <STM32F746_PD13_FUNC_QUADSPI_BK1_IO3>,
+			       <STM32F746_PE2_FUNC_QUADSPI_BK1_IO2>;
+			slew-rate = <2>;
+		};
+	};
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v4 00/10] Add Basic SoC support for MT6797
From: Mars Cheng @ 2017-04-08  1:20 UTC (permalink / raw)
  To: Stephen Boyd, Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Loda Chou,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih, Miles Chen,
	Kevin-CW Chen, linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Yingjoe Chen, linux-clk-u79uwXL29TY76Z2rM5mHXA

This patch set adds basic SoC support for mediatek's first 10-core
chip, X20, also known as MT6797.

- based on 4.11-rc1
- support common clk framework
- apply patches about intpol just accepted to get full feature support:
http://lists.infradead.org/pipermail/linux-mediatek/2017-March/008371.html
http://lists.infradead.org/pipermail/linux-mediatek/2017-March/008375.html
http://lists.infradead.org/pipermail/linux-mediatek/2017-March/008373.html

Changes since v3:
- since intpol patches accepted in v3, remove them
- clk ID header separated from original clk driver submit
- clean up clk driver, including unnecessary header and fields in structure

Changes since v2:
- prevent uncessary #intpol-bases for mtk-sysirq
- add fast path for mtk-sysirq set_type when introducing multiple bases
- add acked-by and tested-by
- remove wrong usage for timer node

Changes since v1:
- add multiple base addresses support, v1 only allow 2 bases
- clean up clk driver

Kevin-CW Chen (2):
  dt-bindings: arm: mediatek: document clk bindings for MT6797
  clk: mediatek: add clk support for MT6797

Mars Cheng (8):
  dt-bindings: mediatek: Add bindings for mediatek MT6797 Platform
  arm64: dts: mediatek: add mt6797 support
  clk: mediatek: add mt6797 clock IDs
  soc: mediatek: avoid using fixed spm power status defines
  soc: mediatek: add vdec item for scpsys
  dt-bindings: mediatek: add MT6797 power dt-bindings
  soc: mediatek: add MT6797 scpsys support
  arm64: dts: mediatek: add clk and scp nodes for MT6797

 Documentation/devicetree/bindings/arm/mediatek.txt |    4 +
 .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |    1 +
 .../bindings/arm/mediatek/mediatek,imgsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,infracfg.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |    1 +
 .../bindings/arm/mediatek/mediatek,topckgen.txt    |    1 +
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |    1 +
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |    3 +-
 .../interrupt-controller/mediatek,sysirq.txt       |    1 +
 .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    6 +-
 arch/arm64/boot/dts/mediatek/Makefile              |    1 +
 arch/arm64/boot/dts/mediatek/mt6797-evb.dts        |   36 +
 arch/arm64/boot/dts/mediatek/mt6797.dtsi           |  245 +++++++
 drivers/clk/mediatek/Kconfig                       |   32 +
 drivers/clk/mediatek/Makefile                      |    5 +
 drivers/clk/mediatek/clk-mt6797-img.c              |   76 +++
 drivers/clk/mediatek/clk-mt6797-mm.c               |  136 ++++
 drivers/clk/mediatek/clk-mt6797-vdec.c             |   93 +++
 drivers/clk/mediatek/clk-mt6797-venc.c             |   78 +++
 drivers/clk/mediatek/clk-mt6797.c                  |  714 ++++++++++++++++++++
 drivers/soc/mediatek/mtk-scpsys.c                  |  149 +++-
 include/dt-bindings/clock/mt6797-clk.h             |  281 ++++++++
 include/dt-bindings/power/mt6797-power.h           |   30 +
 24 files changed, 1889 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6797.dtsi
 create mode 100644 drivers/clk/mediatek/clk-mt6797-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt6797.c
 create mode 100644 include/dt-bindings/clock/mt6797-clk.h
 create mode 100644 include/dt-bindings/power/mt6797-power.h

--
1.7.9.5

^ permalink raw reply

* [PATCH v4 01/10] dt-bindings: mediatek: Add bindings for mediatek MT6797 Platform
From: Mars Cheng @ 2017-04-08  1:20 UTC (permalink / raw)
  To: Stephen Boyd, Matthias Brugger
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, CC Hwang,
	wsd_upstream-NuS5LvNUpcJWk0Htik3J/w, Mars Cheng, Loda Chou,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jades Shih, Miles Chen,
	Kevin-CW Chen, linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Yingjoe Chen, linux-clk-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1491614435-23754-1-git-send-email-mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

This adds dt-binding documentation for Mediatek MT6797. Only
include very basic items, gic, uart timer and cpu.

Signed-off-by: Mars Cheng <mars.cheng-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/mediatek.txt |    4 ++++
 .../interrupt-controller/mediatek,sysirq.txt       |    1 +
 .../devicetree/bindings/serial/mtk-uart.txt        |    1 +
 3 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
index c860b24..2d3344d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek.txt
@@ -12,6 +12,7 @@ compatible: Must contain one of
    "mediatek,mt6592"
    "mediatek,mt6755"
    "mediatek,mt6795"
+   "mediatek,mt6797"
    "mediatek,mt7623"
    "mediatek,mt8127"
    "mediatek,mt8135"
@@ -38,6 +39,9 @@ Supported boards:
 - Evaluation board for MT6795(Helio X10):
     Required root node properties:
       - compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
+- Evaluation board for MT6797(Helio X20):
+    Required root node properties:
+      - compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
 - Evaluation board for MT7623:
     Required root node properties:
       - compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
index 40bf9b9..04e162a 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
@@ -9,6 +9,7 @@ Required properties:
 	"mediatek,mt8135-sysirq"
 	"mediatek,mt8127-sysirq"
 	"mediatek,mt6795-sysirq"
+	"mediatek,mt6797-sysirq"
 	"mediatek,mt6755-sysirq"
 	"mediatek,mt6592-sysirq"
 	"mediatek,mt6589-sysirq"
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index 0015c72..5b8513d 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -8,6 +8,7 @@ Required properties:
   * "mediatek,mt6589-uart" for MT6589 compatible UARTS
   * "mediatek,mt6755-uart" for MT6755 compatible UARTS
   * "mediatek,mt6795-uart" for MT6795 compatible UARTS
+  * "mediatek,mt6797-uart" for MT6797 compatible UARTS
   * "mediatek,mt7623-uart" for MT7623 compatible UARTS
   * "mediatek,mt8127-uart" for MT8127 compatible UARTS
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox