* Re: [RESEND PATCH 1/2] arc: axs10x: Add DT bindings for I2S audio playback
From: Vineet Gupta @ 2017-04-26 23:31 UTC (permalink / raw)
To: Jose Abreu,
linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: Carlos Palminha, Alexey Brodkin, Rob Herring,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <c02ea9db-db90-1b2e-1baf-f2940e64201f-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
On 04/26/2017 01:55 AM, Jose Abreu wrote:
> Hi Vineet,
>
>
> On 24-04-2017 18:36, Vineet Gupta wrote:
>> On 04/21/2017 03:15 AM, Jose Abreu wrote:
>>> This patch adds the necessary DT bindings to get HDMI audio
>>> output in ARC AXS10x SDP. The bindings for I2S controller were
>>> added as well as the bindings for simple audio card.
>> Are these waiting on Rob or is it OK for me to pick these up for 4.12 ?
> Yes, I was waiting for Rob ack but he has been silent. It would
> be nice if these went for 4.12.
Ok lets wait another couple of days before I pick those up.
In the mean time, can you please restest the series against 4.11-rcX and report
here that patches are still valid and do as intended !
Thx,
-Vineet
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 2/2] Input: add support for the STMicroelectronics FingerTip touchscreen
From: Dmitry Torokhov @ 2017-04-27 0:39 UTC (permalink / raw)
To: Andi Shyti
Cc: Rob Herring, Javier Martinez Canillas, Andrzej Hajda,
Chanwoo Choi, linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andi Shyti
In-Reply-To: <20170327130743.27783-3-andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Hi Andi,
Quick question:
On Mon, Mar 27, 2017 at 10:07:43PM +0900, Andi Shyti wrote:
> +static irqreturn_t stmfts_irq_handler(int irq, void *dev)
> +{
> + struct stmfts_data *sdata = dev;
> + int ret;
> +
> + mutex_lock(&sdata->mutex);
> + ret = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_ONE_EVENT,
> + STMFTS_EVENT_SIZE, sdata->data);
> +
> + if (ret < 0 || ret != STMFTS_EVENT_SIZE)
> + goto exit;
Why do we split read into 2 chunks? Can we issue STMFTS_READ_ALL_EVENT
right away instead of reading first event, analyzing it, and then (maybe)
fetching the rest?
Also, why do we use smbus protocol for the first event and i2c for the
rest?
Thanks.
--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2] NFC: trf7970a: Correct register settings for 27MHz clock
From: Geoff Lansberry @ 2017-04-27 1:41 UTC (permalink / raw)
To: linux-wireless, sameo
Cc: kernel-janitors, linux-kernel, linux-nfc, devicetree, mgreer,
justin, colin.king, wharms, Geoff Lansberry
In prior commits the selected clock frequency does not propagate
correctly to what is written the the TRF7970A_MODULATOR_SYS_CLK_CTRL
register.
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
---
drivers/nfc/trf7970a.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 5f040e6..c278b0e 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -2079,6 +2079,13 @@ static int trf7970a_probe(struct spi_device *spi)
return -EINVAL;
}
+ if (clk_freq == TRF7970A_27MHZ_CLOCK_FREQUENCY) {
+ trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_27MHZ;
+ dev_dbg(trf->dev, "trf7970a configured for 27MHz crystal\n");
+ } else {
+ trf->modulator_sys_clk_ctrl = 0;
+ }
+
if (of_property_read_bool(np, "en2-rf-quirk"))
trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 0/9][resend] ASoC: add OF-graph base simple-card
From: Kuninori Morimoto @ 2017-04-27 1:59 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
Hi Mark, Rob
These are resend of v7 of OF-graph sound card support.
I posted because Japan will have long holiday from tomorrow
1) - 4) : OF-graph base functions
5) - 9) : OF-graph + simple-card (= audio_graph_card)
Kuninori Morimoto (9):
of-graph: export symbol of_phandle_iterator_init/next
of_graph: add of_graph_get_remote_endpoint()
of_graph: add of_graph_get_port_parent()
of_graph: add of_graph_get_endpoint_count()
ASoC: soc-core: enable "dai-format" on snd_soc_of_parse_daifmt()
ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name
ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
ASoC: add audio-graph-card document
ASoC: add audio-graph-card support
.../devicetree/bindings/sound/audio-graph-card.txt | 124 +++++++++
drivers/of/base.c | 62 ++++-
include/linux/of_graph.h | 21 ++
include/sound/simple_card_utils.h | 10 +
sound/soc/generic/Kconfig | 8 +
sound/soc/generic/Makefile | 2 +
sound/soc/generic/audio-graph-card.c | 308 +++++++++++++++++++++
sound/soc/generic/simple-card-utils.c | 73 ++++-
sound/soc/soc-core.c | 10 +-
9 files changed, 600 insertions(+), 18 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/audio-graph-card.txt
create mode 100644 sound/soc/generic/audio-graph-card.c
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v7 1/9][resend] of-graph: export symbol of_phandle_iterator_init/next
From: Kuninori Morimoto @ 2017-04-27 2:01 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
of_for_each_phandle() uses of_phandle_iterator_init/next
but it isn't exported. So kernel module complile will say
ERROR: "of_phandle_iterator_init" [xxx.ko] undefined!
ERROR: "of_phandle_iterator_next" [xxx.ko] undefined!
This patch solved this issue
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
v6 -> v7
- no change
drivers/of/base.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d7c4629..d9adaa9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1570,6 +1570,7 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,
return 0;
}
+EXPORT_SYMBOL_GPL(of_phandle_iterator_init);
int of_phandle_iterator_next(struct of_phandle_iterator *it)
{
@@ -1639,6 +1640,7 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it)
return -EINVAL;
}
+EXPORT_SYMBOL_GPL(of_phandle_iterator_next);
int of_phandle_iterator_args(struct of_phandle_iterator *it,
uint32_t *args,
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 2/9][resend] of_graph: add of_graph_get_remote_endpoint()
From: Kuninori Morimoto @ 2017-04-27 2:01 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
It should use same method to get same result.
To getting remote-endpoint node,
let's use of_graph_get_remote_endpoint()
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- no change
drivers/of/base.c | 18 ++++++++++++++++--
include/linux/of_graph.h | 8 ++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d9adaa9..1ae2510 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2457,6 +2457,20 @@ struct device_node *of_graph_get_endpoint_by_regs(
EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
/**
+ * of_graph_get_remote_endpoint() - get remote endpoint node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote endpoint node associated with remote endpoint node linked
+ * to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
+{
+ /* Get remote endpoint node. */
+ return of_parse_phandle(node, "remote-endpoint", 0);
+}
+EXPORT_SYMBOL(of_graph_get_remote_endpoint);
+
+/**
* of_graph_get_remote_port_parent() - get remote port's parent node
* @node: pointer to a local endpoint device_node
*
@@ -2470,7 +2484,7 @@ struct device_node *of_graph_get_remote_port_parent(
unsigned int depth;
/* Get remote endpoint node. */
- np = of_parse_phandle(node, "remote-endpoint", 0);
+ np = of_graph_get_remote_endpoint(node);
/* Walk 3 levels up only if there is 'ports' node. */
for (depth = 3; depth && np; depth--) {
@@ -2494,7 +2508,7 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
struct device_node *np;
/* Get remote endpoint node. */
- np = of_parse_phandle(node, "remote-endpoint", 0);
+ np = of_graph_get_remote_endpoint(node);
if (!np)
return NULL;
return of_get_next_parent(np);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index abdb02e..0c9473a 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -48,6 +48,8 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
struct device_node *of_graph_get_endpoint_by_regs(
const struct device_node *parent, int port_reg, int reg);
+struct device_node *of_graph_get_remote_endpoint(
+ const struct device_node *node);
struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node);
struct device_node *of_graph_get_remote_port(const struct device_node *node);
@@ -80,6 +82,12 @@ static inline struct device_node *of_graph_get_endpoint_by_regs(
return NULL;
}
+static inline struct device_node *of_graph_get_remote_endpoint(
+ const struct device_node *node)
+{
+ return NULL;
+}
+
static inline struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node)
{
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 3/9][resend] of_graph: add of_graph_get_port_parent()
From: Kuninori Morimoto @ 2017-04-27 2:02 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Linux kernel already has of_graph_get_remote_port_parent(),
but, sometimes we want to get own port parent.
This patch adds of_graph_get_port_parent()
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- no change
drivers/of/base.c | 30 ++++++++++++++++++++++--------
include/linux/of_graph.h | 7 +++++++
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1ae2510..acda15b 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2471,6 +2471,27 @@ struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
EXPORT_SYMBOL(of_graph_get_remote_endpoint);
/**
+ * of_graph_get_port_parent() - get port's parent node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: device node associated with endpoint node linked
+ * to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_port_parent(struct device_node *node)
+{
+ unsigned int depth;
+
+ /* Walk 3 levels up only if there is 'ports' node. */
+ for (depth = 3; depth && node; depth--) {
+ node = of_get_next_parent(node);
+ if (depth == 2 && of_node_cmp(node->name, "ports"))
+ break;
+ }
+ return node;
+}
+EXPORT_SYMBOL(of_graph_get_port_parent);
+
+/**
* of_graph_get_remote_port_parent() - get remote port's parent node
* @node: pointer to a local endpoint device_node
*
@@ -2481,18 +2502,11 @@ struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node)
{
struct device_node *np;
- unsigned int depth;
/* Get remote endpoint node. */
np = of_graph_get_remote_endpoint(node);
- /* Walk 3 levels up only if there is 'ports' node. */
- for (depth = 3; depth && np; depth--) {
- np = of_get_next_parent(np);
- if (depth == 2 && of_node_cmp(np->name, "ports"))
- break;
- }
- return np;
+ return of_graph_get_port_parent(np);
}
EXPORT_SYMBOL(of_graph_get_remote_port_parent);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 0c9473a..9db632d 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -50,6 +50,7 @@ struct device_node *of_graph_get_endpoint_by_regs(
const struct device_node *parent, int port_reg, int reg);
struct device_node *of_graph_get_remote_endpoint(
const struct device_node *node);
+struct device_node *of_graph_get_port_parent(struct device_node *node);
struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node);
struct device_node *of_graph_get_remote_port(const struct device_node *node);
@@ -88,6 +89,12 @@ static inline struct device_node *of_graph_get_remote_endpoint(
return NULL;
}
+static inline struct device_node *of_graph_get_port_parent(
+ struct device_node *node)
+{
+ return NULL;
+}
+
static inline struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node)
{
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 4/9][resend] of_graph: add of_graph_get_endpoint_count()
From: Kuninori Morimoto @ 2017-04-27 2:02 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
OF graph want to count its endpoint number, same as
of_get_child_count(). This patch adds of_graph_get_endpoint_count()
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- no change
drivers/of/base.c | 12 ++++++++++++
include/linux/of_graph.h | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index acda15b..bc42f91 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2529,6 +2529,18 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
}
EXPORT_SYMBOL(of_graph_get_remote_port);
+int of_graph_get_endpoint_count(const struct device_node *np)
+{
+ struct device_node *endpoint;
+ int num = 0;
+
+ for_each_endpoint_of_node(np, endpoint)
+ num++;
+
+ return num;
+}
+EXPORT_SYMBOL(of_graph_get_endpoint_count);
+
/**
* of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
* @node: pointer to parent device_node containing graph port/endpoint
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 9db632d..3e058f0 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -43,6 +43,7 @@ struct of_endpoint {
#ifdef CONFIG_OF
int of_graph_parse_endpoint(const struct device_node *node,
struct of_endpoint *endpoint);
+int of_graph_get_endpoint_count(const struct device_node *np);
struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
@@ -64,6 +65,11 @@ static inline int of_graph_parse_endpoint(const struct device_node *node,
return -ENOSYS;
}
+static inline int of_graph_get_endpoint_count(const struct device_node *np)
+{
+ return 0;
+}
+
static inline struct device_node *of_graph_get_port_by_id(
struct device_node *node, u32 id)
{
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 5/9][resend] ASoC: soc-core: enable "dai-format" on snd_soc_of_parse_daifmt()
From: Kuninori Morimoto @ 2017-04-27 2:02 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Current snd_soc_of_parse_daifmt() detects [prefix]format, but
"format" was unclear in some case. This patch checks "dai-format"
first, and try to check "[prefix]format" if "dai-format" was not
exist.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- no change
sound/soc/soc-core.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 8be2ce1..e84a820 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3955,11 +3955,15 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
prefix = "";
/*
- * check "[prefix]format = xxx"
+ * check "dai-format = xxx"
+ * or "[prefix]format = xxx"
* SND_SOC_DAIFMT_FORMAT_MASK area
*/
- snprintf(prop, sizeof(prop), "%sformat", prefix);
- ret = of_property_read_string(np, prop, &str);
+ ret = of_property_read_string(np, "dai-format", &str);
+ if (ret < 0) {
+ snprintf(prop, sizeof(prop), "%sformat", prefix);
+ ret = of_property_read_string(np, prop, &str);
+ }
if (ret == 0) {
for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
if (strcmp(str, of_fmt_table[i].name) == 0) {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 6/9][resend] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name
From: Kuninori Morimoto @ 2017-04-27 2:02 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Current asoc_simple_card_parse_card_name() detects [prefix]name,
but in generally, we uses "label" for user visible names.
This patch enables it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- don't allow "[prefix]label"
sound/soc/generic/simple-card-utils.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 343b291..c5ab8ad 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -81,15 +81,21 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix)
{
- char prop[128];
int ret;
- snprintf(prop, sizeof(prop), "%sname", prefix);
+ if (!prefix)
+ prefix = "";
/* Parse the card name from DT */
- ret = snd_soc_of_parse_card_name(card, prop);
- if (ret < 0)
- return ret;
+ ret = snd_soc_of_parse_card_name(card, "label");
+ if (ret < 0) {
+ char prop[128];
+
+ snprintf(prop, sizeof(prop), "%sname", prefix);
+ ret = snd_soc_of_parse_card_name(card, prop);
+ if (ret < 0)
+ return ret;
+ }
if (!card->name && card->dai_link)
card->name = card->dai_link->name;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 7/9][resend] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
From: Kuninori Morimoto @ 2017-04-27 2:03 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
simple-card already has asoc_simple_card_parse_dai(),
but graph base parsing needs graph specific version of it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- no change
include/sound/simple_card_utils.h | 10 ++++++
sound/soc/generic/simple-card-utils.c | 57 +++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index af58d23..efab584 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -60,6 +60,16 @@ int asoc_simple_card_parse_dai(struct device_node *node,
const char *cells_name,
int *is_single_links);
+#define asoc_simple_card_parse_graph_cpu(ep, dai_link) \
+ asoc_simple_card_parse_graph_dai(ep, &dai_link->cpu_of_node, \
+ &dai_link->cpu_dai_name)
+#define asoc_simple_card_parse_graph_codec(ep, dai_link) \
+ asoc_simple_card_parse_graph_dai(ep, &dai_link->codec_of_node, \
+ &dai_link->codec_dai_name)
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+ struct device_node **endpoint_np,
+ const char **dai_name);
+
int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
struct asoc_simple_dai *simple_dai);
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index c5ab8ad..5a3d51e 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <sound/simple_card_utils.h>
int asoc_simple_card_parse_daifmt(struct device *dev,
@@ -171,6 +172,62 @@ int asoc_simple_card_parse_dai(struct device_node *node,
}
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
+static int asoc_simple_card_get_dai_id(struct device_node *ep)
+{
+ struct device_node *node;
+ struct device_node *endpoint;
+ int i, id;
+
+ node = of_graph_get_port_parent(ep);
+
+ i = 0;
+ id = -1;
+ for_each_endpoint_of_node(node, endpoint) {
+ if (endpoint == ep)
+ id = i;
+ i++;
+ }
+ if (id < 0)
+ return -ENODEV;
+
+ return id;
+}
+
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+ struct device_node **dai_of_node,
+ const char **dai_name)
+{
+ struct device_node *node;
+ struct of_phandle_args args;
+ int ret;
+
+ if (!ep)
+ return 0;
+ if (!dai_name)
+ return 0;
+
+ /*
+ * of_graph_get_port_parent() will call
+ * of_node_put(). So, call of_node_get() here
+ */
+ of_node_get(ep);
+ node = of_graph_get_port_parent(ep);
+
+ /* Get dai->name */
+ args.np = node;
+ args.args[0] = asoc_simple_card_get_dai_id(ep);
+ args.args_count = (of_graph_get_endpoint_count(node) > 1);
+
+ ret = snd_soc_get_dai_name(&args, dai_name);
+ if (ret < 0)
+ return ret;
+
+ *dai_of_node = node;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai);
+
int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
struct asoc_simple_dai *simple_dai)
{
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 8/9][resend] ASoC: add audio-graph-card document
From: Kuninori Morimoto @ 2017-04-27 2:03 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
"Audio Graph Card" = "Simple Card" + "OF-graph"
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
v6 -> v7
- no change
.../devicetree/bindings/sound/audio-graph-card.txt | 124 +++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/audio-graph-card.txt
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card.txt b/Documentation/devicetree/bindings/sound/audio-graph-card.txt
new file mode 100644
index 0000000..bac4b1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/audio-graph-card.txt
@@ -0,0 +1,124 @@
+Audio Graph Card:
+
+Audio Graph Card specifies audio DAI connections of SoC <-> codec.
+It is based on common bindings for device graphs.
+see ${LINUX}/Documentation/devicetree/bindings/graph.txt
+
+Basically, Audio Graph Card property is same as Simple Card.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+
+Below are same as Simple-Card.
+
+- label
+- dai-format
+- frame-master
+- bitclock-master
+- bitclock-inversion
+- frame-inversion
+- dai-tdm-slot-num
+- dai-tdm-slot-width
+- clocks / system-clock-frequency
+
+Required properties:
+
+- compatible : "audio-graph-card";
+- dais : list of CPU DAI port{s}
+
+Example: Single DAI case
+
+ sound_card {
+ compatible = "audio-graph-card";
+
+ dais = <&cpu_port>;
+ };
+
+ dai-controller {
+ ...
+ cpu_port: port {
+ cpu_endpoint: endpoint {
+ remote-endpoint = <&codec_endpoint>;
+
+ dai-format = "left_j";
+ ...
+ };
+ };
+ };
+
+ audio-codec {
+ ...
+ port {
+ codec_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint>;
+ };
+ };
+ };
+
+Example: Multi DAI case
+
+ sound-card {
+ compatible = "audio-graph-card";
+
+ label = "sound-card";
+
+ dais = <&cpu_port0
+ &cpu_port1
+ &cpu_port2>;
+ };
+
+ audio-codec@0 {
+ ...
+ port {
+ codec0_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint0>;
+ };
+ };
+ };
+
+ audio-codec@1 {
+ ...
+ port {
+ codec1_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint1>;
+ };
+ };
+ };
+
+ audio-codec@2 {
+ ...
+ port {
+ codec2_endpoint: endpoint {
+ remote-endpoint = <&cpu_endpoint2>;
+ };
+ };
+ };
+
+ dai-controller {
+ ...
+ ports {
+ cpu_port0: port@0 {
+ cpu_endpoint0: endpoint {
+ remote-endpoint = <&codec0_endpoint>;
+
+ dai-format = "left_j";
+ ...
+ };
+ };
+ cpu_port1: port@1 {
+ cpu_endpoint1: endpoint {
+ remote-endpoint = <&codec1_endpoint>;
+
+ dai-format = "i2s";
+ ...
+ };
+ };
+ cpu_port2: port@2 {
+ cpu_endpoint2: endpoint {
+ remote-endpoint = <&codec2_endpoint>;
+
+ dai-format = "i2s";
+ ...
+ };
+ };
+ };
+ };
+
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 9/9][resend] ASoC: add audio-graph-card support
From: Kuninori Morimoto @ 2017-04-27 2:03 UTC (permalink / raw)
To: Mark Brown, Rob Herring; +Cc: Linux-ALSA, Simon, Linux-DT
In-Reply-To: <871ssesjgn.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
OF-graph base DT binding are used on V4L2, and ALSA SoC is using
different style of DT today. Now ALSA SoC supports simple-card driver
for generic/simple sound card.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged.
This patch adds new Audio Graph Card which is OF-graph base of
simple-card
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
v6 -> v7
- no change
sound/soc/generic/Kconfig | 8 +
sound/soc/generic/Makefile | 2 +
sound/soc/generic/audio-graph-card.c | 308 +++++++++++++++++++++++++++++++++++
3 files changed, 318 insertions(+)
create mode 100644 sound/soc/generic/audio-graph-card.c
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index d023959..121a48e 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -14,3 +14,11 @@ config SND_SIMPLE_SCU_CARD
help
This option enables generic simple SCU sound card support.
It supports DPCM of multi CPU single Codec system.
+
+config SND_AUDIO_GRAPH_CARD
+ tristate "ASoC Audio Graph sound card support"
+ depends on OF
+ select SND_SIMPLE_CARD_UTILS
+ help
+ This option enables generic simple simple sound card support
+ with OF-graph DT bindings.
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index ee750f3..670068f 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,7 +1,9 @@
snd-soc-simple-card-utils-objs := simple-card-utils.o
snd-soc-simple-card-objs := simple-card.o
snd-soc-simple-scu-card-objs := simple-scu-card.o
+snd-soc-audio-graph-card-objs := audio-graph-card.o
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
obj-$(CONFIG_SND_SIMPLE_SCU_CARD) += snd-soc-simple-scu-card.o
+obj-$(CONFIG_SND_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
new file mode 100644
index 0000000..07e010d
--- /dev/null
+++ b/sound/soc/generic/audio-graph-card.c
@@ -0,0 +1,308 @@
+/*
+ * ASoC audio graph sound card support
+ *
+ * Copyright (C) 2016 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
+ *
+ * based on ${LINUX}/sound/soc/generic/simple-card.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/simple_card_utils.h>
+
+struct graph_card_data {
+ struct snd_soc_card snd_card;
+ struct graph_dai_props {
+ struct asoc_simple_dai cpu_dai;
+ struct asoc_simple_dai codec_dai;
+ } *dai_props;
+ struct snd_soc_dai_link *dai_link;
+};
+
+#define graph_priv_to_card(priv) (&(priv)->snd_card)
+#define graph_priv_to_props(priv, i) ((priv)->dai_props + (i))
+#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev)
+#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
+
+static int asoc_graph_card_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
+ int ret;
+
+ ret = clk_prepare_enable(dai_props->cpu_dai.clk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(dai_props->codec_dai.clk);
+ if (ret)
+ clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+ return ret;
+}
+
+static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
+
+ clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+ clk_disable_unprepare(dai_props->codec_dai.clk);
+}
+
+static struct snd_soc_ops asoc_graph_card_ops = {
+ .startup = asoc_graph_card_startup,
+ .shutdown = asoc_graph_card_shutdown,
+};
+
+static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *codec = rtd->codec_dai;
+ struct snd_soc_dai *cpu = rtd->cpu_dai;
+ struct graph_dai_props *dai_props =
+ graph_priv_to_props(priv, rtd->num);
+ int ret;
+
+ ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
+ struct graph_card_data *priv,
+ int idx)
+{
+ struct device *dev = graph_priv_to_dev(priv);
+ struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, idx);
+ struct graph_dai_props *dai_props = graph_priv_to_props(priv, idx);
+ struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
+ struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
+ struct snd_soc_card *card = graph_priv_to_card(priv);
+ struct device_node *cpu_ep = of_get_next_child(cpu_port, NULL);
+ struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+ struct device_node *rcpu_ep = of_graph_get_remote_endpoint(codec_ep);
+ int ret;
+
+ if (rcpu_ep != cpu_ep) {
+ dev_err(dev, "remote-endpoint missmatch (%s/%s/%s)\n",
+ cpu_ep->name, codec_ep->name, rcpu_ep->name);
+ ret = -EINVAL;
+ goto dai_link_of_err;
+ }
+
+ ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
+ NULL, &dai_link->dai_fmt);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ /*
+ * we need to consider "mclk-fs" around here
+ * see simple-card
+ */
+
+ ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = snd_soc_of_parse_tdm_slot(cpu_ep,
+ &cpu_dai->tx_slot_mask,
+ &cpu_dai->rx_slot_mask,
+ &cpu_dai->slots,
+ &cpu_dai->slot_width);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = snd_soc_of_parse_tdm_slot(codec_ep,
+ &codec_dai->tx_slot_mask,
+ &codec_dai->rx_slot_mask,
+ &codec_dai->slots,
+ &codec_dai->slot_width);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_canonicalize_dailink(dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+ "%s-%s",
+ dai_link->cpu_dai_name,
+ dai_link->codec_dai_name);
+ if (ret < 0)
+ goto dai_link_of_err;
+
+ dai_link->ops = &asoc_graph_card_ops;
+ dai_link->init = asoc_graph_card_dai_init;
+
+ dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
+ dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
+ dev_dbg(dev, "\tcpu : %s / %d\n",
+ dai_link->cpu_dai_name,
+ cpu_dai->sysclk);
+ dev_dbg(dev, "\tcodec : %s / %d\n",
+ dai_link->codec_dai_name,
+ codec_dai->sysclk);
+
+ asoc_simple_card_canonicalize_cpu(dai_link,
+ card->num_links == 1);
+
+dai_link_of_err:
+ of_node_put(cpu_ep);
+ of_node_put(rcpu_ep);
+ of_node_put(codec_ep);
+
+ return ret;
+}
+
+static int asoc_graph_card_parse_of(struct graph_card_data *priv)
+{
+ struct of_phandle_iterator it;
+ struct device *dev = graph_priv_to_dev(priv);
+ struct snd_soc_card *card = graph_priv_to_card(priv);
+ struct device_node *node = dev->of_node;
+ int rc, idx = 0;
+ int ret;
+
+ /*
+ * we need to consider "widgets", "routing", "mclk-fs" around here
+ * see simple-card
+ */
+
+ of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
+ ret = asoc_graph_card_dai_link_of(it.node, priv, idx++);
+ of_node_put(it.node);
+ if (ret < 0)
+ return ret;
+ }
+
+ return asoc_simple_card_parse_card_name(card, NULL);
+}
+
+static int asoc_graph_get_dais_count(struct device *dev)
+{
+ struct of_phandle_iterator it;
+ struct device_node *node = dev->of_node;
+ int count = 0;
+ int rc;
+
+ of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
+ count++;
+ of_node_put(it.node);
+ }
+
+ return count;
+}
+
+static int asoc_graph_card_probe(struct platform_device *pdev)
+{
+ struct graph_card_data *priv;
+ struct snd_soc_dai_link *dai_link;
+ struct graph_dai_props *dai_props;
+ struct device *dev = &pdev->dev;
+ struct snd_soc_card *card;
+ int num, ret;
+
+ /* Allocate the private data and the DAI link array */
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ num = asoc_graph_get_dais_count(dev);
+ if (num == 0)
+ return -EINVAL;
+
+ dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+ dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL);
+ if (!dai_props || !dai_link)
+ return -ENOMEM;
+
+ priv->dai_props = dai_props;
+ priv->dai_link = dai_link;
+
+ /* Init snd_soc_card */
+ card = graph_priv_to_card(priv);
+ card->owner = THIS_MODULE;
+ card->dev = dev;
+ card->dai_link = dai_link;
+ card->num_links = num;
+
+ ret = asoc_graph_card_parse_of(priv);
+ if (ret < 0) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "parse error %d\n", ret);
+ goto err;
+ }
+
+ snd_soc_card_set_drvdata(card, priv);
+
+ ret = devm_snd_soc_register_card(dev, card);
+ if (ret >= 0)
+ return ret;
+err:
+ asoc_simple_card_clean_reference(card);
+
+ return ret;
+}
+
+static int asoc_graph_card_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ return asoc_simple_card_clean_reference(card);
+}
+
+static const struct of_device_id asoc_graph_of_match[] = {
+ { .compatible = "audio-graph-card", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
+
+static struct platform_driver asoc_graph_card = {
+ .driver = {
+ .name = "asoc-audio-graph-card",
+ .of_match_table = asoc_graph_of_match,
+ },
+ .probe = asoc_graph_card_probe,
+ .remove = asoc_graph_card_remove,
+};
+module_platform_driver(asoc_graph_card);
+
+MODULE_ALIAS("platform:asoc-audio-graph-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Audio Graph Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>");
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2] NFC: trf7970a: Correct register settings for 27MHz clock
From: Mark Greer @ 2017-04-27 4:02 UTC (permalink / raw)
To: Geoff Lansberry
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
sameo-VuQAYsv1563Yd54FQh9/CA,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-nfc-hn68Rpc1hR1g9hUCZPvPmw,
devicetree-u79uwXL29TY76Z2rM5mHXA, mgreer-luAo+O/VEmrlveNOaEYElw,
justin-R+k406RtEhcAvxtiuMwx3w, colin.king-Z7WLFzj8eWMS+FvcfC7Uqw,
wharms-fPG8STNUNVg
In-Reply-To: <1493257308-32503-1-git-send-email-geoff-R+k406RtEhcAvxtiuMwx3w@public.gmane.org>
On Wed, Apr 26, 2017 at 09:41:48PM -0400, Geoff Lansberry wrote:
Hi Geoff.
> In prior commits the selected clock frequency does not propagate
> correctly to what is written the the TRF7970A_MODULATOR_SYS_CLK_CTRL
> register.
>
> Signed-off-by: Geoff Lansberry <geoff-R+k406RtEhcAvxtiuMwx3w@public.gmane.org>
> ---
> drivers/nfc/trf7970a.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
> index 5f040e6..c278b0e 100644
> --- a/drivers/nfc/trf7970a.c
> +++ b/drivers/nfc/trf7970a.c
> @@ -2079,6 +2079,13 @@ static int trf7970a_probe(struct spi_device *spi)
> return -EINVAL;
> }
>
> + if (clk_freq == TRF7970A_27MHZ_CLOCK_FREQUENCY) {
> + trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_27MHZ;
> + dev_dbg(trf->dev, "trf7970a configured for 27MHz crystal\n");
> + } else {
> + trf->modulator_sys_clk_ctrl = 0;
> + }
> +
> if (of_property_read_bool(np, "en2-rf-quirk"))
> trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
Looks fine to me but please rebase it on top of current nfc-next/master
as it doesn't apply to it right now.
Thanks,
Mark
--
--
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] iio: adc: Drop if clock from Renesas GyroADC bindings
From: Jonathan Cameron @ 2017-04-27 5:01 UTC (permalink / raw)
To: Geert Uytterhoeven, Marek Vasut
Cc: Linux-Renesas, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Marek Vasut, Geert Uytterhoeven, Rob Herring
In-Reply-To: <CAMuHMdXFMOZ0c4ptVCUpTK0u7aHfUx1=HfvSozgnbFjJDRorxA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 20/04/17 18:30, Geert Uytterhoeven wrote:
> On Thu, Apr 20, 2017 at 5:42 PM, Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> The "if" interface clock speed is actually derived from the "fck"
>> block clock, as in the hardware they are the same clock. Drop the
>> incorrect second "if" clock and retain only the "fck" clock.
>>
>> Signed-off-by: Marek Vasut <marek.vasut+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Cc: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
>> Cc: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Cc: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> To: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
Applied to the togreg branch of iio.git and pushed out as testing.
Device tree ack welcome, but I 'think' this is safe enough to take without
as it won't break any existing device trees.
Jonathan
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/3] iio: adc: at91-sama5d2_adc: add hw trigger and buffer support
From: Jonathan Cameron @ 2017-04-27 5:18 UTC (permalink / raw)
To: Eugen Hristev, nicolas.ferre, alexandre.belloni, linux-iio, lars,
linux-arm-kernel, devicetree, linux-kernel
Cc: ludovic.desroches
In-Reply-To: <1492590045-17329-3-git-send-email-eugen.hristev@microchip.com>
On 19/04/17 09:20, Eugen Hristev wrote:
> Added support for the external hardware trigger on pin ADTRG,
> integrated the three possible edge triggers into the subsystem
> and created buffer management for data retrieval
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
> drivers/iio/adc/at91-sama5d2_adc.c | 207 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 204 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index e10dca3..09a8c3d 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -23,8 +23,15 @@
> #include <linux/platform_device.h>
> #include <linux/sched.h>
> #include <linux/wait.h>
> +#include <linux/slab.h>
> +
> #include <linux/iio/iio.h>
> #include <linux/iio/sysfs.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +
> #include <linux/regulator/consumer.h>
>
> /* Control Register */
> @@ -132,6 +139,17 @@
> #define AT91_SAMA5D2_PRESSR 0xbc
> /* Trigger Register */
> #define AT91_SAMA5D2_TRGR 0xc0
> +/* Mask for TRGMOD field of TRGR register */
> +#define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
> +/* No trigger, only software trigger can start conversions */
> +#define AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER 0
> +/* Trigger Mode external trigger rising edge */
> +#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE 1
> +/* Trigger Mode external trigger falling edge */
> +#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL 2
> +/* Trigger Mode external trigger any edge */
> +#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY 3
> +
> /* Correction Select Register */
> #define AT91_SAMA5D2_COSR 0xd0
> /* Correction Value Register */
> @@ -145,14 +163,20 @@
> /* Version Register */
> #define AT91_SAMA5D2_VERSION 0xfc
>
> +#define AT91_SAMA5D2_HW_TRIG_CNT 3
> +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> +
> #define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \
> { \
> .type = IIO_VOLTAGE, \
> .channel = num, \
> .address = addr, \
> + .scan_index = num, \
> .scan_type = { \
> .sign = 'u', \
> .realbits = 12, \
> + .storagebits = 16, \
> }, \
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> @@ -168,9 +192,11 @@
> .channel = num, \
> .channel2 = num2, \
> .address = addr, \
> + .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT, \
> .scan_type = { \
> .sign = 's', \
> .realbits = 12, \
> + .storagebits = 16, \
> }, \
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> @@ -188,18 +214,26 @@ struct at91_adc_soc_info {
> unsigned max_sample_rate;
> };
>
> +struct at91_adc_trigger {
> + char *name;
> + unsigned int trgmod_value;
> +};
> +
> struct at91_adc_state {
> void __iomem *base;
> int irq;
> struct clk *per_clk;
> struct regulator *reg;
> struct regulator *vref;
> + u16 *buffer;
> int vref_uv;
> const struct iio_chan_spec *chan;
> bool conversion_done;
> u32 conversion_value;
> struct at91_adc_soc_info soc_info;
> wait_queue_head_t wq_data_available;
> + struct iio_trigger **trig;
> + const struct at91_adc_trigger *trigger_list;
> /*
> * lock to prevent concurrent 'single conversion' requests through
> * sysfs.
> @@ -207,6 +241,21 @@ struct at91_adc_state {
> struct mutex lock;
> };
>
> +static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> + {
> + .name = "external-rising",
> + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE,
> + },
> + {
> + .name = "external-falling",
> + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL,
> + },
> + {
> + .name = "external-any",
> + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY,
> + },
> +};
> +
> static const struct iio_chan_spec at91_adc_channels[] = {
> AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> @@ -226,8 +275,141 @@ static const struct iio_chan_spec at91_adc_channels[] = {
> AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> + IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_SINGLE_CHAN_CNT
> + + AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
> };
>
> +static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> +{
> + struct iio_dev *indio = iio_trigger_get_drvdata(trig);
> + struct at91_adc_state *st = iio_priv(indio);
> + u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> + u8 bit;
> + int i;
> +
> + /* clear TRGMOD */
> + status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> +
> + /* if we are disabling the trigger, it's enough to clear TRGMOD */
> + if (!state) {
> + at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> + kfree(st->buffer);
Would normally expect to see elements related to the buffer in the
preenable callback for the buffer. In this case it might not make
much difference, but that's conceptually where it belongs.
> + return 0;
> + }
> +
> + st->buffer = kmalloc(indio->scan_bytes, GFP_KERNEL);
How big does this get? I'd be tempted to just use a fixed size big
enough to take the maximum possible. Will probably end up more
efficient than allocating it separately. Not to mention slightly
simplified code.
> + if (!st->buffer)
> + return -ENOMEM;
> +
> + for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++) {
> + if (!strstr(trig->name, st->trigger_list[i].name)) {
> + status |= st->trigger_list[i].trgmod_value;
> + break;
> + }
> + }
> +
> + /* setup hw trigger */
> + at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> +
> + for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
> + struct iio_chan_spec const *chan = indio->channels + bit;
> +
> + at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> + at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> + }
> +
> + return 0;
> +}
> +
> +static const struct iio_trigger_ops at91_adc_trigger_ops = {
> + .owner = THIS_MODULE,
> + .set_trigger_state = &at91_adc_configure_trigger,
> +};
> +
> +static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio,
> + char *trigger_name)
> +{
> + struct iio_trigger *trig;
> + int ret;
> +
> + trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name,
> + indio->id, trigger_name);
> + if (!trig)
> + return NULL;
> +
> + trig->dev.parent = indio->dev.parent;
> + iio_trigger_set_drvdata(trig, indio);
> + trig->ops = &at91_adc_trigger_ops;
> +
> + ret = devm_iio_trigger_register(&indio->dev, trig);
> +
> + if (ret)
> + return NULL;
> +
> + return trig;
> +}
> +
> +static int at91_adc_trigger_init(struct iio_dev *indio)
> +{
> + struct at91_adc_state *st = iio_priv(indio);
> + int i;
> +
> + st->trig = devm_kzalloc(&indio->dev,
> + AT91_SAMA5D2_HW_TRIG_CNT * sizeof(*st->trig),
> + GFP_KERNEL);
Given it's a fixed sized allocation, why not just make the resulting array
part of st directly?
> +
> + if (!st->trig) {
> + dev_err(&indio->dev, "could not allocate trig list memory\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++) {
> + st->trig[i] = at91_adc_allocate_trigger(indio,
> + st->trigger_list[i].name);
> + if (!st->trig[i]) {
> + dev_err(&indio->dev,
> + "could not allocate trigger %d\n", i);
> + return -ENOMEM;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
> +{
> + struct iio_poll_func *pf = p;
> + struct iio_dev *indio = pf->indio_dev;
> + struct at91_adc_state *st = iio_priv(indio);
> + int i = 0;
> + u8 bit;
> +
> + for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
> + struct iio_chan_spec const *chan = indio->channels + bit;
> +
> + st->buffer[i] = at91_adc_readl(st, chan->address);
> + i++;
> + }
> +
> + iio_push_to_buffers_with_timestamp(indio, st->buffer, pf->timestamp);
> +
> + iio_trigger_notify_done(indio->trig);
> +
> + /* Needed to ACK the DRDY interruption */
> + at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +
> + enable_irq(st->irq);
Unusual to have to disable the irq until this point. Firstly
if you did need to do this, it should be in the tryreeenable callback.
You haven't restricted this trigger to just this device, so other
drivers could be hanging of it.
Secondly this irq is always defined to be a threaded oneshot irq
so it should be nicely masked anyway.
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int at91_adc_buffer_init(struct iio_dev *indio)
> +{
> + return devm_iio_triggered_buffer_setup(&indio->dev, indio,
> + &iio_pollfunc_store_time,
> + &at91_adc_trigger_handler, NULL);
This particular wrapper doesn't seem to add much over having it
inline. I'd be tempted to drop it but unimportant if you'd rather
keep it.
> +}
> +
> static unsigned at91_adc_startup_time(unsigned startup_time_min,
> unsigned adc_clk_khz)
> {
> @@ -293,14 +475,19 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
>
> - if (status & imr) {
> + if (!(status & imr))
> + return IRQ_NONE;
> +
> + if (iio_buffer_enabled(indio)) {
> + disable_irq_nosync(irq);
> + iio_trigger_poll(indio->trig);
> + } else {
> st->conversion_value = at91_adc_readl(st, st->chan->address);
> st->conversion_done = true;
> wake_up_interruptible(&st->wq_data_available);
> - return IRQ_HANDLED;
> }
>
> - return IRQ_NONE;
> + return IRQ_HANDLED;
> }
>
> static int at91_adc_read_raw(struct iio_dev *indio_dev,
> @@ -406,6 +593,8 @@ static int at91_adc_probe(struct platform_device *pdev)
>
> st = iio_priv(indio_dev);
>
> + st->trigger_list = at91_adc_trigger_list;Given it's const, why not just use it directly?
> +
> ret = of_property_read_u32(pdev->dev.of_node,
> "atmel,min-sample-rate-hz",
> &st->soc_info.min_sample_rate);
> @@ -499,6 +688,18 @@ static int at91_adc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, indio_dev);
>
> + ret = at91_adc_buffer_init(indio_dev);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
> + goto per_clk_disable_unprepare;
> + }
> +
> + ret = at91_adc_trigger_init(indio_dev);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "couldn't setup the triggers.\n");
> + goto per_clk_disable_unprepare;
> + }
> +
> ret = iio_device_register(indio_dev);
> if (ret < 0)
> goto per_clk_disable_unprepare;
>
^ permalink raw reply
* Re: [PATCH 3/3] iio: tools: generic_buffer: increase trigger length
From: Jonathan Cameron @ 2017-04-27 5:19 UTC (permalink / raw)
To: Eugen Hristev, nicolas.ferre, alexandre.belloni, linux-iio, lars,
linux-arm-kernel, devicetree, linux-kernel
Cc: ludovic.desroches
In-Reply-To: <1492590045-17329-4-git-send-email-eugen.hristev@microchip.com>
On 19/04/17 09:20, Eugen Hristev wrote:
> Increased trigger length to 50 in order to cope with trigger names like
> fc030000.adc-dev0-external-rising
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
This is fine (though I'd go bigger as Daniel suggested)
I'll pick it up with the revised series.
thanks,
Jonathan
> ---
> tools/iio/iio_utils.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h
> index 780f201..9d59771 100644
> --- a/tools/iio/iio_utils.h
> +++ b/tools/iio/iio_utils.h
> @@ -13,7 +13,7 @@
> #include <stdint.h>
>
> /* Made up value to limit allocation sizes */
> -#define IIO_MAX_NAME_LENGTH 30
> +#define IIO_MAX_NAME_LENGTH 50
>
> #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
> #define FORMAT_TYPE_FILE "%s_type"
>
^ permalink raw reply
* Re: [PATCH] [media] mtk-mdp: Fix g_/s_selection capture/compose logic
From: houlong wei @ 2017-04-27 6:11 UTC (permalink / raw)
To: Wu-Cheng Li (李務誠)
Cc: Minghsiu Tsai, Hans Verkuil, Daniel Thompson, Rob Herring,
Mauro Carvalho Chehab, Matthias Brugger, Daniel Kurtz,
Pawel Osciak, srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Eddie Huang,
Yingjoe Chen, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-media-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <CAOMLVLiLkZsBfezx6b9Xq=kyPjUZOXwHC4LfHh1=wy6Ynt=zSQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Thu, 2017-04-13 at 14:50 +0800, Wu-Cheng Li (李務誠) wrote:
> Reviewed-by: Wu-Cheng Li <wuchengli-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>
> On Thu, Apr 13, 2017 at 12:18 PM, Minghsiu Tsai
> <minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> wrote:
> > From: Daniel Kurtz <djkurtz-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> >
> > Experiments show that the:
> > (1) mtk-mdp uses the _MPLANE form of CAPTURE/OUTPUT
> > (2) CAPTURE types use CROP targets, and OUTPUT types use COMPOSE targets
> >
> > Signed-off-by: Daniel Kurtz <djkurtz-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> > Signed-off-by: Minghsiu Tsai <minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Acked-by:Houlong Wei <houlong.wei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> >
> > ---
> > drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 18 +++++++++---------
> > 1 file changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> > index 13afe48..8ab7ca0 100644
> > --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> > +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> > @@ -837,12 +837,12 @@ static int mtk_mdp_m2m_g_selection(struct file *file, void *fh,
> > struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
> > bool valid = false;
> >
> > - if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> > - if (mtk_mdp_is_target_compose(s->target))
> > - valid = true;
> > - } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> > + if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> > if (mtk_mdp_is_target_crop(s->target))
> > valid = true;
> > + } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> > + if (mtk_mdp_is_target_compose(s->target))
> > + valid = true;
> > }
> > if (!valid) {
> > mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type,
> > @@ -907,12 +907,12 @@ static int mtk_mdp_m2m_s_selection(struct file *file, void *fh,
> > int ret;
> > bool valid = false;
> >
> > - if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> > - if (s->target == V4L2_SEL_TGT_COMPOSE)
> > - valid = true;
> > - } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> > + if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> > if (s->target == V4L2_SEL_TGT_CROP)
> > valid = true;
> > + } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> > + if (s->target == V4L2_SEL_TGT_COMPOSE)
> > + valid = true;
> > }
> > if (!valid) {
> > mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type,
> > @@ -925,7 +925,7 @@ static int mtk_mdp_m2m_s_selection(struct file *file, void *fh,
> > if (ret)
> > return ret;
> >
> > - if (mtk_mdp_is_target_crop(s->target))
> > + if (mtk_mdp_is_target_compose(s->target))
> > frame = &ctx->s_frame;
> > else
> > frame = &ctx->d_frame;
> > --
> > 1.9.1
> >
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2] leds-pca963x: add bindings to invert polarity
From: Anders Darander @ 2017-04-27 6:37 UTC (permalink / raw)
To: jacek.anaszewski-Re5JQEeQqe8AvxtiuMwx3w, pavel-+ZI9xUNit7I,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-leds-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: rpurdie-Fm38FmjxZ/leoWH0uzbU5w, Anders Darander
Add a new DT property, nxp,inverted-out, to invert the polarity of the output.
Tested on PCA9634.
Signed-off-by: Anders Darander <anders-7UjN0b3lYz2SbKU13Z4Etw@public.gmane.org>
---
Documentation/devicetree/bindings/leds/pca963x.txt | 1 +
drivers/leds/leds-pca963x.c | 17 +++++++++++++++--
include/linux/platform_data/leds-pca963x.h | 6 ++++++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/leds/pca963x.txt b/Documentation/devicetree/bindings/leds/pca963x.txt
index dfbdb123a9bf..4eee41482041 100644
--- a/Documentation/devicetree/bindings/leds/pca963x.txt
+++ b/Documentation/devicetree/bindings/leds/pca963x.txt
@@ -10,6 +10,7 @@ Optional properties:
- nxp,period-scale : In some configurations, the chip blinks faster than expected.
This parameter provides a scaling ratio (fixed point, decimal divided
by 1000) to compensate, e.g. 1300=1.3x and 750=0.75x.
+- nxp,inverted-out: invert the polarity of the generated PWM
Each led is represented as a sub-node of the nxp,pca963x device.
diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index ded1e4dac36a..3bf9a1271819 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -342,6 +342,12 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip)
if (of_property_read_u32(np, "nxp,period-scale", &chip->scaling))
chip->scaling = 1000;
+ /* default to non-inverted output, unless inverted is specified */
+ if (of_property_read_bool(np, "nxp,inverted-out"))
+ pdata->dir = PCA963X_INVERTED;
+ else
+ pdata->dir = PCA963X_NORMAL;
+
return pdata;
}
@@ -452,11 +458,18 @@ static int pca963x_probe(struct i2c_client *client,
i2c_smbus_write_byte_data(client, PCA963X_MODE1, BIT(4));
if (pdata) {
+ u8 mode2 = i2c_smbus_read_byte_data(pca963x->chip->client,
+ PCA963X_MODE2);
/* Configure output: open-drain or totem pole (push-pull) */
if (pdata->outdrv == PCA963X_OPEN_DRAIN)
- i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01);
+ mode2 |= 0x01;
else
- i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x05);
+ mode2 |= 0x05;
+ /* Configure direction: normal or inverted */
+ if (pdata->dir == PCA963X_INVERTED)
+ mode2 |= 0x10;
+ i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
+ mode2);
}
return 0;
diff --git a/include/linux/platform_data/leds-pca963x.h b/include/linux/platform_data/leds-pca963x.h
index e731f0036329..54e845ffb5ed 100644
--- a/include/linux/platform_data/leds-pca963x.h
+++ b/include/linux/platform_data/leds-pca963x.h
@@ -33,10 +33,16 @@ enum pca963x_blink_type {
PCA963X_HW_BLINK,
};
+enum pca963x_direction {
+ PCA963X_NORMAL,
+ PCA963X_INVERTED,
+};
+
struct pca963x_platform_data {
struct led_platform_data leds;
enum pca963x_outdrv outdrv;
enum pca963x_blink_type blink_type;
+ enum pca963x_direction dir;
};
#endif /* __LINUX_PCA963X_H*/
--
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: [PATCH RFC 0/5] *** SPI Slave mode support ***
From: Jiada Wang @ 2017-04-27 6:43 UTC (permalink / raw)
To: Mark Brown
Cc: Geert Uytterhoeven, Rob Herring, Mark Rutland, Shawn Guo,
Sascha Hauer, Fabio Estevam, linux-spi,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20170425103113.lxpwoq6sbxvg3ihl@sirena.org.uk>
Hello Geert and Mark
On 04/25/2017 03:31 AM, Mark Brown wrote:
> On Mon, Apr 24, 2017 at 12:55:21PM +0200, Geert Uytterhoeven wrote:
>> On Fri, Apr 14, 2017 at 7:39 AM, Jiada Wang<jiada_wang@mentor.com> wrote:
>>> Our use case is to use spidev as an interface to communicate with external
>>> SPI master devices.
>>> meanwhile the SPI bus controller can also act as master device to send data
>>> to other
>>> SPI slave devices on the board.
>> That sounds a bit hackish to me. SPI was never meant to be a multi-master bus.
>> While it can be done, you will need external synchronization (signals) to
>> avoid conflicts between the SPI masters.
>>> I found in your implementation, SPI bus controller is limited to either work
>>> in master mode or
>>> slave mode, is there any reasoning to not configure SPI mode based on SPI
>>> devices use case?
>> If you really need both master and slave support, you can use 2 subnodes
>> in DT, the first representing the master, the second the slave.
>> Mark, what's your opinion about this?
> That sounds like a mess... we *could* put the slave flag on the device
> rather than the controller I guess but there's also going to need to be
> something representing whatever avoids collisions on the bus somewhere.
The reason I gave the example use case is want to point out that
with Geert's patch set, a SPI device (with only one controller) can no
longer
act as master and slave at the same time. because IMO as a SPI core
function,
it needs to cover all the use cases, and to be as generic as possible.
BUT if you think the use case don't need to be supported from SPI core,
then I don't have objection either, I will only submit imx SPI slave
support patch,
after your SPI slave support patch set been applied
Thanks,
Jiada
^ permalink raw reply
* Re: [PATCH v2] leds-pca963x: add bindings to invert polarity
From: Anders Darander @ 2017-04-27 6:45 UTC (permalink / raw)
To: jacek.anaszewski, pavel, robh+dt, mark.rutland, linux-leds,
devicetree, linux-kernel
Cc: rpurdie
In-Reply-To: <20170427063733.32323-1-anders@chargestorm.se>
Hi all,
* Anders Darander <anders@chargestorm.se> [170427 08:37]:
> Add a new DT property, nxp,inverted-out, to invert the polarity of the output.
> Tested on PCA9634.
I'm making a 2nd attempt at this. The ability to invert the output from
the PCA9634 is important, and I'd like to avoid out-of-tree patches as
much as possible.
In replies to my previous attempt [1] another attempt at adding this
support was mentioned [2]. However, that attempt seems to have stalled
[3]. Even if the rest of the fixes / improvements from that series
aren't merged, I'd like to see the support for the inverted output.
Cheers,
Anders
[1] https://lkml.org/lkml/2016/5/4/120
[2] https://lkml.org/lkml/2016/4/19/90
[3] https://lkml.org/lkml/2016/9/6/187
^ permalink raw reply
* Re: [linux-sunxi] Re: [PATCH v5 02/11] clk: sunxi-ng: add support for DE2 CCU
From: Maxime Ripard @ 2017-04-27 7:12 UTC (permalink / raw)
To: icenowy-h8G6r0blFSE
Cc: Rob Herring, Chen-Yu Tsai, Jernej Skrabec,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <9def8a6b635880095e6b75e3a53af1f4-h8G6r0blFSE@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1267 bytes --]
On Mon, Apr 24, 2017 at 06:26:51PM +0800, icenowy-h8G6r0blFSE@public.gmane.org wrote:
> 在 2017-04-24 16:51,Maxime Ripard 写道:
> > Hi,
> >
> > On Sun, Apr 23, 2017 at 06:37:45PM +0800, Icenowy Zheng wrote:
> > > +static const struct of_device_id sunxi_de2_clk_ids[] = {
> > > + {
> > > + .compatible = "allwinner,sun8i-a83t-de2-clk",
> > > + .data = &sun8i_a83t_de2_clk_desc,
> > > + },
> > > + {
> > > + .compatible = "allwinner,sun50i-h5-de2-clk",
> > > + .data = &sun50i_a64_de2_clk_desc,
> > > + },
> > > + /*
> > > + * The Allwinner A64 SoC needs some bit to be poke in syscon to make
> > > + * DE2 really working.
> > > + * So there's currently no A64 compatible here.
> > > + * H5 shares the same reset line with A64, so here H5 is using the
> > > + * clock description of A64.
> > > + */
> > > + { }
> > > +};
> >
> > So that A64 driver would require more than just what you defined in
> > the binding in order to operate?
>
> Yes. When trying to do A64 driver, I will send out first a patch to
> add the needed binding bit.
Then remove the A64 compatible from the binding document.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v9 07/16] mmc: sdhci-msm: Add get_min_clock() and get_max_clock() callback
From: Georgi Djakov @ 2017-04-27 7:58 UTC (permalink / raw)
To: Andy Gross, stable
Cc: Ritesh Harjani, ulf.hansson, linux-mmc, adrian.hunter, sboyd,
shawn.lin, devicetree, linux-clk, david.brown, linux-arm-msm,
georgi.djakov, alex.lemberg, mateusz.nowak, Yuliy.Izrailov,
asutoshd, david.griego, stummala, venkatg, rnayak, pramod.gurav,
jeremymc
In-Reply-To: <20170426214443.GA32019@hector.attlocal.net>
On 04/27/2017 12:44 AM, Andy Gross wrote:
> On Mon, Nov 21, 2016 at 12:07:17PM +0530, Ritesh Harjani wrote:
>> This add get_min_clock() and get_max_clock() callback
>> for sdhci-msm. sdhci-msm min/max clocks may be different
>> hence implement these callbacks.
>>
>> Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
>> Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
>> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>
> This patch needs to be picked up for stable as 4.9 is currently broken w.r.t.
> MMC on Qualcomm platforms.
>
> Fixes: d84be51d1c1d ("mmc: sdhci-msm: Enable few quirks")
Agree! Applying this patch (80031bdeb764) in stable fixes the
broken mmc. Otherwise the following error is seen since v4.9.22:
mmc0: Hardware doesn't specify base clock frequency.
Thanks,
Georgi
^ permalink raw reply
* [PATCH v5 00/10] Renesas RZ/A1 pin and gpio controller
From: Jacopo Mondi @ 2017-04-27 8:19 UTC (permalink / raw)
To: linus.walleij, geert+renesas, laurent.pinchart, chris.brandt,
robh+dt, mark.rutland, linux
Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel
Hi Geert,
this is 5th round of gpio/pincontroller for RZ/A1 devices.
I have updated the pin controller driver to use the newly introduced
"pinctrl_enable()" function.
This is required since v4.11-rc7 as otherwise, as reported by Chris Brandt,
the pin controller does not start.
I have incorporated your comments on the device tree bindings documentation,
and added to pinctrl-generic.h header file two macros to unpack generic
properties and their arguments.
Tested with SCIF, RIIC, ETHER and gpio-leds on Genmai board.
Thanks
j
v1 -> v2:
- change pin configuration flags as suggested by Chris
- gpio set direction function fixed as suggested by Chris
- add some more example on pin configuration flag usage to dt-binding doc
- fix gpio-controller names to remove unit address as suggested by Geert
- some comments chopped here and there to make the driver less verbose
v2 -> v3:
- fix grammar and syntax in comment and documentation
- fix code style (reverse xmas tree ordering in variable declaration)
- use irqsave/irqrestore in spinlock lock/unlock
- use devm_ version of kasprintf (memory returned was not properly free)
- use bitops.h operation ffs and fls to make sure a single bit is set in pmx
mask
- Add Geert's reviewed-by to DTS patches
v3 -> v4:
- use "pinmux" property in pmx sub-nodes in place of "renesas,pins"
- use pinconf standard properties to set pin mux additional flags
- add "bi-directional" and "output-enable" to pinconf generic properties
- perform pmx function parsing at dt_node_to_map() time
- change DT bindings to use GENERIC_PINCONF
- change DT bindings to allow sub-nodes to have "pinmux" property specified
- several renames (register names, DT parse functions, set_mux() function)
v4 -> v5:
- use pinctrl_enable() function in pin controller registration function
- update bindings documentation to incorporate Geert's comments
- add generic properties unpack macros
Jacopo Mondi (10):
pinctrl: generic: Add bi-directional and output-enable
pinctrl: generic: Add macros to unpack properties
pinctrl: Renesas RZ/A1 pin and gpio controller
dt-bindings: pinctrl: Add RZ/A1 bindings doc
arm: dts: dt-bindings: Add Renesas RZ/A1 pinctrl header
arm: dts: r7s72100: Add pin controller node
arm: dts: genmai: Add SCIF2 pin group
arm: dts: genmai: Add RIIC2 pin group
arm: dts: genmai: Add user led device nodes
arm: dts: genmai: Add ethernet pin group
.../bindings/pinctrl/pinctrl-bindings.txt | 2 +
.../bindings/pinctrl/renesas,rza1-pinctrl.txt | 219 +++++
arch/arm/boot/dts/r7s72100-genmai.dts | 76 ++
arch/arm/boot/dts/r7s72100.dtsi | 78 ++
drivers/pinctrl/Kconfig | 11 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinconf-generic.c | 3 +
drivers/pinctrl/pinctrl-rza1.c | 995 +++++++++++++++++++++
include/dt-bindings/pinctrl/r7s72100-pinctrl.h | 16 +
include/linux/pinctrl/pinconf-generic.h | 7 +-
10 files changed, 1407 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/pinctrl/renesas,rza1-pinctrl.txt
create mode 100644 drivers/pinctrl/pinctrl-rza1.c
create mode 100644 include/dt-bindings/pinctrl/r7s72100-pinctrl.h
--
2.7.4
^ permalink raw reply
* [PATCH v5 01/10] pinctrl: generic: Add bi-directional and output-enable
From: Jacopo Mondi @ 2017-04-27 8:19 UTC (permalink / raw)
To: linus.walleij, geert+renesas, laurent.pinchart, chris.brandt,
robh+dt, mark.rutland, linux
Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493281194-5200-1-git-send-email-jacopo+renesas@jmondi.org>
Add bi-directional and output-enable pin configuration properties.
bi-directional allows to specify when a pin shall operate in input and
output mode at the same time. This is particularly useful in platforms
where input and output buffers have to be manually enabled.
output-enable is just syntactic sugar to specify that a pin shall
operate in output mode, ignoring the provided argument.
This pairs with input-enable pin configuration option.
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | 2 ++
drivers/pinctrl/pinconf-generic.c | 3 +++
include/linux/pinctrl/pinconf-generic.h | 3 +++
3 files changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
index bf3f7b0..f2ed458 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
@@ -222,6 +222,7 @@ bias-bus-hold - latch weakly
bias-pull-up - pull up the pin
bias-pull-down - pull down the pin
bias-pull-pin-default - use pin-default pull state
+bi-directional - pin supports simultaneous input/output operations
drive-push-pull - drive actively high and low
drive-open-drain - drive with open drain
drive-open-source - drive with open source
@@ -234,6 +235,7 @@ input-debounce - debounce mode with debound time X
power-source - select between different power supplies
low-power-enable - enable low power mode
low-power-disable - disable low power mode
+output-enable - enable output on pin regardless of output value
output-low - set the pin to output mode with low level
output-high - set the pin to output mode with high level
slew-rate - set the slew rate
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index ce3335a..03e6808 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -35,6 +35,7 @@ static const struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
"input bias pull to pin specific state", NULL, false),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false),
+ PCONFDUMP(PIN_CONFIG_BIDIRECTIONAL, "bi-directional pin operations", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false),
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false),
@@ -160,6 +161,7 @@ static const struct pinconf_generic_params dt_params[] = {
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+ { "bi-directional", PIN_CONFIG_BIDIRECTIONAL, 1 },
{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
@@ -172,6 +174,7 @@ static const struct pinconf_generic_params dt_params[] = {
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
+ { "output-enable", PIN_CONFIG_OUTPUT, 1, },
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index 7620eb1..279e3c5 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -42,6 +42,8 @@
* @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
* impedance to VDD). If the argument is != 0 pull-up is enabled,
* if it is 0, pull-up is total, i.e. the pin is connected to VDD.
+ * @PIN_CONFIG_BIDIRECTIONAL: the pin will be configured to allow simultaneous
+ * input and output operations.
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
* collector) which means it is usually wired with other output ports
* which are then pulled up with an external resistor. Setting this
@@ -96,6 +98,7 @@ enum pin_config_param {
PIN_CONFIG_BIAS_PULL_DOWN,
PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
PIN_CONFIG_BIAS_PULL_UP,
+ PIN_CONFIG_BIDIRECTIONAL,
PIN_CONFIG_DRIVE_OPEN_DRAIN,
PIN_CONFIG_DRIVE_OPEN_SOURCE,
PIN_CONFIG_DRIVE_PUSH_PULL,
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox