* Re: [PATCH RFC] serial: imx: support an enable-gpio
From: Rob Herring @ 2017-04-03 20:25 UTC (permalink / raw)
To: Fabio Estevam
Cc: Uwe Kleine-König,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Sascha Hauer
In-Reply-To: <CAOMZO5A4e7H-6feNN-cTABOKv+CUCU9Em_yFMhorZwXfeA-h0w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Apr 3, 2017 at 10:01 AM, Fabio Estevam <festevam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi Uwe,
>
> On Wed, Jul 13, 2016 at 6:01 AM, Uwe Kleine-König
> <u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org> wrote:
>> A part of my machine looks as follows (simplified):
>>
>> ,------------------------.
>> | ,---------. |
>> | | imx25 o--RX----◁---o---
>> | | o--GPIO--' |
>> | `---------' |
>> `------------------------'
>>
>> that is, there is a driver on the RX line that must be enabled before
>> the UART can be used. (That is necessary because the default mux of the
>> RX pad after reset is an output.)
>>
>> To represent this in the device tree I do:
>>
>> pinctrl_uart5: uart5 {
>> fsl,pins = <
>> ...
>> MX25_PAD_LBA__UART5_RXD 0x00000000
>> MX25_PAD_CS5__GPIO_3_21 0x00002001
>> ...
>> };
>>
>> &uart5 {
>> pinctrl-names = "default";
>> pinctrl-0 = <&pinctrl_uart5>;
>>
>> enable-gpio = <&gpio3 21 GPIO_ACTIVE_LOW>;
enable-gpios
I imagine you already know this needs documentation. Make it common please.
>> ...
>> };
>>
>> This way it's ensured that the gpio is only enabled when the LBA pad is
>> muxed as RX (together with the bootloader that sets the GPIO high).
>>
>> Signed-off-by: Uwe Kleine-König <u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
>
> Since this is not imx serial specific it could be made more generic.
>
> What about extending
> Documentation/devicetree/bindings/serial/slave-device.txt to handle
> this GPIO, or maybe a regulator?
This is more like a phy than a device you talk to. It could also be
something like an RS-232 xcvr enable (no one has done that already?).
I think it belongs in the uart's node. You could additionally have an
enable-gpios for a slave device.
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
* [PATCH 3/3] ARM: dts: da850: Add node for LEGO MINDSTORMS EV3 Battery
From: David Lechner @ 2017-04-03 20:23 UTC (permalink / raw)
To: linux-pm, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Sekhar Nori,
Sebastian Reichel, linux-kernel, Rob Herring
In-Reply-To: <1491251029-23256-1-git-send-email-david@lechnology.com>
This adds a new node to the LEGO MINDSTORMS EV3 device tree for the battery.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/boot/dts/da850-lego-ev3.dts | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/arm/boot/dts/da850-lego-ev3.dts b/arch/arm/boot/dts/da850-lego-ev3.dts
index c20580a..99cd561 100644
--- a/arch/arm/boot/dts/da850-lego-ev3.dts
+++ b/arch/arm/boot/dts/da850-lego-ev3.dts
@@ -172,6 +172,18 @@
gpio = <&gpio 111 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ /*
+ * The EV3 can use 6-AA batteries or a rechargable Li-ion battery pack.
+ */
+ battery {
+ pinctrl-names = "default";
+ pintctrl-0 = <&battery_pins>;
+ compatible = "lego,ev3-battery";
+ io-channels = <&adc 4>, <&adc 3>;
+ io-channel-names = "voltage", "current";
+ rechargeable-gpios = <&gpio 136 GPIO_ACTIVE_LOW>;
+ };
};
&pmx_core {
@@ -235,6 +247,15 @@
0x34 0x00000008 0x0000000f
>;
};
+
+ battery_pins: pinmux_battery_pins {
+ pinctrl-single,bits = <
+ /* GP0[6] */
+ 0x04 0x00000080 0x000000f0
+ /* GP8[8] */
+ 0x4c 0x00000080 0x000000f0
+ >;
+ };
};
&pinconf {
@@ -349,6 +370,13 @@
&gpio {
status = "okay";
+
+ /* Don't pull down battery voltage adc io channel */
+ batt_volt_en {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_HIGH>;
+ output-low;
+ };
};
&usb_phy {
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] power: supply: New driver for LEGO MINDSTORMS EV3 battery
From: David Lechner @ 2017-04-03 20:23 UTC (permalink / raw)
To: linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: David Lechner, Sebastian Reichel, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1491251029-23256-1-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
This adds a new driver for the LEGO MINDSTORMS EV3 battery. The EV3 is
an embedded ARM device that can use 6 AA batteries or a special rechargeable
Li-ion battery pack. The rechargeable battery pack presses a special key
switch in the battery compartment to indicate that it is present.
The EV3 is only capable of monitoring battery voltage and current. The
charging circuit is built into the rechargeable battery pack and there is
no way to communicate with is, so we can't provide any information about
charging status.
When not using the rechargeable battery pack, it is most common to use
alkaline batteries to power the device, but it is also common for people to
use rechargeable NiMH batteries. Since there is not a way to automatically
differentiate between these, the technology property is made writable.
Signed-off-by: David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
---
drivers/power/supply/Kconfig | 6 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/lego_ev3_battery.c | 237 ++++++++++++++++++++++++++++++++
3 files changed, 244 insertions(+)
create mode 100644 drivers/power/supply/lego_ev3_battery.c
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index cc50e15..e00bf25 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -117,6 +117,12 @@ config BATTERY_DS2782
Say Y here to enable support for the DS2782/DS2786 standalone battery
gas-gauge.
+config BATTERY_LEGO_EV3
+ tristate "LEGO MINDSTORMS EV3 battery"
+ depends on OF && IIO && GPIOLIB
+ help
+ Say Y here to enable support for the LEGO MINDSTORMS EV3 battery.
+
config BATTERY_PMU
tristate "Apple PMU battery"
depends on PPC32 && ADB_PMU
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 3789a2c..dfeadbc 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o
obj-$(CONFIG_BATTERY_GAUGE_LTC2941) += ltc2941-battery-gauge.o
obj-$(CONFIG_BATTERY_GOLDFISH) += goldfish_battery.o
+obj-$(CONFIG_BATTERY_LEGO_EV3) += lego_ev3_battery.o
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
diff --git a/drivers/power/supply/lego_ev3_battery.c b/drivers/power/supply/lego_ev3_battery.c
new file mode 100644
index 0000000..87230bd
--- /dev/null
+++ b/drivers/power/supply/lego_ev3_battery.c
@@ -0,0 +1,237 @@
+/*
+ * Battery driver for LEGO MINDSTORMS EV3
+ *
+ * Copyright (C) 2017 David Lechner <david-nq/r/kbU++upp/zk7JDF2g@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 version 2 as
+ * published by the Free Software Foundation.
+
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/consumer.h>
+#include <linux/iio/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+struct lego_ev3_battery {
+ struct iio_channel *iio_v;
+ struct iio_channel *iio_i;
+ struct gpio_desc *rechargeable_gpio;
+ struct power_supply *psy;
+ int technology;
+ int v_max;
+ int v_min;
+};
+
+static int lego_ev3_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct lego_ev3_battery *batt = power_supply_get_drvdata(psy);
+ int val2;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = batt->technology;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ /* battery voltage is iio channel * 2 + Vce of transistor */
+ iio_read_channel_processed(batt->iio_v, &val->intval);
+ val->intval *= 2000;
+ val->intval += 200000;
+ /* plus adjust for shunt resistor drop */
+ iio_read_channel_processed(batt->iio_i, &val2);
+ val2 *= 1000;
+ val2 /= 15;
+ val->intval += val2;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ val->intval = batt->v_max;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ val->intval = batt->v_min;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ /* battery current is iio channel / 15 / 0.05 ohms */
+ iio_read_channel_processed(batt->iio_i, &val->intval);
+ val->intval *= 20000;
+ val->intval /= 15;
+ break;
+ case POWER_SUPPLY_PROP_SCOPE:
+ val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int lego_ev3_battery_set_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct lego_ev3_battery *batt = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ /*
+ * Only allow changing technology from Unknown to NiMH. Li-ion
+ * batteries are automatically detected and should not be
+ * overridden. Rechargeable AA batteries, on the other hand,
+ * cannot be automatically detected, and so must be manually
+ * specified. This should only be set once during system init,
+ * so there is no mechanism to go back to Unknown.
+ */
+ if (batt->technology != POWER_SUPPLY_TECHNOLOGY_UNKNOWN)
+ return -EINVAL;
+ switch (val->intval) {
+ case POWER_SUPPLY_TECHNOLOGY_NiMH:
+ batt->technology = POWER_SUPPLY_TECHNOLOGY_NiMH;
+ batt->v_max = 7800000;
+ batt->v_min = 5400000;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int lego_ev3_battery_property_is_writeable(struct power_supply *psy,
+ enum power_supply_property psp)
+{
+ struct lego_ev3_battery *batt = power_supply_get_drvdata(psy);
+
+ return psp == POWER_SUPPLY_PROP_TECHNOLOGY &&
+ batt->technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+}
+
+static enum power_supply_property lego_ev3_battery_props[] = {
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_SCOPE,
+};
+
+static const struct power_supply_desc lego_ev3_battery_desc = {
+ .name = "lego-ev3-battery",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = lego_ev3_battery_props,
+ .num_properties = ARRAY_SIZE(lego_ev3_battery_props),
+ .get_property = lego_ev3_battery_get_property,
+ .set_property = lego_ev3_battery_set_property,
+ .property_is_writeable = lego_ev3_battery_property_is_writeable,
+};
+
+static int lego_ev3_battery_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct lego_ev3_battery *batt;
+ struct power_supply_config psy_cfg = {};
+ int err;
+
+ batt = devm_kzalloc(dev, sizeof(*batt), GFP_KERNEL);
+ if (!batt)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, batt);
+
+ batt->iio_v = devm_iio_channel_get(dev, "voltage");
+ err = PTR_ERR_OR_ZERO(batt->iio_v);
+ if (err) {
+ if (err != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get voltage iio channel\n");
+ return err;
+ }
+
+ batt->iio_i = devm_iio_channel_get(dev, "current");
+ err = PTR_ERR_OR_ZERO(batt->iio_i);
+ if (err) {
+ if (err != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get current iio channel\n");
+ return err;
+ }
+
+ batt->rechargeable_gpio = devm_gpiod_get(dev, "rechargeable", GPIOD_IN);
+ err = PTR_ERR_OR_ZERO(batt->rechargeable_gpio);
+ if (err) {
+ if (err != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get rechargeable gpio\n");
+ return err;
+ }
+
+ /*
+ * The rechargeable battery indication switch cannot be changed without
+ * removing the battery, so we only need to read it once.
+ */
+ if (gpiod_get_value(batt->rechargeable_gpio)) {
+ /* 2-cell Li-ion, 7.4V nominal */
+ batt->technology = POWER_SUPPLY_TECHNOLOGY_LION;
+ batt->v_max = 84000000;
+ batt->v_min = 60000000;
+ } else {
+ /* 6x AA Alkaline, 9V nominal */
+ batt->technology = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+ batt->v_max = 90000000;
+ batt->v_min = 48000000;
+ }
+
+ psy_cfg.of_node = pdev->dev.of_node;
+ psy_cfg.drv_data = batt;
+
+ batt->psy = power_supply_register(dev, &lego_ev3_battery_desc, &psy_cfg);
+ err = PTR_ERR_OR_ZERO(batt->psy);
+ if (err) {
+ dev_err(dev, "failed to register power supply\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int lego_ev3_battery_remove(struct platform_device *pdev)
+{
+ struct lego_ev3_battery *batt = platform_get_drvdata(pdev);
+
+ power_supply_unregister(batt->psy);
+
+ return 0;
+}
+
+static const struct of_device_id of_lego_ev3_battery_match[] = {
+ { .compatible = "lego,ev3-battery", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, of_lego_ev3_battery_match);
+
+static struct platform_driver lego_ev3_battery_driver = {
+ .driver = {
+ .name = "lego-ev3-battery",
+ .of_match_table = of_lego_ev3_battery_match,
+ },
+ .probe = lego_ev3_battery_probe,
+ .remove = lego_ev3_battery_remove,
+};
+module_platform_driver(lego_ev3_battery_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>");
+MODULE_DESCRIPTION("LEGO MINDSTORMS EV3 Battery Driver");
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/3] dt-bindings: power: supply: New bindings for LEGO MINDSTORMS EV3 battery
From: David Lechner @ 2017-04-03 20:23 UTC (permalink / raw)
To: linux-pm, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Sekhar Nori,
Sebastian Reichel, linux-kernel, Rob Herring
In-Reply-To: <1491251029-23256-1-git-send-email-david@lechnology.com>
This add a new device tree binding for LEGO MINDSTORMS EV3 battery. The EV3
has some built-in capability for monitoring the attached battery.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../bindings/power/supply/lego_ev3_battery.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/lego_ev3_battery.txt
diff --git a/Documentation/devicetree/bindings/power/supply/lego_ev3_battery.txt b/Documentation/devicetree/bindings/power/supply/lego_ev3_battery.txt
new file mode 100644
index 0000000..5485633
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/lego_ev3_battery.txt
@@ -0,0 +1,21 @@
+LEGO MINDSTORMS EV3 Battery
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LEGO MINDSTORMS EV3 has some built-in capability for monitoring the battery.
+It uses 6 AA batteries or a special Li-ion rechargeable battery pack that is
+detected by a key switch in the battery compartment.
+
+Required properties:
+ - compatible: Must be "lego,ev3-battery"
+ - io-channels: phandles to analog inputs for reading voltage and current
+ - io-channel-names: Must be "voltage", "current"
+ - rechargeable-gpios: phandle to the rechargeable battery indication gpio
+
+Example:
+
+ battery {
+ compatible = "lego,ev3-battery";
+ io-channels = <&adc 4>, <&adc 3>;
+ io-channel-names = "voltage", "current";
+ rechargeable-gpios = <&gpio 136 GPIO_ACTIVE_LOW>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH 0/3] LEGO MINDSTORMS EV3 Battery
From: David Lechner @ 2017-04-03 20:23 UTC (permalink / raw)
To: linux-pm, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Sekhar Nori,
Sebastian Reichel, linux-kernel, Rob Herring
This series adds support for the LEGO MINDSTORMS EV3 battery.
David Lechner (3):
dt-bindings: power: supply: New bindings for LEGO MINDSTORMS EV3
battery
power: supply: New driver for LEGO MINDSTORMS EV3 battery
ARM: dts: da850: Add node for LEGO MINDSTORMS EV3 Battery
.../bindings/power/supply/lego_ev3_battery.txt | 21 ++
arch/arm/boot/dts/da850-lego-ev3.dts | 28 +++
drivers/power/supply/Kconfig | 6 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/lego_ev3_battery.c | 237 +++++++++++++++++++++
5 files changed, 293 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/lego_ev3_battery.txt
create mode 100644 drivers/power/supply/lego_ev3_battery.c
--
2.7.4
^ permalink raw reply
* Re: [PATCH v3 05/11] Documentation: DT: bindings: input: touschcreen: remove sun4i documentation
From: Dmitry Torokhov @ 2017-04-03 20:09 UTC (permalink / raw)
To: Lee Jones
Cc: Quentin Schulz, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
linux-I+IVW8TIWO2tmTQ+vhA3Yw, jic23-DgEjT+Ai2ygdnm+yROfE0A,
knaack.h-Mmb7MZpHnFY, lars-Qo5EllUWu/uELgA04lAiVw,
pmeerw-jW+XmwGofnusTnJN9+BGXg,
thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, icenowy-ymACFijhrKM
In-Reply-To: <20170329075826.4curjodxgi34tgco@dell>
On Wed, Mar 29, 2017 at 08:58:26AM +0100, Lee Jones wrote:
> On Tue, 21 Mar 2017, Quentin Schulz wrote:
>
> > This patch removes the sun4i touchscreen controller binding
> > documentation since it has been merged with the sun4i GPADC binding
> > documentation.
> >
> > Signed-off-by: Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> > Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > ---
> >
> > added in v2
> >
> > .../bindings/input/touchscreen/sun4i.txt | 38 ----------------------
>
> Just an Input Ack missing here.
Acked-by: Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> > 1 file changed, 38 deletions(-)
> > delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
> >
> > diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
> > deleted file mode 100644
> > index 89abecd..0000000
> > --- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
> > +++ /dev/null
> > @@ -1,38 +0,0 @@
> > -sun4i resistive touchscreen controller
> > ---------------------------------------
> > -
> > -Required properties:
> > - - compatible: "allwinner,sun4i-a10-ts", "allwinner,sun5i-a13-ts" or
> > - "allwinner,sun6i-a31-ts"
> > - - reg: mmio address range of the chip
> > - - interrupts: interrupt to which the chip is connected
> > - - #thermal-sensor-cells: shall be 0
> > -
> > -Optional properties:
> > - - allwinner,ts-attached : boolean indicating that an actual touchscreen
> > - is attached to the controller
> > - - allwinner,tp-sensitive-adjust : integer (4 bits)
> > - adjust sensitivity of pen down detection
> > - between 0 (least sensitive) and 15
> > - (defaults to 15)
> > - - allwinner,filter-type : integer (2 bits)
> > - select median and averaging filter
> > - samples used for median / averaging filter
> > - 0: 4/2
> > - 1: 5/3
> > - 2: 8/4
> > - 3: 16/8
> > - (defaults to 1)
> > -
> > -Example:
> > -
> > - rtp: rtp@01c25000 {
> > - compatible = "allwinner,sun4i-a10-ts";
> > - reg = <0x01c25000 0x100>;
> > - interrupts = <29>;
> > - allwinner,ts-attached;
> > - #thermal-sensor-cells = <0>;
> > - /* sensitive/noisy touch panel */
> > - allwinner,tp-sensitive-adjust = <0>;
> > - allwinner,filter-type = <3>;
> > - };
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
--
Dmitry
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [RFC PATCH 4/5] dt-bindings: soc/fsl: Update reserved memory binding for QBMan
From: Roy Pledge @ 2017-04-03 19:49 UTC (permalink / raw)
To: Rob Herring
Cc: robin.murphy-5wv7dgnIgG8@public.gmane.org,
oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Madalin-Cristian Bucur
In-Reply-To: <20170403154229.mf63zeiwv5naxyrr@rob-hp-laptop>
On 4/3/2017 11:42 AM, Rob Herring wrote:
> On Wed, Mar 29, 2017 at 05:13:56PM -0400, Roy Pledge wrote:
>> Updates the QMan and BMan device tree bindings for reserved memory
>> nodes. This makes the reserved memory allocation compatiable with
> s/compatiable/compatible/
>
>> the shared-dma-pool usage.
> This change is not backwards compatible. Please state that and explain
> why that is okay. If PPC needs to not change, then the old strings and
> properties should remain, but deprecated.
I think I can make the old device trees compatible since the
"compatible" string changed without too much effort or ifdefery in the
code. However I would like to eventually see all PPC users move to the
new mode as I do believe it is more in alignment with the spirit of the
reserved-memory framework that is in the kernel. Do I need to mention
the old mode in the binding.txt file? I'm trying to keep things clean
so someone reading the binding doesn't get a headache and trying to
preserve my own sanity as we move forward with adding new features to
this driver.
Roy
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/2 v2] ARM: i.MX25: globally disable supervisor protect
From: Martin Kaiser @ 2017-04-03 19:47 UTC (permalink / raw)
To: Shawn Guo
Cc: Sascha Hauer, linux-arm-kernel, devicetree, linux-kernel,
Martin Kaiser
In-Reply-To: <1491248825-23041-1-git-send-email-martin@kaiser.cx>
The problem described in 6befda9a272b98bfb1dc772efc3564644cbfb270
for the i.MX53 platform applies to i.MX25 as well.
E.g. CSPI1+SDMA and SSI1+SDMA are not working with the default AIPS
configuration. Modifiy the AIPS configuration to allow access to the bus
by SDMA and peripherals.
Signed-off-by: Martin Kaiser <martin@kaiser.cx>
---
v2:
rebased against latest linux-next
re-sending both patches, it seems they got lost along the way
arch/arm/mach-imx/mach-imx25.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/mach-imx/mach-imx25.c b/arch/arm/mach-imx/mach-imx25.c
index 32dcb5e..353b86e 100644
--- a/arch/arm/mach-imx/mach-imx25.c
+++ b/arch/arm/mach-imx/mach-imx25.c
@@ -23,6 +23,11 @@ static void __init imx25_init_early(void)
mxc_set_cpu_type(MXC_CPU_MX25);
}
+static void __init imx25_dt_init(void)
+{
+ imx_aips_allow_unprivileged_access("fsl,imx25-aips");
+}
+
static void __init mx25_init_irq(void)
{
struct device_node *np;
@@ -41,6 +46,7 @@ static const char * const imx25_dt_board_compat[] __initconst = {
DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
.init_early = imx25_init_early,
+ .init_machine = imx25_dt_init,
.init_late = imx25_pm_init,
.init_irq = mx25_init_irq,
.dt_compat = imx25_dt_board_compat,
--
2.1.4
^ permalink raw reply related
* [PATCH 1/2 v4] ARM: dts: i.MX25: add AIPS control registers
From: Martin Kaiser @ 2017-04-03 19:47 UTC (permalink / raw)
To: Shawn Guo
Cc: Sascha Hauer, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Martin Kaiser
In-Reply-To: <1485890402-22974-1-git-send-email-martin-XxZfDwE/svGeZLLa646FqQ@public.gmane.org>
The i.MX25 contains two AHB to IP bridges (AIPS), each of which has a set of
control registers. Add the memory regions for the control registers to
the Device Tree.
Signed-off-by: Martin Kaiser <martin-XxZfDwE/svGeZLLa646FqQ@public.gmane.org>
Reviewed-by: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
v4:
rebased against latest linux-next
re-sending both patches, it seems they got lost along the way
v3:
fixed the size of the memory regions, both are 16KBytes long
v2:
removed the "fsl,imx53-aipstz" property as per Sascha's request
arch/arm/boot/dts/imx25.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 89c8f8f..0cdf333 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -93,6 +93,11 @@
reg = <0x43f00000 0x100000>;
ranges;
+ aips1: bridge@43f00000 {
+ compatible = "fsl,imx25-aips";
+ reg = <0x43f00000 0x4000>;
+ };
+
i2c1: i2c@43f80000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -342,6 +347,11 @@
reg = <0x53f00000 0x100000>;
ranges;
+ aips2: bridge@53f00000 {
+ compatible = "fsl,imx25-aips";
+ reg = <0x53f00000 0x4000>;
+ };
+
clks: ccm@53f80000 {
compatible = "fsl,imx25-ccm";
reg = <0x53f80000 0x4000>;
--
2.1.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 v2 2/2] iio: adc: stm32: add dt option to set resolution
From: Jonathan Cameron @ 2017-04-03 19:46 UTC (permalink / raw)
To: Fabrice Gasnier, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, lars-Qo5EllUWu/uELgA04lAiVw,
knaack.h-Mmb7MZpHnFY, pmeerw-jW+XmwGofnusTnJN9+BGXg,
benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A,
benjamin.gaignard-qxv4g6HH51o,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <8d440abd-3548-6aab-bba9-3f62fe27e72d-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
On 02/04/17 09:54, Jonathan Cameron wrote:
> On 31/03/17 13:32, Fabrice Gasnier wrote:
>> stm32 adc supports several resolution. Add 'assigned-resolution-bits'
>> dt optional property to set it. Default to maximum resolution in case
>> it isn't set.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier-qxv4g6HH51o@public.gmane.org>
> The code is fine. Just waiting on review of the binding.
>
> Give me a poke if I seem to have dropped this in a week or two.
Applied to the togreg branch of iio.git and pushed out as
testing for the autobuilders to play with it.
Thanks,
Jonathan
>
> Thanks,
>
> Jonathan
>> ---
>> Changes in v2:
>> - rename property from 'st,adc-res' to 'assigned-resolution-bits', so it
>> is more common.
>> ---
>> drivers/iio/adc/stm32-adc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 49 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
>> index 9b49a6ad..c28e7ff 100644
>> --- a/drivers/iio/adc/stm32-adc.c
>> +++ b/drivers/iio/adc/stm32-adc.c
>> @@ -60,6 +60,8 @@
>> #define STM32F4_EOC BIT(1)
>>
>> /* STM32F4_ADC_CR1 - bit fields */
>> +#define STM32F4_RES_SHIFT 24
>> +#define STM32F4_RES_MASK GENMASK(25, 24)
>> #define STM32F4_SCAN BIT(8)
>> #define STM32F4_EOCIE BIT(5)
>>
>> @@ -141,6 +143,7 @@ struct stm32_adc_regs {
>> * @lock: spinlock
>> * @bufi: data buffer index
>> * @num_conv: expected number of scan conversions
>> + * @res: data resolution (e.g. RES bitfield value)
>> * @trigger_polarity: external trigger polarity (e.g. exten)
>> * @dma_chan: dma channel
>> * @rx_buf: dma rx buffer cpu address
>> @@ -157,6 +160,7 @@ struct stm32_adc {
>> spinlock_t lock; /* interrupt lock */
>> unsigned int bufi;
>> unsigned int num_conv;
>> + u32 res;
>> u32 trigger_polarity;
>> struct dma_chan *dma_chan;
>> u8 *rx_buf;
>> @@ -196,6 +200,11 @@ struct stm32_adc_chan_spec {
>> { IIO_VOLTAGE, 15, "in15" },
>> };
>>
>> +static const unsigned int stm32f4_adc_resolutions[] = {
>> + /* sorted values so the index matches RES[1:0] in STM32F4_ADC_CR1 */
>> + 12, 10, 8, 6,
>> +};
>> +
>> /**
>> * stm32f4_sq - describe regular sequence registers
>> * - L: sequence len (register & bit field)
>> @@ -302,6 +311,14 @@ static void stm32_adc_conv_irq_disable(struct stm32_adc *adc)
>> stm32_adc_clr_bits(adc, STM32F4_ADC_CR1, STM32F4_EOCIE);
>> }
>>
>> +static void stm32_adc_set_res(struct stm32_adc *adc)
>> +{
>> + u32 val = stm32_adc_readl(adc, STM32F4_ADC_CR1);
>> +
>> + val = (val & ~STM32F4_RES_MASK) | (adc->res << STM32F4_RES_SHIFT);
>> + stm32_adc_writel(adc, STM32F4_ADC_CR1, val);
>> +}
>> +
>> /**
>> * stm32_adc_start_conv() - Start conversions for regular channels.
>> * @adc: stm32 adc instance
>> @@ -870,11 +887,37 @@ static irqreturn_t stm32_adc_trigger_handler(int irq, void *p)
>> {},
>> };
>>
>> +static int stm32_adc_of_get_resolution(struct iio_dev *indio_dev)
>> +{
>> + struct device_node *node = indio_dev->dev.of_node;
>> + struct stm32_adc *adc = iio_priv(indio_dev);
>> + unsigned int i;
>> + u32 res;
>> +
>> + if (of_property_read_u32(node, "assigned-resolution-bits", &res))
>> + res = stm32f4_adc_resolutions[0];
>> +
>> + for (i = 0; i < ARRAY_SIZE(stm32f4_adc_resolutions); i++)
>> + if (res == stm32f4_adc_resolutions[i])
>> + break;
>> + if (i >= ARRAY_SIZE(stm32f4_adc_resolutions)) {
>> + dev_err(&indio_dev->dev, "Bad resolution: %u bits\n", res);
>> + return -EINVAL;
>> + }
>> +
>> + dev_dbg(&indio_dev->dev, "Using %u bits resolution\n", res);
>> + adc->res = i;
>> +
>> + return 0;
>> +}
>> +
>> static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
>> struct iio_chan_spec *chan,
>> const struct stm32_adc_chan_spec *channel,
>> int scan_index)
>> {
>> + struct stm32_adc *adc = iio_priv(indio_dev);
>> +
>> chan->type = channel->type;
>> chan->channel = channel->channel;
>> chan->datasheet_name = channel->name;
>> @@ -883,7 +926,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
>> chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
>> chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
>> chan->scan_type.sign = 'u';
>> - chan->scan_type.realbits = 12;
>> + chan->scan_type.realbits = stm32f4_adc_resolutions[adc->res];
>> chan->scan_type.storagebits = 16;
>> chan->ext_info = stm32_adc_ext_info;
>> }
>> @@ -1022,6 +1065,11 @@ static int stm32_adc_probe(struct platform_device *pdev)
>> return ret;
>> }
>>
>> + ret = stm32_adc_of_get_resolution(indio_dev);
>> + if (ret < 0)
>> + goto err_clk_disable;
>> + stm32_adc_set_res(adc);
>> +
>> ret = stm32_adc_chan_of_init(indio_dev);
>> if (ret < 0)
>> goto err_clk_disable;
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" 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 1/2] dt-bindings: iio: stm32-adc: add option to set resolution
From: Jonathan Cameron @ 2017-04-03 19:45 UTC (permalink / raw)
To: Rob Herring, Fabrice Gasnier
Cc: linux-I+IVW8TIWO2tmTQ+vhA3Yw,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-iio-u79uwXL29TY76Z2rM5mHXA, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, lars-Qo5EllUWu/uELgA04lAiVw,
knaack.h-Mmb7MZpHnFY, pmeerw-jW+XmwGofnusTnJN9+BGXg,
benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A,
benjamin.gaignard-qxv4g6HH51o,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <20170403164600.siab6ghtoeuxokg5@rob-hp-laptop>
On 03/04/17 17:46, Rob Herring wrote:
> On Fri, Mar 31, 2017 at 02:32:37PM +0200, Fabrice Gasnier wrote:
>> Add documentation for 'assigned-resolution-bits' dt optional property.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier-qxv4g6HH51o@public.gmane.org>
>> ---
>> Changes in v2:
>> - rename property from 'st,adc-res' to 'assigned-resolution-bits' so it
>> is more common.
>> ---
>> Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt | 4 ++++
>> 1 file changed, 4 insertions(+)
>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Thanks.
Applied to the togreg branch of iio.git. Will push out as testing for
the autobuilders to have a chance to play with it.
Jonathan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" 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] leds: Add driver for Qualcomm LPG
From: Bjorn Andersson @ 2017-04-03 19:00 UTC (permalink / raw)
To: Jacek Anaszewski
Cc: Pavel Machek, Rob Herring, Richard Purdie, linux-kernel,
linux-leds, linux-arm-msm, Mark Rutland, devicetree
In-Reply-To: <bf999f34-4509-6f0b-602c-f82d50a18e97@gmail.com>
On Fri 31 Mar 02:28 PDT 2017, Jacek Anaszewski wrote:
> Hi Bjorn and Pavel,
>
> On 03/30/2017 09:43 AM, Pavel Machek wrote:
> > Hi!
> >
> >>>> There is a binding for ti,lp55xx, but there's nothing I can reuse from
> >>>> that binding...because it's completely different hardware.
> >>>
> >>> Agreed, if you drop the pattern stuff from the binding, at least for now.
> >>
> >> I do not have a strong preference to expose these knobs in devicetree
> >> and I do fear that finding some common "pattern" bindings that suits
> >> everyone will be very difficult.
> >>
> >> So I'll drop them from the binding for now.
> >
> > Ok.
> >
> >>> If you want driver merged quickly, I believe the best way would be to
> >>> leave out pattern support for now. We can merge the basic driver
> >>> easily to 4.12.
> >>>
> >>
> >> I'm not that much in a hurry and would rather see that we resolve any
> >> outstanding issues with the implementation of the pattern handling.
> >
> > Ok, good.
> >
> >> But regardless of this we still have the problem that the typical
> >> Qualcomm PMIC has 8 LPG-blocks and any triple could be driving a
> >> RGB-LED. So we would have to create some sort of in-driver-wrapper
> >> around any three instances exposing them as a single LED to the user.
> >
> > Yes, I believe we should do the wrapping. In N900 case,
> >
> >> I rather expose the individual channels and make sure that when we
> >> trigger a blink operation or enable a pattern (i.e. the two operations
> >> that do require synchronization) we will perform that synchronization
> >> under the hood.
> >
> > First, we need a way to tell userspace which LEDs are synchronized,
> > because otherwise it will be confusing.
>
> There is one year old discussion [0] about the possible approaches
> to RGB sub-LEDs synchronization problem and patterns in general.
> My last message with API design proposal has been left unanswered.
>
> Probably we continue that discussion here.
>
> Generally Bjorn's drivers touch two yet to be addressed issues:
> - RGB LED support
> - Generic support for patterns
>
> It is likely that both issues can be solved by utilizing trigger
> mechanism. The possible solution to the problem Bjorn tried to
> address with /sys/class/leds/<led>/pattern comma separated list
> could be a trigger with adjustable number of pattern intervals.
>
> The trigger once activated would create a directory with the
> number of files corresponding to the number of requested intervals,
> and then user could write an interval value by writing it to the
> corresponding file. Somehow related approach has been implemented
> for USB port LED trigger:
>
> 0f247626cbbf ('usb: core: Introduce a USB port LED trigger")
>
> In both RGB and pattern approaches we should assess
> if it is acceptable to provide a pattern for trigger name,
> e.g. blink-pattern-{num_intervals}.
>
> If so, then "echo transition-pattern-15" would create a directory
> e.g. transition_intervals with files interval_0 to interval_14,
> that could be adjusted by userspace.
>
Having a RGB-trigger that proxy a accepts a userspace request of a
brightness-tripple and sets the brightness on the individual associated
LEDs sounds reasonable - but should probably be generalized to any
number of LEDs.
A slightly related matter is the question on how to use a single LED for
multiple trigger sources, e.g. how do I get a single LED to show
activity of two MMCs?.
For the patterns I don't know how a trigger for this would look like,
how would setting the pattern of a trigger be propagated down to the
hardware?
> > Second, there are more issues than just patterns with the RGB
> > LED. Most important is ability to set particular colors. You want to
> > set the RGB LED to "white", but that does not mean you can set
> > red=green=blue=1.0. You want color to look the same on LCD and on the
> > LED, which means coefficients for white and some kind of function for
> > brightness-to-PWM conversion.
>
> Shouldn't we leave that entirely to the userspace? Can we come up
> with coefficients that will guarantee the same result on all existing
> LCD devices?
>
How about we just force user space perform the 3 writes and save us the
cost of another trigger in that case? Configuring the brightness of 3
LEDs is not board specific - and even with a RGB-interface we still need
to specify which RGB-LED should be controlled.
Regards,
Bjorn
^ permalink raw reply
* Re: [PATCH] Input: silead - list all supported compatible strings in binding document
From: Dmitry Torokhov @ 2017-04-03 18:59 UTC (permalink / raw)
To: Rob Herring
Cc: Javier Martinez Canillas, linux-kernel, devicetree, Robert Dolca,
Hans de Goede, linux-input, Mark Rutland
In-Reply-To: <20170403152543.im7tbkhfc3lj7lyt@rob-hp-laptop>
On Mon, Apr 03, 2017 at 10:25:43AM -0500, Rob Herring wrote:
> On Wed, Mar 29, 2017 at 02:25:31PM -0400, Javier Martinez Canillas wrote:
> > The driver contains compatible strings for different models, but the DT
> > binding doc only lists one of them. Add the remaining to the document.
> >
> > Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
> > ---
> >
> > .../devicetree/bindings/input/touchscreen/silead_gsl1680.txt | 7 ++++++-
> > 1 file changed, 6 insertions(+), 1 deletion(-)
>
> "dt-bindings: input: ..." is preferred for the subject, but no need to
> respin just for that.
>
> Acked-by: Rob Herring <robh@kernel.org>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH 1/2] leds: Add driver for Qualcomm LPG
From: Bjorn Andersson @ 2017-04-03 18:21 UTC (permalink / raw)
To: Jacek Anaszewski
Cc: Pavel Machek, Rob Herring, Richard Purdie, linux-kernel,
linux-leds, linux-arm-msm, Mark Rutland, devicetree
In-Reply-To: <1192806d-13bf-3b5c-4179-b7795737ed40@gmail.com>
On Sun 02 Apr 05:54 PDT 2017, Jacek Anaszewski wrote:
> On 03/31/2017 11:28 AM, Jacek Anaszewski wrote:
> > Hi Bjorn and Pavel,
> >
> > On 03/30/2017 09:43 AM, Pavel Machek wrote:
[..]
> > In both RGB and pattern approaches we should assess
> > if it is acceptable to provide a pattern for trigger name,
> > e.g. blink-pattern-{num_intervals}.
>
> Actually we could achieve the goal by listing all available pattern
> configurations for given LED class device, so in case of Qualcomm LPG
> driver we could have transition-pattern-1 to transition-pattern-15
> listed after executing "cat trigger".
>
There's a common pattern-table of 24 (or 64) entries, that is shared
among the 8 LPGs (each LPG simply has to indices pointing into the
shared table). Each entry in the table holds a value between 0 and 511.
So that's a lot of "available pattern configurations".
Unless you go with the path Qualcomm did in their downstream driver,
where the table is filled statically from DeviceTree and each LPG is
statically configured with some range from the table. But I don't like
this and as far as I can tell neither do you guys.
And lastly the request is to create a common interface for userspace to
control patterns among different LED hardware and I do not see how this
would be acceptable to the LP55xx users.
Perhaps I'm not getting what you're proposing?
> In case of RGB trigger we would have qcom-rgb among other triggers
> listed in a result of executing "cat trigger". Then qcom-rgb-1 LED class
> device could appear in /sys/class/leds, which would expose files
> red-led-name, green-led-name and blue-led-name. Once all files are
> initialized with appropriate LED class device names the RGB brightness
> could be updated synchronously in all involved LEDs by executing
> e.g. "echo 1 > update_color". Of course all LEDs that set qcom-rgb
> trigger would have to avoid changing device state on write to
> their brightness file.
>
I don't see that the brightness of the individual LEDs is the problem,
writing individual colors to the 3 LEDs in a serial fashion isn't
user-noticeable. What is a problem is if you start a pulse of some
combined color it's important to synchronize the starting of the pattern
generator, of you will have a color that shifts over time - or in the
case of blink where the colors get out of sync.
And as I said, I suggest that we just make it possible to configure any
LPG channel to be grouped with any others and within a group we always
synchronize the pattern-generator when enabling any LED.
The issue left open is that we expose 3 independent LEDs to userspace
and it seems desired to expose it as a single "RGB" LED. Providing a
"RGB trigger" that any LED in the system can be associated with and then
have that trigger wrap the individual LEDs sounds like a reasonable path
forward. But if we're not going to do things like color "calibration" it
feels like we're replacing the 3 writes in userspace with a single write
and then 3 calls in the kernel; i.e. the only win in my view is some
conceptual benefit.
> I wonder if I'm not missing some vital constraints here that could
> make this design unfeasible.
>
Regardless of how we expose RGBs to userspace, the 8 LPG hardware blocks
are independent of each other. The fact that they end up controlling
something that is perceived by the human eye as some mixed color is to
me a matter of system integration, and as such should not convolute the
implementation of the individual instances.
Regards,
Bjorn
^ permalink raw reply
* [PATCH v2] dt-bindings: arm,nvic: Binding for ARM NVIC interrupt controller on Cortex-M
From: Kumar Gala @ 2017-04-03 17:58 UTC (permalink / raw)
To: Rob Herring; +Cc: Kumar Gala, Device Tree Mailing List, Mark Rutland
Signed-off-by: Kumar Gala <kumar.gala-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
* Dropped arm,nvic, fixed up example to match
.../bindings/interrupt-controller/arm,nvic.txt | 36 ++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt
new file mode 100644
index 0000000..386ab37
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt
@@ -0,0 +1,36 @@
+* ARM Nested Vector Interrupt Controller (NVIC)
+
+The NVIC provides an interrupt controller that is tightly coupled to
+Cortex-M based processor cores. The NVIC implemented on different SoCs
+vary in the number of interrupts and priority bits per interrupt.
+
+Main node required properties:
+
+- compatible : should be one of:
+ "arm,v6m-nvic"
+ "arm,v7m-nvic"
+ "arm,v8m-nvic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The type shall be a <u32> and the value shall be 2.
+
+ The 1st cell contains the interrupt number for the interrupt type.
+
+ The 2nd cell is the priority of the interrupt.
+
+- reg : Specifies base physical address(s) and size of the NVIC registers.
+ This is at a fixed address (0xe000e100) and size (0xc00).
+
+- arm,num-irq-priority-bits: The number of priority bits implemented by the
+ given SoC
+
+Example:
+
+ intc: interrupt-controller@e000e100 {
+ compatible = "arm,v7m-nvic";
+ #interrupt-cells = <2>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0xe000e100 0xc00>;
+ arm,num-irq-priority-bits = <4>;
+ };
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH] dt-bindings: arm,nvic: Binding for ARM NVIC interrupt controller on Cortex-M
From: Kumar Gala @ 2017-04-03 17:58 UTC (permalink / raw)
To: Rob Herring; +Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170403133219.hgnyxw4kwf4medhn@rob-hp-laptop>
> On Apr 3, 2017, at 8:32 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
> On Mon, Mar 27, 2017 at 01:09:05PM -0500, Kumar Gala wrote:
>> Signed-off-by: Kumar Gala <kumar.gala-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>> Note: This is a new binding and not used by the linux kernel code right now for
>> the nvic. The intent would be to support both the current 'arm,armv7m-nvic'
>> compatible and this binding in the code in the future. The 'arm,armv7m-nvic'
>> doesnt have any binding spec covering it today.
>>
>> .../bindings/interrupt-controller/arm,nvic.txt | 37 ++++++++++++++++++++++
>> 1 file changed, 37 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt
>> new file mode 100644
>> index 0000000..60ee89c
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt
>> @@ -0,0 +1,37 @@
>> +* ARM Nested Vector Interrupt Controller (NVIC)
>> +
>> +The NVIC provides an interrupt controller that is tightly coupled to
>> +Cortex-M based processor cores. The NVIC implemented on different SoCs
>> +vary in the number of interrupts and priority bits per interrupt.
>> +
>> +Main node required properties:
>> +
>> +- compatible : should be one of:
>> + "arm,v6m-nvic"
>> + "arm,v7m-nvic"
>> + "arm,v8m-nvic"
>> + "arm,nvic"
>
> I'd drop this last one.
done
>
>> +- interrupt-controller : Identifies the node as an interrupt controller
>> +- #interrupt-cells : Specifies the number of cells needed to encode an
>> + interrupt source. The type shall be a <u32> and the value shall be 2.
>> +
>> + The 1st cell contains the interrupt number for the interrupt type.
>> +
>> + The 2nd cell is the priority of the interrupt.
>
> No level/edge flags needed?
Nope, it seems to be implied in how the IRQs get wired up to the NVIC.
>
>> +
>> +- reg : Specifies base physical address(s) and size of the NVIC registers.
>> + This is at a fixed address (0xe000e100) and size (0xc00).
>> +
>> +- arm,num-irq-priority-bits: The number of priority bits implemented by the
>> + given SoC
>> +
>> +Example:
>> +
>> + intc: interrupt-controller@e000e100 {
>> + compatible = "arm,nvic";
>> + #interrupt-cells = <2>;
>> + #address-cells = <1>;
>> + interrupt-controller;
>> + reg = <0xe000e100 0xc00>;
>> + arm,num-irq-priority-bits = <4>;
>> + };
>> --
>> 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 v4] ASoC: Add support for Maxim Integrated MAX98927 Amplifier
From: Ryan Lee @ 2017-04-03 17:24 UTC (permalink / raw)
To: Rob Herring
Cc: Liam Girdwood, Mark Brown, mark.rutland-5wv7dgnIgG8,
perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k, Kuninori Morimoto,
Arnd Bergmann,
ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
lars-Qo5EllUWu/uELgA04lAiVw, bardliao-Rasf1IRRPZFBDgjK7y7TUQ,
nh6z-fFIq/eER6g8, KCHSU0-KrzQf0k3Iz9BDgjK7y7TUQ, Axel Lin,
romain.perier-ZGY8ohtN/8qB+jHODAdFcQ, Srinivas Kandagatla,
oder_chiou-Rasf1IRRPZFBDgjK7y7TUQ,
Paul.Handrigan-jGc1dHjMKG3QT0dZR+AlfA,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Dylan Reid
In-Reply-To: <20170403163053.u6b3yadkfyh4z7h5@rob-hp-laptop>
On Mon, Apr 3, 2017 at 9:30 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Mar 31, 2017 at 10:16:34AM +0900, Ryan Lee wrote:
>> Signed-off-by: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
>> ---
>>
>> Changes since v4:
>> * Removed support for SND_SOC_DAIFMT_CBS_CFM.
>> * Fixed coding style for indention.
>> * Removed variables if it has only one user.
>> * Assigned ch_size directly.
>> * Removed oring.
>> * Put the return false in the switch statement.
>> * Removed 'Monomix Output' and 'Speaker Source' controls.
>> * Modified control names per control-names.rst.
>> * Moved Revision ID check code to i2c_probe function.
>> * Added 'Current Limit' control.
>> * Removed 'devm__kfree' function.
>>
>> Changes since v3:
>> * Combined MAX98926 and MAX98927 binding. Kept existing property name.
>
> This looks fine, but:
>
>> 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 | 841 +++++++++++++++++++++
>> sound/soc/codecs/max98927.h | 272 +++++++
>> 7 files changed, 1161 insertions(+), 54 deletions(-)
>> delete mode 100644 Documentation/devicetree/bindings/sound/max98925.txt
>> delete mode 100644 Documentation/devicetree/bindings/sound/max98926.txt
>> create mode 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
>
> These should all be 644 mode.
I've changed the mode to 644. Thank you.
>
> 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
* [PATCH v5] ASoC: Add support for Maxim Integrated MAX98927 Amplifier
From: Ryan Lee @ 2017-04-03 17:23 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 v5
* Changed mode to 644.
Changes since v4:
* Removed support for SND_SOC_DAIFMT_CBS_CFM.
* Fixed coding style for indention.
* Removed variables if it has only one user.
* Assigned ch_size directly.
* Removed oring.
* Put the return false in the switch statement.
* Removed 'Monomix Output' and 'Speaker Source' controls.
* Modified control names per control-names.rst.
* Moved Revision ID check code to i2c_probe function.
* Added 'Current Limit' control.
* Removed 'devm__kfree' function.
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 | 841 +++++++++++++++++++++
sound/soc/codecs/max98927.h | 272 +++++++
7 files changed, 1161 insertions(+), 54 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/sound/max98925.txt
delete mode 100644 Documentation/devicetree/bindings/sound/max98926.txt
create mode 100644 Documentation/devicetree/bindings/sound/max9892x.txt
create mode 100644 sound/soc/codecs/max98927.c
create mode 100644 sound/soc/codecs/max98927.h
diff --git a/Documentation/devicetree/bindings/sound/max98925.txt b/Documentation/devicetree/bindings/sound/max98925.txt
deleted file mode 100644
index 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 100644
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
index e49e9da..cbdc8aa 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -89,6 +89,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9867 if I2C
select SND_SOC_MAX98925 if I2C
select SND_SOC_MAX98926 if I2C
+ select SND_SOC_MAX98927 if I2C
select SND_SOC_MAX9850 if I2C
select SND_SOC_MAX9860 if I2C
select SND_SOC_MAX9768 if I2C
@@ -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
index 1796cb9..187a639 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -84,6 +84,7 @@ snd-soc-max98371-objs := max98371.o
snd-soc-max9867-objs := max9867.o
snd-soc-max98925-objs := max98925.o
snd-soc-max98926-objs := max98926.o
+snd-soc-max98927-objs := max98927.o
snd-soc-max9850-objs := max9850.o
snd-soc-max9860-objs := max9860.o
snd-soc-mc13783-objs := mc13783.o
@@ -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 100644
index 0000000..b5ee294
--- /dev/null
+++ b/sound/soc/codecs/max98927.c
@@ -0,0 +1,841 @@
+/*
+ * max98927.c -- MAX98927 ALSA Soc Audio driver
+ *
+ * Copyright (C) 2016 Maxim Integrated Products
+ * Author: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/acpi.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/cdev.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <sound/tlv.h>
+#include "max98927.h"
+
+static struct reg_default max98927_reg[] = {
+ {MAX98927_R0001_INT_RAW1, 0x00},
+ {MAX98927_R0002_INT_RAW2, 0x00},
+ {MAX98927_R0003_INT_RAW3, 0x00},
+ {MAX98927_R0004_INT_STATE1, 0x00},
+ {MAX98927_R0005_INT_STATE2, 0x00},
+ {MAX98927_R0006_INT_STATE3, 0x00},
+ {MAX98927_R0007_INT_FLAG1, 0x00},
+ {MAX98927_R0008_INT_FLAG2, 0x00},
+ {MAX98927_R0009_INT_FLAG3, 0x00},
+ {MAX98927_R000A_INT_EN1, 0x00},
+ {MAX98927_R000B_INT_EN2, 0x00},
+ {MAX98927_R000C_INT_EN3, 0x00},
+ {MAX98927_R000D_INT_FLAG_CLR1, 0x00},
+ {MAX98927_R000E_INT_FLAG_CLR2, 0x00},
+ {MAX98927_R000F_INT_FLAG_CLR3, 0x00},
+ {MAX98927_R0010_IRQ_CTRL, 0x00},
+ {MAX98927_R0011_CLK_MON, 0x00},
+ {MAX98927_R0012_WDOG_CTRL, 0x00},
+ {MAX98927_R0013_WDOG_RST, 0x00},
+ {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x00},
+ {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x00},
+ {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x00},
+ {MAX98927_R0017_PIN_CFG, 0x55},
+ {MAX98927_R0018_PCM_RX_EN_A, 0x00},
+ {MAX98927_R0019_PCM_RX_EN_B, 0x00},
+ {MAX98927_R001A_PCM_TX_EN_A, 0x00},
+ {MAX98927_R001B_PCM_TX_EN_B, 0x00},
+ {MAX98927_R001C_PCM_TX_HIZ_CTRL_A, 0x00},
+ {MAX98927_R001D_PCM_TX_HIZ_CTRL_B, 0x00},
+ {MAX98927_R001E_PCM_TX_CH_SRC_A, 0x00},
+ {MAX98927_R001F_PCM_TX_CH_SRC_B, 0x00},
+ {MAX98927_R0020_PCM_MODE_CFG, 0x40},
+ {MAX98927_R0021_PCM_MASTER_MODE, 0x00},
+ {MAX98927_R0022_PCM_CLK_SETUP, 0x22},
+ {MAX98927_R0023_PCM_SR_SETUP1, 0x00},
+ {MAX98927_R0024_PCM_SR_SETUP2, 0x00},
+ {MAX98927_R0025_PCM_TO_SPK_MONOMIX_A, 0x00},
+ {MAX98927_R0026_PCM_TO_SPK_MONOMIX_B, 0x00},
+ {MAX98927_R0027_ICC_RX_EN_A, 0x00},
+ {MAX98927_R0028_ICC_RX_EN_B, 0x00},
+ {MAX98927_R002B_ICC_TX_EN_A, 0x00},
+ {MAX98927_R002C_ICC_TX_EN_B, 0x00},
+ {MAX98927_R002E_ICC_HIZ_MANUAL_MODE, 0x00},
+ {MAX98927_R002F_ICC_TX_HIZ_EN_A, 0x00},
+ {MAX98927_R0030_ICC_TX_HIZ_EN_B, 0x00},
+ {MAX98927_R0031_ICC_LNK_EN, 0x00},
+ {MAX98927_R0032_PDM_TX_EN, 0x00},
+ {MAX98927_R0033_PDM_TX_HIZ_CTRL, 0x00},
+ {MAX98927_R0034_PDM_TX_CTRL, 0x00},
+ {MAX98927_R0035_PDM_RX_CTRL, 0x00},
+ {MAX98927_R0036_AMP_VOL_CTRL, 0x00},
+ {MAX98927_R0037_AMP_DSP_CFG, 0x02},
+ {MAX98927_R0038_TONE_GEN_DC_CFG, 0x00},
+ {MAX98927_R0039_DRE_CTRL, 0x01},
+ {MAX98927_R003A_AMP_EN, 0x00},
+ {MAX98927_R003B_SPK_SRC_SEL, 0x00},
+ {MAX98927_R003C_SPK_GAIN, 0x00},
+ {MAX98927_R003D_SSM_CFG, 0x01},
+ {MAX98927_R003E_MEAS_EN, 0x00},
+ {MAX98927_R003F_MEAS_DSP_CFG, 0x04},
+ {MAX98927_R0040_BOOST_CTRL0, 0x00},
+ {MAX98927_R0041_BOOST_CTRL3, 0x00},
+ {MAX98927_R0042_BOOST_CTRL1, 0x00},
+ {MAX98927_R0043_MEAS_ADC_CFG, 0x00},
+ {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x00},
+ {MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00},
+ {MAX98927_R0046_ADC_CH0_DIVIDE, 0x00},
+ {MAX98927_R0047_ADC_CH1_DIVIDE, 0x00},
+ {MAX98927_R0048_ADC_CH2_DIVIDE, 0x00},
+ {MAX98927_R0049_ADC_CH0_FILT_CFG, 0x00},
+ {MAX98927_R004A_ADC_CH1_FILT_CFG, 0x00},
+ {MAX98927_R004B_ADC_CH2_FILT_CFG, 0x00},
+ {MAX98927_R004C_MEAS_ADC_CH0_READ, 0x00},
+ {MAX98927_R004D_MEAS_ADC_CH1_READ, 0x00},
+ {MAX98927_R004E_MEAS_ADC_CH2_READ, 0x00},
+ {MAX98927_R0051_BROWNOUT_STATUS, 0x00},
+ {MAX98927_R0052_BROWNOUT_EN, 0x00},
+ {MAX98927_R0053_BROWNOUT_INFINITE_HOLD, 0x00},
+ {MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR, 0x00},
+ {MAX98927_R0055_BROWNOUT_LVL_HOLD, 0x00},
+ {MAX98927_R005A_BROWNOUT_LVL1_THRESH, 0x00},
+ {MAX98927_R005B_BROWNOUT_LVL2_THRESH, 0x00},
+ {MAX98927_R005C_BROWNOUT_LVL3_THRESH, 0x00},
+ {MAX98927_R005D_BROWNOUT_LVL4_THRESH, 0x00},
+ {MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS, 0x00},
+ {MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL, 0x00},
+ {MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL, 0x00},
+ {MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE, 0x00},
+ {MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT, 0x00},
+ {MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1, 0x00},
+ {MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2, 0x00},
+ {MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3, 0x00},
+ {MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT, 0x00},
+ {MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1, 0x00},
+ {MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2, 0x00},
+ {MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3, 0x00},
+ {MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT, 0x00},
+ {MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1, 0x00},
+ {MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2, 0x00},
+ {MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3, 0x00},
+ {MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT, 0x00},
+ {MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1, 0x00},
+ {MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2, 0x00},
+ {MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3, 0x00},
+ {MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, 0x00},
+ {MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY, 0x00},
+ {MAX98927_R0084_ENV_TRACK_REL_RATE, 0x00},
+ {MAX98927_R0085_ENV_TRACK_HOLD_RATE, 0x00},
+ {MAX98927_R0086_ENV_TRACK_CTRL, 0x00},
+ {MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ, 0x00},
+ {MAX98927_R00FF_GLOBAL_SHDN, 0x00},
+ {MAX98927_R0100_SOFT_RESET, 0x00},
+ {MAX98927_R01FF_REV_ID, 0x40},
+};
+
+static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ unsigned int mode = 0;
+ unsigned int format = 0;
+ unsigned int invert = 0;
+
+ dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ mode = MAX98927_PCM_MASTER_MODE_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ max98927->master = true;
+ mode = MAX98927_PCM_MASTER_MODE_MASTER;
+ break;
+ default:
+ dev_err(codec->dev, "DAI clock mode unsupported");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0021_PCM_MASTER_MODE,
+ MAX98927_PCM_MASTER_MODE_MASK,
+ mode);
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
+ break;
+ default:
+ dev_err(codec->dev, "DAI invert mode unsupported");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0020_PCM_MODE_CFG,
+ MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE,
+ invert);
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ max98927->iface |= SND_SOC_DAIFMT_I2S;
+ format = MAX98927_PCM_FORMAT_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
+ format = MAX98927_PCM_FORMAT_LJ;
+ break;
+ case SND_SOC_DAIFMT_PDM:
+ max98927->iface |= SND_SOC_DAIFMT_PDM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* pcm channel configuration */
+ if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0018_PCM_RX_EN_A,
+ MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
+ MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN);
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0020_PCM_MODE_CFG,
+ MAX98927_PCM_MODE_CFG_FORMAT_MASK,
+ format << MAX98927_PCM_MODE_CFG_FORMAT_SHIFT);
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R003B_SPK_SRC_SEL,
+ MAX98927_SPK_SRC_MASK, 0);
+
+ } else
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0018_PCM_RX_EN_A,
+ MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
+
+ /* pdm channel configuration */
+ if (max98927->iface & SND_SOC_DAIFMT_PDM) {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0035_PDM_RX_CTRL,
+ MAX98927_PDM_RX_EN_MASK, 1);
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R003B_SPK_SRC_SEL,
+ MAX98927_SPK_SRC_MASK, 3);
+ } else
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0035_PDM_RX_CTRL,
+ MAX98927_PDM_RX_EN_MASK, 0);
+ return 0;
+}
+
+/* codec MCLK rate in master mode */
+static const int rate_table[] = {
+ 5644800, 6000000, 6144000, 6500000,
+ 9600000, 11289600, 12000000, 12288000,
+ 13000000, 19200000,
+};
+
+static int max98927_set_clock(struct max98927_priv *max98927,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_codec *codec = max98927->codec;
+ /* BCLK/LRCLK ratio calculation */
+ int blr_clk_ratio = params_channels(params) * max98927->ch_size;
+ int value;
+
+ if (max98927->master) {
+ int i;
+ /* match rate to closest value */
+ for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
+ if (rate_table[i] >= max98927->sysclk)
+ break;
+ }
+ if (i == ARRAY_SIZE(rate_table)) {
+ dev_err(codec->dev, "failed to find proper clock rate.\n");
+ return -EINVAL;
+ }
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0021_PCM_MASTER_MODE,
+ MAX98927_PCM_MASTER_MODE_MCLK_MASK,
+ i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
+ }
+
+ switch (blr_clk_ratio) {
+ case 32:
+ value = 2;
+ break;
+ case 48:
+ value = 3;
+ break;
+ case 64:
+ value = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0022_PCM_CLK_SETUP,
+ MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+ value);
+ return 0;
+}
+
+static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ unsigned int sampling_rate = 0;
+ unsigned int chan_sz = 0;
+
+ /* pcm mode configuration */
+ switch (snd_pcm_format_width(params_format(params))) {
+ case 16:
+ chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
+ break;
+ case 24:
+ chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
+ break;
+ case 32:
+ chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
+ break;
+ default:
+ dev_err(codec->dev, "format unsupported %d",
+ params_format(params));
+ goto err;
+ }
+
+ max98927->ch_size = snd_pcm_format_width(params_format(params));
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0020_PCM_MODE_CFG,
+ MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
+
+ dev_dbg(codec->dev, "format supported %d",
+ params_format(params));
+
+ /* sampling rate configuration */
+ switch (params_rate(params)) {
+ case 8000:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_8000;
+ break;
+ case 11025:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_11025;
+ break;
+ case 12000:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_12000;
+ break;
+ case 16000:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_16000;
+ break;
+ case 22050:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_22050;
+ break;
+ case 24000:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_24000;
+ break;
+ case 32000:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_32000;
+ break;
+ case 44100:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_44100;
+ break;
+ case 48000:
+ sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
+ break;
+ default:
+ dev_err(codec->dev, "rate %d not supported\n",
+ params_rate(params));
+ goto err;
+ }
+ /* set DAI_SR to correct LRCLK frequency */
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0023_PCM_SR_SETUP1,
+ MAX98927_PCM_SR_SET1_SR_MASK,
+ sampling_rate);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0024_PCM_SR_SETUP2,
+ MAX98927_PCM_SR_SET2_SR_MASK,
+ sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
+
+ /* set sampling rate of IV */
+ if (max98927->interleave_mode &&
+ sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0024_PCM_SR_SETUP2,
+ MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
+ sampling_rate - 3);
+ else
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0024_PCM_SR_SETUP2,
+ MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
+ sampling_rate);
+ return max98927_set_clock(max98927, params);
+err:
+ return -EINVAL;
+}
+
+#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
+
+#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ max98927->sysclk = freq;
+ return 0;
+}
+
+static const struct snd_soc_dai_ops max98927_dai_ops = {
+ .set_sysclk = max98927_dai_set_sysclk,
+ .set_fmt = max98927_dai_set_fmt,
+ .hw_params = max98927_dai_hw_params,
+};
+
+static int max98927_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R003A_AMP_EN,
+ MAX98927_AMP_EN_MASK, 1);
+ /* enable VMON and IMON */
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R003E_MEAS_EN,
+ MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
+ MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R00FF_GLOBAL_SHDN,
+ MAX98927_GLOBAL_EN_MASK, 1);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R00FF_GLOBAL_SHDN,
+ MAX98927_GLOBAL_EN_MASK, 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R003A_AMP_EN,
+ MAX98927_AMP_EN_MASK, 0);
+ /* disable VMON and IMON */
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R003E_MEAS_EN,
+ MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
+ break;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static const char * const max98927_switch_text[] = {
+ "Left", "Right", "LeftRight"};
+
+static const struct soc_enum dai_sel_enum =
+ SOC_ENUM_SINGLE(MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
+ MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
+ 3, max98927_switch_text);
+
+static const struct snd_kcontrol_new max98927_dai_controls =
+ SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
+
+static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
+ 0, 0, max98927_dac_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
+ &max98927_dai_controls),
+ SND_SOC_DAPM_OUTPUT("BE_OUT"),
+};
+
+static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
+static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
+
+static bool max98927_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX98927_R0001_INT_RAW1 ... MAX98927_R0028_ICC_RX_EN_B:
+ case MAX98927_R002B_ICC_TX_EN_A ... MAX98927_R002C_ICC_TX_EN_B:
+ case MAX98927_R002E_ICC_HIZ_MANUAL_MODE
+ ... MAX98927_R004E_MEAS_ADC_CH2_READ:
+ case MAX98927_R0051_BROWNOUT_STATUS
+ ... MAX98927_R0055_BROWNOUT_LVL_HOLD:
+ case MAX98927_R005A_BROWNOUT_LVL1_THRESH
+ ... MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE:
+ case MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT
+ ... MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
+ case MAX98927_R00FF_GLOBAL_SHDN:
+ case MAX98927_R0100_SOFT_RESET:
+ case MAX98927_R01FF_REV_ID:
+ return true;
+ default:
+ return false;
+ }
+};
+
+static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const char * const max98927_boost_voltage_text[] = {
+ "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
+ "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
+ "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
+ "9.5V", "9.625V", "9.75V", "9.875V", "10V"
+};
+
+static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
+ MAX98927_R0040_BOOST_CTRL0, 0,
+ max98927_boost_voltage_text);
+
+static const char * const max98927_current_limit_text[] = {
+ "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
+ "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
+ "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
+ "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
+};
+
+static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
+ MAX98927_R0042_BOOST_CTRL1, 1,
+ max98927_current_limit_text);
+
+static const struct snd_kcontrol_new max98927_snd_controls[] = {
+ SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
+ 0, 6, 0,
+ max98927_spk_tlv),
+ SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
+ 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
+ max98927_digital_tlv),
+ SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
+ MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
+ SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
+ MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
+ SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
+ MAX98927_DRE_EN_SHIFT, 1, 0),
+ SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
+ MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
+ SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
+ SOC_ENUM("Current Limit", max98927_current_limit),
+};
+
+static const struct snd_soc_dapm_route max98927_audio_map[] = {
+ {"Amp Enable", NULL, "DAI_OUT"},
+ {"DAI Sel Mux", "Left", "Amp Enable"},
+ {"DAI Sel Mux", "Right", "Amp Enable"},
+ {"DAI Sel Mux", "LeftRight", "Amp Enable"},
+ {"BE_OUT", NULL, "DAI Sel Mux"},
+};
+
+static struct snd_soc_dai_driver max98927_dai[] = {
+ {
+ .name = "max98927-aif1",
+ .playback = {
+ .stream_name = "HiFi Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MAX98927_RATES,
+ .formats = MAX98927_FORMATS,
+ },
+ .capture = {
+ .stream_name = "HiFi Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MAX98927_RATES,
+ .formats = MAX98927_FORMATS,
+ },
+ .ops = &max98927_dai_ops,
+ }
+};
+
+static int max98927_probe(struct snd_soc_codec *codec)
+{
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+
+ max98927->codec = codec;
+ codec->control_data = max98927->regmap;
+ codec->cache_bypass = 1;
+
+ /* Software Reset */
+ regmap_write(max98927->regmap,
+ MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
+
+ /* IV default slot configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
+ 0x80);
+ regmap_write(max98927->regmap,
+ MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
+ 0x1);
+ /* Set inital volume (+13dB) */
+ regmap_write(max98927->regmap,
+ MAX98927_R0036_AMP_VOL_CTRL,
+ 0x38);
+ regmap_write(max98927->regmap,
+ MAX98927_R003C_SPK_GAIN,
+ 0x05);
+ /* Enable DC blocker */
+ regmap_write(max98927->regmap,
+ MAX98927_R0037_AMP_DSP_CFG,
+ 0x03);
+ /* Enable IMON VMON DC blocker */
+ regmap_write(max98927->regmap,
+ MAX98927_R003F_MEAS_DSP_CFG,
+ 0xF7);
+ /* Boost Output Voltage & Current limit */
+ regmap_write(max98927->regmap,
+ MAX98927_R0040_BOOST_CTRL0,
+ 0x1C);
+ regmap_write(max98927->regmap,
+ MAX98927_R0042_BOOST_CTRL1,
+ 0x3E);
+ /* Measurement ADC config */
+ regmap_write(max98927->regmap,
+ MAX98927_R0043_MEAS_ADC_CFG,
+ 0x04);
+ regmap_write(max98927->regmap,
+ MAX98927_R0044_MEAS_ADC_BASE_MSB,
+ 0x00);
+ regmap_write(max98927->regmap,
+ MAX98927_R0045_MEAS_ADC_BASE_LSB,
+ 0x24);
+ /* Brownout Level */
+ regmap_write(max98927->regmap,
+ MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
+ 0x06);
+ /* Envelope Tracking configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
+ 0x08);
+ regmap_write(max98927->regmap,
+ MAX98927_R0086_ENV_TRACK_CTRL,
+ 0x01);
+ regmap_write(max98927->regmap,
+ MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
+ 0x10);
+
+ /* voltage, current slot configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R001E_PCM_TX_CH_SRC_A,
+ (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
+ max98927->v_l_slot)&0xFF);
+
+ if (max98927->v_l_slot < 8) {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ 1 << max98927->v_l_slot, 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001A_PCM_TX_EN_A,
+ 1 << max98927->v_l_slot,
+ 1 << max98927->v_l_slot);
+ } else {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ 1 << (max98927->v_l_slot - 8), 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001B_PCM_TX_EN_B,
+ 1 << (max98927->v_l_slot - 8),
+ 1 << (max98927->v_l_slot - 8));
+ }
+
+ if (max98927->i_l_slot < 8) {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ 1 << max98927->i_l_slot, 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001A_PCM_TX_EN_A,
+ 1 << max98927->i_l_slot,
+ 1 << max98927->i_l_slot);
+ } else {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ 1 << (max98927->i_l_slot - 8), 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001B_PCM_TX_EN_B,
+ 1 << (max98927->i_l_slot - 8),
+ 1 << (max98927->i_l_slot - 8));
+ }
+
+ /* Set interleave mode */
+ if (max98927->interleave_mode)
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001F_PCM_TX_CH_SRC_B,
+ MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
+ MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
+ return 0;
+}
+
+static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
+ .probe = max98927_probe,
+ .component_driver = {
+ .controls = max98927_snd_controls,
+ .num_controls = ARRAY_SIZE(max98927_snd_controls),
+ .dapm_widgets = max98927_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
+ .dapm_routes = max98927_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
+ },
+};
+
+static const struct regmap_config max98927_regmap = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = MAX98927_R01FF_REV_ID,
+ .reg_defaults = max98927_reg,
+ .num_reg_defaults = ARRAY_SIZE(max98927_reg),
+ .readable_reg = max98927_readable_register,
+ .volatile_reg = max98927_volatile_reg,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static void max98927_slot_config(struct i2c_client *i2c,
+ struct max98927_priv *max98927)
+{
+ int value;
+
+ if (!of_property_read_u32(i2c->dev.of_node,
+ "vmon-slot-no", &value))
+ max98927->v_l_slot = value & 0xF;
+ else
+ max98927->v_l_slot = 0;
+ if (!of_property_read_u32(i2c->dev.of_node,
+ "imon-slot-no", &value))
+ max98927->i_l_slot = value & 0xF;
+ else
+ max98927->i_l_slot = 1;
+}
+
+static int max98927_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+
+ int ret = 0, value;
+ int reg = 0;
+ struct max98927_priv *max98927 = NULL;
+
+ max98927 = devm_kzalloc(&i2c->dev,
+ sizeof(*max98927), GFP_KERNEL);
+
+ if (!max98927) {
+ ret = -ENOMEM;
+ return ret;
+ }
+ i2c_set_clientdata(i2c, max98927);
+
+ /* update interleave mode info */
+ if (!of_property_read_u32(i2c->dev.of_node,
+ "interleave_mode", &value)) {
+ if (value > 0)
+ max98927->interleave_mode = 1;
+ else
+ max98927->interleave_mode = 0;
+ } else
+ max98927->interleave_mode = 0;
+
+ /* regmap initialization */
+ max98927->regmap
+ = devm_regmap_init_i2c(i2c, &max98927_regmap);
+ if (IS_ERR(max98927->regmap)) {
+ ret = PTR_ERR(max98927->regmap);
+ dev_err(&i2c->dev,
+ "Failed to allocate regmap: %d\n", ret);
+ return ret;
+ }
+
+ /* Check Revision ID */
+ ret = regmap_read(max98927->regmap,
+ MAX98927_R01FF_REV_ID, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev,
+ "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
+ return ret;
+ }
+ dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
+
+ /* voltage/current slot configuration */
+ max98927_slot_config(i2c, max98927);
+
+ /* codec registeration */
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
+ max98927_dai, ARRAY_SIZE(max98927_dai));
+ if (ret < 0)
+ dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+
+ return ret;
+}
+
+static int max98927_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+static const struct i2c_device_id max98927_i2c_id[] = {
+ { "max98927", 0},
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
+
+#if defined(CONFIG_OF)
+static const struct of_device_id max98927_of_match[] = {
+ { .compatible = "maxim,max98927", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max98927_of_match);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id max98927_acpi_match[] = {
+ { "MX98927", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
+#endif
+
+static struct i2c_driver max98927_i2c_driver = {
+ .driver = {
+ .name = "max98927",
+ .of_match_table = of_match_ptr(max98927_of_match),
+ .acpi_match_table = ACPI_PTR(max98927_acpi_match),
+ .pm = NULL,
+ },
+ .probe = max98927_i2c_probe,
+ .remove = max98927_i2c_remove,
+ .id_table = max98927_i2c_id,
+};
+
+module_i2c_driver(max98927_i2c_driver)
+
+MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
+MODULE_AUTHOR("Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
new file mode 100644
index 0000000..ece6a60
--- /dev/null
+++ b/sound/soc/codecs/max98927.h
@@ -0,0 +1,272 @@
+/*
+ * max98927.h -- MAX98927 ALSA Soc Audio driver
+ *
+ * Copyright 2013-15 Maxim Integrated Products
+ * Author: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef _MAX98927_H
+#define _MAX98927_H
+
+/* Register Values */
+#define MAX98927_R0001_INT_RAW1 0x0001
+#define MAX98927_R0002_INT_RAW2 0x0002
+#define MAX98927_R0003_INT_RAW3 0x0003
+#define MAX98927_R0004_INT_STATE1 0x0004
+#define MAX98927_R0005_INT_STATE2 0x0005
+#define MAX98927_R0006_INT_STATE3 0x0006
+#define MAX98927_R0007_INT_FLAG1 0x0007
+#define MAX98927_R0008_INT_FLAG2 0x0008
+#define MAX98927_R0009_INT_FLAG3 0x0009
+#define MAX98927_R000A_INT_EN1 0x000A
+#define MAX98927_R000B_INT_EN2 0x000B
+#define MAX98927_R000C_INT_EN3 0x000C
+#define MAX98927_R000D_INT_FLAG_CLR1 0x000D
+#define MAX98927_R000E_INT_FLAG_CLR2 0x000E
+#define MAX98927_R000F_INT_FLAG_CLR3 0x000F
+#define MAX98927_R0010_IRQ_CTRL 0x0010
+#define MAX98927_R0011_CLK_MON 0x0011
+#define MAX98927_R0012_WDOG_CTRL 0x0012
+#define MAX98927_R0013_WDOG_RST 0x0013
+#define MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH 0x0014
+#define MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH 0x0015
+#define MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS 0x0016
+#define MAX98927_R0017_PIN_CFG 0x0017
+#define MAX98927_R0018_PCM_RX_EN_A 0x0018
+#define MAX98927_R0019_PCM_RX_EN_B 0x0019
+#define MAX98927_R001A_PCM_TX_EN_A 0x001A
+#define MAX98927_R001B_PCM_TX_EN_B 0x001B
+#define MAX98927_R001C_PCM_TX_HIZ_CTRL_A 0x001C
+#define MAX98927_R001D_PCM_TX_HIZ_CTRL_B 0x001D
+#define MAX98927_R001E_PCM_TX_CH_SRC_A 0x001E
+#define MAX98927_R001F_PCM_TX_CH_SRC_B 0x001F
+#define MAX98927_R0020_PCM_MODE_CFG 0x0020
+#define MAX98927_R0021_PCM_MASTER_MODE 0x0021
+#define MAX98927_R0022_PCM_CLK_SETUP 0x0022
+#define MAX98927_R0023_PCM_SR_SETUP1 0x0023
+#define MAX98927_R0024_PCM_SR_SETUP2 0x0024
+#define MAX98927_R0025_PCM_TO_SPK_MONOMIX_A 0x0025
+#define MAX98927_R0026_PCM_TO_SPK_MONOMIX_B 0x0026
+#define MAX98927_R0027_ICC_RX_EN_A 0x0027
+#define MAX98927_R0028_ICC_RX_EN_B 0x0028
+#define MAX98927_R002B_ICC_TX_EN_A 0x002B
+#define MAX98927_R002C_ICC_TX_EN_B 0x002C
+#define MAX98927_R002E_ICC_HIZ_MANUAL_MODE 0x002E
+#define MAX98927_R002F_ICC_TX_HIZ_EN_A 0x002F
+#define MAX98927_R0030_ICC_TX_HIZ_EN_B 0x0030
+#define MAX98927_R0031_ICC_LNK_EN 0x0031
+#define MAX98927_R0032_PDM_TX_EN 0x0032
+#define MAX98927_R0033_PDM_TX_HIZ_CTRL 0x0033
+#define MAX98927_R0034_PDM_TX_CTRL 0x0034
+#define MAX98927_R0035_PDM_RX_CTRL 0x0035
+#define MAX98927_R0036_AMP_VOL_CTRL 0x0036
+#define MAX98927_R0037_AMP_DSP_CFG 0x0037
+#define MAX98927_R0038_TONE_GEN_DC_CFG 0x0038
+#define MAX98927_R0039_DRE_CTRL 0x0039
+#define MAX98927_R003A_AMP_EN 0x003A
+#define MAX98927_R003B_SPK_SRC_SEL 0x003B
+#define MAX98927_R003C_SPK_GAIN 0x003C
+#define MAX98927_R003D_SSM_CFG 0x003D
+#define MAX98927_R003E_MEAS_EN 0x003E
+#define MAX98927_R003F_MEAS_DSP_CFG 0x003F
+#define MAX98927_R0040_BOOST_CTRL0 0x0040
+#define MAX98927_R0041_BOOST_CTRL3 0x0041
+#define MAX98927_R0042_BOOST_CTRL1 0x0042
+#define MAX98927_R0043_MEAS_ADC_CFG 0x0043
+#define MAX98927_R0044_MEAS_ADC_BASE_MSB 0x0044
+#define MAX98927_R0045_MEAS_ADC_BASE_LSB 0x0045
+#define MAX98927_R0046_ADC_CH0_DIVIDE 0x0046
+#define MAX98927_R0047_ADC_CH1_DIVIDE 0x0047
+#define MAX98927_R0048_ADC_CH2_DIVIDE 0x0048
+#define MAX98927_R0049_ADC_CH0_FILT_CFG 0x0049
+#define MAX98927_R004A_ADC_CH1_FILT_CFG 0x004A
+#define MAX98927_R004B_ADC_CH2_FILT_CFG 0x004B
+#define MAX98927_R004C_MEAS_ADC_CH0_READ 0x004C
+#define MAX98927_R004D_MEAS_ADC_CH1_READ 0x004D
+#define MAX98927_R004E_MEAS_ADC_CH2_READ 0x004E
+#define MAX98927_R0051_BROWNOUT_STATUS 0x0051
+#define MAX98927_R0052_BROWNOUT_EN 0x0052
+#define MAX98927_R0053_BROWNOUT_INFINITE_HOLD 0x0053
+#define MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR 0x0054
+#define MAX98927_R0055_BROWNOUT_LVL_HOLD 0x0055
+#define MAX98927_R005A_BROWNOUT_LVL1_THRESH 0x005A
+#define MAX98927_R005B_BROWNOUT_LVL2_THRESH 0x005B
+#define MAX98927_R005C_BROWNOUT_LVL3_THRESH 0x005C
+#define MAX98927_R005D_BROWNOUT_LVL4_THRESH 0x005D
+#define MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS 0x005E
+#define MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL 0x005F
+#define MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL 0x0060
+#define MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE 0x0061
+#define MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT 0x0072
+#define MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1 0x0073
+#define MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2 0x0074
+#define MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3 0x0075
+#define MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT 0x0076
+#define MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1 0x0077
+#define MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2 0x0078
+#define MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3 0x0079
+#define MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT 0x007A
+#define MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1 0x007B
+#define MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2 0x007C
+#define MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3 0x007D
+#define MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT 0x007E
+#define MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1 0x007F
+#define MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2 0x0080
+#define MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3 0x0081
+#define MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM 0x0082
+#define MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY 0x0083
+#define MAX98927_R0084_ENV_TRACK_REL_RATE 0x0084
+#define MAX98927_R0085_ENV_TRACK_HOLD_RATE 0x0085
+#define MAX98927_R0086_ENV_TRACK_CTRL 0x0086
+#define MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ 0x0087
+#define MAX98927_R00FF_GLOBAL_SHDN 0x00FF
+#define MAX98927_R0100_SOFT_RESET 0x0100
+#define MAX98927_R01FF_REV_ID 0x01FF
+
+/* MAX98927_R0018_PCM_RX_EN_A */
+#define MAX98927_PCM_RX_CH0_EN (0x1 << 0)
+#define MAX98927_PCM_RX_CH1_EN (0x1 << 1)
+#define MAX98927_PCM_RX_CH2_EN (0x1 << 2)
+#define MAX98927_PCM_RX_CH3_EN (0x1 << 3)
+#define MAX98927_PCM_RX_CH4_EN (0x1 << 4)
+#define MAX98927_PCM_RX_CH5_EN (0x1 << 5)
+#define MAX98927_PCM_RX_CH6_EN (0x1 << 6)
+#define MAX98927_PCM_RX_CH7_EN (0x1 << 7)
+
+/* MAX98927_R001A_PCM_TX_EN_A */
+#define MAX98927_PCM_TX_CH0_EN (0x1 << 0)
+#define MAX98927_PCM_TX_CH1_EN (0x1 << 1)
+#define MAX98927_PCM_TX_CH2_EN (0x1 << 2)
+#define MAX98927_PCM_TX_CH3_EN (0x1 << 3)
+#define MAX98927_PCM_TX_CH4_EN (0x1 << 4)
+#define MAX98927_PCM_TX_CH5_EN (0x1 << 5)
+#define MAX98927_PCM_TX_CH6_EN (0x1 << 6)
+#define MAX98927_PCM_TX_CH7_EN (0x1 << 7)
+
+/* MAX98927_R001E_PCM_TX_CH_SRC_A */
+#define MAX98927_PCM_TX_CH_SRC_A_V_SHIFT (0)
+#define MAX98927_PCM_TX_CH_SRC_A_I_SHIFT (4)
+
+/* MAX98927_R001F_PCM_TX_CH_SRC_B */
+#define MAX98927_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 5)
+
+/* MAX98927_R0020_PCM_MODE_CFG */
+#define MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE (0x1 << 2)
+#define MAX98927_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3)
+#define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
+#define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
+#define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
+
+#define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
+#define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
+#define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
+#define MAX98927_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6)
+
+/* MAX98927_R0021_PCM_MASTER_MODE */
+#define MAX98927_PCM_MASTER_MODE_MASK (0x3 << 0)
+#define MAX98927_PCM_MASTER_MODE_SLAVE (0x0 << 0)
+#define MAX98927_PCM_MASTER_MODE_MASTER (0x3 << 0)
+
+#define MAX98927_PCM_MASTER_MODE_MCLK_MASK (0xF << 2)
+#define MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT (2)
+
+/* MAX98927_R0022_PCM_CLK_SETUP */
+#define MAX98927_PCM_CLK_SETUP_BSEL_MASK (0xF << 0)
+
+/* MAX98927_R0023_PCM_SR_SETUP1 */
+#define MAX98927_PCM_SR_SET1_SR_MASK (0xF << 0)
+
+#define MAX98927_PCM_SR_SET1_SR_8000 (0x0 << 0)
+#define MAX98927_PCM_SR_SET1_SR_11025 (0x1 << 0)
+#define MAX98927_PCM_SR_SET1_SR_12000 (0x2 << 0)
+#define MAX98927_PCM_SR_SET1_SR_16000 (0x3 << 0)
+#define MAX98927_PCM_SR_SET1_SR_22050 (0x4 << 0)
+#define MAX98927_PCM_SR_SET1_SR_24000 (0x5 << 0)
+#define MAX98927_PCM_SR_SET1_SR_32000 (0x6 << 0)
+#define MAX98927_PCM_SR_SET1_SR_44100 (0x7 << 0)
+#define MAX98927_PCM_SR_SET1_SR_48000 (0x8 << 0)
+
+/* MAX98927_R0024_PCM_SR_SETUP2 */
+#define MAX98927_PCM_SR_SET2_SR_MASK (0xF << 4)
+#define MAX98927_PCM_SR_SET2_SR_SHIFT (4)
+#define MAX98927_PCM_SR_SET2_IVADC_SR_MASK (0xf << 0)
+
+/* MAX98927_R0025_PCM_TO_SPK_MONOMIX_A */
+#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6)
+#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT (6)
+
+/* MAX98927_R0035_PDM_RX_CTRL */
+#define MAX98927_PDM_RX_EN_MASK (0x1 << 0)
+
+/* MAX98927_R0036_AMP_VOL_CTRL */
+#define MAX98927_AMP_VOL_SEL (0x1 << 7)
+#define MAX98927_AMP_VOL_SEL_WIDTH (1)
+#define MAX98927_AMP_VOL_SEL_SHIFT (7)
+#define MAX98927_AMP_VOL_MASK (0x7f << 0)
+#define MAX98927_AMP_VOL_WIDTH (7)
+#define MAX98927_AMP_VOL_SHIFT (0)
+
+/* MAX98927_R0037_AMP_DSP_CFG */
+#define MAX98927_AMP_DSP_CFG_DCBLK_EN (0x1 << 0)
+#define MAX98927_AMP_DSP_CFG_DITH_EN (0x1 << 1)
+#define MAX98927_AMP_DSP_CFG_RMP_BYPASS (0x1 << 4)
+#define MAX98927_AMP_DSP_CFG_DAC_INV (0x1 << 5)
+#define MAX98927_AMP_DSP_CFG_RMP_SHIFT (4)
+
+/* MAX98927_R0039_DRE_CTRL */
+#define MAX98927_DRE_CTRL_DRE_EN (0x1 << 0)
+#define MAX98927_DRE_EN_SHIFT 0x1
+
+/* MAX98927_R003A_AMP_EN */
+#define MAX98927_AMP_EN_MASK (0x1 << 0)
+
+/* MAX98927_R003B_SPK_SRC_SEL */
+#define MAX98927_SPK_SRC_MASK (0x3 << 0)
+
+/* MAX98927_R003C_SPK_GAIN */
+#define MAX98927_SPK_PCM_GAIN_MASK (0x7 << 0)
+#define MAX98927_SPK_PDM_GAIN_MASK (0x7 << 4)
+#define MAX98927_SPK_GAIN_WIDTH (3)
+
+/* MAX98927_R003E_MEAS_EN */
+#define MAX98927_MEAS_V_EN (0x1 << 0)
+#define MAX98927_MEAS_I_EN (0x1 << 1)
+
+/* MAX98927_R0040_BOOST_CTRL0 */
+#define MAX98927_BOOST_CTRL0_VOUT_MASK (0x1f << 0)
+#define MAX98927_BOOST_CTRL0_PVDD_MASK (0x1 << 7)
+#define MAX98927_BOOST_CTRL0_PVDD_EN_SHIFT (7)
+
+/* MAX98927_R0052_BROWNOUT_EN */
+#define MAX98927_BROWNOUT_BDE_EN (0x1 << 0)
+#define MAX98927_BROWNOUT_AMP_EN (0x1 << 1)
+#define MAX98927_BROWNOUT_DSP_EN (0x1 << 2)
+#define MAX98927_BROWNOUT_DSP_SHIFT (2)
+
+/* MAX98927_R0100_SOFT_RESET */
+#define MAX98927_SOFT_RESET (0x1 << 0)
+
+/* MAX98927_R00FF_GLOBAL_SHDN */
+#define MAX98927_GLOBAL_EN_MASK (0x1 << 0)
+
+struct max98927_priv {
+ struct regmap *regmap;
+ struct snd_soc_codec *codec;
+ struct max98927_pdata *pdata;
+ unsigned int spk_gain;
+ unsigned int sysclk;
+ unsigned int v_l_slot;
+ unsigned int i_l_slot;
+ bool interleave_mode;
+ unsigned int ch_size;
+ unsigned int rate;
+ unsigned int iface;
+ unsigned int master;
+ unsigned int digital_gain;
+};
+#endif
--
2.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 0/5] iommu/arm-smmu: Add runtime pm/sleep support
From: Will Deacon @ 2017-04-03 17:23 UTC (permalink / raw)
To: Rob Clark
Cc: Sricharan R, Mark Rutland, devicetree@vger.kernel.org,
Mathieu Poirier, linux-arm-msm, Stephen Boyd,
iommu@lists.linux-foundation.org, Rob Herring, linux-clk,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAF6AEGv_1pNvhCc-mVP5S28Yt5kTJmTRfe8tKSJpEmxfOKM7Jg@mail.gmail.com>
On Fri, Mar 31, 2017 at 10:58:16PM -0400, Rob Clark wrote:
> On Fri, Mar 31, 2017 at 1:54 PM, Will Deacon <will.deacon@arm.com> wrote:
> > On Thu, Mar 09, 2017 at 09:05:43PM +0530, Sricharan R wrote:
> >> This series provides the support for turning on the arm-smmu's
> >> clocks/power domains using runtime pm. This is done using the
> >> recently introduced device links patches, which lets the symmu's
> >> runtime to follow the master's runtime pm, so the smmu remains
> >> powered only when the masters use it.
> >
> > Do you have any numbers for the power savings you achieve with this?
> > How often do we actually manage to stop the SMMU clocks on an SoC with
> > a handful of masters?
> >
> > In other words, is this too coarse-grained to be useful, or is it common
> > that all the devices upstream of the SMMU are suspended?
>
> well, if you think about a phone/tablet with a command mode panel,
> pretty much all devices will be suspended most of the time ;-)
Well, that's really what I was asking about. I assumed that periodic
modem/radio transactions would keep the SMMU clocked, so would like to get a
rough idea of the power savings achieved with this coarse-grained approach.
Will
^ permalink raw reply
* Re: [PATCH v5 1/2] Documentation: dt-bindings: Document bindings for Aspeed ADC
From: Rick Altherr @ 2017-04-03 17:17 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Joel Stanley, OpenBMC Maillist, Linux Kernel Mailing List,
devicetree, linux-iio, Hartmut Knaack, Rob Herring,
Lars-Peter Clausen, Mark Rutland, Peter Meerwald-Stadler
In-Reply-To: <968a3a78-49d3-138b-ef6e-7cee3c133471@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 2671 bytes --]
On Sat, Apr 1, 2017 at 3:51 AM, Jonathan Cameron <jic23@kernel.org> wrote:
> On 29/03/17 03:33, Joel Stanley wrote:
> > On Wed, Mar 29, 2017 at 8:22 AM, Rick Altherr <raltherr@google.com>
> wrote:
> >> Signed-off-by: Rick Altherr <raltherr@google.com>
> >> ---
> >
> > Acked-by: Joel Stanley <joel@jms.id.au>
> I can't see why Rob would mind any of the changes made since he
> Acked this (and having acked it I doubt he is looking at newer versions!)
> so I'm going to take the view his Ack still applies.
>
> Applied to the togreg branch of iio.git which will get pushed out first
> as testing for the autobuilders to have a chance to play with it.
>
> Thanks,
>
> Jonathan
>
Thanks! I realized I forgot to include Acks when I sent out later
versions. I'll be more careful on that for future patches.
> >
> >>
> >> Changes in v5: None
> >> Changes in v4: None
> >> Changes in v3:
> >> - Consistently write hex contstants with lowercase letters
> >> - Drop model numbers from description as same IP is used in every
> generation
> >>
> >> Changes in v2:
> >> - Rewritten as an IIO ADC device
> >>
> >> .../devicetree/bindings/iio/adc/aspeed_adc.txt | 20
> ++++++++++++++++++++
> >> 1 file changed, 20 insertions(+)
> >> create mode 100644 Documentation/devicetree/
> bindings/iio/adc/aspeed_adc.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt
> b/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt
> >> new file mode 100644
> >> index 000000000000..674e133b7cd7
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt
> >> @@ -0,0 +1,20 @@
> >> +Aspeed ADC
> >> +
> >> +This device is a 10-bit converter for 16 voltage channels. All inputs
> are
> >> +single ended.
> >> +
> >> +Required properties:
> >> +- compatible: Should be "aspeed,ast2400-adc" or "aspeed,ast2500-adc"
> >> +- reg: memory window mapping address and length
> >> +- clocks: Input clock used to derive the sample clock. Expected to be
> the
> >> + SoC's APB clock.
> >> +- #io-channel-cells: Must be set to <1> to indicate channels are
> selected
> >> + by index.
> >> +
> >> +Example:
> >> + adc@1e6e9000 {
> >> + compatible = "aspeed,ast2400-adc";
> >> + reg = <0x1e6e9000 0xb0>;
> >> + clocks = <&clk_apb>;
> >> + #io-channel-cells = <1>;
> >> + };
> >> --
> >> 2.12.2.564.g063fe858b8-goog
> >>
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
>
[-- Attachment #2: Type: text/html, Size: 4197 bytes --]
^ permalink raw reply
* Re: [PATCH v7 06/13] dt: bindings: Add bindings for Marvell Xenon SD Host Controller
From: Hu Ziji @ 2017-04-03 17:07 UTC (permalink / raw)
To: Rob Herring, Gregory CLEMENT
Cc: Jimmy Xu, Andrew Lunn, Ulf Hansson, linux-mmc, Mike Turquette,
linux-kernel, Nadav Haklai, Victor Gu, Doug Jones, linux-clk,
Jisheng Zhang, Yehuda Yitschak, Marcin Wojtas, Kostya Porotchkin,
Hanna Hawa, Sebastian Hesselbarth, devicetree, Jason Cooper,
Ryan Gao, Wei(SOCP) Liu, linux-arm-kernel, Thomas Petazzoni,
Stephen Boyd, Adrian Hunter, Wilson Ding <dingwe>
In-Reply-To: <20170403161926.wfj7foddu33gxuae@rob-hp-laptop>
Hi Rob,
On 2017/4/4 0:19, Rob Herring wrote:
> ----------------------------------------------------------------------
> On Thu, Mar 30, 2017 at 05:22:58PM +0200, Gregory CLEMENT wrote:
>> From: Hu Ziji <huziji@marvell.com>
>>
>> Marvell Xenon SDHC can support eMMC/SD/SDIO.
>> Add Xenon-specific properties.
>> Also add properties for Xenon PHY setting.
>>
>> Signed-off-by: Hu Ziji <huziji@marvell.com>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>> Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt | 170 +++++++-
>> 1 file changed, 170 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt
>
> I acked v6 and it seems like a minor change, though I had to search for
> both because there is no revision history nor explanation why you didn't
> add my ack.
>
Sorry for missing your ACK.
I add a few but important comments on common Xenon power implementations
in the examples. It is recorded in the cover letter.
v6->v7:
- Add comments on vqmmc and vmmc in examples in dt binding doc.
I was a little unsure if we can still add your ACK after adding the comment.
We will add your ACK back if we have to release another version later.
Thank you.
Best regards,
Hu Ziji
> Acked-by: Rob Herring <robh@kernel.org>
>
^ permalink raw reply
* [PATCH v3 4/4] ARM: dts: sun7i: Add can0_pins_a pinctrl settings
From: Patrick Menschel @ 2017-04-03 17:00 UTC (permalink / raw)
To: robh+dt, mark.rutland, linux, maxime.ripard, wens, devicetree,
linux-arm-kernel, linux-kernel, linux-can
Cc: Patrick Menschel
In-Reply-To: <1491238814-4888-1-git-send-email-menschel.p@posteo.de>
The A20 SoC has an on-board CAN controller. This patch adds
the pinctrl settings for pins PH20 and PH21.
This patch is adapted from the description in
Documentation/devicetree/bindings/net/can/sun4i_can.txt
Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index c637e10..8536caf 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -1096,6 +1096,11 @@
#interrupt-cells = <3>;
#gpio-cells = <3>;
+ can0_pins_a: can0@0 {
+ pins = "PH20","PH21";
+ function = "can";
+ };
+
clk_out_a_pins_a: clk_out_a@0 {
pins = "PI12";
function = "clk_out_a";
--
1.9.1
^ permalink raw reply related
* [PATCH v3 3/4] ARM: dts: sun7i: Add CAN node
From: Patrick Menschel @ 2017-04-03 17:00 UTC (permalink / raw)
To: robh+dt, mark.rutland, linux, maxime.ripard, wens, devicetree,
linux-arm-kernel, linux-kernel, linux-can
Cc: Patrick Menschel
In-Reply-To: <1491238814-4888-1-git-send-email-menschel.p@posteo.de>
The A20 SoC has an on-board CAN controller.
This patch adds the device node.
The CAN controller is inherited from the A10 SoC and uses the same driver.
This patch is adapted from the description in
Documentation/devicetree/bindings/net/can/sun4i_can.txt
Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 2db97fc..c637e10 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -1582,6 +1582,15 @@
#size-cells = <0>;
};
+ can0: can@01c2bc00 {
+ compatible = "allwinner,sun7i-a20-can",
+ "allwinner,sun4i-a10-can";
+ reg = <0x01c2bc00 0x400>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 4>;
+ status = "disabled";
+ };
+
i2c4: i2c@01c2c000 {
compatible = "allwinner,sun7i-a20-i2c",
"allwinner,sun4i-a10-i2c";
--
1.9.1
^ permalink raw reply related
* [PATCH v3 2/4] ARM: dts: sun4i: Add can0_pins_a pinctrl settings
From: Patrick Menschel @ 2017-04-03 17:00 UTC (permalink / raw)
To: robh+dt, mark.rutland, linux, maxime.ripard, wens, devicetree,
linux-arm-kernel, linux-kernel, linux-can
Cc: Patrick Menschel
In-Reply-To: <1491238814-4888-1-git-send-email-menschel.p@posteo.de>
The A10 SoC has an on-board CAN controller. This patch adds the
pinctrl settings for pins PH20 and PH21.
This patch is adapted from the description in
Documentation/devicetree/bindings/net/can/sun4i_can.txt
Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 7c559e7..f7dced4 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -974,6 +974,11 @@
#interrupt-cells = <3>;
#gpio-cells = <3>;
+ can0_pins_a: can0@0 {
+ pins = "PH20","PH21";
+ function = "can";
+ };
+
emac_pins_a: emac0@0 {
pins = "PA0", "PA1", "PA2",
"PA3", "PA4", "PA5", "PA6",
--
1.9.1
^ permalink raw reply related
* [PATCH v3 1/4] ARM: dts: sun4i: Add CAN node
From: Patrick Menschel @ 2017-04-03 17:00 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-can-u79uwXL29TY76Z2rM5mHXA
Cc: Patrick Menschel
In-Reply-To: <1491238814-4888-1-git-send-email-menschel.p-1KBjaw7Xf1+zQB+pC5nmwQ@public.gmane.org>
The A10 SoC has an on-board CAN controller.
This patch adds the device node.
This patch is adapted from the description in
Documentation/devicetree/bindings/net/can/sun4i_can.txt
Signed-off-by: Patrick Menschel <menschel.p-1KBjaw7Xf1+zQB+pC5nmwQ@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index ba20b48..7c559e7 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -1313,6 +1313,14 @@
#size-cells = <0>;
};
+ can0: can@01c2bc00 {
+ compatible = "allwinner,sun4i-a10-can";
+ reg = <0x01c2bc00 0x400>;
+ interrupts = <26>;
+ clocks = <&apb1_gates 4>;
+ status = "disabled";
+ };
+
ps20: ps2@01c2a000 {
compatible = "allwinner,sun4i-a10-ps2";
reg = <0x01c2a000 0x400>;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox