* [PATCH 0/2] cec: STM32 driver
@ 2017-05-16 9:01 Benjamin Gaignard
[not found] ` <1494925280-4527-1-git-send-email-benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Benjamin Gaignard @ 2017-05-16 9:01 UTC (permalink / raw)
To: yannick.ferte, alexandre.torgue, hverkuil, devicetree,
linux-media, robh, hans.verkuil
Cc: Benjamin Gaignard
This serie of patches add cec driver for STM32 platforms.
This code doesn't implement cec notifier because STM32 doesn't
provide HDMI yet but it will be added later.
Those patches have been developped on top of media_tree master branch
where STM32 DCMI code has not been merged so conflict in Kconfig and Makefile
could occur depending of merge ordering.
Compliance has been tested on STM32F769.
~ # cec-ctl -p 1.0.0.0 --playback
Driver Info:
Driver Name : stm32-cec
Adapter Name : stm32-cec
Capabilities : 0x0000000f
Physical Address
Logical Addresses
Transmit
Passthrough
Driver version : 4.11.0
Available Logical Addresses: 1
Physical Address : 1.0.0.0
Logical Address Mask : 0x0010
CEC Version : 2.0
Vendor ID : 0x000c03 (HDMI)
OSD Name : 'Playback'
Logical Addresses : 1 (Allow RC Passthrough)
Logical Address : 4 (Playback Device 1)
Primary Device Type : Playback
Logical Address Type : Playback
All Device Types : Playback
RC TV Profile : None
Device Features :
None
~ # cec-compliance -A
cec-compliance SHA : 6acac5cec698de39b9398b66c4f5f4db6b2730d8
Driver Info:
Driver Name : stm32-cec
Adapter Name : stm32-cec
Capabilities : 0x0000000f
Physical Address
Logical Addresses
Transmit
Passthrough
Driver version : 4.11.0
Available Logical Addresses: 1
Physical Address : 1.0.0.0
Logical Address Mask : 0x0010
CEC Version : 2.0
Vendor ID : 0x000c03
Logical Addresses : 1 (Allow RC Passthrough)
Logical Address : 4
Primary Device Type : Playback
Logical Address Type : Playback
All Device Types : Playback
RC TV Profile : None
Device Features :
None
Compliance test for device /dev/cec0:
The test results mean the following:
OK Supported correctly by the device.
OK (Not Supported) Not supported and not mandatory for the device.
OK (Presumed) Presumably supported. Manually check to confirm.
OK (Unexpected) Supported correctly but is not expected to be supported for this device.
OK (Refused) Supported by the device, but was refused.
FAIL Failed and was expected to be supported by this device.
Find remote devices:
Polling: OK
CEC API:
CEC_ADAP_G_CAPS: OK
CEC_DQEVENT: OK
CEC_ADAP_G/S_PHYS_ADDR: OK
CEC_ADAP_G/S_LOG_ADDRS: OK
CEC_TRANSMIT: OK
CEC_RECEIVE: OK
CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed)
CEC_G/S_MODE: OK
CEC_EVENT_LOST_MSGS: OK
Network topology:
System Information for device 0 (TV) from device 4 (Playback Device 1):
CEC Version : 1.4
Physical Address : 0.0.0.0
Primary Device Type : TV
Vendor ID : 0x00903e
OSD Name : 'TV'
Menu Language : fre
Power Status : On
Total: 10, Succeeded: 10, Failed: 0, Warnings: 0
Benjamin Gaignard (2):
binding for stm32 cec driver
cec: add STM32 cec driver
.../devicetree/bindings/media/st,stm32-cec.txt | 19 ++
drivers/media/platform/Kconfig | 11 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/stm32/Makefile | 1 +
drivers/media/platform/stm32/stm32-cec.c | 368 +++++++++++++++++++++
5 files changed, 401 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/st,stm32-cec.txt
create mode 100644 drivers/media/platform/stm32/Makefile
create mode 100644 drivers/media/platform/stm32/stm32-cec.c
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] binding for stm32 cec driver
[not found] ` <1494925280-4527-1-git-send-email-benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2017-05-16 9:01 ` Benjamin Gaignard
0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Gaignard @ 2017-05-16 9:01 UTC (permalink / raw)
To: yannick.ferte-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA, robh-DgEjT+Ai2ygdnm+yROfE0A,
hans.verkuil-FYB4Gu1CFyUAvxtiuMwx3w
Cc: Benjamin Gaignard
Signed-off-by: Benjamin Gaignard <benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
.../devicetree/bindings/media/st,stm32-cec.txt | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/st,stm32-cec.txt
diff --git a/Documentation/devicetree/bindings/media/st,stm32-cec.txt b/Documentation/devicetree/bindings/media/st,stm32-cec.txt
new file mode 100644
index 0000000..6be2381
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/st,stm32-cec.txt
@@ -0,0 +1,19 @@
+STMicroelectronics STM32 CEC driver
+
+Required properties:
+ - compatible : value should be "st,stm32-cec"
+ - reg : Physical base address of the IP registers and length of memory
+ mapped region.
+ - clocks : from common clock binding: handle to CEC clocks
+ - clock-names : from common clock binding: must be "cec" and "hdmi-cec".
+ - interrupts : CEC interrupt number to the CPU.
+
+Example for stm32f746:
+
+cec: cec@40006c00 {
+ compatible = "st,stm32-cec";
+ reg = <0x40006C00 0x400>;
+ interrupts = <94>;
+ clocks = <&rcc 0 STM32F7_APB1_CLOCK(CEC)>, <&rcc 1 CLK_HDMI_CEC>;
+ clock-names = "cec", "hdmi-cec";
+};
--
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 [flat|nested] 7+ messages in thread
* [PATCH 2/2] cec: add STM32 cec driver
2017-05-16 9:01 [PATCH 0/2] cec: STM32 driver Benjamin Gaignard
[not found] ` <1494925280-4527-1-git-send-email-benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2017-05-16 9:01 ` Benjamin Gaignard
2017-05-16 9:33 ` Hans Verkuil
2017-05-16 9:10 ` [PATCH 0/2] cec: STM32 driver Benjamin Gaignard
2 siblings, 1 reply; 7+ messages in thread
From: Benjamin Gaignard @ 2017-05-16 9:01 UTC (permalink / raw)
To: yannick.ferte, alexandre.torgue, hverkuil, devicetree,
linux-media, robh, hans.verkuil
Cc: Benjamin Gaignard
This patch add cec driver for STM32 platforms.
cec hardware block isn't not always used with hdmi so
cec notifier is not implemented. That will be done later
when STM32 DSI driver will be available.
Driver compliance has been tested with cec-ctl and cec-compliance
tools.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
---
drivers/media/platform/Kconfig | 11 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/stm32/Makefile | 1 +
drivers/media/platform/stm32/stm32-cec.c | 368 +++++++++++++++++++++++++++++++
4 files changed, 382 insertions(+)
create mode 100644 drivers/media/platform/stm32/Makefile
create mode 100644 drivers/media/platform/stm32/stm32-cec.c
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index ac026ee..72efe34 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -519,4 +519,15 @@ config VIDEO_STI_HDMI_CEC
CEC bus is present in the HDMI connector and enables communication
between compatible devices.
+config VIDEO_STM32_HDMI_CEC
+ tristate "STMicroelectronics STM32 HDMI CEC driver"
+ depends on CEC_CORE && (ARCH_STM32 || COMPILE_TEST)
+ select REGMAP
+ select REGMAP_MMIO
+ ---help---
+ This is a driver for STM32 interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
endif #CEC_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 63303d6..7cd9965 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -44,6 +44,8 @@ obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/
obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/
+obj-$(CONFIG_VIDEO_STM32_HDMI_CEC) += stm32/
+
obj-$(CONFIG_BLACKFIN) += blackfin/
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
diff --git a/drivers/media/platform/stm32/Makefile b/drivers/media/platform/stm32/Makefile
new file mode 100644
index 0000000..632b04c
--- /dev/null
+++ b/drivers/media/platform/stm32/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_STM32_HDMI_CEC) += stm32-cec.o
diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c
new file mode 100644
index 0000000..a40a6eb
--- /dev/null
+++ b/drivers/media/platform/stm32/stm32-cec.c
@@ -0,0 +1,368 @@
+/*
+ * STM32 CEC driver
+ * Copyright (C) STMicroelectronic SA 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <media/cec.h>
+
+#define CEC_NAME "stm32-cec"
+
+/* CEC registers */
+#define CEC_CR 0x0000 /* Control Register */
+#define CEC_CFGR 0x0004 /* ConFiGuration Register */
+#define CEC_TXDR 0x0008 /* Rx data Register */
+#define CEC_RXDR 0x000C /* Rx data Register */
+#define CEC_ISR 0x0010 /* Interrupt and status Register */
+#define CEC_IER 0x0014 /* Interrupt enable Register */
+
+#define TXEOM BIT(2)
+#define TXSOM BIT(1)
+#define CECEN BIT(0)
+
+#define LSTN BIT(31)
+#define OAR GENMASK(30, 16)
+#define SFTOP BIT(8)
+#define BRDNOGEN BIT(7)
+#define LBPEGEN BIT(6)
+#define BREGEN BIT(5)
+#define BRESTP BIT(4)
+#define RXTOL BIT(3)
+#define SFT GENMASK(2, 0)
+#define FULL_CFG (LSTN | SFTOP | BRDNOGEN | LBPEGEN | BREGEN | BRESTP \
+ | RXTOL | SFT | BRDNOGEN)
+
+#define TXACKE BIT(12)
+#define TXERR BIT(11)
+#define TXUDR BIT(10)
+#define TXEND BIT(9)
+#define TXBR BIT(8)
+#define ARBLST BIT(7)
+#define RXACKE BIT(6)
+#define RXOVR BIT(2)
+#define RXEND BIT(1)
+#define RXBR BIT(0)
+
+#define ALL_TX_IT (TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST)
+#define ALL_RX_IT (RXEND | RXBR | RXACKE | RXOVR)
+
+struct stm32_cec {
+ struct cec_adapter *adap;
+ struct device *dev;
+ struct clk *clk_cec;
+ struct clk *clk_hdmi_cec;
+ struct reset_control *rstc;
+ struct regmap *regmap;
+ int irq;
+ u32 irq_status;
+ u8 rx_msg[CEC_MAX_MSG_SIZE];
+ u8 tx_msg[CEC_MAX_MSG_SIZE];
+ int rx_len;
+ int tx_len;
+ int tx_cnt;
+};
+
+static void cec_hw_init(struct stm32_cec *cec)
+{
+ regmap_update_bits(cec->regmap, CEC_CR, TXEOM | TXSOM | CECEN, 0);
+
+ regmap_update_bits(cec->regmap, CEC_IER, ALL_TX_IT | ALL_RX_IT,
+ ALL_TX_IT | ALL_RX_IT);
+
+ regmap_update_bits(cec->regmap, CEC_CFGR, FULL_CFG, FULL_CFG);
+}
+
+static void stm32_tx_done(struct stm32_cec *cec, u32 status)
+{
+ if (status & (TXERR | TXUDR)) {
+ cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR,
+ 0, 0, 0, 1);
+ return;
+ }
+
+ if (status & ARBLST) {
+ cec_transmit_done(cec->adap, CEC_TX_STATUS_ARB_LOST,
+ 1, 0, 0, 0);
+ return;
+ }
+
+ if (status & TXACKE) {
+ cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK,
+ 0, 1, 0, 0);
+ return;
+ }
+
+ if (cec->irq_status & TXBR) {
+ /* send next byte */
+ if (cec->tx_cnt < cec->tx_len)
+ regmap_write(cec->regmap, CEC_TXDR,
+ cec->tx_msg[cec->tx_cnt++]);
+
+ /* TXEOM is set to command transmission of the last byte */
+ if (cec->tx_cnt == cec->tx_len)
+ regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
+ }
+
+ if (cec->irq_status & TXEND)
+ cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
+}
+
+static void stm32_rx_done(struct stm32_cec *cec, u32 status)
+{
+ if (cec->irq_status & (RXACKE | RXOVR)) {
+ cec->rx_len = 0;
+ return;
+ }
+
+ if (cec->irq_status & RXBR) {
+ u32 val;
+
+ regmap_read(cec->regmap, CEC_RXDR, &val);
+ cec->rx_msg[cec->rx_len++] = val & 0xFF;
+ }
+
+ if (cec->irq_status & RXEND) {
+ struct cec_msg msg = {};
+
+ msg.len = cec->rx_len;
+ memcpy(msg.msg, cec->rx_msg, msg.len);
+ cec_received_msg(cec->adap, &msg);
+
+ cec->rx_len = 0;
+ }
+}
+
+static irqreturn_t stm32_cec_irq_thread(int irq, void *arg)
+{
+ struct stm32_cec *cec = arg;
+
+ if (cec->irq_status & ALL_TX_IT)
+ stm32_tx_done(cec, cec->irq_status);
+
+ if (cec->irq_status & ALL_RX_IT)
+ stm32_rx_done(cec, cec->irq_status);
+
+ cec->irq_status = 0;
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t stm32_cec_irq_handler(int irq, void *arg)
+{
+ struct stm32_cec *cec = arg;
+
+ regmap_read(cec->regmap, CEC_ISR, &cec->irq_status);
+
+ regmap_update_bits(cec->regmap, CEC_ISR,
+ ALL_TX_IT | ALL_RX_IT,
+ ALL_TX_IT | ALL_RX_IT);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct stm32_cec *cec = adap->priv;
+ int ret = 0;
+
+ if (enable) {
+ ret = clk_enable(cec->clk_cec);
+ if (ret)
+ dev_err(cec->dev, "fail to enable cec clock\n");
+
+ clk_enable(cec->clk_hdmi_cec);
+ regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
+ } else {
+ clk_disable(cec->clk_cec);
+ clk_disable(cec->clk_hdmi_cec);
+ regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
+ }
+
+ return ret;
+}
+
+static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+ struct stm32_cec *cec = adap->priv;
+
+ regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
+
+ if (logical_addr == CEC_LOG_ADDR_INVALID)
+ regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
+ else
+ regmap_update_bits(cec->regmap, CEC_CFGR, OAR,
+ (1 << logical_addr) << 16);
+
+ regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
+
+ return 0;
+}
+
+static int stm32_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct stm32_cec *cec = adap->priv;
+
+ /* Copy message */
+ memcpy(cec->tx_msg, msg->msg, msg->len);
+
+ cec->tx_len = msg->len;
+ cec->tx_cnt = 0;
+
+ /*
+ * If the CEC message consists of only one byte,
+ * TXEOM must be set before of TXSOM.
+ */
+ if (cec->tx_len == 1)
+ regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
+
+ /* TXSOM is set to command transmission of the first byte */
+ regmap_update_bits(cec->regmap, CEC_CR, TXSOM, TXSOM);
+
+ /* Write the header (first byte of message) */
+ regmap_write(cec->regmap, CEC_TXDR, cec->tx_msg[0]);
+ cec->tx_cnt++;
+
+ return 0;
+}
+
+static const struct cec_adap_ops stm32_cec_adap_ops = {
+ .adap_enable = stm32_cec_adap_enable,
+ .adap_log_addr = stm32_cec_adap_log_addr,
+ .adap_transmit = stm32_cec_adap_transmit,
+};
+
+static const struct regmap_config stm32_cec_regmap_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = sizeof(u32),
+ .max_register = 0x14,
+ .fast_io = true,
+};
+
+static int stm32_cec_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct stm32_cec *cec;
+ void __iomem *mmio;
+ int ret;
+
+ cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+ if (!cec)
+ return -ENOMEM;
+
+ cec->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mmio = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mmio))
+ return PTR_ERR(mmio);
+
+ cec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "cec", mmio,
+ &stm32_cec_regmap_cfg);
+
+ if (IS_ERR(cec->regmap))
+ return PTR_ERR(cec->regmap);
+
+ cec->irq = platform_get_irq(pdev, 0);
+ if (cec->irq < 0)
+ return cec->irq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
+ stm32_cec_irq_handler,
+ stm32_cec_irq_thread,
+ 0,
+ pdev->name, cec);
+ if (ret)
+ return ret;
+
+ cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
+ if (IS_ERR(cec->clk_cec)) {
+ dev_err(&pdev->dev, "Cannot get cec clock\n");
+ return PTR_ERR(cec->clk_cec);
+ }
+
+ ret = clk_prepare(cec->clk_cec);
+ if (ret) {
+ dev_err(&pdev->dev, "Unable to prepare cec clock\n");
+ return ret;
+ }
+
+ cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
+ if (!IS_ERR(cec->clk_hdmi_cec)) {
+ ret = clk_prepare(cec->clk_hdmi_cec);
+ if (ret) {
+ dev_err(&pdev->dev, "Unable to prepare hdmi-cec clock\n");
+ return ret;
+ }
+ }
+
+ cec->adap = cec_allocate_adapter(&stm32_cec_adap_ops, cec,
+ CEC_NAME,
+ CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH |
+ CEC_CAP_PHYS_ADDR | CEC_CAP_TRANSMIT, 1);
+ ret = PTR_ERR_OR_ZERO(cec->adap);
+ if (ret)
+ return ret;
+
+ ret = cec_register_adapter(cec->adap, &pdev->dev);
+ if (ret) {
+ cec_delete_adapter(cec->adap);
+ return ret;
+ }
+
+ cec_hw_init(cec);
+
+ platform_set_drvdata(pdev, cec);
+
+ return 0;
+}
+
+static int stm32_cec_remove(struct platform_device *pdev)
+{
+ struct stm32_cec *cec = platform_get_drvdata(pdev);
+
+ clk_unprepare(cec->clk_cec);
+ clk_unprepare(cec->clk_hdmi_cec);
+
+ cec_unregister_adapter(cec->adap);
+
+ cec_delete_adapter(cec->adap);
+
+ return 0;
+}
+
+static const struct of_device_id stm32_cec_of_match[] = {
+ { .compatible = "st,stm32-cec" },
+ { /* end node */ }
+};
+MODULE_DEVICE_TABLE(of, stm32_cec_of_match);
+
+static struct platform_driver stm32_cec_driver = {
+ .probe = stm32_cec_probe,
+ .remove = stm32_cec_remove,
+ .driver = {
+ .name = CEC_NAME,
+ .of_match_table = stm32_cec_of_match,
+ },
+};
+
+module_platform_driver(stm32_cec_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics STM32 Consumer Electronics Control");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] cec: STM32 driver
2017-05-16 9:01 [PATCH 0/2] cec: STM32 driver Benjamin Gaignard
[not found] ` <1494925280-4527-1-git-send-email-benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-05-16 9:01 ` [PATCH 2/2] cec: add STM32 " Benjamin Gaignard
@ 2017-05-16 9:10 ` Benjamin Gaignard
[not found] ` <CA+M3ks6eO7144jNyBQZQfQ=ANwgxQjKKCY03iBnQB4mik6uFMQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2 siblings, 1 reply; 7+ messages in thread
From: Benjamin Gaignard @ 2017-05-16 9:10 UTC (permalink / raw)
To: Alexandre Torgue, Hans Verkuil, devicetree,
linux-media@vger.kernel.org, Rob Herring, Hans Verkuil,
Yannick Fertre
Cc: Benjamin Gaignard
+ Yannick who is the original writer of this driver (sorry)
2017-05-16 11:01 GMT+02:00 Benjamin Gaignard <benjamin.gaignard@linaro.org>:
> This serie of patches add cec driver for STM32 platforms.
>
> This code doesn't implement cec notifier because STM32 doesn't
> provide HDMI yet but it will be added later.
>
> Those patches have been developped on top of media_tree master branch
> where STM32 DCMI code has not been merged so conflict in Kconfig and Makefile
> could occur depending of merge ordering.
>
> Compliance has been tested on STM32F769.
>
> ~ # cec-ctl -p 1.0.0.0 --playback
> Driver Info:
> Driver Name : stm32-cec
> Adapter Name : stm32-cec
> Capabilities : 0x0000000f
> Physical Address
> Logical Addresses
> Transmit
> Passthrough
> Driver version : 4.11.0
> Available Logical Addresses: 1
> Physical Address : 1.0.0.0
> Logical Address Mask : 0x0010
> CEC Version : 2.0
> Vendor ID : 0x000c03 (HDMI)
> OSD Name : 'Playback'
> Logical Addresses : 1 (Allow RC Passthrough)
>
> Logical Address : 4 (Playback Device 1)
> Primary Device Type : Playback
> Logical Address Type : Playback
> All Device Types : Playback
> RC TV Profile : None
> Device Features :
> None
>
> ~ # cec-compliance -A
> cec-compliance SHA : 6acac5cec698de39b9398b66c4f5f4db6b2730d8
>
> Driver Info:
> Driver Name : stm32-cec
> Adapter Name : stm32-cec
> Capabilities : 0x0000000f
> Physical Address
> Logical Addresses
> Transmit
> Passthrough
> Driver version : 4.11.0
> Available Logical Addresses: 1
> Physical Address : 1.0.0.0
> Logical Address Mask : 0x0010
> CEC Version : 2.0
> Vendor ID : 0x000c03
> Logical Addresses : 1 (Allow RC Passthrough)
>
> Logical Address : 4
> Primary Device Type : Playback
> Logical Address Type : Playback
> All Device Types : Playback
> RC TV Profile : None
> Device Features :
> None
>
> Compliance test for device /dev/cec0:
>
> The test results mean the following:
> OK Supported correctly by the device.
> OK (Not Supported) Not supported and not mandatory for the device.
> OK (Presumed) Presumably supported. Manually check to confirm.
> OK (Unexpected) Supported correctly but is not expected to be supported for this device.
> OK (Refused) Supported by the device, but was refused.
> FAIL Failed and was expected to be supported by this device.
>
> Find remote devices:
> Polling: OK
>
> CEC API:
> CEC_ADAP_G_CAPS: OK
> CEC_DQEVENT: OK
> CEC_ADAP_G/S_PHYS_ADDR: OK
> CEC_ADAP_G/S_LOG_ADDRS: OK
> CEC_TRANSMIT: OK
> CEC_RECEIVE: OK
> CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed)
> CEC_G/S_MODE: OK
> CEC_EVENT_LOST_MSGS: OK
>
> Network topology:
> System Information for device 0 (TV) from device 4 (Playback Device 1):
> CEC Version : 1.4
> Physical Address : 0.0.0.0
> Primary Device Type : TV
> Vendor ID : 0x00903e
> OSD Name : 'TV'
> Menu Language : fre
> Power Status : On
>
> Total: 10, Succeeded: 10, Failed: 0, Warnings: 0
>
> Benjamin Gaignard (2):
> binding for stm32 cec driver
> cec: add STM32 cec driver
>
> .../devicetree/bindings/media/st,stm32-cec.txt | 19 ++
> drivers/media/platform/Kconfig | 11 +
> drivers/media/platform/Makefile | 2 +
> drivers/media/platform/stm32/Makefile | 1 +
> drivers/media/platform/stm32/stm32-cec.c | 368 +++++++++++++++++++++
> 5 files changed, 401 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/st,stm32-cec.txt
> create mode 100644 drivers/media/platform/stm32/Makefile
> create mode 100644 drivers/media/platform/stm32/stm32-cec.c
>
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] cec: STM32 driver
[not found] ` <CA+M3ks6eO7144jNyBQZQfQ=ANwgxQjKKCY03iBnQB4mik6uFMQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-05-16 9:18 ` Hans Verkuil
[not found] ` <f0eb8619-e2e3-f5db-bffd-0a51580e725c-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Hans Verkuil @ 2017-05-16 9:18 UTC (permalink / raw)
To: Benjamin Gaignard, Alexandre Torgue,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Hans Verkuil, Yannick Fertre
On 16/05/17 11:10, Benjamin Gaignard wrote:
> + Yannick who is the original writer of this driver (sorry)
>
> 2017-05-16 11:01 GMT+02:00 Benjamin Gaignard <benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>:
>> This serie of patches add cec driver for STM32 platforms.
>>
>> This code doesn't implement cec notifier because STM32 doesn't
>> provide HDMI yet but it will be added later.
When will that happen? Is that in 4.12?
Regards,
Hans
>>
>> Those patches have been developped on top of media_tree master branch
>> where STM32 DCMI code has not been merged so conflict in Kconfig and Makefile
>> could occur depending of merge ordering.
>>
>> Compliance has been tested on STM32F769.
>>
>> ~ # cec-ctl -p 1.0.0.0 --playback
>> Driver Info:
>> Driver Name : stm32-cec
>> Adapter Name : stm32-cec
>> Capabilities : 0x0000000f
>> Physical Address
>> Logical Addresses
>> Transmit
>> Passthrough
>> Driver version : 4.11.0
>> Available Logical Addresses: 1
>> Physical Address : 1.0.0.0
>> Logical Address Mask : 0x0010
>> CEC Version : 2.0
>> Vendor ID : 0x000c03 (HDMI)
>> OSD Name : 'Playback'
>> Logical Addresses : 1 (Allow RC Passthrough)
>>
>> Logical Address : 4 (Playback Device 1)
>> Primary Device Type : Playback
>> Logical Address Type : Playback
>> All Device Types : Playback
>> RC TV Profile : None
>> Device Features :
>> None
>>
>> ~ # cec-compliance -A
>> cec-compliance SHA : 6acac5cec698de39b9398b66c4f5f4db6b2730d8
>>
>> Driver Info:
>> Driver Name : stm32-cec
>> Adapter Name : stm32-cec
>> Capabilities : 0x0000000f
>> Physical Address
>> Logical Addresses
>> Transmit
>> Passthrough
>> Driver version : 4.11.0
>> Available Logical Addresses: 1
>> Physical Address : 1.0.0.0
>> Logical Address Mask : 0x0010
>> CEC Version : 2.0
>> Vendor ID : 0x000c03
>> Logical Addresses : 1 (Allow RC Passthrough)
>>
>> Logical Address : 4
>> Primary Device Type : Playback
>> Logical Address Type : Playback
>> All Device Types : Playback
>> RC TV Profile : None
>> Device Features :
>> None
>>
>> Compliance test for device /dev/cec0:
>>
>> The test results mean the following:
>> OK Supported correctly by the device.
>> OK (Not Supported) Not supported and not mandatory for the device.
>> OK (Presumed) Presumably supported. Manually check to confirm.
>> OK (Unexpected) Supported correctly but is not expected to be supported for this device.
>> OK (Refused) Supported by the device, but was refused.
>> FAIL Failed and was expected to be supported by this device.
>>
>> Find remote devices:
>> Polling: OK
>>
>> CEC API:
>> CEC_ADAP_G_CAPS: OK
>> CEC_DQEVENT: OK
>> CEC_ADAP_G/S_PHYS_ADDR: OK
>> CEC_ADAP_G/S_LOG_ADDRS: OK
>> CEC_TRANSMIT: OK
>> CEC_RECEIVE: OK
>> CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed)
>> CEC_G/S_MODE: OK
>> CEC_EVENT_LOST_MSGS: OK
>>
>> Network topology:
>> System Information for device 0 (TV) from device 4 (Playback Device 1):
>> CEC Version : 1.4
>> Physical Address : 0.0.0.0
>> Primary Device Type : TV
>> Vendor ID : 0x00903e
>> OSD Name : 'TV'
>> Menu Language : fre
>> Power Status : On
>>
>> Total: 10, Succeeded: 10, Failed: 0, Warnings: 0
>>
>> Benjamin Gaignard (2):
>> binding for stm32 cec driver
>> cec: add STM32 cec driver
>>
>> .../devicetree/bindings/media/st,stm32-cec.txt | 19 ++
>> drivers/media/platform/Kconfig | 11 +
>> drivers/media/platform/Makefile | 2 +
>> drivers/media/platform/stm32/Makefile | 1 +
>> drivers/media/platform/stm32/stm32-cec.c | 368 +++++++++++++++++++++
>> 5 files changed, 401 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/media/st,stm32-cec.txt
>> create mode 100644 drivers/media/platform/stm32/Makefile
>> create mode 100644 drivers/media/platform/stm32/stm32-cec.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 [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] cec: STM32 driver
[not found] ` <f0eb8619-e2e3-f5db-bffd-0a51580e725c-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
@ 2017-05-16 9:24 ` Benjamin Gaignard
0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Gaignard @ 2017-05-16 9:24 UTC (permalink / raw)
To: Hans Verkuil
Cc: Alexandre Torgue, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Hans Verkuil, Yannick Fertre
2017-05-16 11:18 GMT+02:00 Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>:
> On 16/05/17 11:10, Benjamin Gaignard wrote:
>> + Yannick who is the original writer of this driver (sorry)
>>
>> 2017-05-16 11:01 GMT+02:00 Benjamin Gaignard <benjamin.gaignard@linaro.org>:
>>> This serie of patches add cec driver for STM32 platforms.
>>>
>>> This code doesn't implement cec notifier because STM32 doesn't
>>> provide HDMI yet but it will be added later.
>
> When will that happen? Is that in 4.12?
We have send the patches yesterday for DSI support to dri-devel mailing list.
I guess the discussions will take some time but cec hardware could
work without it.
>
> Regards,
>
> Hans
>
>>>
>>> Those patches have been developped on top of media_tree master branch
>>> where STM32 DCMI code has not been merged so conflict in Kconfig and Makefile
>>> could occur depending of merge ordering.
>>>
>>> Compliance has been tested on STM32F769.
>>>
>>> ~ # cec-ctl -p 1.0.0.0 --playback
>>> Driver Info:
>>> Driver Name : stm32-cec
>>> Adapter Name : stm32-cec
>>> Capabilities : 0x0000000f
>>> Physical Address
>>> Logical Addresses
>>> Transmit
>>> Passthrough
>>> Driver version : 4.11.0
>>> Available Logical Addresses: 1
>>> Physical Address : 1.0.0.0
>>> Logical Address Mask : 0x0010
>>> CEC Version : 2.0
>>> Vendor ID : 0x000c03 (HDMI)
>>> OSD Name : 'Playback'
>>> Logical Addresses : 1 (Allow RC Passthrough)
>>>
>>> Logical Address : 4 (Playback Device 1)
>>> Primary Device Type : Playback
>>> Logical Address Type : Playback
>>> All Device Types : Playback
>>> RC TV Profile : None
>>> Device Features :
>>> None
>>>
>>> ~ # cec-compliance -A
>>> cec-compliance SHA : 6acac5cec698de39b9398b66c4f5f4db6b2730d8
>>>
>>> Driver Info:
>>> Driver Name : stm32-cec
>>> Adapter Name : stm32-cec
>>> Capabilities : 0x0000000f
>>> Physical Address
>>> Logical Addresses
>>> Transmit
>>> Passthrough
>>> Driver version : 4.11.0
>>> Available Logical Addresses: 1
>>> Physical Address : 1.0.0.0
>>> Logical Address Mask : 0x0010
>>> CEC Version : 2.0
>>> Vendor ID : 0x000c03
>>> Logical Addresses : 1 (Allow RC Passthrough)
>>>
>>> Logical Address : 4
>>> Primary Device Type : Playback
>>> Logical Address Type : Playback
>>> All Device Types : Playback
>>> RC TV Profile : None
>>> Device Features :
>>> None
>>>
>>> Compliance test for device /dev/cec0:
>>>
>>> The test results mean the following:
>>> OK Supported correctly by the device.
>>> OK (Not Supported) Not supported and not mandatory for the device.
>>> OK (Presumed) Presumably supported. Manually check to confirm.
>>> OK (Unexpected) Supported correctly but is not expected to be supported for this device.
>>> OK (Refused) Supported by the device, but was refused.
>>> FAIL Failed and was expected to be supported by this device.
>>>
>>> Find remote devices:
>>> Polling: OK
>>>
>>> CEC API:
>>> CEC_ADAP_G_CAPS: OK
>>> CEC_DQEVENT: OK
>>> CEC_ADAP_G/S_PHYS_ADDR: OK
>>> CEC_ADAP_G/S_LOG_ADDRS: OK
>>> CEC_TRANSMIT: OK
>>> CEC_RECEIVE: OK
>>> CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed)
>>> CEC_G/S_MODE: OK
>>> CEC_EVENT_LOST_MSGS: OK
>>>
>>> Network topology:
>>> System Information for device 0 (TV) from device 4 (Playback Device 1):
>>> CEC Version : 1.4
>>> Physical Address : 0.0.0.0
>>> Primary Device Type : TV
>>> Vendor ID : 0x00903e
>>> OSD Name : 'TV'
>>> Menu Language : fre
>>> Power Status : On
>>>
>>> Total: 10, Succeeded: 10, Failed: 0, Warnings: 0
>>>
>>> Benjamin Gaignard (2):
>>> binding for stm32 cec driver
>>> cec: add STM32 cec driver
>>>
>>> .../devicetree/bindings/media/st,stm32-cec.txt | 19 ++
>>> drivers/media/platform/Kconfig | 11 +
>>> drivers/media/platform/Makefile | 2 +
>>> drivers/media/platform/stm32/Makefile | 1 +
>>> drivers/media/platform/stm32/stm32-cec.c | 368 +++++++++++++++++++++
>>> 5 files changed, 401 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/media/st,stm32-cec.txt
>>> create mode 100644 drivers/media/platform/stm32/Makefile
>>> create mode 100644 drivers/media/platform/stm32/stm32-cec.c
>>>
>>> --
>>> 1.9.1
>>>
>
--
Benjamin Gaignard
Graphic Study Group
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] cec: add STM32 cec driver
2017-05-16 9:01 ` [PATCH 2/2] cec: add STM32 " Benjamin Gaignard
@ 2017-05-16 9:33 ` Hans Verkuil
0 siblings, 0 replies; 7+ messages in thread
From: Hans Verkuil @ 2017-05-16 9:33 UTC (permalink / raw)
To: Benjamin Gaignard, yannick.ferte, alexandre.torgue, devicetree,
linux-media, robh, hans.verkuil
Hi Benjamin,
Thanks for the patch! Always nice to see new CEC drivers.
On 16/05/17 11:01, Benjamin Gaignard wrote:
> This patch add cec driver for STM32 platforms.
> cec hardware block isn't not always used with hdmi so
> cec notifier is not implemented. That will be done later
> when STM32 DSI driver will be available.
>
> Driver compliance has been tested with cec-ctl and cec-compliance
> tools.
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Since Yannick wrote the original driver, shouldn't there be a Signed-off-by
from him as well?
> ---
> drivers/media/platform/Kconfig | 11 +
> drivers/media/platform/Makefile | 2 +
> drivers/media/platform/stm32/Makefile | 1 +
> drivers/media/platform/stm32/stm32-cec.c | 368 +++++++++++++++++++++++++++++++
> 4 files changed, 382 insertions(+)
> create mode 100644 drivers/media/platform/stm32/Makefile
> create mode 100644 drivers/media/platform/stm32/stm32-cec.c
>
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index ac026ee..72efe34 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -519,4 +519,15 @@ config VIDEO_STI_HDMI_CEC
> CEC bus is present in the HDMI connector and enables communication
> between compatible devices.
>
> +config VIDEO_STM32_HDMI_CEC
> + tristate "STMicroelectronics STM32 HDMI CEC driver"
> + depends on CEC_CORE && (ARCH_STM32 || COMPILE_TEST)
> + select REGMAP
> + select REGMAP_MMIO
> + ---help---
> + This is a driver for STM32 interface. It uses the
> + generic CEC framework interface.
> + CEC bus is present in the HDMI connector and enables communication
> + between compatible devices.
> +
> endif #CEC_PLATFORM_DRIVERS
> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> index 63303d6..7cd9965 100644
> --- a/drivers/media/platform/Makefile
> +++ b/drivers/media/platform/Makefile
> @@ -44,6 +44,8 @@ obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/
>
> obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/
>
> +obj-$(CONFIG_VIDEO_STM32_HDMI_CEC) += stm32/
> +
> obj-$(CONFIG_BLACKFIN) += blackfin/
>
> obj-$(CONFIG_ARCH_DAVINCI) += davinci/
> diff --git a/drivers/media/platform/stm32/Makefile b/drivers/media/platform/stm32/Makefile
> new file mode 100644
> index 0000000..632b04c
> --- /dev/null
> +++ b/drivers/media/platform/stm32/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_VIDEO_STM32_HDMI_CEC) += stm32-cec.o
> diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c
> new file mode 100644
> index 0000000..a40a6eb
> --- /dev/null
> +++ b/drivers/media/platform/stm32/stm32-cec.c
> @@ -0,0 +1,368 @@
> +/*
> + * STM32 CEC driver
> + * Copyright (C) STMicroelectronic SA 2017
Isn't it STMicroelectronics instead of STMicroelectronic?
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <media/cec.h>
> +
> +#define CEC_NAME "stm32-cec"
> +
> +/* CEC registers */
> +#define CEC_CR 0x0000 /* Control Register */
> +#define CEC_CFGR 0x0004 /* ConFiGuration Register */
> +#define CEC_TXDR 0x0008 /* Rx data Register */
> +#define CEC_RXDR 0x000C /* Rx data Register */
> +#define CEC_ISR 0x0010 /* Interrupt and status Register */
> +#define CEC_IER 0x0014 /* Interrupt enable Register */
> +
> +#define TXEOM BIT(2)
> +#define TXSOM BIT(1)
> +#define CECEN BIT(0)
> +
> +#define LSTN BIT(31)
> +#define OAR GENMASK(30, 16)
> +#define SFTOP BIT(8)
> +#define BRDNOGEN BIT(7)
> +#define LBPEGEN BIT(6)
> +#define BREGEN BIT(5)
> +#define BRESTP BIT(4)
> +#define RXTOL BIT(3)
> +#define SFT GENMASK(2, 0)
> +#define FULL_CFG (LSTN | SFTOP | BRDNOGEN | LBPEGEN | BREGEN | BRESTP \
> + | RXTOL | SFT | BRDNOGEN)
> +
> +#define TXACKE BIT(12)
> +#define TXERR BIT(11)
> +#define TXUDR BIT(10)
> +#define TXEND BIT(9)
> +#define TXBR BIT(8)
> +#define ARBLST BIT(7)
> +#define RXACKE BIT(6)
> +#define RXOVR BIT(2)
> +#define RXEND BIT(1)
> +#define RXBR BIT(0)
> +
> +#define ALL_TX_IT (TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST)
> +#define ALL_RX_IT (RXEND | RXBR | RXACKE | RXOVR)
> +
> +struct stm32_cec {
> + struct cec_adapter *adap;
> + struct device *dev;
> + struct clk *clk_cec;
> + struct clk *clk_hdmi_cec;
> + struct reset_control *rstc;
> + struct regmap *regmap;
> + int irq;
> + u32 irq_status;
> + u8 rx_msg[CEC_MAX_MSG_SIZE];
> + u8 tx_msg[CEC_MAX_MSG_SIZE];
> + int rx_len;
> + int tx_len;
> + int tx_cnt;
> +};
> +
> +static void cec_hw_init(struct stm32_cec *cec)
> +{
> + regmap_update_bits(cec->regmap, CEC_CR, TXEOM | TXSOM | CECEN, 0);
> +
> + regmap_update_bits(cec->regmap, CEC_IER, ALL_TX_IT | ALL_RX_IT,
> + ALL_TX_IT | ALL_RX_IT);
> +
> + regmap_update_bits(cec->regmap, CEC_CFGR, FULL_CFG, FULL_CFG);
> +}
> +
> +static void stm32_tx_done(struct stm32_cec *cec, u32 status)
> +{
> + if (status & (TXERR | TXUDR)) {
> + cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR,
> + 0, 0, 0, 1);
> + return;
> + }
> +
> + if (status & ARBLST) {
> + cec_transmit_done(cec->adap, CEC_TX_STATUS_ARB_LOST,
> + 1, 0, 0, 0);
> + return;
> + }
> +
> + if (status & TXACKE) {
> + cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK,
> + 0, 1, 0, 0);
> + return;
> + }
> +
> + if (cec->irq_status & TXBR) {
> + /* send next byte */
> + if (cec->tx_cnt < cec->tx_len)
> + regmap_write(cec->regmap, CEC_TXDR,
> + cec->tx_msg[cec->tx_cnt++]);
> +
> + /* TXEOM is set to command transmission of the last byte */
> + if (cec->tx_cnt == cec->tx_len)
> + regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
> + }
> +
> + if (cec->irq_status & TXEND)
> + cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
> +}
> +
> +static void stm32_rx_done(struct stm32_cec *cec, u32 status)
> +{
> + if (cec->irq_status & (RXACKE | RXOVR)) {
> + cec->rx_len = 0;
> + return;
> + }
> +
> + if (cec->irq_status & RXBR) {
> + u32 val;
> +
> + regmap_read(cec->regmap, CEC_RXDR, &val);
> + cec->rx_msg[cec->rx_len++] = val & 0xFF;
Wouldn't it be safer to handle this IRQ and the TXBR interrupt in
stm32_cec_irq_handler()? This can be done in atomic context and these are
more time-sensitive.
> + }
> +
> + if (cec->irq_status & RXEND) {
> + struct cec_msg msg = {};
> +
> + msg.len = cec->rx_len;
> + memcpy(msg.msg, cec->rx_msg, msg.len);
Most drivers just embed a cec_msg struct in the top-level struct (stm32_cec
in this case). That way there is no need to have your own copies of the length
and message data (rx_len and rx_msg in this case).
Actually, the same applies to the tx part, just embed a cec_msg tx_msg.
> + cec_received_msg(cec->adap, &msg);
> +
> + cec->rx_len = 0;
> + }
> +}
> +
> +static irqreturn_t stm32_cec_irq_thread(int irq, void *arg)
> +{
> + struct stm32_cec *cec = arg;
> +
> + if (cec->irq_status & ALL_TX_IT)
> + stm32_tx_done(cec, cec->irq_status);
> +
> + if (cec->irq_status & ALL_RX_IT)
> + stm32_rx_done(cec, cec->irq_status);
> +
> + cec->irq_status = 0;
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t stm32_cec_irq_handler(int irq, void *arg)
> +{
> + struct stm32_cec *cec = arg;
> +
> + regmap_read(cec->regmap, CEC_ISR, &cec->irq_status);
> +
> + regmap_update_bits(cec->regmap, CEC_ISR,
> + ALL_TX_IT | ALL_RX_IT,
> + ALL_TX_IT | ALL_RX_IT);
> +
> + return IRQ_WAKE_THREAD;
> +}
> +
> +static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
> +{
> + struct stm32_cec *cec = adap->priv;
> + int ret = 0;
> +
> + if (enable) {
> + ret = clk_enable(cec->clk_cec);
> + if (ret)
> + dev_err(cec->dev, "fail to enable cec clock\n");
> +
> + clk_enable(cec->clk_hdmi_cec);
> + regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
> + } else {
> + clk_disable(cec->clk_cec);
> + clk_disable(cec->clk_hdmi_cec);
> + regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
> + }
> +
> + return ret;
> +}
> +
> +static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> + struct stm32_cec *cec = adap->priv;
> +
> + regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
> +
> + if (logical_addr == CEC_LOG_ADDR_INVALID)
> + regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
> + else
> + regmap_update_bits(cec->regmap, CEC_CFGR, OAR,
> + (1 << logical_addr) << 16);
Since this is a mask I assume that this CEC implementation can handle multiple
logical addresses? In that case you should allow that when you call cec_allocate_adapter:
instead of '1' use CEC_MAX_LOG_ADDRS as the last argument.
> +
> + regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
> +
> + return 0;
> +}
> +
> +static int stm32_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
> + u32 signal_free_time, struct cec_msg *msg)
> +{
> + struct stm32_cec *cec = adap->priv;
> +
> + /* Copy message */
> + memcpy(cec->tx_msg, msg->msg, msg->len);
> +
> + cec->tx_len = msg->len;
> + cec->tx_cnt = 0;
> +
> + /*
> + * If the CEC message consists of only one byte,
> + * TXEOM must be set before of TXSOM.
> + */
> + if (cec->tx_len == 1)
> + regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
> +
> + /* TXSOM is set to command transmission of the first byte */
> + regmap_update_bits(cec->regmap, CEC_CR, TXSOM, TXSOM);
> +
> + /* Write the header (first byte of message) */
> + regmap_write(cec->regmap, CEC_TXDR, cec->tx_msg[0]);
> + cec->tx_cnt++;
> +
> + return 0;
> +}
> +
> +static const struct cec_adap_ops stm32_cec_adap_ops = {
> + .adap_enable = stm32_cec_adap_enable,
> + .adap_log_addr = stm32_cec_adap_log_addr,
> + .adap_transmit = stm32_cec_adap_transmit,
> +};
> +
> +static const struct regmap_config stm32_cec_regmap_cfg = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = sizeof(u32),
> + .max_register = 0x14,
> + .fast_io = true,
> +};
> +
> +static int stm32_cec_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + struct stm32_cec *cec;
> + void __iomem *mmio;
> + int ret;
> +
> + cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> + if (!cec)
> + return -ENOMEM;
> +
> + cec->dev = &pdev->dev;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + mmio = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(mmio))
> + return PTR_ERR(mmio);
> +
> + cec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "cec", mmio,
> + &stm32_cec_regmap_cfg);
> +
> + if (IS_ERR(cec->regmap))
> + return PTR_ERR(cec->regmap);
> +
> + cec->irq = platform_get_irq(pdev, 0);
> + if (cec->irq < 0)
> + return cec->irq;
> +
> + ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> + stm32_cec_irq_handler,
> + stm32_cec_irq_thread,
> + 0,
> + pdev->name, cec);
> + if (ret)
> + return ret;
> +
> + cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
> + if (IS_ERR(cec->clk_cec)) {
> + dev_err(&pdev->dev, "Cannot get cec clock\n");
> + return PTR_ERR(cec->clk_cec);
> + }
> +
> + ret = clk_prepare(cec->clk_cec);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to prepare cec clock\n");
> + return ret;
> + }
> +
> + cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
> + if (!IS_ERR(cec->clk_hdmi_cec)) {
> + ret = clk_prepare(cec->clk_hdmi_cec);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to prepare hdmi-cec clock\n");
> + return ret;
> + }
> + }
> +
> + cec->adap = cec_allocate_adapter(&stm32_cec_adap_ops, cec,
> + CEC_NAME,
> + CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH |
> + CEC_CAP_PHYS_ADDR | CEC_CAP_TRANSMIT, 1);
Add CEC_CAP_RC.
Add a comment that CEC_CAP_PHYS_ADDR is temporary until this driver is
switched to using a cec_notifier.
There is no CEC bus monitoring support for this hardware?
> + ret = PTR_ERR_OR_ZERO(cec->adap);
> + if (ret)
> + return ret;
> +
> + ret = cec_register_adapter(cec->adap, &pdev->dev);
> + if (ret) {
> + cec_delete_adapter(cec->adap);
> + return ret;
> + }
> +
> + cec_hw_init(cec);
> +
> + platform_set_drvdata(pdev, cec);
> +
> + return 0;
> +}
> +
> +static int stm32_cec_remove(struct platform_device *pdev)
> +{
> + struct stm32_cec *cec = platform_get_drvdata(pdev);
> +
> + clk_unprepare(cec->clk_cec);
> + clk_unprepare(cec->clk_hdmi_cec);
> +
> + cec_unregister_adapter(cec->adap);
> +
> + cec_delete_adapter(cec->adap);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id stm32_cec_of_match[] = {
> + { .compatible = "st,stm32-cec" },
> + { /* end node */ }
> +};
> +MODULE_DEVICE_TABLE(of, stm32_cec_of_match);
> +
> +static struct platform_driver stm32_cec_driver = {
> + .probe = stm32_cec_probe,
> + .remove = stm32_cec_remove,
> + .driver = {
> + .name = CEC_NAME,
> + .of_match_table = stm32_cec_of_match,
> + },
> +};
> +
> +module_platform_driver(stm32_cec_driver);
> +
> +MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
> +MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
> +MODULE_DESCRIPTION("STMicroelectronics STM32 Consumer Electronics Control");
> +MODULE_LICENSE("GPL v2");
>
Regards,
Hans
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-05-16 9:33 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-16 9:01 [PATCH 0/2] cec: STM32 driver Benjamin Gaignard
[not found] ` <1494925280-4527-1-git-send-email-benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-05-16 9:01 ` [PATCH 1/2] binding for stm32 cec driver Benjamin Gaignard
2017-05-16 9:01 ` [PATCH 2/2] cec: add STM32 " Benjamin Gaignard
2017-05-16 9:33 ` Hans Verkuil
2017-05-16 9:10 ` [PATCH 0/2] cec: STM32 driver Benjamin Gaignard
[not found] ` <CA+M3ks6eO7144jNyBQZQfQ=ANwgxQjKKCY03iBnQB4mik6uFMQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-05-16 9:18 ` Hans Verkuil
[not found] ` <f0eb8619-e2e3-f5db-bffd-0a51580e725c-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
2017-05-16 9:24 ` Benjamin Gaignard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).