Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver
From: Linus Walleij @ 2017-03-29  2:07 UTC (permalink / raw)
  To: Nandor Han
  Cc: Alexandre Courbot, Rob Herring, Mark Rutland,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Semi Malinen
In-Reply-To: <6bf04ba1761f0692cb461558f0c8836f0d1f7ad8.1490595641.git.nandor.han-JJi787mZWgc@public.gmane.org>

On Mon, Mar 27, 2017 at 8:23 AM, Nandor Han <nandor.han-JJi787mZWgc@public.gmane.org> wrote:

> This is a simple driver that provides a /sys/class/gpio
> interface for controlling and configuring the GPIO lines.

Use the gpio tools in tools/gpio, use the characcter device.
Do not use sysfs. Change this to reference the tools.

> It does not provide support for chip select or interrupts.
>
> Signed-off-by: Nandor Han <nandor.han-JJi787mZWgc@public.gmane.org>
> Signed-off-by: Semi Malinen <semi.malinen-JJi787mZWgc@public.gmane.org>
(...)
> +exar   Exar Corporation

Send this as a separate patch to the DT bindings maintainer
(Rob Herring.)

> +static int xra1403_get_byte(struct xra1403 *xra, unsigned int addr)
> +{
> +       return spi_w8r8(xra->spi, XRA_READ | (addr << 1));
> +}
> +
> +static int xra1403_get_bit(struct xra1403 *xra, unsigned int addr,
> +                          unsigned int bit)
> +{
> +       int ret;
> +
> +       ret = xra1403_get_byte(xra, addr + (bit > 7));
> +       if (ret < 0)
> +               return ret;
> +
> +       return !!(ret & BIT(bit % 8));
> +}

This looks like it can use regmap-spi right off, do you agree?

git grep devm_regmap_init_spi
should give you some examples of how to use it.

If it's not off-the shelf regmap drivers like
drivers/iio/pressure/mpl115_spi.c
give examples of how to make more elaborate custom
SPI transfers with regmap.

> +static int xra1403_set_bit(struct xra1403 *xra, unsigned int addr,
> +                          unsigned int bit, int value)
> +{
> +       int ret;
> +       u8 mask;
> +       u8 tx[2];
> +
> +       addr += bit > 7;
> +
> +       mutex_lock(&xra->lock);
> +
> +       ret = xra1403_get_byte(xra, addr);
> +       if (ret < 0)
> +               goto out_unlock;
> +
> +       mask = BIT(bit % 8);
> +       if (value)
> +               value = ret | mask;
> +       else
> +               value = ret & ~mask;
> +
> +       if (value != ret) {
> +               tx[0] = addr << 1;
> +               tx[1] = value;
> +               ret = spi_write(xra->spi, tx, sizeof(tx));
> +       } else {
> +               ret = 0;
> +       }
> +
> +out_unlock:
> +       mutex_unlock(&xra->lock);
> +
> +       return ret;
> +}

Classical mask-and-set implementation right?
With regmap this becomes simply regmap_update_bits(map, addr, mask, set)

> +static int xra1403_probe(struct spi_device *spi)
> +{
> +       struct xra1403 *xra;
> +       struct gpio_desc *reset_gpio;
> +
> +       xra = devm_kzalloc(&spi->dev, sizeof(*xra), GFP_KERNEL);
> +       if (!xra)
> +               return -ENOMEM;
> +
> +       /* bring the chip out of reset */
> +       reset_gpio = gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
> +       if (IS_ERR(reset_gpio))
> +               dev_warn(&spi->dev, "could not get reset-gpios\n");
> +       else if (reset_gpio)
> +               gpiod_put(reset_gpio);

I don't think you should put it, other than in the remove()
function and in that case you need to have it in the
state container.

> +       mutex_init(&xra->lock);
> +
> +       xra->chip.direction_input = xra1403_direction_input;
> +       xra->chip.direction_output = xra1403_direction_output;

Please implement .get_direction(). This is very nice to have.

> +static int xra1403_remove(struct spi_device *spi)
> +{
> +       struct xra1403 *xra = spi_get_drvdata(spi);
> +
> +       gpiochip_remove(&xra->chip);

Use devm_gpiochip_add_data() and this remove is not
needed at all.

> +static int __init xra1403_init(void)
> +{
> +       return spi_register_driver(&xra1403_driver);
> +}
> +
> +/*
> + * register after spi postcore initcall and before
> + * subsys initcalls that may rely on these GPIOs
> + */
> +subsys_initcall(xra1403_init);
> +
> +static void __exit xra1403_exit(void)
> +{
> +       spi_unregister_driver(&xra1403_driver);
> +}
> +module_exit(xra1403_exit);

This seems like tricksy. Just module_spi_driver()
should be fine don't you think?

Yours,
Linus Walleij
--
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: [PATCHv2] phy: cpcap-usb: Add CPCAP PMIC USB support
From: Rob Herring @ 2017-03-29  2:04 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kishon Vijay Abraham I, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Marcel Partap, Michael Scott
In-Reply-To: <20170322234602.5888-1-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>

On Wed, Mar 22, 2017 at 04:46:02PM -0700, Tony Lindgren wrote:
> Some Motorola phones like droid 4 use a custom CPCAP PMIC that has a
> multiplexing USB PHY.
> 
> This USB PHY can operate at least in four modes using pin multiplexing
> and two control GPIOS:
> 
> - Pass through companion PHY for the SoC USB PHY
> - ULPI PHY for the SoC
> - Pass through USB for the modem
> - UART debug console for the SoC
> 
> This patch adds support for droid 4 USB PHY and debug UART modes,
> support for other modes can be added later on as needed.
> 
> Both peripheral and host mode are working for the USB. The
> host mode depends on the cpcap-charger driver for VBUS.
> 
> VBUS and ID pin detection are done using cpcap-adc IIO ADC
> driver.
> 
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Marcel Partap <mpartap-hi6Y0CQ0nG0@public.gmane.org>
> Cc: Michael Scott <michael.scott-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Tested-by: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> ---
> 
> Changes since v1:
> 
> - Use iio_read_channel_processed() instead of iio_read_channel_scaled()
>   as changed in the v2 of the ADC driver 
> 
> - Keep Tested-by from Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> as the change
>   from v1 is trivial
> 
> ---
>  .../devicetree/bindings/phy/phy-cpcap-usb.txt      |  40 ++

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

>  drivers/phy/Kconfig                                |   8 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-cpcap-usb.c                        | 695 +++++++++++++++++++++
>  4 files changed, 744 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/phy-cpcap-usb.txt
>  create mode 100644 drivers/phy/phy-cpcap-usb.c
--
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] input: matrix_keypad: add option to drive inactive columns
From: Rob Herring @ 2017-03-29  2:02 UTC (permalink / raw)
  To: David Rivshin
  Cc: Dmitry Torokhov, Mark Rutland, linux-input-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170322201650.9072-1-drivshin-WHIoityCHfoAvxtiuMwx3w@public.gmane.org>

On Wed, Mar 22, 2017 at 04:16:50PM -0400, David Rivshin wrote:
> From: David Rivshin <DRivshin-5fOYsn7Fw8lBDgjK7y7TUQ@public.gmane.org>
> 
> The gpio-matrix-keypad driver normally sets inactive columns as inputs
> while scanning. This does not work for all hardware, which may require
> the inactive columns to be actively driven in order to overcome any
> pull-ups/downs on the columns.
> 
> Signed-off-by: David Rivshin <drivshin-5fOYsn7Fw8lBDgjK7y7TUQ@public.gmane.org>
> ---
>  .../devicetree/bindings/input/gpio-matrix-keypad.txt        |  2 ++
>  drivers/input/keyboard/matrix_keypad.c                      | 13 +++++++++----
>  include/linux/input/matrix_keypad.h                         |  3 +++
>  3 files changed, 14 insertions(+), 4 deletions(-)

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: [RESEND PATCH v2 13/53] mtd: nand: denali_dt: enable HW_ECC_FIXUP for Altera SOCFPGA variant
From: Rob Herring @ 2017-03-29  2:00 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: laurent.monat, Boris Brezillon, thorsten.christiansson,
	Richard Weinberger, Marek Vasut, Artem Bityutskiy,
	Cyrille Pitchen, Mark Rutland, linux-kernel, Dinh Nguyen,
	devicetree, linux-mtd, Masami Hiramatsu, Chuanxiao Dong,
	Jassi Brar, Brian Norris, Enrico Jorns, David Woodhouse,
	Graham Moore
In-Reply-To: <1490213273-8571-14-git-send-email-yamada.masahiro@socionext.com>

On Thu, Mar 23, 2017 at 05:07:12AM +0900, Masahiro Yamada wrote:
> There are various customizable parameters, so several variants for
> this IP.  A generic compatible like "denali,denali-nand-dt" is
> useless.  Moreover, there are multiple things wrong with this string.
> (Refer to Rob's comment [1])
> 
> The denali_dt.c was split out and this compatible was added by Altera
> for the SOCFPGA port.  So, replace it with a more specific string.
> 
> The Denali IP on SOCFPGA incorporates the hardware ECC fixup feature.
> So, this capability should be associated with the compatible string.
> 
> [1] https://lkml.org/lkml/2016/12/1/450
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
> 
> Changes in v2:
>   - Add caps flag to of_device_id data, not hard-code in driver code
>   - Add Altera-specific compatible.
> 
>  Documentation/devicetree/bindings/mtd/denali-nand.txt |  5 +++--
>  drivers/mtd/nand/denali_dt.c                          | 14 ++++++++++----
>  2 files changed, 13 insertions(+), 6 deletions(-)

You should also mention there are no users (in-tree) of the old string.

Acked-by: Rob Herring <robh@kernel.org>

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply

* Re: [PATCH v8 2/3] dt-bindings: input: touchscreen: Add max11801-ts binding
From: Rob Herring @ 2017-03-29  1:57 UTC (permalink / raw)
  To: Jagan Teki
  Cc: linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jagan Teki, Dmitry Torokhov,
	Mark Rutland, Shawn Guo, Michael Trimarchi
In-Reply-To: <1490209518-20790-2-git-send-email-jagan-oRp2ZoJdM/RWk0Htik3J/w@public.gmane.org>

On Thu, Mar 23, 2017 at 12:35:17AM +0530, Jagan Teki wrote:
> From: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> 
> Add missing documentation of max11801-ts dt-binding details.
> 
> Cc: Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Shawn Guo <shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Michael Trimarchi <michael-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> ---
> Changes for v8:
> - Use IRQ_TYPE_EDGE_FALLING for interrupt trigger type. 
> Changes for v7:
> - add vendor prefix as maxim
> Changes for v6:
> - Replace the lable and name of the node
>    ts: max11801 => max11801: touchscreen@48
> Changes for v5:
> - Newly added patch
> 
>  .../bindings/input/touchscreen/max11801-ts.txt         | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/max11801-ts.txt

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 v5 6/9] coresight: add support for CPU debug module
From: Leo Yan @ 2017-03-29  1:54 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
	Catalin Marinas, Will Deacon, Andy Gross, David Brown,
	Michael Turquette, Stephen Boyd, Guodong Xu, John Stultz,
	linux-doc, linux-kernel, devicetree, linux-arm-kernel,
	linux-arm-msm, linux-soc, linux-clk, mike.leach, Suzuki.Poulose,
	sudeep.holla
In-Reply-To: <20170328165010.GA21937@linaro.org>

Hi Mathieu,

On Tue, Mar 28, 2017 at 10:50:10AM -0600, Mathieu Poirier wrote:
> On Sun, Mar 26, 2017 at 02:23:14AM +0800, Leo Yan wrote:

[...]

> > +static void debug_force_cpu_powered_up(struct debug_drvdata *drvdata)
> > +{
> > +	int timeout = DEBUG_WAIT_TIMEOUT;
> > +
> > +	drvdata->edprsr = readl_relaxed(drvdata->base + EDPRSR);
> > +
> > +	CS_UNLOCK(drvdata->base);
> > +
> > +	/* Bail out if CPU is powered up yet */
> > +	if (drvdata->edprsr & EDPRSR_PU)
> > +		goto out_powered_up;
> > +
> > +	/*
> > +	 * Send request to power management controller and assert
> > +	 * DBGPWRUPREQ signal; if power management controller has
> > +	 * sane implementation, it should enable CPU power domain
> > +	 * in case CPU is in low power state.
> > +	 */
> > +	drvdata->edprsr = readl(drvdata->base + EDPRCR);
> > +	drvdata->edprsr |= EDPRCR_COREPURQ;
> > +	writel(drvdata->edprsr, drvdata->base + EDPRCR);
> 
> Here ->edprsr is used but EDPRCR is accessed.  Is this intentional or a
> copy/paste error?  The same is true for accesses in the out_powered_up section.

Thanks for pointing out. This is a typo error and will fix.

> > +
> > +	/* Wait for CPU to be powered up (timeout~=32ms) */
> > +	while (timeout--) {
> > +		drvdata->edprsr = readl_relaxed(drvdata->base + EDPRSR);
> > +		if (drvdata->edprsr & EDPRSR_PU)
> > +			break;
> > +
> > +		usleep_range(1000, 2000);
> > +	}
> 
> See if function readx_poll_timeout() can be used.

Will use it.

> > +
> > +	/*
> > +	 * Unfortunately the CPU cannot be powered up, so return
> > +	 * back and later has no permission to access other
> > +	 * registers. For this case, should set 'idle_constraint'
> > +	 * to ensure CPU power domain is enabled!
> > +	 */
> > +	if (!(drvdata->edprsr & EDPRSR_PU)) {
> > +		pr_err("%s: power up request for CPU%d failed\n",
> > +			__func__, drvdata->cpu);
> > +		goto out;
> > +	}
> > +
> > +out_powered_up:
> > +	debug_os_unlock(drvdata);
> > +
> > +	/*
> > +	 * At this point the CPU is powered up, so set the no powerdown
> > +	 * request bit so we don't lose power and emulate power down.
> > +	 */
> > +	drvdata->edprsr = readl(drvdata->base + EDPRCR);
> > +	drvdata->edprsr |= EDPRCR_COREPURQ | EDPRCR_CORENPDRQ;
> 
> If we are here the core is already up.  Shouldn't we need to set
> EDPRCR_CORENPDRQ only?

Yeah. Will fix.

> > +	writel(drvdata->edprsr, drvdata->base + EDPRCR);
> 
> This section is a little racy - between the time the PU bit has been
> checked and the time COREPDRQ has been flipped, the state of PU may have
> changed.  You can probably get around this by checking edprsr.PU rigth here.  If
> it is not set you go through the process again.  Note that doing this will
> probably force a refactoring of the whole function.  

Agree. Will handle this.

[...]

> > +static ssize_t debug_func_knob_write(struct file *f,
> > +		const char __user *buf, size_t count, loff_t *ppos)
> > +{
> > e	u8 on;
> > +	int ret;
> > +
> > +	ret = kstrtou8_from_user(buf, count, 2, &on);
> > +	if (ret)
> > +		return ret;
> > +
> > +	mutex_lock(&debug_lock);
> > +
> > +	if (!on ^ debug_enable)
> > +		goto out;
> 
> I had to read this condition too many times - please refactor.

Will do it.

> > +
> > +	if (on) {
> > +		ret = debug_enable_func();
> > +		if (ret) {
> > +			pr_err("%s: unable to disable debug function: %d\n",
> > +			       __func__, ret);
> 
> Based on the semantic this is the wrong error message.

Yeah. Will fix.

> > +			goto err;
> > +		}
> > +	} else
> > +		debug_disable_func();
> 
> Did checkpatch.pl complain about extra curly braces?  If not please add them.

checkpatch.pl doesn't report for this. Will add.

> > +
> > +	debug_enable = on;
> 
> Here we can't set debug_enable if we just called debug_disable_func().  Maybe
> I'm missing something.  If that's the case a comment in the code would be worth
> it.

After called debug_disable_func(), debug_enable is set to 0 (on = 0).

> > +
> > +out:
> > +	ret = count;
> > +err:
> > +	mutex_unlock(&debug_lock);
> > +	return ret;
> > +}
> > +
> > +static ssize_t debug_func_knob_read(struct file *f,
> > +		char __user *ubuf, size_t count, loff_t *ppos)
> > +{
> > +	char val[] = { '0' + debug_enable, '\n' };
> > +
> > +	return simple_read_from_buffer(ubuf, count, ppos, val, sizeof(val));
> 
> Use the debug_lock to avoid race conditions.

Will do it.

> > +}
> > +
> > +static ssize_t debug_idle_constraint_write(struct file *f,
> > +		const char __user *buf, size_t count, loff_t *ppos)
> > +{
> > +	int val;
> > +	ssize_t ret;
> > +
> > +	ret = kstrtoint_from_user(buf, count, 10, &val);
> > +	if (ret)
> > +		return ret;
> > +
> > +	mutex_lock(&debug_lock);
> > +	idle_constraint = val;
> > +
> > +	if (debug_enable)
> > +		pm_qos_update_request(&debug_qos_req, idle_constraint);
> > +
> > +	mutex_unlock(&debug_lock);
> > +	return count;
> > +}
> > +
> > +static ssize_t debug_idle_constraint_read(struct file *f,
> > +		char __user *ubuf, size_t count, loff_t *ppos)
> > +{
> > +	char buf[32];
> > +	int len;
> > +
> > +	if (*ppos)
> > +		return 0;
> > +
> > +	len = sprintf(buf, "%d\n", idle_constraint);
> > +	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
> 
> Use the debug_lock to avoid race conditions.

Will do it.

> > +}
> > +
> > +static const struct file_operations debug_func_knob_fops = {
> > +	.open	= simple_open,
> > +	.read	= debug_func_knob_read,
> > +	.write	= debug_func_knob_write,
> > +};
> > +
> > +static const struct file_operations debug_idle_constraint_fops = {
> > +	.open	= simple_open,
> > +	.read	= debug_idle_constraint_read,
> > +	.write	= debug_idle_constraint_write,
> > +};
> > +
> > +static int debug_func_init(void)
> > +{
> > +	struct dentry *file;
> > +	int ret;
> > +
> > +	/* Create debugfs node */
> > +	debug_debugfs_dir = debugfs_create_dir("coresight_cpu_debug", NULL);
> > +	if (!debug_debugfs_dir) {
> > +		pr_err("%s: unable to create debugfs directory\n", __func__);
> > +		return -ENOMEM;
> 
> return PTR_ERR(debug_debugfs_dir);

Here cannot use PTR_ERR(debug_debugfs_dir). If create debugfs failed
the pointer is NULL value, so finally we will return zero value for
PTR_ERR(debug_debugfs_dir).

[...]

> > +	}
> > +
> > +	file = debugfs_create_file("enable", S_IRUGO | S_IWUSR,
> > +			debug_debugfs_dir, NULL, &debug_func_knob_fops);
> > +	if (!file) {
> > +		pr_err("%s: unable to create enable knob file\n", __func__);
> > +		ret = -ENOMEM;
> 
> Same as above.
> 
> > +		goto err;
> > +	}
> > +
> > +	file = debugfs_create_file("idle_constraint", S_IRUGO | S_IWUSR,
> > +			debug_debugfs_dir, NULL, &debug_idle_constraint_fops);
> > +	if (!file) {
> > +		pr_err("%s: unable to create idle constraint file\n", __func__);
> > +		ret = -ENOMEM;
> 
> Same as above.
> 
> > +		goto err;
> > +	}
> > +
> > +	/* Use sysfs node to enable functionality */
> > +	if (!debug_enable)
> > +		return 0;
> > +
> > +	/* Enable debug module at boot time */
> > +	ret = debug_enable_func();
> > +	if (ret) {
> > +		pr_err("%s: unable to disable debug function: %d\n",
> > +		       __func__, ret);
> > +		goto err;
> > +	}
> 
> Use the debug_lock to avoid race conditions.

I'm struggling to understand what's race condition at here? The
function pairs debug_func_init()/debug_func_exit() are used for
module's probing and removing, so naturally module's probing and
removing are sequential, right?

> > +
> > +	return 0;
> > +
> > +err:
> > +	debugfs_remove_recursive(debug_debugfs_dir);
> > +	return ret;
> > +}
> > +
> > +static void debug_func_exit(void)
> > +{
> > +	debugfs_remove_recursive(debug_debugfs_dir);
> > +
> > +	/* Disable functionality if has enabled */
> > +	if (debug_enable)
> > +		debug_disable_func();
> > +}
> > +
> > +static int debug_probe(struct amba_device *adev, const struct amba_id *id)
> > +{
> > +	void __iomem *base;
> > +	struct device *dev = &adev->dev;
> > +	struct debug_drvdata *drvdata;
> > +	struct resource *res = &adev->res;
> > +	struct device_node *np = adev->dev.of_node;
> > +	int ret;
> > +
> > +	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > +	if (!drvdata)
> > +		return -ENOMEM;
> > +
> > +	drvdata->cpu = np ? of_coresight_get_cpu(np) : 0;
> > +	if (per_cpu(debug_drvdata, drvdata->cpu)) {
> > +		dev_err(dev, "CPU's drvdata has been initialized\n");
> 
> Might be worth adding the CPU number in the error message.

Yeah, will add it.

[...]

> This driver doesn't call the pm_runtime_put/get() operations needed to handle the
> debug power domain.  See the other CoreSight drivers for details. 

Sure, will do it.

> Also, from the conversation that followed the previous post we agreed that we wouldn't
> deal with CPUidle issues in this driver.  We deal with the CPU power domain
> using the EDPRCR register (like you did) and that's it.  System that don't honor that register
> can use other (external) means to solve this.  As such please remove the
> pm_qos_xyz() functions. 

>From previous discussion, Mike reminds the CPU power domain design is
quite SoC specific and usually the SoC has many different low power
states, e.g. except CPU level and cluster level low power states, they
also can define SoC level low power states. Any SoC with any power
state is possible finally impact CPU power domain, so this is why I add
this interface to let user can have the final decision based on their
working platform.

We can rely on "nohlt" and "cpuidle.off=1" in kernel command line to
disable whole SoC low power states at boot time; or we can use sysfs
node "echo 1 > /sys/devices/system/cpu/cpuX/cpuidle/stateX/disble" to
disable CPU low power states at runtime. But that means we need use
different interfaces to control CPU power domain for booting and
runtime, it's not nice for usage.

So this is why add "idle_constraint" as a central place to control
power domain for CPU debug purpose and I also think this is more
friendly for hardware design, e.g. some platforms can enable partial
low power states to save power and avoid overheat after using this
driver.

How about you think for this?

Thanks,
Leo Yan

^ permalink raw reply

* Re: [PATCH v7 1/7] clocksource/drivers/clksrc-evt-probe: Describe with the DT both the clocksource and the clockevent
From: Rob Herring @ 2017-03-29  1:51 UTC (permalink / raw)
  To: Alexander Kochetkov
  Cc: Mark Rutland, devicetree, Huang Tao, Heiko Stuebner,
	Daniel Lezcano, linux-kernel, Russell King, linux-rockchip,
	Thomas Gleixner, linux-arm-kernel, Caesar Wang
In-Reply-To: <1490197714-25415-2-git-send-email-al.kochet@gmail.com>

On Wed, Mar 22, 2017 at 06:48:28PM +0300, Alexander Kochetkov wrote:
> From: Daniel Lezcano <daniel.lezcano@linaro.org>
> 
> The CLOCKSOURCE_OF_DECLARE() was introduced before the
> CLOCKEVENT_OF_DECLARE() and that resulted in some abuse where the
> clockevent and the clocksource are both initialized in the same init
> routine.
> 
> With the introduction of the CLOCKEVENT_OF_DECLARE(), the driver can
> now split the clocksource and the clockevent init code. However, the
> device tree may specify a single node, so the same node will be passed
> to the clockevent/clocksource's init function, with the same base
> address.
> 
> with this patch it is possible to specify an attribute to the timer's node to
> specify if it is a clocksource or a clockevent and define two timers node.

Daniel and I discussed and agreed against this a while back. What 
changed?

> 
> For example:
> 
>         timer: timer@98400000 {
>                 compatible = "moxa,moxart-timer";
>                 reg = <0x98400000 0x42>;

This overlaps the next node. You can change this to 0x10, but are these 
really 2 independent h/w blocks? Don't design the nodes around the 
current needs of Linux.

>                 interrupts = <19 1>;
>                 clocks = <&coreclk>;
>                 clockevent;

This is not needed. The presence of "interrupts" is enough to say use 
this timer for clockevent.

>         };
> 
>         timer: timer@98400010 {
>                 compatible = "moxa,moxart-timer";
>                 reg = <0x98400010 0x42>;
>                 clocks = <&coreclk>;
>                 clocksource;

Likewise.

>         };
> 
> With this approach, we allow a mechanism to clearly define a clocksource or a
> clockevent without aerobatics we can find around in some drivers:
> 	timer-sp804.c, arc-timer.c, dw_apb_timer_of.c, mps2-timer.c,
> 	renesas-ostm.c, time-efm32.c, time-lpc32xx.c.

These all already have bindings and work. What problem are you trying to 
solve other than restructuring Linux?

> 
> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
> ---
>  Documentation/devicetree/bindings/timer/timer.txt |   38 +++++++++++++++++++++
>  drivers/clocksource/clkevt-probe.c                |    7 ++++
>  drivers/clocksource/clksrc-probe.c                |    7 ++++
>  3 files changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/timer/timer.txt
> 
> diff --git a/Documentation/devicetree/bindings/timer/timer.txt b/Documentation/devicetree/bindings/timer/timer.txt
> new file mode 100644
> index 0000000..f1ee0cf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/timer.txt
> @@ -0,0 +1,38 @@
> +
> +Specifying timer information for devices
> +========================================
> +
> +The timer can be declared via the macro:
> +
> +CLOCKSOURCE_OF_DECLARE(name, init) if it is a clocksource
> +CLOCKEVENT_OF_DECLARE(name, init) if it is a clockevent
> +
> +The CLOCKSOURCE_OF_DECLARE() was introduced before the
> +CLOCKEVENT_OF_DECLARE() and that resulted in some abuse where the
> +clockevent and the clocksource are both initialized in the same init
> +routine.
> +
> +With the introduction of the CLOCKEVENT_OF_DECLARE(), the driver can
> +now split the clocksource and the clockevent init code. However, the
> +device tree may specify a single node, so the same node will be passed
> +to the clockevent/clocksource's init function, with the same base
> +address. It is possible to specify an attribute to the timer's node to
> +specify if it is a clocksource or a clockevent and define two timers
> +node.

This is all Linux details and doesn't belong in binding docs.

> +
> +Example:
> +
> +	timer: timer@98400000 {
> +		compatible = "moxa,moxart-timer";
> +		reg = <0x98400000 0x42>;
> +		interrupts = <19 1>;
> +		clocks = <&coreclk>;
> +		clockevent;
> +	};
> +
> +	timer: timer@98400010 {
> +		compatible = "moxa,moxart-timer";
> +		reg = <0x98400010 0x42>;
> +		clocks = <&coreclk>;
> +		clocksource;
> +	};
> diff --git a/drivers/clocksource/clkevt-probe.c b/drivers/clocksource/clkevt-probe.c
> index eb89b50..fa02ac1 100644
> --- a/drivers/clocksource/clkevt-probe.c
> +++ b/drivers/clocksource/clkevt-probe.c
> @@ -37,6 +37,13 @@ int __init clockevent_probe(void)
>  
>  		init_func = match->data;
>  
> +		/*
> +		 * The device node describes a clocksource, ignore it
> +		 * as we are in the clockevent init routine.
> +		 */
> +		if (of_property_read_bool(np, "clocksource"))
> +			continue;
> +
>  		ret = init_func(np);
>  		if (ret) {
>  			pr_warn("Failed to initialize '%s' (%d)\n",
> diff --git a/drivers/clocksource/clksrc-probe.c b/drivers/clocksource/clksrc-probe.c
> index bc62be9..ce50f33 100644
> --- a/drivers/clocksource/clksrc-probe.c
> +++ b/drivers/clocksource/clksrc-probe.c
> @@ -38,6 +38,13 @@ void __init clocksource_probe(void)
>  
>  		init_func_ret = match->data;
>  
> +		/*
> +		 * The device node describes a clockevent, ignore it
> +		 * as we are in the clocksource init routine.
> +		 */
> +		if (of_property_read_bool(np, "clockevent"))
> +			continue;
> +
>  		ret = init_func_ret(np);
>  		if (ret) {
>  			pr_err("Failed to initialize '%s': %d",
> -- 
> 1.7.9.5
> 

^ permalink raw reply

* Re: [PATCH 0/3] XRA1403,gpio - add XRA1403 gpio expander driver
From: Linus Walleij @ 2017-03-29  1:50 UTC (permalink / raw)
  To: Nandor Han
  Cc: Alexandre Courbot, Rob Herring, Mark Rutland,
	linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <cover.1490595641.git.nandor.han@ge.com>

On Mon, Mar 27, 2017 at 8:22 AM, Nandor Han <nandor.han@ge.com> wrote:

> Testing:
>
> 1. XRA1403 connected to iMX53 MCU
> 2. Export gpio from userspace
> 3. Verify that corresponding gpio directories are created
>    in `/sys/class/gpio/gpioXX`
> 4. Export gpios from first and second bank as output
> 5. Set the output gpio pin to high/low and verify with the
>    oscilloscope that gpio status is according with the configured
>    value.

Do *NOT* use the sysfs for testing GPIO.
This is being phased out.

Use the tools in tools/gpio/* so that you exercise the
character device instead of the old deprecated ABI.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v1 2/7] devicetree: power: Add docs for TI BQ24190 battery charger
From: Liam Breck @ 2017-03-29  1:48 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Tony Lindgren, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	Hans de Goede, devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck
In-Reply-To: <20170329004743.6mwpk3lzt5l666gw@rob-hp-laptop>

Hi Rob,

On Tue, Mar 28, 2017 at 5:47 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Tue, Mar 21, 2017 at 03:09:16PM -0700, Liam Breck wrote:
>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>
>> Document monitored-battery and ti,system-minimum-microvolt properties.
>>
>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>> ---
>>  .../devicetree/bindings/power/supply/bq24190.txt   | 47 ++++++++++++++++++++++
>>  1 file changed, 47 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/power/supply/bq24190.txt
>>
>> diff --git a/Documentation/devicetree/bindings/power/supply/bq24190.txt b/Documentation/devicetree/bindings/power/supply/bq24190.txt
>> new file mode 100644
>> index 0000000..d252d10
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power/supply/bq24190.txt
>> @@ -0,0 +1,47 @@
>> +Binding for TI BQ24190 Li-Ion Battery Charger
>> +
>> +Required properties:
>> +- compatible: Should contain one of the following:
>> +    * "ti,bq24190"
>> +- reg: integer, I2C address of the device.
>> +
>> +Optional properties:
>> +- monitored-battery: phandle of battery information devicetree node
>> +    These battery properties are relevant:
>> +    + precharge-current-microamp: maximum charge current during precharge
>> +      phase (typically 20% of battery capacity).
>> +    + endcharge-current-microamp: a charge cycle terminates when the
>> +      battery voltage is above recharge threshold, and the current is below
>> +      this setting (typically 10% of battery capacity).
>> +    See Documentation/devicetree/bindings/power/supply/battery.txt
>
> This isn't really relevant to the binding. The battery properties
> shouldn't vary with the charger.

Different components need different properties from the battery node.
This charger needs the above two, so we should document that, no?

>> +- ti,system-minimum-microvolt: when power is connected and the battery
>> +    is below minimum system voltage, the system will be regulated above this
>> +    setting.
>> +
>> +Other features:
>> +- Use gpio-hog to set the OTG pin high to enable 500mA charge current on USB SDP port.
>> +
>> +Example:
>> +
>> +bat: battery {
>> +     compatible = "simple-battery";
>> +     precharge-current-microamp = <256000>;
>> +     endcharge-current-microamp = <128000>;
>> +};
>> +
>> +bq24190 charger@6a {
>> +     compatible = "ti,bq24190";
>> +     reg = <0x6a>;
>> +     // interrupt configuration here
>> +     monitored-battery = <&bat>;
>> +     ti,system-minimum-microvolt = <3200000>;
>> +};
>> +
>> +&twl_gpio {
>> +     otg {
>> +             gpio-hog;
>> +             gpios = <6 0>;
>> +             output-high;
>> +             line-name = "otg-gpio";
>> +     };
>> +};
>> --
>> 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

* Re: [PATCH v3 1/7] pinctrl: Renesas RZ/A1 pin and gpio controller
From: Linus Walleij @ 2017-03-29  1:43 UTC (permalink / raw)
  To: jacopo
  Cc: Jacopo Mondi, Geert Uytterhoeven, Laurent Pinchart, Chris Brandt,
	Rob Herring, Mark Rutland, Russell King, Linux-Renesas,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20170324164559.GA15925@w540>

On Fri, Mar 24, 2017 at 5:45 PM, jacopo <jacopo-AW8dsiIh9cEdnm+yROfE0A@public.gmane.org> wrote:

> I initially created a whole new sub-directory where all the Renesas
> devices with this kind of pin controller would have gone
> (drivers/pinctrl/rz-pfc) but since as of now the only available
> hardware of that type is RZ/A1 and some of its variants, we decided to go
> with a single driver supporting that platform only.
> If more will come, we'll think about supporting them through this
> driver if possible, or create a dedicated directory.
>
> Are you ok with this?

Yep it's OK. It's no big deal to move it into a new subdir if many
new drivers start popping in anyway.

Right now I see the use of renesas,pins as the only big blocker,
I would much like it to use just pins = <>;

Yours,
Linus Walleij
--
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 v1 1/7] devicetree: power: battery: Add properties for pre-charge and end-charge current
From: Liam Breck @ 2017-03-29  1:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Tony Lindgren, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	Hans de Goede, devicetree-u79uwXL29TY76Z2rM5mHXA, Quentin Schulz
In-Reply-To: <20170329003946.3eyqmsozj2sxrtiw@rob-hp-laptop>

Hi Rob,

On Tue, Mar 28, 2017 at 5:39 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Tue, Mar 21, 2017 at 03:09:15PM -0700, Liam Breck wrote:
>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>
>> precharge-current-microamp and endcharge-current-microamp are used
>> by battery chargers at the beginning and end of a charging cycle.
>>
>> Depends-on: https://patchwork.kernel.org/patch/9633605/
>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/power/supply/battery.txt | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>> index 53a68c0..494374a 100644
>> --- a/Documentation/devicetree/bindings/power/supply/battery.txt
>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>> @@ -12,6 +12,8 @@ Optional Properties:
>>   - voltage-min-design-microvolt: drained battery voltage
>>   - energy-full-design-microwatt-hours: battery design energy
>>   - charge-full-design-microamp-hours: battery design capacity
>> + - precharge-current-microamp: current for pre-charge phase
>> + - endcharge-current-microamp: current for charge termination phase
>
> current is implied by microamp, so perhaps just pre-charge-microamp and
> end-charge-microamp.

Ah, this is why I want to document the naming scheme for battery node
properties in battery.txt, by referring to a linux header file :-)

The names mirror enum power_supply_property elements wherever
possible. Shortening them as you suggest makes dts code a little more
terse, but obscures their relationship with power_supply sysfs
attributes. I prefer brevity myself, but there is no strong case to
reword the names for DT use.

> I know little about batteries, but don't you also need to know when each
> phase starts/ends?

Meaning at what voltage levels? We don't need it for this
battery/charger pair; no idea about others...

> I mainly ask because we just added the previous properties and now we're
> adding 2 more. While fine to add features to a driver one by one, we
> really shouldn't for bindings. The h/w is not evolving (in a month).

And a third patchset from Quentin Schulz adds another :-)

I think you may need to accept piecemeal assembly in this case... No
one has made a study of all properties that should be in the battery
node. (precharge_current wasn't even in power_supply_property until
this patchset.) Sebastian requested we create this binding in the
process of adding DT support to a fuel gauge, so we coded what that
called for.

I hope that helps...
--
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 v3 1/5] dt-bindings: Document STM32 IWDG bindings
From: Rob Herring @ 2017-03-29  1:40 UTC (permalink / raw)
  To: Yannick Fertre
  Cc: Wim Van Sebroeck, Guenter Roeck, Alexandre TORGUE,
	Benjamin Gaignard, Maxime Coquelin,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Philippe Cornu,
	Gabriel FERNANDEZ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1490195083-25117-2-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>

On Wed, Mar 22, 2017 at 04:04:39PM +0100, Yannick Fertre wrote:
> From: Yannick Fertre <yfertre.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

"dt-bindings: watchdog: ..." for subject.
> 
> This adds documentation of device tree bindings for the STM32 IWDG
> (Independent WatchDoG).
> 
> Change-Id: Idadacc806d00205fe9af2e8606af229b4b760558
> Signed-off-by: Yannick Fertre <yannick.fertre-qxv4g6HH51o@public.gmane.org>
> ---
>  .../devicetree/bindings/watchdog/st,stm32-iwdg.txt        | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt
> new file mode 100644
> index 0000000..036b040
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt
> @@ -0,0 +1,15 @@
> +STM32 Independent WatchDoG (IWDG)
> +---------------------------------
> +
> +Required properties:
> +- compatible: "st,stm32-iwdg"
> +- reg: physical base address and length of the registers set for the device
> +- clocks: must contain a single entry describing the clock input
> +
> +Example:
> +
> +iwdg@40003000 {

watchdog@...

> +	compatible = "st,stm32-iwdg";
> +	reg = <0x40003000 0x400>;
> +	clocks = <&clk_lsi>;
> +};
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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 2/3] clk: qcom: Elaborate on "active" clocks in the RPM clock bindings
From: Linus Walleij @ 2017-03-29  1:33 UTC (permalink / raw)
  To: Rob Herring
  Cc: Michael Turquette, Stephen Boyd, linux-clk,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20170329005943.xqs6ouqbqwdzaayf@rob-hp-laptop>

On Wed, Mar 29, 2017 at 2:59 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Wed, Mar 22, 2017 at 09:18:42AM +0100, Linus Walleij wrote:
>> The concept of "active" clocks is just explained in a bried comment in the
>> device driver, let's explain it a bit more in the device tree bindings
>> so everyone understands this.
>>
>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
>> index d470a0187035..cf80a00b7ff2 100644
>> --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
>> +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
>> @@ -18,6 +18,14 @@ Required properties :
>>
>>  - #clock-cells : shall contain 1
>>
>> +The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h>
>> +and come in pairs: FOO_CLK followed by FOO_A_CLK. The latter clock
>> +is an "active" clock, which means that the consumer only care that the
>> +clock is available when the system is active, i.e. not suspended. If
>> +it is important that the clock keeps running during system suspend,
>> +you need to specify the non-active clock, the one not containing
>> +*_A_* in the enumerator name.
>> +
>
> Sounds like abuse as the clock id is encoding policy into it. The number
> of clocks should be the number of inputs to a block. I wouldn't be
> opposed to some flags for clocks, but that should be a separate cell.

I'm sorry about that, but I'm just documenting what is already a fact and
was previously just implicit in the name.

I first had no idea what this *_A_* infix notation was about so after some
reading I found a comment in the driver saying this.

I guess Stephen can confirm and/or elaborate on this.

Keeping them around is I guess the lesser evil (as compard to
pulling up the deployed bindings with the roots) at this point.

Yours,
Linus Walleij
--
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/7] rtc: Add rtc-sh
From: Rob Herring @ 2017-03-29  1:24 UTC (permalink / raw)
  To: Chris Brandt
  Cc: Alessandro Zummo, Alexandre Belloni, Mark Rutland, Simon Horman,
	Geert Uytterhoeven, rtc-linux, devicetree, linux-renesas-soc
In-Reply-To: <20170322142754.30888-3-chris.brandt@renesas.com>

On Wed, Mar 22, 2017 at 10:27:49AM -0400, Chris Brandt wrote:
> rtc-sh is an RTC for SuperH and RZ/A SoCs.

Please work on the subject. It's a bit brief. "dt-bindings: rtc: " is 
the preferred prefix.

> 
> Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
> ---
> v2:
> * added interrupt-names and clock-names
> * clocks now include counting sources
> * changed 'is a RTC' to 'is an RTC' in commit message
> ---
>  Documentation/devicetree/bindings/rtc/rtc-sh.txt | 29 ++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/rtc-sh.txt
> 
> diff --git a/Documentation/devicetree/bindings/rtc/rtc-sh.txt b/Documentation/devicetree/bindings/rtc/rtc-sh.txt
> new file mode 100644
> index 0000000..adbb8af
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/rtc-sh.txt
> @@ -0,0 +1,29 @@
> +* Real Time Clock for Renesas SH and ARM SoCs
> +
> +Required properties:
> +- compatible: Should be "renesas,r7s72100-rtc" and "renesas,sh-rtc" as a
> +  fallback.
> +- reg: physical base address and length of memory mapped region.
> +- interrupts: 3 interrupts for alarm, period, and carry.
> +- interrupt-names: The interrupts should be labeled as "alarm", "period", and
> +  "carry".
> +- clocks: The functional clock source for the RTC controller must be listed
> +  first (if exists). Additionally, potential clock counting sources are to be
> +  listed.
> +- clock-names: The functional clock must be labeled as "fck". Other clocks
> +  may be named in accordance to the SoC hardware manuals.
> +
> +
> +Example:
> +rtc: rtc@fcff1000 {
> +	compatible = "renesas,r7s72100-rtc", "renesas,sh-rtc";
> +	reg = <0xfcff1000 0x2e>;
> +	interrupts = <GIC_SPI 276 IRQ_TYPE_EDGE_RISING
> +		      GIC_SPI 277 IRQ_TYPE_EDGE_RISING
> +		      GIC_SPI 278 IRQ_TYPE_EDGE_RISING>;
> +	interrupt-names = "alarm", "period", "carry";
> +	clocks = <&mstp6_clks R7S72100_CLK_RTC>, <&rtc_x1_clk>,
> +		 <&rtc_x3_clk>, <&extal_clk>;
> +	clock-names = "fck", "rtc_x1", "rtc_x3", "extal";
> +	power-domains = <&cpg_clocks>;

Not documented.

Rob

^ permalink raw reply

* Re: [PATCH] ipmi: bt-bmc: Add ast2500 compatible string
From: Rob Herring @ 2017-03-29  1:22 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Corey Minyard,
	openipmi-developer-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Cédric Le Goater,
	Andrew Jeffery, Mark Rutland
In-Reply-To: <20170322140112.2479-1-joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>

On Thu, Mar 23, 2017 at 12:31:12AM +1030, Joel Stanley wrote:
> The ast2500 SoCs contain the same IPMI BT device.
> 
> Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt | 4 +++-
>  drivers/char/ipmi/bt-bmc.c                                        | 1 +
>  2 files changed, 4 insertions(+), 1 deletion(-)

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/2] clk: qcom: clk-smd-rpm: add msm8996 rpmclks
From: Rob Herring @ 2017-03-29  1:21 UTC (permalink / raw)
  To: Rajendra Nayak
  Cc: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1490175566-4084-2-git-send-email-rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On Wed, Mar 22, 2017 at 03:09:25PM +0530, Rajendra Nayak wrote:
> Add all RPM controlled clocks on msm8996 platform
> 
> Signed-off-by: Rajendra Nayak <rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> [srini: Fixed various issues with offsets and made names specific to msm8996]
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  .../devicetree/bindings/clock/qcom,rpmcc.txt       |  1 +
>  drivers/clk/qcom/clk-smd-rpm.c                     | 82 ++++++++++++++++++++++
>  include/dt-bindings/clock/qcom,rpmcc.h             | 14 ++++
>  include/linux/soc/qcom/smd-rpm.h                   |  4 ++
>  4 files changed, 101 insertions(+)

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 2/3] clk: qcom: Elaborate on "active" clocks in the RPM clock bindings
From: Rob Herring @ 2017-03-29  0:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170322081842.20495-1-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Wed, Mar 22, 2017 at 09:18:42AM +0100, Linus Walleij wrote:
> The concept of "active" clocks is just explained in a bried comment in the
> device driver, let's explain it a bit more in the device tree bindings
> so everyone understands this.
> 
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
> index d470a0187035..cf80a00b7ff2 100644
> --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
> +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
> @@ -18,6 +18,14 @@ Required properties :
>  
>  - #clock-cells : shall contain 1
>  
> +The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h>
> +and come in pairs: FOO_CLK followed by FOO_A_CLK. The latter clock
> +is an "active" clock, which means that the consumer only care that the
> +clock is available when the system is active, i.e. not suspended. If
> +it is important that the clock keeps running during system suspend,
> +you need to specify the non-active clock, the one not containing
> +*_A_* in the enumerator name.
> +

Sounds like abuse as the clock id is encoding policy into it. The number 
of clocks should be the number of inputs to a block. I wouldn't be 
opposed to some flags for clocks, but that should be a separate cell.

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

* Re: [PATCH 1/3] clk: qcom: Update DT bindings for the MSM8660/APQ8060 RPMCC
From: Rob Herring @ 2017-03-29  0:55 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-msm,
	devicetree
In-Reply-To: <20170322081823.20446-1-linus.walleij@linaro.org>

On Wed, Mar 22, 2017 at 09:18:23AM +0100, Linus Walleij wrote:
> These compatible strings need to be added to extend support
> for the RPM CC to cover MSM8660/APQ8060. We also need to add
> enumberators to the include file for a few clocks that were
> missing.
> 
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 2 ++
>  include/dt-bindings/clock/qcom,rpmcc.h                 | 4 ++++
>  2 files changed, 6 insertions(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH] Add initial SX3000b platform related documentation to document tree
From: Rob Herring @ 2017-03-29  0:55 UTC (permalink / raw)
  To: Amit Kama IL
  Cc: corbet@lwn.net, ralf@linux-mips.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mips@linux-mips.org,
	tglx@linutronix.de, jason@lakedaemon.net, marc.zyngier@arm.com,
	linux-doc@vger.kernel.org
In-Reply-To: <AM4PR0201MB21799759E18C64A7032A2C3EE43C0@AM4PR0201MB2179.eurprd02.prod.outlook.com>

On Wed, Mar 22, 2017 at 05:59:49AM +0000, Amit Kama IL wrote:
> Add initial SX3000b platform related documentation to document tree:
>  - Vendor prefix
>  - Platform binding documentation
>  - Interrupt Controller Unit binding documentation.

Probably should be 3 patches. Preferred subject prefix is "dt-bindings: 
..."

> 
> Signed-off-by: Amit Kama <amit.kama@staixfy.com>
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/satixfy-icu.txt b/Documentation/devicetree/bindings/interrupt-controller/satixfy-icu.txt
> index 0000000..1893393
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/satixfy-icu.txt
> @@ -0,0 +1,47 @@
> +Satixfy SX3000B Interrupt Controller Unit (ICU)
> +
> +The ICU routes HW interrupts from the inter-module fabric to the
> +processor. For the MIPS interaptive, all interrupts are then routed

interaptive or interaptiv? I see both in the doc.


> +to the GIC.
> +
> +Required properties:
> +- compatible : Should be "satixfy,icu".

icu is fairly generic sounding. Should be satixfy,sx3000b-icu.

> +- reg - must be present and equal <0x1D4D0000 0x1C0>
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> +  interrupt specifier.  Should be 1 - the GIC interrupt number
> +- interrupt-parent - Currently only the MIPS GIC is supported, so
> +<&gic> must be specified as parent
> +- interrupts : in interrupt parent form. For GIC it's
> +<GIC_SHARED x IRQ_TYPE_EDGE_RISING> where x is the interrupt number
> +allocated for ICU in GIC.
> +
> +
> +
> +
> +
> +Example:
> +
> +	icu: interrupt-controller@1d4d0000 {
> +		compatible = "sx,icu";
> +		reg = <0x1D4D0000 0x1C0>;

lowercase

> +
> +		interrupt-controller;
> +		#interrupt-cells = <1>;
> +
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SHARED 25 IRQ_TYPE_EDGE_RISING>;
> +	};
> +
> +	uart0: uart@1D4D09C0 {

serial@1d4d09c0

> +		compatible = "ns16550a";
> +		reg = <0x1D4D09C0 0x100>;

lowercase

> +
> +		interrupt-parent = <&icu>;
> +		interrupts = <3>;
> +
> +		clock-frequency = <270000000>;
> +
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +	};
> diff --git a/Documentation/devicetree/bindings/mips/satixfy/sx3000b.txt b/Documentation/devicetree/bindings/mips/satixfy/sx3000b.txt
> index 0000000..7cae67b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/satixfy/sx3000b.txt
> @@ -0,0 +1,37 @@
> +Satixfy SX3000b SoC
> +=========================
> +
> +Required properties:
> +--------------------
> + - compatible: Must include "satixfy,sx3000".

The "b" in SX3000b is not significant?

> +
> +CPU nodes:
> +----------
> +A "cpus" node is required.  Required properties:
> + - #address-cells: Must be 1.
> + - #size-cells: Must be 0.
> +A CPU sub-node is also required for at least CPU 0.  Since the topology may
> +be probed via CPS, it is not necessary to specify secondary CPUs.  Required
> +properties:
> + - device_type: Must be "cpu".
> + - compatible: Must be "mti,interaptiv".
> + - reg: CPU number.
> + - clocks: Must include the CPU clock.  See ../../clock/clock-bindings.txt for
> +   details on clock bindings.
> +Example:
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		cpu@0 {
> +			device_type = "cpu";
> +			compatible = "mti,interaptiv";
> +			clocks	= <&ext>;
> +			reg = <0>;
> +		};
> +	};
> +
> +Interrupt controllers:
> +----------------------
> +Two nodes are required:
> + - mips,gic - MIPS Global Interrupt Controller - see Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt
> + - satixfy,icu - SX3000b SoC Interrupt Controller Unit - see Documentation/devicetree/bindings/interrupt-controller/satixfy-icu.txt
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index ec0bfb9..76819dd
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -261,6 +261,7 @@ rockchip	Fuzhou Rockchip Electronics Co., Ltd
>  samsung	Samsung Semiconductor
>  samtec	Samtec/Softing company
>  sandisk	Sandisk Corporation
> +satixfy Satixfy Technologies Ltd
>  sbs	Smart Battery System
>  schindler	Schindler
>  seagate	Seagate Technology PLC
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v3] ASoC: Add support for Maxim Integrated MAX98927 Amplifier
From: Ryan Lee @ 2017-03-29  0:53 UTC (permalink / raw)
  To: lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ, arnd-r2nGTMty4D4,
	ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	lars-Qo5EllUWu/uELgA04lAiVw, bardliao-Rasf1IRRPZFBDgjK7y7TUQ,
	nh6z-fFIq/eER6g8, KCHSU0-KrzQf0k3Iz9BDgjK7y7TUQ,
	axel.lin-8E1dMatC8ynQT0dZR+AlfA,
	romain.perier-ZGY8ohtN/8qB+jHODAdFcQ,
	srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A,
	oder_chiou-Rasf1IRRPZFBDgjK7y7TUQ,
	Paul.Handrigan-jGc1dHjMKG3QT0dZR+AlfA,
	ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: dgreid-hpIqsD4AKlfQT0dZR+AlfA,
	ryan.lee.maxim-Re5JQEeQqe8AvxtiuMwx3w

Signed-off-by: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
---

Changes since v3:
	* Combined MAX98926 and MAX98927 binding. Kept existing property name.

Changes since v2:
	* Removed local register read/write function to avoid duplication of ASoC core function.
	
 .../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                        | 826 +++++++++++++++++++++
 sound/soc/codecs/max98927.h                        | 267 +++++++
 7 files changed, 1141 insertions(+), 54 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/max98925.txt
 delete mode 100644 Documentation/devicetree/bindings/sound/max98926.txt
 create mode 100755 Documentation/devicetree/bindings/sound/max9892x.txt
 mode change 100644 => 100755 sound/soc/codecs/Kconfig
 mode change 100644 => 100755 sound/soc/codecs/Makefile
 create mode 100755 sound/soc/codecs/max98927.c
 create mode 100755 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 27be63e..0000000
--- 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 0b7f4e4..0000000
--- 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 100755
index 0000000..f617159
--- /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
old mode 100644
new mode 100755
index e49e9da..cbdc8aa
--- 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
@@ -588,6 +589,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
old mode 100644
new mode 100755
index 1796cb9..187a639
--- 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
@@ -313,6 +314,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 100755
index 0000000..15f2192
--- /dev/null
+++ b/sound/soc/codecs/max98927.c
@@ -0,0 +1,826 @@
+/*
+ * 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 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;
+	case SND_SOC_DAIFMT_CBS_CFM:
+		mode = MAX98927_PCM_MASTER_MODE_HYBRID;
+	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;
+
+	break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
+	break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(max98927->regmap,
+		MAX98927_R0020_PCM_MODE_CFG,
+		max98927->iface, max98927->iface);
+
+	/* pcm channel configuration */
+	if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J))
+		regmap_write(max98927->regmap,
+			MAX98927_R0018_PCM_RX_EN_A,
+			MAX98927_PCM_RX_CH0_EN|
+			MAX98927_PCM_RX_CH1_EN);
+
+	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 reg = MAX98927_R0022_PCM_CLK_SETUP;
+	int mask = MAX98927_PCM_CLK_SETUP_BSEL_MASK;
+	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, reg, 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;
+		max98927->ch_size = 16;
+		break;
+	case 24:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
+		max98927->ch_size = 24;
+		break;
+	case 32:
+		chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
+		max98927->ch_size = 32;
+		break;
+	default:
+		dev_err(codec->dev, "format unsupported %d",
+			params_format(params));
+		goto err;
+	}
+
+	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;
+	}
+	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 const char * const max98927_speaker_source_text[] = {
+	"i2s", "reserved", "tone", "pdm"
+};
+
+static const char * const max98927_monomix_output_text[] = {
+	"ch_0", "ch_1", "ch_1_2_div"
+};
+
+static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
+		MAX98927_R0040_BOOST_CTRL0, 0,
+		max98927_boost_voltage_text);
+
+static SOC_ENUM_SINGLE_DECL(max98927_spk_source,
+		MAX98927_R003B_SPK_SRC_SEL, 0,
+		max98927_speaker_source_text);
+
+static SOC_ENUM_SINGLE_DECL(max98927_monomix_output,
+		MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
+		MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
+		max98927_monomix_output_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 Gain", MAX98927_R0036_AMP_VOL_CTRL,
+		0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
+		max98927_digital_tlv),
+	SOC_SINGLE("Amp DSP Enable", 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 EN", MAX98927_R0039_DRE_CTRL,
+		MAX98927_DRE_EN_SHIFT, 1, 0),
+	SOC_SINGLE("Amp Volume Location", MAX98927_R0036_AMP_VOL_CTRL,
+		MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
+	SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
+	SOC_ENUM("Speaker Source", max98927_spk_source),
+	SOC_ENUM("Monomix Output", max98927_monomix_output),
+};
+
+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);
+	int ret = 0, reg = 0;
+
+	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);
+
+	/* Check Revision ID */
+	ret = regmap_read(max98927->regmap,
+		MAX98927_R01FF_REV_ID, &reg);
+	if (ret < 0)
+		dev_err(codec->dev,
+			"Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
+	else
+		dev_info(codec->dev,
+			"MAX98927 revisionID: 0x%02X\n", reg);
+
+	/* 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 ret;
+}
+
+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;
+	struct max98927_priv *max98927 = NULL;
+
+	max98927 = devm_kzalloc(&i2c->dev,
+		sizeof(*max98927), GFP_KERNEL);
+
+	if (!max98927) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	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);
+		goto err;
+	}
+
+	/* 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;
+
+err:
+	if (max98927)
+		devm_kfree(&i2c->dev, max98927);
+	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 100755
index 0000000..e13e18a
--- /dev/null
+++ b/sound/soc/codecs/max98927.h
@@ -0,0 +1,267 @@
+/*
+ * 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_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_HYBRID (0x1 << 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_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.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 v3] ASoC: Add support for Maxim Integrated MAX98927 Amplifier
From: Ryan Lee @ 2017-03-29  0:49 UTC (permalink / raw)
  To: Mark Brown
  Cc: lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ, arnd-r2nGTMty4D4,
	ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	lars-Qo5EllUWu/uELgA04lAiVw, bardliao-Rasf1IRRPZFBDgjK7y7TUQ,
	nh6z-fFIq/eER6g8, KCHSU0-KrzQf0k3Iz9BDgjK7y7TUQ,
	axel.lin-8E1dMatC8ynQT0dZR+AlfA,
	romain.perier-ZGY8ohtN/8qB+jHODAdFcQ,
	srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A,
	oder_chiou-Rasf1IRRPZFBDgjK7y7TUQ,
	Paul.Handrigan-jGc1dHjMKG3QT0dZR+AlfA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dgreid-hpIqsD4AKlfQT0dZR+AlfA
In-Reply-To: <20170328163928.jtjnfzcd3turhhl7-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>

On Tue, Mar 28, 2017 at 9:39 AM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Wed, Mar 29, 2017 at 12:32:28AM +0900, Ryan Lee wrote:
>> Signed-off-by: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
>
> Please stop sending patches in the middle of existing threads, it makes
> it hard to see new versions and for multi-patch serieses makes it hard
> to see what the current version of the series is.

I'm sorry to make it get confused. I'll resend it on the top.
--
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 v1 2/7] devicetree: power: Add docs for TI BQ24190 battery charger
From: Rob Herring @ 2017-03-29  0:47 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Tony Lindgren, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	Hans de Goede, devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck
In-Reply-To: <20170321220921.5834-3-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>

On Tue, Mar 21, 2017 at 03:09:16PM -0700, Liam Breck wrote:
> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> 
> Document monitored-battery and ti,system-minimum-microvolt properties.
> 
> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> ---
>  .../devicetree/bindings/power/supply/bq24190.txt   | 47 ++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/bq24190.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/bq24190.txt b/Documentation/devicetree/bindings/power/supply/bq24190.txt
> new file mode 100644
> index 0000000..d252d10
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/bq24190.txt
> @@ -0,0 +1,47 @@
> +Binding for TI BQ24190 Li-Ion Battery Charger
> +
> +Required properties:
> +- compatible: Should contain one of the following:
> +    * "ti,bq24190"
> +- reg: integer, I2C address of the device.
> +
> +Optional properties:
> +- monitored-battery: phandle of battery information devicetree node
> +    These battery properties are relevant:
> +    + precharge-current-microamp: maximum charge current during precharge
> +      phase (typically 20% of battery capacity).
> +    + endcharge-current-microamp: a charge cycle terminates when the
> +      battery voltage is above recharge threshold, and the current is below
> +      this setting (typically 10% of battery capacity).
> +    See Documentation/devicetree/bindings/power/supply/battery.txt

This isn't really relevant to the binding. The battery properties 
shouldn't vary with the charger.

> +- ti,system-minimum-microvolt: when power is connected and the battery
> +    is below minimum system voltage, the system will be regulated above this
> +    setting.
> +
> +Other features:
> +- Use gpio-hog to set the OTG pin high to enable 500mA charge current on USB SDP port.
> +
> +Example:
> +
> +bat: battery {
> +	compatible = "simple-battery";
> +	precharge-current-microamp = <256000>;
> +	endcharge-current-microamp = <128000>;
> +};
> +
> +bq24190 charger@6a {
> +	compatible = "ti,bq24190";
> +	reg = <0x6a>;
> +	// interrupt configuration here
> +	monitored-battery = <&bat>;
> +	ti,system-minimum-microvolt = <3200000>;
> +};
> +
> +&twl_gpio {
> +	otg {
> +		gpio-hog;
> +		gpios = <6 0>;
> +		output-high;
> +		line-name = "otg-gpio";
> +	};
> +};
> -- 
> 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

* Re: [PATCH v1 1/7] devicetree: power: battery: Add properties for pre-charge and end-charge current
From: Rob Herring @ 2017-03-29  0:43 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Tony Lindgren, linux-pm, Hans de Goede,
	devicetree, Liam Breck
In-Reply-To: <CAKvHMgQt=C1tmfPz3pp_vwhc3b9DHKau2t=jwp3Rv2b2U6hsaQ@mail.gmail.com>

On Fri, Mar 24, 2017 at 05:34:26PM -0700, Liam Breck wrote:
> On Fri, Mar 24, 2017 at 2:01 AM, Sebastian Reichel <sre@kernel.org> wrote:
> > Hi,
> >
> > On Tue, Mar 21, 2017 at 03:09:15PM -0700, Liam Breck wrote:
> >> From: Liam Breck <kernel@networkimprov.net>
> >>
> >> precharge-current-microamp and endcharge-current-microamp are used
> >> by battery chargers at the beginning and end of a charging cycle.
> >>
> >> Depends-on: https://patchwork.kernel.org/patch/9633605/
> >> Cc: Rob Herring <robh@kernel.org>
> >> Cc: devicetree@vger.kernel.org
> >> Signed-off-by: Liam Breck <kernel@networkimprov.net>
> >
> > Acked-by: Sebastian Reichel <sre@kernel.org>
> >
> > I think it makes sense to merge this into the patch adding
> > simple-battery.

Agreed.

> 
> It would make sense, but it means a new _prop_precharge/endcharge
> patch in that patchset, and I am trying to constrain it at this stage.

Please make bindings complete as possible. You don't have to have the 
driver side.

Rob

^ permalink raw reply

* Re: [PATCH v1 1/7] devicetree: power: battery: Add properties for pre-charge and end-charge current
From: Rob Herring @ 2017-03-29  0:39 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Tony Lindgren, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	Hans de Goede, devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck
In-Reply-To: <20170321220921.5834-2-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>

On Tue, Mar 21, 2017 at 03:09:15PM -0700, Liam Breck wrote:
> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> 
> precharge-current-microamp and endcharge-current-microamp are used
> by battery chargers at the beginning and end of a charging cycle.
> 
> Depends-on: https://patchwork.kernel.org/patch/9633605/
> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/power/supply/battery.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
> index 53a68c0..494374a 100644
> --- a/Documentation/devicetree/bindings/power/supply/battery.txt
> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
> @@ -12,6 +12,8 @@ Optional Properties:
>   - voltage-min-design-microvolt: drained battery voltage
>   - energy-full-design-microwatt-hours: battery design energy
>   - charge-full-design-microamp-hours: battery design capacity
> + - precharge-current-microamp: current for pre-charge phase
> + - endcharge-current-microamp: current for charge termination phase

current is implied by microamp, so perhaps just pre-charge-microamp and 
end-charge-microamp.

I know little about batteries, but don't you also need to know when each 
phase starts/ends? 

I mainly ask because we just added the previous properties and now we're 
adding 2 more. While fine to add features to a driver one by one, we 
really shouldn't for bindings. The h/w is not evolving (in a month).

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

* Re: [PATCH v6 02/39] [media] dt-bindings: Add bindings for i.MX media driver
From: Steve Longerbeam @ 2017-03-29  0:35 UTC (permalink / raw)
  To: Rob Herring, Steve Longerbeam
  Cc: Mark Rutland, Andrew-CT Chen (陳智迪),
	Minghsiu Tsai, Sakari Ailus, Nick Dyer, Songjun Wu, Hans Verkuil,
	Pavel Machek, Robert Jarzmik, devel, markus.heiser,
	Laurent Pinchart, shuah, Russell King, Geert Uytterhoeven,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	kernel@pengutronix.de, Arnd Bergmann, Mauro Carvalho Chehab,
	Benoit Parrot
In-Reply-To: <CAL_JsqJm_JjuVPcOBERCqsnjTDdNoKr9xRE9MXMO4ivxGath2Q@mail.gmail.com>



On 03/28/2017 05:21 PM, Rob Herring wrote:
> On Mon, Mar 27, 2017 at 7:40 PM, Steve Longerbeam <slongerbeam@gmail.com> wrote:
>> Add bindings documentation for the i.MX media driver.
>>
>> <snip>
>> +
>> +mipi_csi2 node
>> +--------------
>> +
>> +This is the device node for the MIPI CSI-2 Receiver, required for MIPI
>> +CSI-2 sensors.
>> +
>> +Required properties:
>> +- compatible   : "fsl,imx6-mipi-csi2", "snps,dw-mipi-csi2";
>
> As I mentioned in v5, there's a DW CSI2 binding in progress. This
> needs to be based on that.

Hi Rob, I'm not sure what you are asking me to do.

I assume if there's another binding doc in progress, it means
someone is working on another Synopsys DW CSI-2 subdevice driver.

Unfortunately I don't have the time to contribute and switch to
this other subdevice, and do test/debug.

For now I would prefer if this patchset is merged as is, and
then contribute/switch to another CSI-2 subdev later. It is
also getting very difficult managing all these patches (39 as
of this version), and I'd prefer not to spam the lists with
such large patchsets for too much longer.


Steve

^ permalink raw reply


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