* Re: [RFC PATCH v2 1/4] dt-bindings: update the Allwinner GPADC device tree binding for H3
From: Icenowy Zheng @ 2017-04-05 19:11 UTC (permalink / raw)
To: Rob Herring
Cc: Zhang Rui, linux-sunxi, linux-pm, linux-kernel, linux-iio,
devicetree, Quentin Schulz, Lee Jones, Maxime Ripard,
Jonathan Cameron, linux-arm-kernel, Chen-Yu Tsai
2017年4月6日 03:04于 Rob Herring <robh@kernel.org>写道:
>
> On Tue, Apr 4, 2017 at 10:02 AM, Icenowy Zheng <icenowy@aosc.io> wrote:
> >
> >
> > 在 2017年04月04日 22:47, Rob Herring 写道:
> >>
> >> On Sun, Apr 02, 2017 at 09:33:01PM +0800, Icenowy Zheng wrote:
> >>>
> >>> Allwinner H3 features a thermal sensor like the one in A33, but has its
> >>> register re-arranged, the clock divider moved to CCU (originally the
> >>> clock divider is in ADC) and added a pair of bus clock and reset.
> >>>
> >>> Update the binding document to cover H3.
> >>>
> >>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> >>> ---
> >>> .../devicetree/bindings/mfd/sun4i-gpadc.txt | 23
> >>> ++++++++++++++++++++--
> >>> 1 file changed, 21 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> index badff3611a98..7753133ca0ff 100644
> >>> --- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> +++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> @@ -4,12 +4,20 @@ The Allwinner SoCs all have an ADC that can also act as
> >>> a thermal sensor
> >>> and sometimes as a touchscreen controller.
> >>>
> >>> Required properties:
> >>> - - compatible: "allwinner,sun8i-a33-ths",
> >>> + - compatible: must contain one of the following compatibles:
> >>> + - "allwinner,sun8i-a33-ths"
> >>> + - "allwinner,sun8i-h3-ths"
> >>> - reg: mmio address range of the chip,
> >>> - #thermal-sensor-cells: shall be 0,
> >>> - #io-channel-cells: shall be 0,
> >>>
> >>> -Example:
> >>> +Required properties for the following compatibles:
> >>> + - "allwinner,sun8i-h3-ths"
> >>> + - clocks: the bus clock and the input clock of the ADC,
> >>> + - clock-names: should be "bus" and "ths",
> >>> + - resets: the bus reset of the ADC,
> >>> +
> >>> +Example for A33:
> >>> ths: ths@01c25000 {
> >>> compatible = "allwinner,sun8i-a33-ths";
> >>> reg = <0x01c25000 0x100>;
> >>> @@ -17,6 +25,17 @@ Example:
> >>> #io-channel-cells = <0>;
> >>> };
> >>>
> >>> +Example for H3:
> >>> + ths: ths@01c25000 {
> >>
> >>
> >> adc@...
> >
> >
> > It's a thermal sensor, so I think call it THS is more appropriate
> > here. It's implemented as an ADC driver just because the internal
> > code reusing of Linux. From device tree binding view I choose to
> > call it ths.
>
> There's numerous occurrences in this file and the filename that call it an ADC.
>
> Furthermore, node names are supposed to be generic, not part #'s or
> whatever you decide to make up. So pick from adc or temperature-sensor
> as those are the standard names .
OK. I will make it :
ths: temperature-sensor@1c25000
(Calling it temperature sensor is according to the datasheet name)
>
> Rob
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] dt-bindings: update the Allwinner GPADC device tree binding for H3
From: Icenowy Zheng @ 2017-04-05 19:11 UTC (permalink / raw)
To: Rob Herring
Cc: Zhang Rui, linux-sunxi, linux-pm-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Quentin Schulz, Lee Jones,
Maxime Ripard, Jonathan Cameron,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Chen-Yu Tsai
2017年4月6日 03:04于 Rob Herring <robh@kernel.org>写道:
>
> On Tue, Apr 4, 2017 at 10:02 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
> >
> >
> > 在 2017年04月04日 22:47, Rob Herring 写道:
> >>
> >> On Sun, Apr 02, 2017 at 09:33:01PM +0800, Icenowy Zheng wrote:
> >>>
> >>> Allwinner H3 features a thermal sensor like the one in A33, but has its
> >>> register re-arranged, the clock divider moved to CCU (originally the
> >>> clock divider is in ADC) and added a pair of bus clock and reset.
> >>>
> >>> Update the binding document to cover H3.
> >>>
> >>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> >>> ---
> >>> .../devicetree/bindings/mfd/sun4i-gpadc.txt | 23
> >>> ++++++++++++++++++++--
> >>> 1 file changed, 21 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> index badff3611a98..7753133ca0ff 100644
> >>> --- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> +++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
> >>> @@ -4,12 +4,20 @@ The Allwinner SoCs all have an ADC that can also act as
> >>> a thermal sensor
> >>> and sometimes as a touchscreen controller.
> >>>
> >>> Required properties:
> >>> - - compatible: "allwinner,sun8i-a33-ths",
> >>> + - compatible: must contain one of the following compatibles:
> >>> + - "allwinner,sun8i-a33-ths"
> >>> + - "allwinner,sun8i-h3-ths"
> >>> - reg: mmio address range of the chip,
> >>> - #thermal-sensor-cells: shall be 0,
> >>> - #io-channel-cells: shall be 0,
> >>>
> >>> -Example:
> >>> +Required properties for the following compatibles:
> >>> + - "allwinner,sun8i-h3-ths"
> >>> + - clocks: the bus clock and the input clock of the ADC,
> >>> + - clock-names: should be "bus" and "ths",
> >>> + - resets: the bus reset of the ADC,
> >>> +
> >>> +Example for A33:
> >>> ths: ths@01c25000 {
> >>> compatible = "allwinner,sun8i-a33-ths";
> >>> reg = <0x01c25000 0x100>;
> >>> @@ -17,6 +25,17 @@ Example:
> >>> #io-channel-cells = <0>;
> >>> };
> >>>
> >>> +Example for H3:
> >>> + ths: ths@01c25000 {
> >>
> >>
> >> adc@...
> >
> >
> > It's a thermal sensor, so I think call it THS is more appropriate
> > here. It's implemented as an ADC driver just because the internal
> > code reusing of Linux. From device tree binding view I choose to
> > call it ths.
>
> There's numerous occurrences in this file and the filename that call it an ADC.
>
> Furthermore, node names are supposed to be generic, not part #'s or
> whatever you decide to make up. So pick from adc or temperature-sensor
> as those are the standard names .
OK. I will make it :
ths: temperature-sensor@1c25000
(Calling it temperature sensor is according to the datasheet name)
>
> Rob
--
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 v2 1/4] dt-bindings: update the Allwinner GPADC device tree binding for H3
From: Rob Herring @ 2017-04-05 19:04 UTC (permalink / raw)
To: Icenowy Zheng
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Quentin Schulz, linux-sunxi, Jonathan Cameron, Maxime Ripard,
Chen-Yu Tsai, Lee Jones, Zhang Rui,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <bdc43a73-a2d6-01ae-8113-277f7174697c-h8G6r0blFSE@public.gmane.org>
On Tue, Apr 4, 2017 at 10:02 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
>
>
> 在 2017年04月04日 22:47, Rob Herring 写道:
>>
>> On Sun, Apr 02, 2017 at 09:33:01PM +0800, Icenowy Zheng wrote:
>>>
>>> Allwinner H3 features a thermal sensor like the one in A33, but has its
>>> register re-arranged, the clock divider moved to CCU (originally the
>>> clock divider is in ADC) and added a pair of bus clock and reset.
>>>
>>> Update the binding document to cover H3.
>>>
>>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>>> ---
>>> .../devicetree/bindings/mfd/sun4i-gpadc.txt | 23
>>> ++++++++++++++++++++--
>>> 1 file changed, 21 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
>>> b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
>>> index badff3611a98..7753133ca0ff 100644
>>> --- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
>>> +++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
>>> @@ -4,12 +4,20 @@ The Allwinner SoCs all have an ADC that can also act as
>>> a thermal sensor
>>> and sometimes as a touchscreen controller.
>>>
>>> Required properties:
>>> - - compatible: "allwinner,sun8i-a33-ths",
>>> + - compatible: must contain one of the following compatibles:
>>> + - "allwinner,sun8i-a33-ths"
>>> + - "allwinner,sun8i-h3-ths"
>>> - reg: mmio address range of the chip,
>>> - #thermal-sensor-cells: shall be 0,
>>> - #io-channel-cells: shall be 0,
>>>
>>> -Example:
>>> +Required properties for the following compatibles:
>>> + - "allwinner,sun8i-h3-ths"
>>> + - clocks: the bus clock and the input clock of the ADC,
>>> + - clock-names: should be "bus" and "ths",
>>> + - resets: the bus reset of the ADC,
>>> +
>>> +Example for A33:
>>> ths: ths@01c25000 {
>>> compatible = "allwinner,sun8i-a33-ths";
>>> reg = <0x01c25000 0x100>;
>>> @@ -17,6 +25,17 @@ Example:
>>> #io-channel-cells = <0>;
>>> };
>>>
>>> +Example for H3:
>>> + ths: ths@01c25000 {
>>
>>
>> adc@...
>
>
> It's a thermal sensor, so I think call it THS is more appropriate
> here. It's implemented as an ADC driver just because the internal
> code reusing of Linux. From device tree binding view I choose to
> call it ths.
There's numerous occurrences in this file and the filename that call it an ADC.
Furthermore, node names are supposed to be generic, not part #'s or
whatever you decide to make up. So pick from adc or temperature-sensor
as those are the standard names .
Rob
--
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
* [PATCH 4/4] arm64: dts: hikey: add WL1835 Bluetooth device node
From: Rob Herring @ 2017-04-05 18:30 UTC (permalink / raw)
To: Marcel Holtmann, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Gustavo Padovan, Johan Hedberg, Mark Rutland, Wei Xu, Eyal Reizer,
Satish Patel, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170405183005.20570-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
This adds the serial slave device for the WL1835 Bluetooth interface.
Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Wei Xu <xuwei5-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
---
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index dba3c131c62c..9b4ba7169210 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -98,6 +98,11 @@
assigned-clocks = <&sys_ctrl HI6220_UART1_SRC>;
assigned-clock-rates = <150000000>;
status = "ok";
+
+ bluetooth {
+ compatible = "ti,wl1835-st";
+ enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
};
uart2: uart@f7112000 {
--
2.10.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/4] bluetooth: hci_uart: add LL protocol serdev driver support
From: Rob Herring @ 2017-04-05 18:30 UTC (permalink / raw)
To: Marcel Holtmann, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Gustavo Padovan, Johan Hedberg, Mark Rutland, Wei Xu, Eyal Reizer,
Satish Patel, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170405183005.20570-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Turns out that the LL protocol and the TI-ST are the same thing AFAICT.
The TI-ST adds firmware loading, GPIO control, and shared access for
NFC, FM radio, etc. For now, we're only implementing what is needed for
BT. This mirrors other drivers like BCM and Intel, but uses the new
serdev bus.
The firmware loading is greatly simplified by using existing
infrastructure to send commands. It may be a bit slower than the
original code using synchronous functions, but the real bottleneck is
likely doing firmware load at 115.2kbps.
Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Marcel Holtmann <marcel-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org>
Cc: Gustavo Padovan <gustavo-THi1TnShQwVAfugRpC6u6w@public.gmane.org>
Cc: Johan Hedberg <johan.hedberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: linux-bluetooth-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
drivers/bluetooth/hci_ll.c | 261 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 260 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 02692fe30279..9b2054f5502d 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -34,20 +34,23 @@
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
+#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/poll.h>
#include <linux/slab.h>
-#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/signal.h>
#include <linux/ioctl.h>
+#include <linux/serdev.h>
#include <linux/skbuff.h>
+#include <linux/ti_wilink_st.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+#include <linux/gpio/consumer.h>
#include "hci_uart.h"
@@ -76,6 +79,12 @@ struct hcill_cmd {
u8 cmd;
} __packed;
+struct ll_device {
+ struct hci_uart hu;
+ struct serdev_device *serdev;
+ struct gpio_desc *enable_gpio;
+};
+
struct ll_struct {
unsigned long rx_state;
unsigned long rx_count;
@@ -136,6 +145,9 @@ static int ll_open(struct hci_uart *hu)
hu->priv = ll;
+ if (hu->serdev)
+ serdev_device_open(hu->serdev);
+
return 0;
}
@@ -164,6 +176,13 @@ static int ll_close(struct hci_uart *hu)
kfree_skb(ll->rx_skb);
+ if (hu->serdev) {
+ struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
+ gpiod_set_value_cansleep(lldev->enable_gpio, 0);
+
+ serdev_device_close(hu->serdev);
+ }
+
hu->priv = NULL;
kfree(ll);
@@ -505,9 +524,245 @@ static struct sk_buff *ll_dequeue(struct hci_uart *hu)
return skb_dequeue(&ll->txq);
}
+#ifdef CONFIG_SERIAL_DEV_BUS
+static int read_local_version(struct hci_dev *hdev)
+{
+ int err = 0;
+ unsigned short version = 0;
+ struct sk_buff *skb;
+ struct hci_rp_read_local_version *ver;
+
+ skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Reading TI version information failed (%ld)",
+ PTR_ERR(skb));
+ err = PTR_ERR(skb);
+ goto out;
+ }
+ if (skb->len != sizeof(*ver)) {
+ err = -EILSEQ;
+ goto out;
+ }
+
+ ver = (struct hci_rp_read_local_version *)skb->data;
+ if (le16_to_cpu(ver->manufacturer) != 13) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ version = le16_to_cpu(ver->lmp_subver);
+
+out:
+ if (err) bt_dev_err(hdev, "Failed to read TI version info: %d", err);
+ kfree_skb(skb);
+ return err ? err : version;
+}
+
+/**
+ * download_firmware -
+ * internal function which parses through the .bts firmware
+ * script file intreprets SEND, DELAY actions only as of now
+ */
+static int download_firmware(struct ll_device *lldev)
+{
+ unsigned short chip, min_ver, maj_ver;
+ int version, err, len;
+ unsigned char *ptr, *action_ptr;
+ unsigned char bts_scr_name[40]; /* 40 char long bts scr name? */
+ const struct firmware *fw;
+ struct sk_buff *skb;
+ struct hci_command *cmd;
+
+ version = read_local_version(lldev->hu.hdev);
+ if (version < 0)
+ return version;
+
+ chip = (version & 0x7C00) >> 10;
+ min_ver = (version & 0x007F);
+ maj_ver = (version & 0x0380) >> 7;
+ if (version & 0x8000)
+ maj_ver |= 0x0008;
+
+ snprintf(bts_scr_name, sizeof(bts_scr_name),
+ "ti-connectivity/TIInit_%d.%d.%d.bts",
+ chip, maj_ver, min_ver);
+
+ err = request_firmware(&fw, bts_scr_name, &lldev->serdev->dev);
+ if (err || !fw->data || !fw->size) {
+ bt_dev_err(lldev->hu.hdev, "request_firmware failed(errno %d) for %s",
+ err, bts_scr_name);
+ return -EINVAL;
+ }
+ ptr = (void *)fw->data;
+ len = fw->size;
+ /* bts_header to remove out magic number and
+ * version
+ */
+ ptr += sizeof(struct bts_header);
+ len -= sizeof(struct bts_header);
+
+ while (len > 0 && ptr) {
+ bt_dev_dbg(lldev->hu.hdev, " action size %d, type %d ",
+ ((struct bts_action *)ptr)->size,
+ ((struct bts_action *)ptr)->type);
+
+ action_ptr = &(((struct bts_action *)ptr)->data[0]);
+
+ switch (((struct bts_action *)ptr)->type) {
+ case ACTION_SEND_COMMAND: /* action send */
+ bt_dev_dbg(lldev->hu.hdev, "S");
+ cmd = (struct hci_command *)action_ptr;
+ if (cmd->opcode == 0xff36) {
+ /* ignore remote change
+ * baud rate HCI VS command */
+ bt_dev_warn(lldev->hu.hdev, "change remote baud rate command in firmware");
+ break;
+ }
+ if (cmd->prefix != 1)
+ bt_dev_dbg(lldev->hu.hdev, "command type %d\n", cmd->prefix);
+
+ skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(lldev->hu.hdev, "send command failed\n");
+ goto out_rel_fw;
+ }
+ kfree_skb(skb);
+ break;
+ case ACTION_WAIT_EVENT: /* wait */
+ /* no need to wait as command was synchronous */
+ bt_dev_dbg(lldev->hu.hdev, "W");
+ break;
+ case ACTION_DELAY: /* sleep */
+ bt_dev_info(lldev->hu.hdev, "sleep command in scr");
+ mdelay(((struct bts_action_delay *)action_ptr)->msec);
+ break;
+ }
+ len -= (sizeof(struct bts_action) +
+ ((struct bts_action *)ptr)->size);
+ ptr += sizeof(struct bts_action) +
+ ((struct bts_action *)ptr)->size;
+ }
+
+out_rel_fw:
+ /* fw download complete */
+ release_firmware(fw);
+ return err;
+}
+
+static int ll_setup(struct hci_uart *hu)
+{
+ int err, retry = 3;
+ struct ll_device *lldev;
+ struct serdev_device *serdev = hu->serdev;
+ u32 speed;
+
+ if (!serdev)
+ return 0;
+
+ lldev = serdev_device_get_drvdata(serdev);
+
+ serdev_device_set_flow_control(serdev, true);
+
+ do {
+ /* Configure BT_EN to HIGH state */
+ gpiod_set_value_cansleep(lldev->enable_gpio, 0);
+ msleep(5);
+ gpiod_set_value_cansleep(lldev->enable_gpio, 1);
+ msleep(100);
+
+ err = download_firmware(lldev);
+ if (!err)
+ break;
+
+ /* Toggle BT_EN and retry */
+ bt_dev_err(hu->hdev, "download firmware failed, retrying...");
+ } while (retry--);
+
+ if (err)
+ return err;
+
+ /* Operational speed if any */
+ if (hu->oper_speed)
+ speed = hu->oper_speed;
+ else if (hu->proto->oper_speed)
+ speed = hu->proto->oper_speed;
+ else
+ speed = 0;
+
+ if (speed) {
+ struct sk_buff *skb = __hci_cmd_sync(hu->hdev, 0xff36, sizeof(speed), &speed, HCI_INIT_TIMEOUT);
+ if (!IS_ERR(skb)) {
+ kfree_skb(skb);
+ serdev_device_set_baudrate(serdev, speed);
+ }
+ }
+
+ return 0;
+}
+
+static const struct hci_uart_proto llp;
+
+static int hci_ti_probe(struct serdev_device *serdev)
+{
+ struct hci_uart *hu;
+ struct ll_device *lldev;
+ u32 max_speed = 3000000;
+
+ lldev = devm_kzalloc(&serdev->dev, sizeof(struct ll_device), GFP_KERNEL);
+ if (!lldev)
+ return -ENOMEM;
+ hu = &lldev->hu;
+
+ serdev_device_set_drvdata(serdev, lldev);
+ lldev->serdev = hu->serdev = serdev;
+
+ lldev->enable_gpio = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(lldev->enable_gpio))
+ return PTR_ERR(lldev->enable_gpio);
+
+ of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed);
+ hci_uart_set_speeds(hu, 115200, max_speed);
+
+ return hci_uart_register_device(hu, &llp);
+}
+
+static void hci_ti_remove(struct serdev_device *serdev)
+{
+ struct ll_device *lldev = serdev_device_get_drvdata(serdev);
+ struct hci_uart *hu = &lldev->hu;
+ struct hci_dev *hdev = hu->hdev;
+
+ cancel_work_sync(&hu->write_work);
+
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+ hu->proto->close(hu);
+}
+
+static const struct of_device_id hci_ti_of_match[] = {
+ { .compatible = "ti,wl1831-st" },
+ { .compatible = "ti,wl1835-st" },
+ { .compatible = "ti,wl1837-st" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, hci_ti_of_match);
+
+static struct serdev_device_driver hci_ti_drv = {
+ .driver = {
+ .name = "hci-ti",
+ .of_match_table = of_match_ptr(hci_ti_of_match),
+ },
+ .probe = hci_ti_probe,
+ .remove = hci_ti_remove,
+};
+#else
+#define ll_setup NULL
+#endif
+
static const struct hci_uart_proto llp = {
.id = HCI_UART_LL,
.name = "LL",
+ .setup = ll_setup,
.open = ll_open,
.close = ll_close,
.recv = ll_recv,
@@ -518,10 +773,14 @@ static const struct hci_uart_proto llp = {
int __init ll_init(void)
{
+ serdev_device_driver_register(&hci_ti_drv);
+
return hci_uart_register_proto(&llp);
}
int __exit ll_deinit(void)
{
+ serdev_device_driver_unregister(&hci_ti_drv);
+
return hci_uart_unregister_proto(&llp);
}
--
2.10.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/4] bluetooth: hci_uart: remove unused hci_uart_init_tty
From: Rob Herring @ 2017-04-05 18:30 UTC (permalink / raw)
To: Marcel Holtmann, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Gustavo Padovan, Johan Hedberg, Mark Rutland, Wei Xu, Eyal Reizer,
Satish Patel, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170405183005.20570-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
There are no users of hci_uart_init_tty, so remove it.
Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Marcel Holtmann <marcel-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org>
Cc: Gustavo Padovan <gustavo-THi1TnShQwVAfugRpC6u6w@public.gmane.org>
Cc: Johan Hedberg <johan.hedberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: linux-bluetooth-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
drivers/bluetooth/hci_ldisc.c | 19 -------------------
drivers/bluetooth/hci_uart.h | 1 -
2 files changed, 20 deletions(-)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 17bcbc13623f..cec4438ede01 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -319,25 +319,6 @@ void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
hu->oper_speed = oper_speed;
}
-void hci_uart_init_tty(struct hci_uart *hu)
-{
- struct tty_struct *tty = hu->tty;
- struct ktermios ktermios;
-
- /* Bring the UART into a known 8 bits no parity hw fc state */
- ktermios = tty->termios;
- ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
- INLCR | IGNCR | ICRNL | IXON);
- ktermios.c_oflag &= ~OPOST;
- ktermios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- ktermios.c_cflag &= ~(CSIZE | PARENB);
- ktermios.c_cflag |= CS8;
- ktermios.c_cflag |= CRTSCTS;
-
- /* tty_set_termios() return not checked as it is always 0 */
- tty_set_termios(tty, &ktermios);
-}
-
void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed)
{
struct tty_struct *tty = hu->tty;
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 1b41c661bbb8..2b05e557fad0 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -114,7 +114,6 @@ int hci_uart_register_device(struct hci_uart *hu, const struct hci_uart_proto *p
int hci_uart_tx_wakeup(struct hci_uart *hu);
int hci_uart_init_ready(struct hci_uart *hu);
-void hci_uart_init_tty(struct hci_uart *hu);
void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed);
void hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
--
2.10.1
^ permalink raw reply related
* [PATCH 1/4] dt-bindings: net: Add TI WiLink shared transport binding
From: Rob Herring @ 2017-04-05 18:30 UTC (permalink / raw)
To: Marcel Holtmann, linux-bluetooth
Cc: linux-arm-kernel, Gustavo Padovan, Johan Hedberg, Mark Rutland,
Wei Xu, Eyal Reizer, Satish Patel, netdev, devicetree
In-Reply-To: <20170405183005.20570-1-robh@kernel.org>
Add serial slave device binding for the TI WiLink series of Bluetooth/FM/GPS
devices.
Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: netdev@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
.../devicetree/bindings/net/ti,wilink-st.txt | 35 ++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/ti,wilink-st.txt
diff --git a/Documentation/devicetree/bindings/net/ti,wilink-st.txt b/Documentation/devicetree/bindings/net/ti,wilink-st.txt
new file mode 100644
index 000000000000..cbad73a84ac4
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ti,wilink-st.txt
@@ -0,0 +1,35 @@
+TI WiLink 7/8 (wl12xx/wl18xx) Shared Transport BT/FM/GPS devices
+
+TI WiLink devices have a UART interface for providing Bluetooth, FM radio,
+and GPS over what's called "shared transport". The shared transport is
+standard BT HCI protocol with additional channels for the other functions.
+
+These devices also have a separate WiFi interface as described in
+wireless/ti,wlcore.txt.
+
+This bindings follows the UART slave device binding in
+../serial/slave-device.txt.
+
+Required properties:
+ - compatible: should be one of the following:
+ "ti,wl1271-st"
+ "ti,wl1273-st"
+ "ti,wl1831-st"
+ "ti,wl1835-st"
+ "ti,wl1837-st"
+
+Optional properties:
+ - enable-gpios : GPIO signal controlling enabling of BT. Active high.
+ - vio-supply : Vio input supply (1.8V)
+ - vbat-supply : Vbat input supply (2.9-4.8V)
+
+Example:
+
+&serial0 {
+ compatible = "ns16550a";
+ ...
+ bluetooth {
+ compatible = "ti,wl1835-st";
+ enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+};
--
2.10.1
^ permalink raw reply related
* [PATCH 0/4] TI Bluetooth serdev support
From: Rob Herring @ 2017-04-05 18:30 UTC (permalink / raw)
To: Marcel Holtmann, linux-bluetooth
Cc: linux-arm-kernel, Gustavo Padovan, Johan Hedberg, Mark Rutland,
Wei Xu, Eyal Reizer, Satish Patel, netdev, devicetree
This series adds serdev support to the HCI LL protocol used on TI BT
modules and enables support on HiKey board with with the WL1835 module.
With this the custom TI UIM daemon and btattach are no longer needed.
The series is available on this git branch[1]. Patch 2 is just clean-up
and can be applied independently. Patch 3 is dependent on the series
"Nokia H4+ support". I'd suggest both series are merged thru the BT tree.
Rob
[1] git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git ti-bluetooth
Rob Herring (4):
dt-bindings: net: Add TI WiLink shared transport binding
bluetooth: hci_uart: remove unused hci_uart_init_tty
bluetooth: hci_uart: add LL protocol serdev driver support
arm64: dts: hikey: add WL1835 Bluetooth device node
.../devicetree/bindings/net/ti,wilink-st.txt | 35 +++
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 5 +
drivers/bluetooth/hci_ldisc.c | 19 --
drivers/bluetooth/hci_ll.c | 261 ++++++++++++++++++++-
drivers/bluetooth/hci_uart.h | 1 -
5 files changed, 300 insertions(+), 21 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/ti,wilink-st.txt
^ permalink raw reply
* Re: [PATCHv3 00/10] Nokia H4+ support
From: Rob Herring @ 2017-04-05 18:16 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Marcel Holtmann, Sebastian Reichel, Gustavo F. Padovan,
Johan Hedberg, Samuel Thibault, Pavel Machek, Tony Lindgren,
Jiri Slaby, Mark Rutland, open list:BLUETOOTH DRIVERS,
linux-serial@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, David S. Miller
In-Reply-To: <20170331133353.GA32267@kroah.com>
On Fri, Mar 31, 2017 at 8:33 AM, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> On Wed, Mar 29, 2017 at 11:33:26PM +0200, Marcel Holtmann wrote:
>> Hi Rob,
>>
>> >> Here is PATCHv3 for the Nokia bluetooth patchset. I addressed all comments from
>> >> Rob and Pavel regarding the serdev patches and dropped the *.dts patches, since
>> >> they were queued by Tony. I also changed the patch order, so that the serdev
>> >> patches come first. All of them have Acked-by from Rob, so I think it makes
>> >> sense to merge them to serdev subsystem (now) and provide an immutable branch
>> >> for the bluetooth subsystem.
>> >
>> > Greg doesn't read cover letters generally and since the serdev patches
>> > are Cc rather than To him, he's probably not planning to pick them up.
>>
>> I wonder actually if we should merge all of these via bluetooth-next
>> tree with proper Ack from Greg. However it would be good to also get
>> buy in from Dave for merging this ultimately through net-next.
>
> I don't really care where it goes. I can take the whole thing in my
> tty/serial tree now if no one objects and I get an ack from the relevant
> maintainers {hint...}
I think it is better if it goes thru BT tree. I have another driver
converted that is dependent on this series. There's a couple other
serdev changes on the list too, but this shouldn't depend on them.
Rob
^ permalink raw reply
* Re: [PATCH v6 17/39] platform: add video-multiplexer subdevice driver
From: Pavel Machek @ 2017-04-05 18:05 UTC (permalink / raw)
To: Lucas Stach
Cc: mark.rutland, andrew-ct.chen, minghsiu.tsai, nick, songjun.wu,
hverkuil, shuah, devel, markus.heiser, Steve Longerbeam,
robert.jarzmik, linux, geert, Steve Longerbeam, p.zabel,
linux-media, devicetree, sakari.ailus, arnd, Sascha Hauer,
tiffany.lin, bparrot, laurent.pinchart+renesas, horms+renesas,
mchehab, linux-arm-kernel, niklas.soderlund+renesas, gregkh,
linux-kernel, robh+dt, jean-christophe.trotin, kernel
In-Reply-To: <1491393519.2904.40.camel@pengutronix.de>
[-- Attachment #1.1: Type: text/plain, Size: 1220 bytes --]
On Wed 2017-04-05 13:58:39, Lucas Stach wrote:
> Am Mittwoch, den 05.04.2017, 13:18 +0200 schrieb Pavel Machek:
> > Hi!
> >
> > > + * video stream multiplexer controlled via gpio or syscon
> > > + *
> > > + * Copyright (C) 2013 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
> > > + * Copyright (C) 2016 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
> >
> > This is actually quite interesting. Same email address for two
> > people...
> >
> > Plus, I believe this wants to say that copyright is with Pengutronix,
> > not Sascha and Philipp. In that case you probably want to list
> > copyright and authors separately?
> >
> Nope, copyright doesn't get transferred to the employer within the rules
> of the German "Urheberrecht", but stays at the original author of the
> code.
Ok, then I guess it should be
Copyright (C) 2013 Sascha Hauer
Work sponsored by Pengutronix, use <kernel@pengutronix.de> as contact address
or something? I know license change is not on the table, but I guess
it is good to get legal stuff right.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply
* Re: [PATCH v4] of/pci: Fix memory leak in of_pci_get_host_bridge_resources
From: kbuild test robot @ 2017-04-05 17:39 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, linux-pci-u79uwXL29TY76Z2rM5mHXA,
robh-DgEjT+Ai2ygdnm+yROfE0A, toshi.kani-ZPxbGqLxI0U,
shawn.lin-TNX95d0MmH7DzftRWevZcw,
briannorris-F7+t8E8rja9g9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dianders-F7+t8E8rja9g9hUCZPvPmw, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
dtor-F7+t8E8rja9g9hUCZPvPmw, Jeffy Chen,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Frank Rowand
In-Reply-To: <1491358521-17834-2-git-send-email-jeffy.chen-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2915 bytes --]
Hi Jeffy,
[auto build test ERROR on pci/next]
[also build test ERROR on v4.11-rc5 next-20170405]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jeffy-Chen/of-pci-Fix-memory-leak-in-of_pci_get_host_bridge_resources/20170406-005941
base: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: x86_64-lkp (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers//pci/bus.c: In function 'pci_add_resource_offset':
>> drivers//pci/bus.c:36:2: error: expected ';' before 'entry'
entry->offset = offset;
^~~~~
vim +36 drivers//pci/bus.c
0efd5aab Bjorn Helgaas 2012-02-23 20 void pci_add_resource_offset(struct list_head *resources, struct resource *res,
0efd5aab Bjorn Helgaas 2012-02-23 21 resource_size_t offset)
45ca9e97 Bjorn Helgaas 2011-10-28 22 {
14d76b68 Jiang Liu 2015-02-05 23 struct resource_entry *entry;
45ca9e97 Bjorn Helgaas 2011-10-28 24
fa904d0d Jeffy Chen 2017-04-05 25 entry = resource_list_create_entry(NULL, 0);
14d76b68 Jiang Liu 2015-02-05 26 if (!entry) {
0efd5aab Bjorn Helgaas 2012-02-23 27 printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
45ca9e97 Bjorn Helgaas 2011-10-28 28 return;
45ca9e97 Bjorn Helgaas 2011-10-28 29 }
45ca9e97 Bjorn Helgaas 2011-10-28 30
fa904d0d Jeffy Chen 2017-04-05 31 if (res->flags & IORESOURCE_AUTO)
fa904d0d Jeffy Chen 2017-04-05 32 *entry->res = *res;
fa904d0d Jeffy Chen 2017-04-05 33 else
fa904d0d Jeffy Chen 2017-04-05 34 entry->res = res
fa904d0d Jeffy Chen 2017-04-05 35
14d76b68 Jiang Liu 2015-02-05 @36 entry->offset = offset;
14d76b68 Jiang Liu 2015-02-05 37 resource_list_add_tail(entry, resources);
0efd5aab Bjorn Helgaas 2012-02-23 38 }
0efd5aab Bjorn Helgaas 2012-02-23 39 EXPORT_SYMBOL(pci_add_resource_offset);
0efd5aab Bjorn Helgaas 2012-02-23 40
0efd5aab Bjorn Helgaas 2012-02-23 41 void pci_add_resource(struct list_head *resources, struct resource *res)
0efd5aab Bjorn Helgaas 2012-02-23 42 {
0efd5aab Bjorn Helgaas 2012-02-23 43 pci_add_resource_offset(resources, res, 0);
45ca9e97 Bjorn Helgaas 2011-10-28 44 }
:::::: The code at line 36 was first introduced by commit
:::::: 14d76b68f2819a1d0b50236a7e9e9f2ea69869d9 PCI: Use common resource list management code instead of private implementation
:::::: TO: Jiang Liu <jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
:::::: CC: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25168 bytes --]
^ permalink raw reply
* Re: [PATCH v4] of/pci: Fix memory leak in of_pci_get_host_bridge_resources
From: kbuild test robot @ 2017-04-05 17:36 UTC (permalink / raw)
Cc: kbuild-all, linux-pci, robh, toshi.kani, shawn.lin, briannorris,
linux-kernel, dianders, bhelgaas, dtor, Jeffy Chen, devicetree,
Rob Herring, Frank Rowand
In-Reply-To: <1491358521-17834-2-git-send-email-jeffy.chen@rock-chips.com>
[-- Attachment #1: Type: text/plain, Size: 4036 bytes --]
Hi Jeffy,
[auto build test ERROR on pci/next]
[also build test ERROR on v4.11-rc5 next-20170405]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jeffy-Chen/of-pci-Fix-memory-leak-in-of_pci_get_host_bridge_resources/20170406-005941
base: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: i386-randconfig-n0-04051821 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers//of/of_pci.c: In function 'of_pci_get_host_bridge_resources':
>> drivers//of/of_pci.c:215:30: error: incompatible type for argument 2 of 'pci_add_resource'
pci_add_resource(resources, res);
^~~
In file included from include/linux/of_pci.h:4:0,
from drivers//of/of_pci.c:8:
include/linux/pci.h:1152:6: note: expected 'struct resource *' but argument is of type 'struct resource'
void pci_add_resource(struct list_head *resources, struct resource *res);
^~~~~~~~~~~~~~~~
>> drivers//of/of_pci.c:261:9: error: invalid type argument of '->' (have 'struct resource')
res->start - range.pci_addr);
^~
>> drivers//of/of_pci.c:260:38: error: incompatible type for argument 2 of 'pci_add_resource_offset'
pci_add_resource_offset(resources, res,
^~~
In file included from include/linux/of_pci.h:4:0,
from drivers//of/of_pci.c:8:
include/linux/pci.h:1153:6: note: expected 'struct resource *' but argument is of type 'struct resource'
void pci_add_resource_offset(struct list_head *resources, struct resource *res,
^~~~~~~~~~~~~~~~~~~~~~~
vim +/pci_add_resource +215 drivers//of/of_pci.c
209 } else {
210 if (res.end > res.start + bus_max)
211 res.end = res.start + bus_max;
212 }
213
214 res.flags |= IORESOURCE_AUTO;
> 215 pci_add_resource(resources, res);
216
217 /* Check for ranges property */
218 err = of_pci_range_parser_init(&parser, dev);
219 if (err)
220 goto parse_failed;
221
222 pr_debug("Parsing ranges property...\n");
223 for_each_of_pci_range(&parser, &range) {
224 /* Read next ranges element */
225 if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
226 snprintf(range_type, 4, " IO");
227 else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
228 snprintf(range_type, 4, "MEM");
229 else
230 snprintf(range_type, 4, "err");
231 pr_info(" %s %#010llx..%#010llx -> %#010llx\n", range_type,
232 range.cpu_addr, range.cpu_addr + range.size - 1,
233 range.pci_addr);
234
235 /*
236 * If we failed translation or got a zero-sized region
237 * then skip this range
238 */
239 if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
240 continue;
241
242 err = of_pci_range_to_resource(&range, dev, &res);
243 if (err)
244 continue;
245
246 if (resource_type(&res) == IORESOURCE_IO) {
247 if (!io_base) {
248 pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
249 dev->full_name);
250 err = -EINVAL;
251 goto parse_failed;
252 }
253 if (*io_base != (resource_size_t)OF_BAD_ADDR)
254 pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
255 dev->full_name);
256 *io_base = range.cpu_addr;
257 }
258
259 res.flags |= IORESOURCE_AUTO;
> 260 pci_add_resource_offset(resources, res,
> 261 res->start - range.pci_addr);
262 }
263
264 return 0;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25202 bytes --]
^ permalink raw reply
* Applied "regulator: DT: Add settling time property for non-linear voltage change" to the regulator tree
From: Mark Brown @ 2017-04-05 17:31 UTC (permalink / raw)
To: Laxman Dewangan; +Cc: Rob Herring, Mark Brown
In-Reply-To: <1479898960-14166-1-git-send-email-ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
The patch
regulator: DT: Add settling time property for non-linear voltage change
has been applied to the regulator tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From cfd2cedb482ae29ce13a3db46cc24f0c082ca9cf Mon Sep 17 00:00:00 2001
From: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Date: Tue, 4 Apr 2017 18:59:49 +0530
Subject: [PATCH] regulator: DT: Add settling time property for non-linear
voltage change
Some regulators (some PWM regulators) have the voltage transition
exponentially. On such cases, the settling time for voltage change
is treated as constant time.
Add DT property for providing the settling time for any level of
voltage change for non-linear voltage change.
signed-off-by: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
Documentation/devicetree/bindings/regulator/regulator.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 6ab5aef619d9..d18edb075e1c 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -21,6 +21,9 @@ Optional properties:
design requires. This property describes the total system ramp time
required due to the combination of internal ramping of the regulator itself,
and board design issues such as trace capacitance and load on the supply.
+- regulator-settling-time-us: Settling time, in microseconds, for voltage
+ change if regulator have the constant time for any level voltage change.
+ This is useful when regulator have exponential voltage change.
- regulator-soft-start: Enable soft start so that voltage ramps slowly
- regulator-state-mem sub-root node for Suspend-to-RAM mode
: suspend to memory, the device goes to sleep, but all data stored in memory,
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Applied "regulator: Add settling time for non-linear voltage transition" to the regulator tree
From: Mark Brown @ 2017-04-05 17:31 UTC (permalink / raw)
To: Laxman Dewangan; +Cc: Mark Brown
In-Reply-To: <1491312590-20887-2-git-send-email-ldewangan@nvidia.com>
The patch
regulator: Add settling time for non-linear voltage transition
has been applied to the regulator tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From d6c1dc3f52e3a65f35c58433ba57d14c0bad902f Mon Sep 17 00:00:00 2001
From: Laxman Dewangan <ldewangan@nvidia.com>
Date: Tue, 4 Apr 2017 18:59:50 +0530
Subject: [PATCH] regulator: Add settling time for non-linear voltage
transition
Some regulators (some PWM regulators) have the voltage transition
non-linear i.e. exponentially. On such cases, the settling time
for voltage transition can not be presented in the voltage-ramp-delay.
Add new property for non-linear voltage transition and handle this
in getting the voltage settling time.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/regulator/core.c | 2 ++
drivers/regulator/of_regulator.c | 4 ++++
include/linux/regulator/machine.h | 3 +++
3 files changed, 9 insertions(+)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 04baac9a165b..3a641d64f8e1 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2753,6 +2753,8 @@ static int _regulator_set_voltage_time(struct regulator_dev *rdev,
ramp_delay = rdev->constraints->ramp_delay;
else if (rdev->desc->ramp_delay)
ramp_delay = rdev->desc->ramp_delay;
+ else if (rdev->constraints->settling_time)
+ return rdev->constraints->settling_time;
if (ramp_delay == 0) {
rdev_dbg(rdev, "ramp_delay not set\n");
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 4f613ec99500..09d677d5d3f0 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -86,6 +86,10 @@ static void of_get_regulation_constraints(struct device_node *np,
constraints->ramp_disable = true;
}
+ ret = of_property_read_u32(np, "regulator-settling-time-us", &pval);
+ if (!ret)
+ constraints->settling_time = pval;
+
ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
if (!ret)
constraints->enable_time = pval;
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index ad3e5158e586..598a493b3927 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -108,6 +108,8 @@ struct regulator_state {
* @initial_state: Suspend state to set by default.
* @initial_mode: Mode to set at startup.
* @ramp_delay: Time to settle down after voltage change (unit: uV/us)
+ * @settling_time: Time to settle down after voltage change when voltage
+ * change is non-linear (unit: microseconds).
* @active_discharge: Enable/disable active discharge. The enum
* regulator_active_discharge values are used for
* initialisation.
@@ -149,6 +151,7 @@ struct regulation_constraints {
unsigned int initial_mode;
unsigned int ramp_delay;
+ unsigned int settling_time;
unsigned int enable_time;
unsigned int active_discharge;
--
2.11.0
^ permalink raw reply related
* Applied "ASoC: wm_adsp: Add support for ADSP2V2" to the asoc tree
From: Mark Brown @ 2017-04-05 17:31 UTC (permalink / raw)
To: Richard Fitzgerald
Cc: Charles Keepax, Mark Brown, linus.walleij, gnurou, robh+dt, tglx,
jason, lee.jones
In-Reply-To: <1491386884-30689-12-git-send-email-rf@opensource.wolfsonmicro.com>
The patch
ASoC: wm_adsp: Add support for ADSP2V2
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From e1ea1879f2889a26370bd0bc29c1e95caf9d36f2 Mon Sep 17 00:00:00 2001
From: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date: Wed, 5 Apr 2017 11:07:59 +0100
Subject: [PATCH] ASoC: wm_adsp: Add support for ADSP2V2
Adds support for ADSP2V2 cores. Primary differences are that
they use a 32-bit register map compared to the 16-bit register
map of ADSP2V1, and there are some changes to clocking control.
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/codecs/wm_adsp.c | 187 ++++++++++++++++++++++++++++++++++-----------
sound/soc/codecs/wm_adsp.h | 1 +
2 files changed, 145 insertions(+), 43 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index bbdb72f73df1..a9acf222b502 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -112,17 +112,22 @@
#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */
#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
-#define ADSP2_CONTROL 0x0
-#define ADSP2_CLOCKING 0x1
-#define ADSP2_STATUS1 0x4
-#define ADSP2_WDMA_CONFIG_1 0x30
-#define ADSP2_WDMA_CONFIG_2 0x31
-#define ADSP2_RDMA_CONFIG_1 0x34
-
-#define ADSP2_SCRATCH0 0x40
-#define ADSP2_SCRATCH1 0x41
-#define ADSP2_SCRATCH2 0x42
-#define ADSP2_SCRATCH3 0x43
+#define ADSP2_CONTROL 0x0
+#define ADSP2_CLOCKING 0x1
+#define ADSP2V2_CLOCKING 0x2
+#define ADSP2_STATUS1 0x4
+#define ADSP2_WDMA_CONFIG_1 0x30
+#define ADSP2_WDMA_CONFIG_2 0x31
+#define ADSP2V2_WDMA_CONFIG_2 0x32
+#define ADSP2_RDMA_CONFIG_1 0x34
+
+#define ADSP2_SCRATCH0 0x40
+#define ADSP2_SCRATCH1 0x41
+#define ADSP2_SCRATCH2 0x42
+#define ADSP2_SCRATCH3 0x43
+
+#define ADSP2V2_SCRATCH0_1 0x40
+#define ADSP2V2_SCRATCH2_3 0x42
/*
* ADSP2 Control
@@ -153,6 +158,17 @@
#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
/*
+ * ADSP2V2 clocking
+ */
+#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */
+#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */
+#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
+
+#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */
+#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */
+#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */
+
+/*
* ADSP2 Status 1
*/
#define ADSP2_RAM_RDY 0x0001
@@ -683,6 +699,9 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
+ SOC_ENUM_SINGLE(0, 4, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
+ SOC_ENUM_SINGLE(0, 5, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
+ SOC_ENUM_SINGLE(0, 6, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
};
const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
@@ -694,6 +713,12 @@ const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
wm_adsp_fw_get, wm_adsp_fw_put),
SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
wm_adsp_fw_get, wm_adsp_fw_put),
+ SOC_ENUM_EXT("DSP5 Firmware", wm_adsp_fw_enum[4],
+ wm_adsp_fw_get, wm_adsp_fw_put),
+ SOC_ENUM_EXT("DSP6 Firmware", wm_adsp_fw_enum[5],
+ wm_adsp_fw_get, wm_adsp_fw_put),
+ SOC_ENUM_EXT("DSP7 Firmware", wm_adsp_fw_enum[6],
+ wm_adsp_fw_get, wm_adsp_fw_put),
};
EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
@@ -750,6 +775,29 @@ static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
be16_to_cpu(scratch[3]));
}
+static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp)
+{
+ u32 scratch[2];
+ int ret;
+
+ ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
+ scratch, sizeof(scratch));
+
+ if (ret) {
+ adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
+ return;
+ }
+
+ scratch[0] = be32_to_cpu(scratch[0]);
+ scratch[1] = be32_to_cpu(scratch[1]);
+
+ adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
+ scratch[0] & 0xFFFF,
+ scratch[0] >> 16,
+ scratch[1] & 0xFFFF,
+ scratch[1] >> 16);
+}
+
static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext)
{
return container_of(ext, struct wm_coeff_ctl, bytes_ext);
@@ -2435,10 +2483,17 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
unsigned int val;
int ret, count;
- ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL,
- ADSP2_SYS_ENA, ADSP2_SYS_ENA);
- if (ret != 0)
- return ret;
+ switch (dsp->rev) {
+ case 0:
+ ret = regmap_update_bits_async(dsp->regmap,
+ dsp->base + ADSP2_CONTROL,
+ ADSP2_SYS_ENA, ADSP2_SYS_ENA);
+ if (ret != 0)
+ return ret;
+ break;
+ default:
+ break;
+ }
/* Wait for the RAM to start, should be near instantaneous */
for (count = 0; count < 10; ++count) {
@@ -2497,11 +2552,17 @@ static void wm_adsp2_boot_work(struct work_struct *work)
if (ret != 0)
goto err_ena;
- /* Turn DSP back off until we are ready to run */
- ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
- ADSP2_SYS_ENA, 0);
- if (ret != 0)
- goto err_ena;
+ switch (dsp->rev) {
+ case 0:
+ /* Turn DSP back off until we are ready to run */
+ ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+ ADSP2_SYS_ENA, 0);
+ if (ret != 0)
+ goto err_ena;
+ break;
+ default:
+ break;
+ }
dsp->booted = true;
@@ -2523,12 +2584,21 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
{
int ret;
- ret = regmap_update_bits_async(dsp->regmap,
- dsp->base + ADSP2_CLOCKING,
- ADSP2_CLK_SEL_MASK,
- freq << ADSP2_CLK_SEL_SHIFT);
- if (ret != 0)
- adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
+ switch (dsp->rev) {
+ case 0:
+ ret = regmap_update_bits_async(dsp->regmap,
+ dsp->base + ADSP2_CLOCKING,
+ ADSP2_CLK_SEL_MASK,
+ freq << ADSP2_CLK_SEL_SHIFT);
+ if (ret) {
+ adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
+ return;
+ }
+ break;
+ default:
+ /* clock is handled by parent codec driver */
+ break;
+ }
}
int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
@@ -2664,22 +2734,46 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN);
/* Log firmware state, it can be useful for analysis */
- wm_adsp2_show_fw_status(dsp);
+ switch (dsp->rev) {
+ case 0:
+ wm_adsp2_show_fw_status(dsp);
+ break;
+ default:
+ wm_adsp2v2_show_fw_status(dsp);
+ break;
+ }
mutex_lock(&dsp->pwr_lock);
dsp->running = false;
- regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+ regmap_update_bits(dsp->regmap,
+ dsp->base + ADSP2_CONTROL,
ADSP2_CORE_ENA | ADSP2_START, 0);
/* Make sure DMAs are quiesced */
- regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
- regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
- regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
-
- regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
- ADSP2_SYS_ENA, 0);
+ switch (dsp->rev) {
+ case 0:
+ regmap_write(dsp->regmap,
+ dsp->base + ADSP2_RDMA_CONFIG_1, 0);
+ regmap_write(dsp->regmap,
+ dsp->base + ADSP2_WDMA_CONFIG_1, 0);
+ regmap_write(dsp->regmap,
+ dsp->base + ADSP2_WDMA_CONFIG_2, 0);
+
+ regmap_update_bits(dsp->regmap,
+ dsp->base + ADSP2_CONTROL,
+ ADSP2_SYS_ENA, 0);
+ break;
+ default:
+ regmap_write(dsp->regmap,
+ dsp->base + ADSP2_RDMA_CONFIG_1, 0);
+ regmap_write(dsp->regmap,
+ dsp->base + ADSP2_WDMA_CONFIG_1, 0);
+ regmap_write(dsp->regmap,
+ dsp->base + ADSP2V2_WDMA_CONFIG_2, 0);
+ break;
+ }
if (wm_adsp_fw[dsp->fw].num_caps != 0)
wm_adsp_buffer_free(dsp);
@@ -2732,15 +2826,22 @@ int wm_adsp2_init(struct wm_adsp *dsp)
{
int ret;
- /*
- * Disable the DSP memory by default when in reset for a small
- * power saving.
- */
- ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
- ADSP2_MEM_ENA, 0);
- if (ret != 0) {
- adsp_err(dsp, "Failed to clear memory retention: %d\n", ret);
- return ret;
+ switch (dsp->rev) {
+ case 0:
+ /*
+ * Disable the DSP memory by default when in reset for a small
+ * power saving.
+ */
+ ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+ ADSP2_MEM_ENA, 0);
+ if (ret) {
+ adsp_err(dsp,
+ "Failed to clear memory retention: %d\n", ret);
+ return ret;
+ }
+ break;
+ default:
+ break;
}
INIT_LIST_HEAD(&dsp->alg_regions);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 3706b11053a3..997227f4d404 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -40,6 +40,7 @@ struct wm_adsp_compr_buf;
struct wm_adsp {
const char *part;
+ int rev;
int num;
int type;
struct device *dev;
--
2.11.0
^ permalink raw reply related
* Applied "ASoC: wm_adsp: add support for DSP region lock" to the asoc tree
From: Mark Brown @ 2017-04-05 17:31 UTC (permalink / raw)
To: Mayuresh Kulkarni
Cc: Nikesh Oswal, Charles Keepax, Richard Fitzgerald, Mark Brown,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
lee.jones-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1491386884-30689-13-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
The patch
ASoC: wm_adsp: add support for DSP region lock
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 51a2c944ead91171495ef338689da057bbcaab0c Mon Sep 17 00:00:00 2001
From: Mayuresh Kulkarni <mkulkarni-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Date: Wed, 5 Apr 2017 11:08:00 +0100
Subject: [PATCH] ASoC: wm_adsp: add support for DSP region lock
Newer ADSP2V2 codecs include a memory protection unit that can
be set to trap illegal accesses. When enabling an ADSPV2 core we
must configure the memory region traps so that the firmware can
access its own memory.
Signed-off-by: Mayuresh Kulkarni <mkulkarni-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Nikesh Oswal <Nikesh.Oswal-UVNVL95qEvAciDkP5Hr2oA@public.gmane.org>
Signed-off-by: Charles Keepax <ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
sound/soc/codecs/wm_adsp.c | 137 +++++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/wm_adsp.h | 23 ++++++++
2 files changed, 160 insertions(+)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index a9acf222b502..20695b691aff 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -176,6 +176,37 @@
#define ADSP2_RAM_RDY_SHIFT 0
#define ADSP2_RAM_RDY_WIDTH 1
+/*
+ * ADSP2 Lock support
+ */
+#define ADSP2_LOCK_CODE_0 0x5555
+#define ADSP2_LOCK_CODE_1 0xAAAA
+
+#define ADSP2_WATCHDOG 0x0A
+#define ADSP2_BUS_ERR_ADDR 0x52
+#define ADSP2_REGION_LOCK_STATUS 0x64
+#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66
+#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68
+#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A
+#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C
+#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E
+#define ADSP2_LOCK_REGION_CTRL 0x7A
+#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C
+
+#define ADSP2_REGION_LOCK_ERR_MASK 0x8000
+#define ADSP2_SLAVE_ERR_MASK 0x4000
+#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000
+#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002
+#define ADSP2_CTRL_ERR_EINT 0x0001
+
+#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF
+#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF
+#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000
+#define ADSP2_PMEM_ERR_ADDR_SHIFT 16
+#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD
+
+#define ADSP2_LOCK_REGION_SHIFT 16
+
#define ADSP_MAX_STD_CTRL_SIZE 512
#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100
@@ -2638,6 +2669,18 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
+static void wm_adsp_stop_watchdog(struct wm_adsp *dsp)
+{
+ switch (dsp->rev) {
+ case 0:
+ case 1:
+ return;
+ default:
+ regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG,
+ ADSP2_WDT_ENA_MASK, 0);
+ }
+}
+
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event,
unsigned int freq)
@@ -2710,6 +2753,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
if (ret != 0)
goto err;
+ wm_adsp2_lock(dsp, dsp->lock_regions);
+
ret = regmap_update_bits(dsp->regmap,
dsp->base + ADSP2_CONTROL,
ADSP2_CORE_ENA | ADSP2_START,
@@ -2733,6 +2778,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
/* Tell the firmware to cleanup */
wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN);
+ wm_adsp_stop_watchdog(dsp);
+
/* Log firmware state, it can be useful for analysis */
switch (dsp->rev) {
case 0:
@@ -3624,4 +3671,94 @@ int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf,
}
EXPORT_SYMBOL_GPL(wm_adsp_compr_copy);
+int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions)
+{
+ struct regmap *regmap = dsp->regmap;
+ unsigned int code0, code1, lock_reg;
+
+ if (!(lock_regions & WM_ADSP2_REGION_ALL))
+ return 0;
+
+ lock_regions &= WM_ADSP2_REGION_ALL;
+ lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0;
+
+ while (lock_regions) {
+ code0 = code1 = 0;
+ if (lock_regions & BIT(0)) {
+ code0 = ADSP2_LOCK_CODE_0;
+ code1 = ADSP2_LOCK_CODE_1;
+ }
+ if (lock_regions & BIT(1)) {
+ code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT;
+ code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT;
+ }
+ regmap_write(regmap, lock_reg, code0);
+ regmap_write(regmap, lock_reg, code1);
+ lock_regions >>= 2;
+ lock_reg += 2;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wm_adsp2_lock);
+
+irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
+{
+ unsigned int val;
+ struct regmap *regmap = dsp->regmap;
+ int ret = 0;
+
+ ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val);
+ if (ret) {
+ adsp_err(dsp,
+ "Failed to read Region Lock Ctrl register: %d\n", ret);
+ return IRQ_HANDLED;
+ }
+
+ if (val & ADSP2_WDT_TIMEOUT_STS_MASK) {
+ adsp_err(dsp, "watchdog timeout error\n");
+ wm_adsp_stop_watchdog(dsp);
+ }
+
+ if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) {
+ if (val & ADSP2_SLAVE_ERR_MASK)
+ adsp_err(dsp, "bus error: slave error\n");
+ else
+ adsp_err(dsp, "bus error: region lock error\n");
+
+ ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val);
+ if (ret) {
+ adsp_err(dsp,
+ "Failed to read Bus Err Addr register: %d\n",
+ ret);
+ return IRQ_HANDLED;
+ }
+
+ adsp_err(dsp, "bus error address = 0x%x\n",
+ val & ADSP2_BUS_ERR_ADDR_MASK);
+
+ ret = regmap_read(regmap,
+ dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR,
+ &val);
+ if (ret) {
+ adsp_err(dsp,
+ "Failed to read Pmem Xmem Err Addr register: %d\n",
+ ret);
+ return IRQ_HANDLED;
+ }
+
+ adsp_err(dsp, "xmem error address = 0x%x\n",
+ val & ADSP2_XMEM_ERR_ADDR_MASK);
+ adsp_err(dsp, "pmem error address = 0x%x\n",
+ (val & ADSP2_PMEM_ERR_ADDR_MASK) >>
+ ADSP2_PMEM_ERR_ADDR_SHIFT);
+ }
+
+ regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL,
+ ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT);
+
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
+
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 997227f4d404..41cc11c19b83 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -23,6 +23,23 @@
#define WM_ADSP_COMPR_OK 0
#define WM_ADSP_COMPR_VOICE_TRIGGER 1
+#define WM_ADSP2_REGION_0 BIT(0)
+#define WM_ADSP2_REGION_1 BIT(1)
+#define WM_ADSP2_REGION_2 BIT(2)
+#define WM_ADSP2_REGION_3 BIT(3)
+#define WM_ADSP2_REGION_4 BIT(4)
+#define WM_ADSP2_REGION_5 BIT(5)
+#define WM_ADSP2_REGION_6 BIT(6)
+#define WM_ADSP2_REGION_7 BIT(7)
+#define WM_ADSP2_REGION_8 BIT(8)
+#define WM_ADSP2_REGION_9 BIT(9)
+#define WM_ADSP2_REGION_1_9 (WM_ADSP2_REGION_1 | \
+ WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \
+ WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | \
+ WM_ADSP2_REGION_6 | WM_ADSP2_REGION_7 | \
+ WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9)
+#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9)
+
struct wm_adsp_region {
int type;
unsigned int base;
@@ -76,6 +93,8 @@ struct wm_adsp {
struct mutex pwr_lock;
+ unsigned int lock_regions;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root;
char *wmfw_file_name;
@@ -114,6 +133,10 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event,
unsigned int freq);
+
+int wm_adsp2_lock(struct wm_adsp *adsp, unsigned int regions);
+irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp);
+
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [RFC] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Mauro Carvalho Chehab @ 2017-04-05 17:16 UTC (permalink / raw)
To: Devin Heitmueller
Cc: mark.rutland, andrew-ct.chen, minghsiu.tsai,
sakari.ailus@linux.intel.com, nick, songjun.wu, Hans Verkuil,
Steve Longerbeam, Pavel Machek, robert.jarzmik, devel,
markus.heiser, laurent.pinchart+renesas, shuah,
Russell King - ARM Linux, geert, Steve Longerbeam,
Linux Media Mailing List, devicetree, Philipp Zabel,
Arnd Bergmann, Mauro Carvalho Chehab, bparrot, robh+dt,
horms+renesas, tiffany.lin, linux-arm-kernel
In-Reply-To: <CAGoCfiyfXc2bcTR72XwL3Vv8ny-dQUjEUk2OUuy_s4nedNJqxA@mail.gmail.com>
Em Wed, 5 Apr 2017 13:02:52 -0400
Devin Heitmueller <dheitmueller@kernellabs.com> escreveu:
> > I remember I looked on this when I wrote the driver, but I was
> > unable to find a way for em28xx to parse (or forward) such
> > data packets.
>
> I'm pretty sure it's possible, but I haven't looked at the datasheets
> in a number of years and don't recall the details.
>
> Hardware VBI splicing is supported by a number of decoders but it's
> rarely used on commodity PCs (the Conexant and NXP decoders support it
> as well). That said, I won't argue there might be some value on
> really low end platforms. All I would ask is that if you do introduce
> any such functionality into the tvp5150 driver for some embedded
> application that you please not break support for devices such as the
> em28xx.
Yeah, sure. If I write such patchset[1], it will be optional, and
will depend on a DT variable (or platform_data) setup that would
tell what GPIO pin should be used for interrupt.
Not providing it should either disable such feature or enable it
via polling.
[1] Please notice that I don't have any demand of doing it. Yet,
I may do it for fun on my spare time:-)
I added in the past an initial support for sliced VBI API on em28xx,
with got reverted on changeset 1d179eeedc8cb48712bc236ec82ec6c63af42008,
mainly due to the lack of such feature on tvp5150. So, such code was never
tested (and likely need fixes/updates), but if I end by adding sliced VBI
support on tvp5150 and on OMAP3, I may add support for it on em28xx too,
using I2C poll. On such case, I'll likely add a modprobe parameter to
enable such feature.
Thanks,
Mauro
^ permalink raw reply
* Re: Re: [PATCH v3 04/11] drm/sun4i: abstract the layer type
From: icenowy-h8G6r0blFSE @ 2017-04-05 17:14 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: devicetree, Jernej Skrabec, linux-sunxi, linux-kernel, dri-devel,
Rob Herring, Sean Paul, Maxime Ripard, linux-clk,
linux-arm-kernel
In-Reply-To: <CAGb2v66vxP0c3qMTAUCseTCbpJ6gxnKfNGNcC41jPHA_Ye4ggw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
在 2017-04-05 10:27,Chen-Yu Tsai 写道:
> On Wed, Apr 5, 2017 at 3:53 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
>>
>>
>> 在 2017年04月05日 03:28, Sean Paul 写道:
>>>
>>> On Thu, Mar 30, 2017 at 03:46:06AM +0800, Icenowy Zheng wrote:
>>>>
>>>> As we are going to add support for the Allwinner DE2 Mixer in
>>>> sun4i-drm
>>>> driver, we will finally have two types of layer.
>>>>
>>>> Abstract the layer type to void * and a ops struct, which contains
>>>> the
>>>> only function used by crtc -- get the drm_plane struct of the layer.
>>>>
>>>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>>>> ---
>>>> Refactored patch in v3.
>>>>
>>>> drivers/gpu/drm/sun4i/sun4i_crtc.c | 19 +++++++++++--------
>>>> drivers/gpu/drm/sun4i/sun4i_crtc.h | 3 ++-
>>>> drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ++++++++++++++++++-
>>>> drivers/gpu/drm/sun4i/sun4i_layer.h | 2 +-
>>>> drivers/gpu/drm/sun4i/sunxi_layer.h | 17 +++++++++++++++++
>>>> 5 files changed, 49 insertions(+), 11 deletions(-)
>>>> create mode 100644 drivers/gpu/drm/sun4i/sunxi_layer.h
>>>>
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> b/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> index 3c876c3a356a..33854ee7f636 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
>>>> @@ -29,6 +29,7 @@
>>>> #include "sun4i_crtc.h"
>>>> #include "sun4i_drv.h"
>>>> #include "sun4i_layer.h"
>>>> +#include "sunxi_layer.h"
>>>> #include "sun4i_tcon.h"
>>>>
>>>> static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
>>>> @@ -149,7 +150,7 @@ struct sun4i_crtc *sun4i_crtc_init(struct
>>>> drm_device
>>>> *drm,
>>>> scrtc->tcon = tcon;
>>>>
>>>> /* Create our layers */
>>>> - scrtc->layers = sun4i_layers_init(drm, scrtc->backend);
>>>> + scrtc->layers = (void **)sun4i_layers_init(drm, scrtc);
>>>> if (IS_ERR(scrtc->layers)) {
>>>> dev_err(drm->dev, "Couldn't create the planes\n");
>>>> return NULL;
>>>> @@ -157,14 +158,15 @@ struct sun4i_crtc *sun4i_crtc_init(struct
>>>> drm_device *drm,
>>>>
>>>> /* find primary and cursor planes for
>>>> drm_crtc_init_with_planes
>>>> */
>>>> for (i = 0; scrtc->layers[i]; i++) {
>>>> - struct sun4i_layer *layer = scrtc->layers[i];
>>>> + void *layer = scrtc->layers[i];
>>>> + struct drm_plane *plane =
>>>> scrtc->layer_ops->get_plane(layer);
>>>>
>>>> - switch (layer->plane.type) {
>>>> + switch (plane->type) {
>>>> case DRM_PLANE_TYPE_PRIMARY:
>>>> - primary = &layer->plane;
>>>> + primary = plane;
>>>> break;
>>>> case DRM_PLANE_TYPE_CURSOR:
>>>> - cursor = &layer->plane;
>>>> + cursor = plane;
>>>> break;
>>>> default:
>>>> break;
>>>> @@ -190,10 +192,11 @@ struct sun4i_crtc *sun4i_crtc_init(struct
>>>> drm_device *drm,
>>>> /* Set possible_crtcs to this crtc for overlay planes */
>>>> for (i = 0; scrtc->layers[i]; i++) {
>>>> uint32_t possible_crtcs =
>>>> BIT(drm_crtc_index(&scrtc->crtc));
>>>> - struct sun4i_layer *layer = scrtc->layers[i];
>>>> + void *layer = scrtc->layers[i];
>>>> + struct drm_plane *plane =
>>>> scrtc->layer_ops->get_plane(layer);
>>>>
>>>> - if (layer->plane.type == DRM_PLANE_TYPE_OVERLAY)
>>>> - layer->plane.possible_crtcs =
>>>> possible_crtcs;
>>>> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
>>>> + plane->possible_crtcs = possible_crtcs;
>>>> }
>>>>
>>>> return scrtc;
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> b/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> index 230cb8f0d601..a4036ee44cf8 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h
>>>> @@ -19,7 +19,8 @@ struct sun4i_crtc {
>>>>
>>>> struct sun4i_backend *backend;
>>>> struct sun4i_tcon *tcon;
>>>> - struct sun4i_layer **layers;
>>>> + void **layers;
>>>> + const struct sunxi_layer_ops *layer_ops;
>>>
>>>
>>> I think you should probably take a different approach to abstract the
>>> layer
>>> type. How about creating
>>>
>>> struct sunxi_layer {
>>> struct drm_plane plane;
>>> }
>>>
>>> base and then subclassing that for sun4i and sun8i? By doing this you
>>> can
>>> avoid
>>> the nasty casting and you can also get rid of the get_plane() hook
>>> and
>>> layer_ops.
>>
>>
>> For the situation that using ** things are easily to get weird.
>
> That code could be reworked, by initializing the layers directly within
> the crtc init code. If you look at rockchip's drm driver, you'll see
> they do this. There is a good reason to do it this way, as you need
> to first create the primary and cursor layers, pass them in when you
> create the crtc, then initialize any additional layers with the
> possible_crtcs bitmap.
I feel that it's still more proper to offload plane creation code
to *_layers_init function, as:
1. We cannot assume the cursor layer's
existance. In fact currently no code in sun4i-drm (including this
patchset) create a cursor layer.
2. The format of planes heavily depend on the engine type (
sun4i-backend or sun8i-mixer).
3. We should create planes according to the type of engine.
Currently the *_layers_init function is part of engine code (See my
Makefile change).
4. If we do so we will have two codes for plane creating -- one for
primary in sun4i_crtc_init, another for overlays in *_layers_init.
>
> In our driver we are currently initializing all layers, then going
> back and filling in possible_crtcs for the extra layers.
>
> And as Maxime and I mentioned in the other thread, we don't really
> need to keep a reference to **layers.
It's correct, layers doesn't need to be kept.
And the struct sunxi_layer refactor also makes sense.
>
> Regards
> ChenYu
>
>>
>>>
>>> Sean
>>>
>>>
>>>
>>>> };
>>>>
>>>> static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct
>>>> drm_crtc
>>>> *crtc)
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> b/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> index f26bde5b9117..bc4a70d6968b 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
>>>> @@ -16,7 +16,9 @@
>>>> #include <drm/drmP.h>
>>>>
>>>> #include "sun4i_backend.h"
>>>> +#include "sun4i_crtc.h"
>>>> #include "sun4i_layer.h"
>>>> +#include "sunxi_layer.h"
>>>>
>>>> struct sun4i_plane_desc {
>>>> enum drm_plane_type type;
>>>> @@ -100,6 +102,17 @@ static const struct sun4i_plane_desc
>>>> sun4i_backend_planes[] = {
>>>> },
>>>> };
>>>>
>>>> +static struct drm_plane *sun4i_layer_get_plane(void *layer)
>>>> +{
>>>> + struct sun4i_layer *sun4i_layer = layer;
>>>> +
>>>> + return &sun4i_layer->plane;
>>>> +}
>>>> +
>>>> +static const struct sunxi_layer_ops layer_ops = {
>>>> + .get_plane = sun4i_layer_get_plane,
>>>> +};
>>>> +
>>>> static struct sun4i_layer *sun4i_layer_init_one(struct drm_device
>>>> *drm,
>>>> struct sun4i_backend
>>>> *backend,
>>>> const struct
>>>> sun4i_plane_desc *plane)
>>>> @@ -129,9 +142,10 @@ static struct sun4i_layer
>>>> *sun4i_layer_init_one(struct drm_device *drm,
>>>> }
>>>>
>>>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>>>> - struct sun4i_backend
>>>> *backend)
>>>> + struct sun4i_crtc *crtc)
>>>> {
>>>> struct sun4i_layer **layers;
>>>> + struct sun4i_backend *backend = crtc->backend;
>>>> int i;
>>>>
>>>> layers = devm_kcalloc(drm->dev,
>>>> ARRAY_SIZE(sun4i_backend_planes)
>>>> + 1,
>>>> @@ -181,5 +195,8 @@ struct sun4i_layer **sun4i_layers_init(struct
>>>> drm_device *drm,
>>>> layers[i] = layer;
>>>> };
>>>>
>>>> + /* Assign layer ops to the CRTC */
>>>> + crtc->layer_ops = &layer_ops;
>>>> +
>>>> return layers;
>>>> }
>>>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> b/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> index 4be1f0919df2..425eea7b9e3b 100644
>>>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
>>>> @@ -27,6 +27,6 @@ plane_to_sun4i_layer(struct drm_plane *plane)
>>>> }
>>>>
>>>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>>>> - struct sun4i_backend
>>>> *backend);
>>>> + struct sun4i_crtc *crtc);
>>>>
>>>> #endif /* _SUN4I_LAYER_H_ */
>>>> diff --git a/drivers/gpu/drm/sun4i/sunxi_layer.h
>>>> b/drivers/gpu/drm/sun4i/sunxi_layer.h
>>>> new file mode 100644
>>>> index 000000000000..d8838ec39299
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/sun4i/sunxi_layer.h
>>>> @@ -0,0 +1,17 @@
>>>> +/*
>>>> + * Copyright (C) 2017 Icenowy Zheng <icenowy-ymACFijhrKM@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 _SUNXI_LAYER_H_
>>>> +#define _SUNXI_LAYER_H_
>>>> +
>>>> +struct sunxi_layer_ops {
>>>> + struct drm_plane *(*get_plane)(void *layer);
>>>> +};
>>>> +
>>>> +#endif /* _SUNXI_LAYER_H_ */
>>>> --
>>>> 2.12.0
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>
>>>
>>
>> --
>> 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.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Devin Heitmueller @ 2017-04-05 17:02 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Philipp Zabel, Russell King - ARM Linux, Mauro Carvalho Chehab,
Steve Longerbeam, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, fabio.estevam-3arQi8VN3Tc,
Hans Verkuil, nick-gcszYUEDH4VrovVCs/uTlw,
markus.heiser-m1Uo1GnMJf0b1SvskN2V4Q,
laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw,
bparrot-l0cyMroinI0, geert-Td1EMuHUCqxL1ZNQvxDV9g, Arnd Bergmann,
sudipm.mukherjee-Re5JQEeQqe8AvxtiuMwx3w,
minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w,
tiffany.lin-NuS5LvNUpcJWk0Htik3J/w,
jean-christophe.trotin-qxv4g6HH51o,
horms+renesas-/R6kz+dDXgpPR4JQBCEnsQ,
niklas.soderlund+renesas-1zkq55x86MTxsAP9Fp7wbw,
robert.jarzmik-GANU6spQydw, songjun.wu-UWL1GkI3JZL3oGB3hsPCZA,
andrew-ct.chen-NuS5LvNUpcJWk0Htik3J/w, Greg Kroah-Hartman
In-Reply-To: <20170405131725.22c13a1d-ch4gOOMV7nf/PtFMR13I2A@public.gmane.org>
>> For what it's worth, I doubt most of the em28xx designs have the
>> tvp5150 interrupt request line connected in any way.
>
> True. But, on embedded hardware, such line may be connected into the
> SoC. Actually, from the IGEPv3 expansion diagram:
>
> https://www.isee.biz/support/downloads/item/igepv2-expansion-rc-schematics
>
> The INT line is connected to CAM_IRQ. That's connected to GPIO_154 pin
> at OMAP3.
>
> So, on a first glance, it seems possible to use it, instead of polling.
To be clear, I wasn't suggesting that the IRQ request line on the
tvp5150 couldn't be supported in general (for example, for those
embedded targets which have it wired up to a host processor). I'm
just saying you shouldn't expect it to work on most (perhaps all)
em28xx designs which have the tvp5150. In fact on some em28xx designs
the pin is used as a GPIO output tied to a mux to control input
selection. Hence blindly enabling the interrupt request line by
default would do all sorts of bad things.
>> You would likely
>> have to poll the FIFO status register via I2C,
>
> Yes, I considered this option when I wrote the driver. It could work,
> although it would likely have some performance drawback, as the driver
> would need to poll it at least 60 times per second.
>
>> or use the feature to
>> embed the sliced data into as VANC data in the 656 output (as
>> described in sec 3.9 of the tvp5150am1 spec).
>
> True, but the bridge driver would need to handle such data.
Correct.
> I remember I looked on this when I wrote the driver, but I was
> unable to find a way for em28xx to parse (or forward) such
> data packets.
I'm pretty sure it's possible, but I haven't looked at the datasheets
in a number of years and don't recall the details.
Hardware VBI splicing is supported by a number of decoders but it's
rarely used on commodity PCs (the Conexant and NXP decoders support it
as well). That said, I won't argue there might be some value on
really low end platforms. All I would ask is that if you do introduce
any such functionality into the tvp5150 driver for some embedded
application that you please not break support for devices such as the
em28xx.
Thanks,
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v6 01/23] PCI: endpoint: Add EP core layer to enable EP controller and EP functions
From: Bjorn Helgaas @ 2017-04-05 16:52 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: devicetree, Joao Pinto, linux-doc, linux-pci, nsekhar,
linux-kernel, hch, Bjorn Helgaas, linux-omap, linux-arm-kernel
In-Reply-To: <20170405085243.18123-2-kishon@ti.com>
On Wed, Apr 05, 2017 at 02:22:21PM +0530, Kishon Vijay Abraham I wrote:
> Introduce a new EP core layer in order to support endpoint functions in
> linux kernel. This comprises the EPC library (Endpoint Controller Library)
> and EPF library (Endpoint Function Library). EPC library implements
> functions specific to an endpoint controller and EPF library implements
> functions specific to an endpoint function.
> ...
> +/**
> + * pci_epf_linkup() - Notify the function driver that EPC device has
> + * established a connection with the Root Complex.
> + * @epf: the EPF device bound to the EPC device which has established
> + * the connection with the host
> + *
> + * Invoke to notify the function driver that EPC device has established
> + * a connection with the Root Complex.
> + */
> +void pci_epf_linkup(struct pci_epf *epf)
> +{
> + if (!epf->driver)
> + dev_WARN(&epf->dev, "epf device not bound to driver\n");
> +
> + epf->driver->ops->linkup(epf);
I don't understand what's going on here. We warn if epf->driver is
NULL, but the next thing we do is dereference it.
For NULL pointers that are symptoms of Linux defects, I usually prefer
not to check at all so that a dereference generates an oops and we can
debug the problem. For NULL pointers caused by user error, we would
generally return an error that percolates up to the user.
I haven't competely wrapped my head around this endpoint support, but
I assume a NULL pointer here would be caused by user error, not
necessarily a Linux defect. So why would we dereference a NULL
pointer? And what happens when we do? Is this just going to oops an
embedded Linux running inside the endpoint? Is that the correct
behavior?
Bjorn
^ permalink raw reply
* Re: [PATCH 4/4] iio: dac: stm32: add support for waveform generator
From: Fabrice Gasnier @ 2017-04-05 16:46 UTC (permalink / raw)
To: Jonathan Cameron, linux, robh+dt, linux-arm-kernel, devicetree,
linux-kernel
Cc: mark.rutland, benjamin.gaignard, lars, alexandre.torgue,
Hennerich, Michael, linux-iio, pmeerw, amelie.delaunay,
mcoquelin.stm32, knaack.h, linus.walleij, benjamin.gaignard
In-Reply-To: <e6a02296-fa72-50e8-d5e8-25bb5d496085@kernel.org>
JonathanOn 04/02/2017 02:19 PM, Jonathan Cameron wrote:
> On 31/03/17 12:45, Fabrice Gasnier wrote:
>> STM32 DAC has built-in noise or triangle waveform generator.
>> Waveform generator requires trigger to be configured.
>> - "wave" extended attribute selects noise or triangle.
>> - "mamp" extended attribute selects either LFSR (linear feedback
>> shift register) mask for noise waveform, OR triangle amplitude.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>
> Looks like AN3126 is the relevant doc.
> (a quick note from this relevant to earlier patches- doc says
> 1-3 channels - perhaps build that from the start with that
> possibility in mind).
Hi Jonathan,
Just to clarify this, some products like STM32F334xx have 3 channels,
yes. Several STM32 DAC IPs (& so registers) are instantiated: DAC1 have
two outputs (dac1_out1 & dac1_out2), DAC2 have one output (e.g.
dac2_out1). Driver can be instantiated several times. Is it ok ?
>
> As you probably know, this wanders into a large chunk of 'poorly'
> defined ABI within IIO as it stands.
>
> Note there are a number of waveform generators still in staging.
> Not a lot of movement on getting them out of staging unfortunately
> (so far!)
>
> However, let us keep those drivers in mind as we work on ABI and
> I definitely want some input from someone at Analog.
> Lars, who is best for this? I see at least some of these were
> originally Michael's work.
>
> They do have partial docs under
> drivers/staging/iio/Documentation/sysfs-bus-iio-dds
> I'll highlight thoughts from there as I look through this...
Thanks for pointing this out.
>
>
>> ---
>> Documentation/ABI/testing/sysfs-bus-iio-dac-stm32 | 32 ++++++
>> drivers/iio/dac/stm32-dac.c | 124 ++++++++++++++++++++++
>> 2 files changed, 156 insertions(+)
>> create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
>> new file mode 100644
>> index 0000000..c2432e1
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
>> @@ -0,0 +1,32 @@
>> +What: /sys/bus/iio/devices/iio:deviceX/wave
>> +What: /sys/bus/iio/devices/iio:deviceX/wave_available
> Needs to be channel associated. Whilst in your case you have basically
> a pair of single channel devices, in more general case, it's not usual
> to have multiple parallel waveform generators clocked together.
>
> Old ABI is:
> What: /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype etc
>
I'll rework this in V2.
>
>> +KernelVersion: 4.12
>> +Contact: fabrice.gasnier@st.com
>> +Description:
>> + List and/or select waveform generation provided by STM32 DAC:
>> + - "none": (default) means normal DAC operations
> none kind of hints at nothing coming out. Perhaps 'flat' would be closer?
> i.e. only changes when someone tells it to.
>
>> + - "noise": select noise waveform
>> + - "triangle": select triangle waveform
>> + Note: when waveform generator is used, writing _raw sysfs entry
>> + adds a DC offset to generated waveform. Reading it reports
>> + current output value.
> Interesting. This gets fiddly but one option would be to describe the whole
> device as a dds.
>
> Then we have flat type above, combined with an _offset.
I'll update from 'none' to 'flat' in V2, and use _offset.
>
>> +
>> +What: /sys/bus/iio/devices/iio:deviceX/mamp
>> +What: /sys/bus/iio/devices/iio:deviceX/mamp_available
>> +KernelVersion: 4.12
>> +Contact: fabrice.gasnier@st.com
>> +Description:
>> + List and select mask/amplitude used for noise/triangle waveform
>> + generator, which are:
>> + - "0": unmask bit 0 of LFSR / triangle amplitude equal to 1
>> + - "1": unmask bit [1:0] of LFSR / triangle amplitude equal to 3
>> + - "2": unmask bit [2:0] of LFSR / triangle amplitude equal to 7
>> + - "3": unmask bit [3:0] of LFSR / triangle amplitude equal to 15
>> + - "4": unmask bit [4:0] of LFSR / triangle amplitude equal to 31
>> + - "5": unmask bit [5:0] of LFSR / triangle amplitude equal to 63
>> + - "6": unmask bit [6:0] of LFSR / triangle amplitude equal to 127
>> + - "7": unmask bit [7:0] of LFSR / triangle amplitude equal to 255
>> + - "8": unmask bit [8:0] of LFSR / triangle amplitude equal to 511
>> + - "9": unmask bit [9:0] of LFSR / triangle amplitude equal to 1023
>> + - "10": unmask bit [10:0] of LFSR / triangle amplitude equal to 2047
>> + - "11": unmask bit [11:0] of LFSR / triangle amplitude equal to 4095
> I don't fully understand what is going on here - so I'm guessing somewhat.
Sorry for this, this is basically amplitude.
I think best is to rename above to something like 'amplitude' and
'amplitude_available'.
I'll rework this in V2.
>
>
> Let us try describing these generically. If we define standard 'forms' of each
> waveform type. Say a 0 to 1 V peak to peak, then we could use _scale to control
> this nicely.
>
>> diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
>> index 62e43e9..d7dda78 100644
>> --- a/drivers/iio/dac/stm32-dac.c
>> +++ b/drivers/iio/dac/stm32-dac.c
>> @@ -41,10 +41,14 @@
>> /**
>> * struct stm32_dac - private data of DAC driver
>> * @common: reference to DAC common data
>> + * @wave: waveform generator
>> + * @mamp: waveform mask/amplitude
>> * @swtrig: Using software trigger
>> */
>> struct stm32_dac {
>> struct stm32_dac_common *common;
>> + u32 wave;
>> + u32 mamp;
>> bool swtrig;
>> };
>>
>> @@ -157,6 +161,24 @@ static int stm32_dac_is_enabled(struct stm32_dac *dac, int channel)
>> return !!en;
>> }
>>
>> +static int stm32_dac_wavegen(struct stm32_dac *dac, int channel)
>> +{
>> + struct regmap *regmap = dac->common->regmap;
>> + u32 mask, val;
>> +
>> + if (channel == STM32_DAC_CHANNEL_1) {
>> + val = FIELD_PREP(STM32_DAC_CR_WAVE1, dac->wave) |
>> + FIELD_PREP(STM32_DAC_CR_MAMP1, dac->mamp);
>> + mask = STM32_DAC_CR_WAVE1 | STM32_DAC_CR_MAMP1;
>> + } else {
>> + val = FIELD_PREP(STM32_DAC_CR_WAVE2, dac->wave) |
>> + FIELD_PREP(STM32_DAC_CR_MAMP2, dac->mamp);
>> + mask = STM32_DAC_CR_WAVE2 | STM32_DAC_CR_MAMP2;
>> + }
>> +
>> + return regmap_update_bits(regmap, STM32_DAC_CR, mask, val);
>> +}
>> +
>> static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>> {
>> struct stm32_dac *dac = iio_priv(indio_dev);
>> @@ -164,6 +186,17 @@ static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>> STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
>> int ret;
>>
>> + if (dac->wave && !indio_dev->trig) {
>> + dev_err(&indio_dev->dev, "Wavegen requires a trigger\n");
>> + return -EINVAL;
>> + }
>> +
>> + ret = stm32_dac_wavegen(dac, channel);
>> + if (ret < 0) {
>> + dev_err(&indio_dev->dev, "Wavegen setup failed\n");
>> + return ret;
>> + }
>> +
>> ret = stm32_dac_set_trig(dac, indio_dev->trig, channel);
>> if (ret < 0) {
>> dev_err(&indio_dev->dev, "Trigger setup failed\n");
>> @@ -291,6 +324,96 @@ static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
>> .driver_module = THIS_MODULE,
>> };
>>
>> +/* waveform generator wave selection */
>> +static const char * const stm32_dac_wave_desc[] = {
>> + "none",
>> + "noise",
>> + "triangle",
>> +};
>> +
>> +static int stm32_dac_set_wave(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + unsigned int type)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + if (stm32_dac_is_enabled(dac, chan->channel))
>> + return -EBUSY;
>> + dac->wave = type;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_dac_get_wave(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + return dac->wave;
>> +}
>> +
>> +static const struct iio_enum stm32_dac_wave_enum = {
>> + .items = stm32_dac_wave_desc,
>> + .num_items = ARRAY_SIZE(stm32_dac_wave_desc),
>> + .get = stm32_dac_get_wave,
>> + .set = stm32_dac_set_wave,
>> +};
>> +
>> +/*
>> + * waveform generator mask/amplitude selection:
>> + * - noise: LFSR mask (linear feedback shift register, umasks bit 0, [1:0]...)
>> + * - triangle: amplitude (equal to 1, 3, 5, 7... 4095)
>> + */
>> +static const char * const stm32_dac_mamp_desc[] = {
>> + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
>> +};
>> +
>> +static int stm32_dac_set_mamp(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan,
>> + unsigned int type)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + if (stm32_dac_is_enabled(dac, chan->channel))
>> + return -EBUSY;
>> + dac->mamp = type;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_dac_get_mamp(struct iio_dev *indio_dev,
>> + const struct iio_chan_spec *chan)
>> +{
>> + struct stm32_dac *dac = iio_priv(indio_dev);
>> +
>> + return dac->mamp;
>> +}
>> +
>> +static const struct iio_enum stm32_dac_mamp_enum = {
>> + .items = stm32_dac_mamp_desc,
>> + .num_items = ARRAY_SIZE(stm32_dac_mamp_desc),
>> + .get = stm32_dac_get_mamp,
>> + .set = stm32_dac_set_mamp,
>> +};
>> +
>> +static const struct iio_chan_spec_ext_info stm32_dac_ext_info[] = {
>> + IIO_ENUM("wave", IIO_SHARED_BY_ALL, &stm32_dac_wave_enum),
>> + {
>> + .name = "wave_available",
>> + .shared = IIO_SHARED_BY_ALL,
>> + .read = iio_enum_available_read,
>> + .private = (uintptr_t)&stm32_dac_wave_enum,
>> + },
>> + IIO_ENUM("mamp", IIO_SHARED_BY_ALL, &stm32_dac_mamp_enum),
>> + {
>> + .name = "mamp_available",
>> + .shared = IIO_SHARED_BY_ALL,
>> + .read = iio_enum_available_read,
>> + .private = (uintptr_t)&stm32_dac_mamp_enum,
>> + },
>> + {},
>> +};
>> +
>> #define STM32_DAC_CHANNEL(chan, name) { \
>> .type = IIO_VOLTAGE, \
>> .indexed = 1, \
>> @@ -306,6 +429,7 @@ static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
>> .storagebits = 16, \
>> }, \
>> .datasheet_name = name, \
>> + .ext_info = stm32_dac_ext_info \
>> }
>>
>> static const struct iio_chan_spec stm32_dac_channels[] = {
>>
>
^ permalink raw reply
* Re: [PATCH 3/4] iio: dac: stm32: add support for trigger events
From: Fabrice Gasnier @ 2017-04-05 16:44 UTC (permalink / raw)
To: Jonathan Cameron, linux, robh+dt, linux-arm-kernel, devicetree,
linux-kernel
Cc: mark.rutland, benjamin.gaignard, lars, alexandre.torgue,
linux-iio, pmeerw, amelie.delaunay, mcoquelin.stm32, knaack.h,
linus.walleij, benjamin.gaignard
In-Reply-To: <7dba5b17-5f82-e68d-3c06-afe4a4e478e7@kernel.org>
On 04/02/2017 02:21 PM, Jonathan Cameron wrote:
> On 02/04/17 12:45, Jonathan Cameron wrote:
>> On 31/03/17 12:45, Fabrice Gasnier wrote:
>>> STM32 DAC supports triggers to synchronize conversions. When trigger
>>> occurs, data is transferred from DHR (data holding register) to DOR
>>> (data output register) so output voltage is updated.
>>> Both hardware and software triggers are supported.
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>> Hmm. This is a somewhat different use of triggered event from normal...
>>
Waveform generator in STM32 DAC requires a trigger to increment /
decrement internal counter in case of triangle generator. Noise
generator is a bit different, but same trigger usage applies. I agree
this is unusual.
Is it acceptable to use event trigger for this use ?
>> What you have here is rather closer to the output buffers stuff that Analog
>> have in their tree which hasn't made it upstream yet.
>> To that end I'll want Lars to have a look at this... I've completely
>> lost track of where they are with this.
>> Perhaps Lars can give us a quick update?
>>
>> If that was in place (or what I have in my head was true anyway),
>> it would look like the reverse of the triggered buffer input devices.
>> You'd be able to write to a software buffer and it would clock them
>> out as the trigger fires (here I think it would have to keep updating
>> the DHR whenever the trigger occurs).
Hmm.. for waveform generator mode, there is no need for data buffer. DAC
generate samples itself, using trigger. But, i agree it would be nice
for playing data samples (write DHR registers, or dma), yes.
>>
>> Even if it's not there, we aren't necessarily looking at terribly big job
>> to implement it in the core and that would make this handling a lot more
>> 'standard' and consistent.
>
> Having tracked down some limited docs (AN3126 - Audio and waveform
> generation using the DAC in STM32 microcontrollers) the fact this
> can also be driven by DMA definitely argues in favour of working with
> Analog on getting the output buffers support upstream.
>
> *crosses fingers people have the time!*
Hopefully this can happen.
For the time being, I'll propose a similar patch in V2. I found out this
patch is missing a clear path to (re-)assign trigger, once set by
userland. Also, driver never gets informed in case trigger gets changed
or removed, without re-enabling it:
e.g. like echo "" > trigger/current_trigger
I'll propose a small change. Hope you agree with this approach.
Thanks,
Fabrice
>>
>> Jonathan
>>
>>> ---
>>> drivers/iio/dac/Kconfig | 3 +
>>> drivers/iio/dac/stm32-dac-core.h | 12 ++++
>>> drivers/iio/dac/stm32-dac.c | 124 ++++++++++++++++++++++++++++++++++++++-
>>> 3 files changed, 136 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
>>> index 7198648..786c38b 100644
>>> --- a/drivers/iio/dac/Kconfig
>>> +++ b/drivers/iio/dac/Kconfig
>>> @@ -278,6 +278,9 @@ config STM32_DAC
>>> tristate "STMicroelectronics STM32 DAC"
>>> depends on (ARCH_STM32 && OF) || COMPILE_TEST
>>> depends on REGULATOR
>>> + select IIO_TRIGGERED_EVENT
>>> + select IIO_STM32_TIMER_TRIGGER
>>> + select MFD_STM32_TIMERS
>>> select STM32_DAC_CORE
>>> help
>>> Say yes here to build support for STMicroelectronics STM32 Digital
>>> diff --git a/drivers/iio/dac/stm32-dac-core.h b/drivers/iio/dac/stm32-dac-core.h
>>> index d3099f7..3bf211c 100644
>>> --- a/drivers/iio/dac/stm32-dac-core.h
>>> +++ b/drivers/iio/dac/stm32-dac-core.h
>>> @@ -26,6 +26,7 @@
>>>
>>> /* STM32 DAC registers */
>>> #define STM32_DAC_CR 0x00
>>> +#define STM32_DAC_SWTRIGR 0x04
>>> #define STM32_DAC_DHR12R1 0x08
>>> #define STM32_DAC_DHR12R2 0x14
>>> #define STM32_DAC_DOR1 0x2C
>>> @@ -33,8 +34,19 @@
>>>
>>> /* STM32_DAC_CR bit fields */
>>> #define STM32_DAC_CR_EN1 BIT(0)
>>> +#define STM32H7_DAC_CR_TEN1 BIT(1)
>>> +#define STM32H7_DAC_CR_TSEL1_SHIFT 2
>>> +#define STM32H7_DAC_CR_TSEL1 GENMASK(5, 2)
>>> +#define STM32_DAC_CR_WAVE1 GENMASK(7, 6)
>>> +#define STM32_DAC_CR_MAMP1 GENMASK(11, 8)
>>> #define STM32H7_DAC_CR_HFSEL BIT(15)
>>> #define STM32_DAC_CR_EN2 BIT(16)
>>> +#define STM32_DAC_CR_WAVE2 GENMASK(23, 22)
>>> +#define STM32_DAC_CR_MAMP2 GENMASK(27, 24)
>>> +
>>> +/* STM32_DAC_SWTRIGR bit fields */
>>> +#define STM32_DAC_SWTRIGR_SWTRIG1 BIT(0)
>>> +#define STM32_DAC_SWTRIGR_SWTRIG2 BIT(1)
>>>
>>> /**
>>> * struct stm32_dac_common - stm32 DAC driver common data (for all instances)
>>> diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
>>> index ee9711d..62e43e9 100644
>>> --- a/drivers/iio/dac/stm32-dac.c
>>> +++ b/drivers/iio/dac/stm32-dac.c
>>> @@ -23,6 +23,10 @@
>>> #include <linux/bitfield.h>
>>> #include <linux/delay.h>
>>> #include <linux/iio/iio.h>
>>> +#include <linux/iio/timer/stm32-timer-trigger.h>
>>> +#include <linux/iio/trigger.h>
>>> +#include <linux/iio/trigger_consumer.h>
>>> +#include <linux/iio/triggered_event.h>
>>> #include <linux/kernel.h>
>>> #include <linux/module.h>
>>> #include <linux/platform_device.h>
>>> @@ -31,15 +35,112 @@
>>>
>>> #define STM32_DAC_CHANNEL_1 1
>>> #define STM32_DAC_CHANNEL_2 2
>>> +/* channel2 shift */
>>> +#define STM32_DAC_CHAN2_SHIFT 16
>>>
>>> /**
>>> * struct stm32_dac - private data of DAC driver
>>> * @common: reference to DAC common data
>>> + * @swtrig: Using software trigger
>>> */
>>> struct stm32_dac {
>>> struct stm32_dac_common *common;
>>> + bool swtrig;
>>> };
>>>
>>> +/**
>>> + * struct stm32_dac_trig_info - DAC trigger info
>>> + * @name: name of the trigger, corresponding to its source
>>> + * @tsel: trigger selection, value to be configured in DAC_CR.TSELx
>>> + */
>>> +struct stm32_dac_trig_info {
>>> + const char *name;
>>> + u32 tsel;
>>> +};
>>> +
>>> +static const struct stm32_dac_trig_info stm32h7_dac_trinfo[] = {
>>> + { "swtrig", 0 },
>>> + { TIM1_TRGO, 1 },
>>> + { TIM2_TRGO, 2 },
>>> + { TIM4_TRGO, 3 },
>>> + { TIM5_TRGO, 4 },
>>> + { TIM6_TRGO, 5 },
>>> + { TIM7_TRGO, 6 },
>>> + { TIM8_TRGO, 7 },
>>> + {},
>>> +};
>>> +
>>> +static irqreturn_t stm32_dac_trigger_handler(int irq, void *p)
>>> +{
>>> + struct iio_poll_func *pf = p;
>>> + struct iio_dev *indio_dev = pf->indio_dev;
>>> + struct stm32_dac *dac = iio_priv(indio_dev);
>>> + int channel = indio_dev->channels[0].channel;
>>> +
>>> + /* Using software trigger? Then, trigger it now */
>>> + if (dac->swtrig) {
>>> + u32 swtrig;
>>> +
>>> + if (channel == STM32_DAC_CHANNEL_1)
>>> + swtrig = STM32_DAC_SWTRIGR_SWTRIG1;
>>> + else
>>> + swtrig = STM32_DAC_SWTRIGR_SWTRIG2;
>>> + regmap_update_bits(dac->common->regmap, STM32_DAC_SWTRIGR,
>>> + swtrig, swtrig);
>>> + }
>>> +
>>> + iio_trigger_notify_done(indio_dev->trig);
>>> +
>>> + return IRQ_HANDLED;
>>> +}
>>> +
>>> +static unsigned int stm32_dac_get_trig_tsel(struct stm32_dac *dac,
>>> + struct iio_trigger *trig)
>>> +{
>>> + unsigned int i;
>>> +
>>> + /* skip 1st trigger that should be swtrig */
>>> + for (i = 1; stm32h7_dac_trinfo[i].name; i++) {
>>> + /*
>>> + * Checking both stm32 timer trigger type and trig name
>>> + * should be safe against arbitrary trigger names.
>>> + */
>>> + if (is_stm32_timer_trigger(trig) &&
>>> + !strcmp(stm32h7_dac_trinfo[i].name, trig->name)) {
>>> + return stm32h7_dac_trinfo[i].tsel;
>>> + }
>>> + }
>>> +
>>> + /* When no trigger has been found, default to software trigger */
>>> + dac->swtrig = true;
>>> +
>>> + return stm32h7_dac_trinfo[0].tsel;
>>> +}
>>> +
>>> +static int stm32_dac_set_trig(struct stm32_dac *dac, struct iio_trigger *trig,
>>> + int channel)
>>> +{
>>> + struct iio_dev *indio_dev = iio_priv_to_dev(dac);
>>> + u32 shift = channel == STM32_DAC_CHANNEL_1 ? 0 : STM32_DAC_CHAN2_SHIFT;
>>> + u32 val = 0, tsel;
>>> + u32 msk = (STM32H7_DAC_CR_TEN1 | STM32H7_DAC_CR_TSEL1) << shift;
>>> +
>>> + dac->swtrig = false;
>>> + if (trig) {
>>> + /* select & enable trigger (tsel / ten) */
>>> + tsel = stm32_dac_get_trig_tsel(dac, trig);
>>> + val = tsel << STM32H7_DAC_CR_TSEL1_SHIFT;
>>> + val = (val | STM32H7_DAC_CR_TEN1) << shift;
>>> + }
>>> +
>>> + if (trig)
>>> + dev_dbg(&indio_dev->dev, "enable trigger: %s\n", trig->name);
>>> + else
>>> + dev_dbg(&indio_dev->dev, "disable trigger\n");
>>> +
>>> + return regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, val);
>>> +}
>>> +
>>> static int stm32_dac_is_enabled(struct stm32_dac *dac, int channel)
>>> {
>>> u32 en, val;
>>> @@ -63,9 +164,16 @@ static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
>>> STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
>>> int ret;
>>>
>>> + ret = stm32_dac_set_trig(dac, indio_dev->trig, channel);
>>> + if (ret < 0) {
>>> + dev_err(&indio_dev->dev, "Trigger setup failed\n");
>>> + return ret;
>>> + }
>>> +
>>> ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, en, en);
>>> if (ret < 0) {
>>> dev_err(&indio_dev->dev, "Enable failed\n");
>>> + stm32_dac_set_trig(dac, NULL, channel);
>>> return ret;
>>> }
>>>
>>> @@ -88,10 +196,12 @@ static int stm32_dac_disable(struct iio_dev *indio_dev, int channel)
>>> int ret;
>>>
>>> ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, en, 0);
>>> - if (ret)
>>> + if (ret) {
>>> dev_err(&indio_dev->dev, "Disable failed\n");
>>> + return ret;
>>> + }
>>>
>>> - return ret;
>>> + return stm32_dac_set_trig(dac, NULL, channel);
>>> }
>>>
>>> static int stm32_dac_get_value(struct stm32_dac *dac, int channel, int *val)
>>> @@ -258,10 +368,17 @@ static int stm32_dac_probe(struct platform_device *pdev)
>>> if (ret < 0)
>>> return ret;
>>>
>>> - ret = iio_device_register(indio_dev);
>>> + ret = iio_triggered_event_setup(indio_dev, NULL,
>>> + stm32_dac_trigger_handler);
>>> if (ret)
>>> return ret;
>>>
>>> + ret = iio_device_register(indio_dev);
>>> + if (ret) {
>>> + iio_triggered_event_cleanup(indio_dev);
>>> + return ret;
>>> + }
>>> +
>>> return 0;
>>> }
>>>
>>> @@ -269,6 +386,7 @@ static int stm32_dac_remove(struct platform_device *pdev)
>>> {
>>> struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>>
>>> + iio_triggered_event_cleanup(indio_dev);
>>> iio_device_unregister(indio_dev);
>>>
>>> return 0;
>>>
>>
>> --
>> 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
>>
>
^ permalink raw reply
* Re: [PATCH v5 22/23] drivers/fsi: Add hub master support
From: Randy Dunlap @ 2017-04-05 16:36 UTC (permalink / raw)
To: Christopher Bostic, robh+dt, mark.rutland, linux, rostedt, mingo,
gregkh, devicetree, linux-arm-kernel
Cc: andrew, alistair, linux-kernel, joel, benh, Jeremy Kerr
In-Reply-To: <20170405020607.79939-23-cbostic@linux.vnet.ibm.com>
On 04/04/17 19:06, Christopher Bostic wrote:
> From: Chris Bostic <cbostic@linux.vnet.ibm.com>
>
> Add an engine driver to expose a "hub" FSI master - which has a set of
> control registers in the engine address space, and uses a chunk of the
> slave address space for actual FSI communication.
>
> Additional changes from Jeremy Kerr <jk@ozlabs.org>.
>
> Signed-off-by: Chris Bostic <cbostic@linux.vnet.ibm.com>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/fsi/Kconfig | 9 ++
> drivers/fsi/Makefile | 1 +
> drivers/fsi/fsi-master-hub.c | 327 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 337 insertions(+)
> create mode 100644 drivers/fsi/fsi-master-hub.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 0fa265c..e1156b4 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -18,6 +18,15 @@ config FSI_MASTER_GPIO
> ---help---
> This option enables a FSI master driver using GPIO lines.
>
> +config FSI_MASTER_HUB
> + tristate "FSI hub master"
> + depends on FSI
redundant again.
> + ---help---
> + This option enables a FSI hub master driver. Hub is a type of FSI
> + master that is connected to the upstream master via a slave. Hubs
> + allow chaining of FSI links to an arbitrary depth. This allows for
> + a high target device fanout.
> +
> config FSI_SCOM
> tristate "SCOM FSI client device driver"
> depends on FSI
--
~Randy
^ permalink raw reply
* Re: [PATCH v5 21/23] drivers/fsi: Add SCOM FSI client device driver
From: Randy Dunlap @ 2017-04-05 16:35 UTC (permalink / raw)
To: Christopher Bostic, robh+dt, mark.rutland, linux, rostedt, mingo,
gregkh, devicetree, linux-arm-kernel
Cc: andrew, alistair, linux-kernel, joel, Edward A . James, benh,
Jeremy Kerr
In-Reply-To: <20170405020607.79939-22-cbostic@linux.vnet.ibm.com>
On 04/04/17 19:06, Christopher Bostic wrote:
> From: Chris Bostic <cbostic@linux.vnet.ibm.com>
>
> Create a simple SCOM engine device driver that reads and writes
> its control registers via an FSI bus.
>
> Includes changes from Edward A. James <eajames@us.ibm.com>.
>
> Signed-off-by: Chris Bostic <cbostic@linux.vnet.ibm.com>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Signed-off-by: Edward A. James <eajames@us.ibm.com>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
> ---
> drivers/fsi/Kconfig | 6 ++
> drivers/fsi/Makefile | 1 +
> drivers/fsi/fsi-scom.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 270 insertions(+)
> create mode 100644 drivers/fsi/fsi-scom.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 9cf8345..0fa265c 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -18,6 +18,12 @@ config FSI_MASTER_GPIO
> ---help---
> This option enables a FSI master driver using GPIO lines.
>
> +config FSI_SCOM
> + tristate "SCOM FSI client device driver"
> + depends on FSI
depends on FSI is redundant.
> + ---help---
> + This option enables an FSI based SCOM device driver.
> +
> endif
>
--
~Randy
^ permalink raw reply
* Re: [PATCH v5 19/23] drivers/fsi: Add GPIO based FSI master
From: Randy Dunlap @ 2017-04-05 16:35 UTC (permalink / raw)
To: Christopher Bostic, robh+dt, mark.rutland, linux, rostedt, mingo,
gregkh, devicetree, linux-arm-kernel
Cc: andrew, alistair, linux-kernel, joel, Edward A . James, benh,
Jeremy Kerr
In-Reply-To: <20170405020607.79939-20-cbostic@linux.vnet.ibm.com>
On 04/04/17 19:06, Christopher Bostic wrote:
> From: Chris Bostic <cbostic@linux.vnet.ibm.com>
>
> Implement a FSI master using GPIO. Will generate FSI protocol for
> read and write commands to particular addresses. Sends master command
> and waits for and decodes a slave response.
>
> Includes changes from Edward A. James <eajames@us.ibm.com> and Jeremy
> Kerr <jk@ozlabs.org>.
>
> Signed-off-by: Edward A. James <eajames@us.ibm.com>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
> Signed-off-by: Chris Bostic <cbostic@linux.vnet.ibm.com>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/fsi/Kconfig | 11 +
> drivers/fsi/Makefile | 1 +
> drivers/fsi/fsi-master-gpio.c | 610 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 622 insertions(+)
> create mode 100644 drivers/fsi/fsi-master-gpio.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 04c1a0e..9cf8345 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -9,4 +9,15 @@ config FSI
> ---help---
> FSI - the FRU Support Interface - is a simple bus for low-level
> access to POWER-based hardware.
> +
> +if FSI
> +
> +config FSI_MASTER_GPIO
> + tristate "GPIO-based FSI master"
> + depends on FSI && GPIOLIB
depends on FSI is redundant since "if FSI" does the same thing.
> + ---help---
> + This option enables a FSI master driver using GPIO lines.
> +
> +endif
> +
--
~Randy
^ permalink raw reply
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