2017-06-30 06:03:34

by Sean Wang

[permalink] [raw]
Subject: [PATCH v1 0/4] media: rc: add support for IR receiver on MT7622 SoC

From: Sean Wang <[email protected]>

This patchset introduces Consumer IR (CIR) support for MT7622 SoC
implements raw mode for more compatibility with different protocols
as previously SoC did. Before adding support to MT7622 SoC, extra
code refactor is done since there're major differences in register and
field definition from the previous SoC.

Sean Wang (4):
dt-bindings: media: mtk-cir: Add support for MT7622 SoC
media: rc: mtk-cir: add platform data to adapt into various hardware
media: rc: mtk-cir: add support for MediaTek MT7622 SoC
MAINTAINERS: add entry for MediaTek CIR driver

.../devicetree/bindings/media/mtk-cir.txt | 8 +-
MAINTAINERS | 5 +
drivers/media/rc/mtk-cir.c | 242 ++++++++++++++++-----
3 files changed, 197 insertions(+), 58 deletions(-)

--
2.7.4


2017-06-30 06:03:23

by Sean Wang

[permalink] [raw]
Subject: [PATCH v1 1/4] dt-bindings: media: mtk-cir: Add support for MT7622 SoC

From: Sean Wang <[email protected]>

Document the devicetree bindings for CIR on MediaTek MT7622
SoC.

Signed-off-by: Sean Wang <[email protected]>
---
Documentation/devicetree/bindings/media/mtk-cir.txt | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt
index 2be2005..5e18087 100644
--- a/Documentation/devicetree/bindings/media/mtk-cir.txt
+++ b/Documentation/devicetree/bindings/media/mtk-cir.txt
@@ -2,10 +2,14 @@ Device-Tree bindings for Mediatek consumer IR controller
found in Mediatek SoC family

Required properties:
-- compatible : "mediatek,mt7623-cir"
+- compatible : Should be
+ "mediatek,mt7623-cir": for MT7623 SoC
+ "mediatek,mt7622-cir": for MT7622 SoC
- clocks : list of clock specifiers, corresponding to
entries in clock-names property;
-- clock-names : should contain "clk" entries;
+- clock-names : should contain
+ - "clk" entries: for MT7623 SoC
+ - "clk", "bus" entries: for MT7622 SoC
- interrupts : should contain IR IRQ number;
- reg : should contain IO map address for IR.

--
2.7.4

2017-06-30 06:03:29

by Sean Wang

[permalink] [raw]
Subject: [PATCH v1 3/4] media: rc: mtk-cir: add support for MediaTek MT7622 SoC

From: Sean Wang <[email protected]>

This patch adds driver for CIR controller on MT7622 SoC. It has similar
handling logic as the previously MT7623 does, but there are some
differences in the register and field definition. So for ease portability
and maintenance, those differences all are being kept inside the platform
data as other drivers usually do. Currently testing successfully on NEC
and SONY remote controller.

Signed-off-by: Sean Wang <[email protected]>
---
drivers/media/rc/mtk-cir.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
index 32b1031..6672772 100644
--- a/drivers/media/rc/mtk-cir.c
+++ b/drivers/media/rc/mtk-cir.c
@@ -84,6 +84,13 @@ static const u32 mt7623_regs[] = {
[MTK_IRINT_CLR_REG] = 0xd0,
};

+static const u32 mt7622_regs[] = {
+ [MTK_IRCLR_REG] = 0x18,
+ [MTK_CHKDATA_REG] = 0x30,
+ [MTK_IRINT_EN_REG] = 0x1c,
+ [MTK_IRINT_CLR_REG] = 0x20,
+};
+
struct mtk_field_type {
u32 reg;
u8 offset;
@@ -113,6 +120,11 @@ static const struct mtk_field_type mt7623_fields[] = {
[MTK_HW_PERIOD] = {0x10, 0, GENMASK(7, 0)},
};

+static const struct mtk_field_type mt7622_fields[] = {
+ [MTK_CHK_PERIOD] = {0x24, 0, GENMASK(24, 0)},
+ [MTK_HW_PERIOD] = {0x10, 0, GENMASK(24, 0)},
+};
+
/*
* struct mtk_ir - This is the main datasructure for holding the state
* of the driver
@@ -268,8 +280,17 @@ static const struct mtk_ir_data mt7623_data = {
.div = 4,
};

+static const struct mtk_ir_data mt7622_data = {
+ .regs = mt7622_regs,
+ .fields = mt7622_fields,
+ .ok_count = 0xf,
+ .hw_period = 0xffff,
+ .div = 32,
+};
+
static const struct of_device_id mtk_ir_match[] = {
{ .compatible = "mediatek,mt7623-cir", .data = &mt7623_data},
+ { .compatible = "mediatek,mt7622-cir", .data = &mt7622_data},
{},
};
MODULE_DEVICE_TABLE(of, mtk_ir_match);
--
2.7.4

2017-06-30 06:03:39

by Sean Wang

[permalink] [raw]
Subject: [PATCH v1 4/4] MAINTAINERS: add entry for MediaTek CIR driver

From: Sean Wang <[email protected]>

I work for MediaTek on maintaining the MediaTek CIR driver
for the existing SoCs and adding support for the following
SoCs.

Signed-off-by: Sean Wang <[email protected]>
---
MAINTAINERS | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2a1290a..1bc1fb1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8261,6 +8261,11 @@ L: [email protected]
S: Maintained
F: drivers/net/wireless/mediatek/mt7601u/

+MEDIATEK CIR DRIVER
+M: Sean Wang <[email protected]>
+S: Maintained
+F: drivers/media/rc/mtk-cir.c
+
MEDIATEK RANDOM NUMBER GENERATOR SUPPORT
M: Sean Wang <[email protected]>
S: Maintained
--
2.7.4

2017-06-30 06:04:13

by Sean Wang

[permalink] [raw]
Subject: [PATCH v1 2/4] media: rc: mtk-cir: add platform data to adapt into various hardware

From: Sean Wang <[email protected]>

This patch is the preparation patch in order to adapt into various
hardware through adding platform data which holds specific characteristics
and differences among MediaTek supported CIR devices instead of the old
way defining those data in the static way as macro has. And the existing
logic would be slightly changed to operate on those data which the actual
device depends on.

Signed-off-by: Sean Wang <[email protected]>
---
drivers/media/rc/mtk-cir.c | 221 +++++++++++++++++++++++++++++++++------------
1 file changed, 165 insertions(+), 56 deletions(-)

diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
index f1e164e..32b1031 100644
--- a/drivers/media/rc/mtk-cir.c
+++ b/drivers/media/rc/mtk-cir.c
@@ -25,35 +25,28 @@

/* Register to enable PWM and IR */
#define MTK_CONFIG_HIGH_REG 0x0c
-/* Enable IR pulse width detection */
+
+/* Bit to enable IR pulse width detection */
#define MTK_PWM_EN BIT(13)
-/* Enable IR hardware function */
-#define MTK_IR_EN BIT(0)

-/* Register to setting sample period */
-#define MTK_CONFIG_LOW_REG 0x10
-/* Field to set sample period */
-#define CHK_PERIOD DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, \
- MTK_IR_CLK_PERIOD)
-#define MTK_CHK_PERIOD (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
-#define MTK_CHK_PERIOD_MASK (GENMASK(20, 8))
+/*
+ * Register to setting ok count whose unit based on hardware sampling period
+ * indicating IR receiving completion and then making IRQ fires
+ */
+#define MTK_OK_COUNT(x) (((x) & GENMASK(23, 16)) << 16)
+
+/* Bit to enable IR hardware function */
+#define MTK_IR_EN BIT(0)

-/* Register to clear state of state machine */
-#define MTK_IRCLR_REG 0x20
/* Bit to restart IR receiving */
#define MTK_IRCLR BIT(0)

-/* Register containing pulse width data */
-#define MTK_CHKDATA_REG(i) (0x88 + 4 * (i))
+/* Fields containing pulse width data */
#define MTK_WIDTH_MASK (GENMASK(7, 0))

-/* Register to enable IR interrupt */
-#define MTK_IRINT_EN_REG 0xcc
/* Bit to enable interrupt */
#define MTK_IRINT_EN BIT(0)

-/* Register to ack IR interrupt */
-#define MTK_IRINT_CLR_REG 0xd0
/* Bit to clear interrupt status */
#define MTK_IRINT_CLR BIT(0)

@@ -63,24 +56,73 @@
#define MTK_IR_END(v, p) ((v) == MTK_MAX_SAMPLES && (p) == 0)
/* Number of registers to record the pulse width */
#define MTK_CHKDATA_SZ 17
-/* Source clock frequency */
-#define MTK_IR_BASE_CLK 273000000
-/* Frequency after IR internal divider */
-#define MTK_IR_CLK_FREQ (MTK_IR_BASE_CLK / 4)
-/* Period for MTK_IR_CLK in ns*/
-#define MTK_IR_CLK_PERIOD DIV_ROUND_CLOSEST(1000000000ul, \
- MTK_IR_CLK_FREQ)
/* Sample period in ns */
-#define MTK_IR_SAMPLE (MTK_IR_CLK_PERIOD * 0xc00)
+#define MTK_IR_SAMPLE 46000
+
+enum mtk_fields {
+ /* Register to setting software sampling period */
+ MTK_CHK_PERIOD,
+ /* Register to setting hardware sampling period */
+ MTK_HW_PERIOD,
+};
+
+enum mtk_regs {
+ /* Register to clear state of state machine */
+ MTK_IRCLR_REG,
+ /* Register containing pulse width data */
+ MTK_CHKDATA_REG,
+ /* Register to enable IR interrupt */
+ MTK_IRINT_EN_REG,
+ /* Register to ack IR interrupt */
+ MTK_IRINT_CLR_REG
+};
+
+static const u32 mt7623_regs[] = {
+ [MTK_IRCLR_REG] = 0x20,
+ [MTK_CHKDATA_REG] = 0x88,
+ [MTK_IRINT_EN_REG] = 0xcc,
+ [MTK_IRINT_CLR_REG] = 0xd0,
+};
+
+struct mtk_field_type {
+ u32 reg;
+ u8 offset;
+ u32 mask;
+};
+
+/*
+ * struct mtk_ir_data - This is the structure holding all differences among
+ various hardwares
+ * @regs: The pointer to the array holding registers offset
+ * @fields: The pointer to the array holding fields location
+ * @div: The internal divisor for the based reference clock
+ * @ok_count: The count indicating the completion of IR data
+ * receiving when count is reached
+ * @hw_period: The value indicating the hardware sampling period
+ */
+struct mtk_ir_data {
+ const u32 *regs;
+ const struct mtk_field_type *fields;
+ u8 div;
+ u8 ok_count;
+ u32 hw_period;
+};
+
+static const struct mtk_field_type mt7623_fields[] = {
+ [MTK_CHK_PERIOD] = {0x10, 8, GENMASK(20, 8)},
+ [MTK_HW_PERIOD] = {0x10, 0, GENMASK(7, 0)},
+};

/*
* struct mtk_ir - This is the main datasructure for holding the state
* of the driver
* @dev: The device pointer
* @rc: The rc instrance
- * @irq: The IRQ that we are using
* @base: The mapped register i/o base
- * @clk: The clock that we are using
+ * @irq: The IRQ that we are using
+ * @clk: The clock that IR internal is using
+ * @bus: The clock that software decoder is using
+ * @data: Holding specific data for vaious platform
*/
struct mtk_ir {
struct device *dev;
@@ -88,8 +130,36 @@ struct mtk_ir {
void __iomem *base;
int irq;
struct clk *clk;
+ struct clk *bus;
+ const struct mtk_ir_data *data;
};

+static inline u32 mtk_chkdata_reg(struct mtk_ir *ir, u32 i)
+{
+ return ir->data->regs[MTK_CHKDATA_REG] + 4 * i;
+}
+
+static inline u32 mtk_chk_period(struct mtk_ir *ir)
+{
+ u32 val;
+
+ /* Period of raw software sampling in ns */
+ val = DIV_ROUND_CLOSEST(1000000000ul,
+ clk_get_rate(ir->bus) / ir->data->div);
+
+ /*
+ * Period for software decoder used in the
+ * unit of raw software sampling
+ */
+ val = DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, val);
+
+ dev_dbg(ir->dev, "@pwm clk = \t%lu\n",
+ clk_get_rate(ir->bus) / ir->data->div);
+ dev_dbg(ir->dev, "@chkperiod = %08x\n", val);
+
+ return val;
+}
+
static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
{
u32 tmp;
@@ -113,16 +183,16 @@ static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
{
u32 val;

- val = mtk_r32(ir, MTK_IRINT_EN_REG);
- mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
+ val = mtk_r32(ir, ir->data->regs[MTK_IRINT_EN_REG]);
+ mtk_w32(ir, val & ~mask, ir->data->regs[MTK_IRINT_EN_REG]);
}

static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
{
u32 val;

- val = mtk_r32(ir, MTK_IRINT_EN_REG);
- mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
+ val = mtk_r32(ir, ir->data->regs[MTK_IRINT_EN_REG]);
+ mtk_w32(ir, val | mask, ir->data->regs[MTK_IRINT_EN_REG]);
}

static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
@@ -140,7 +210,7 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
* every decoder to reset themselves through long enough
* trailing spaces and 2) the IRQ handler guarantees that
* start of IR message is always contained in and starting
- * from register MTK_CHKDATA_REG(0).
+ * from register mtk_chkdata_reg(ir, i).
*/
ir_raw_event_reset(ir->rc);

@@ -149,7 +219,7 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)

/* Handle all pulse and space IR controller captures */
for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
- val = mtk_r32(ir, MTK_CHKDATA_REG(i));
+ val = mtk_r32(ir, mtk_chkdata_reg(ir, i));
dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);

for (j = 0 ; j < 4 ; j++) {
@@ -181,18 +251,35 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
* Restart controller for the next receive that would
* clear up all CHKDATA registers
*/
- mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
+ mtk_w32_mask(ir, 0x1, MTK_IRCLR, ir->data->regs[MTK_IRCLR_REG]);

/* Clear interrupt status */
- mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
+ mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR,
+ ir->data->regs[MTK_IRINT_CLR_REG]);

return IRQ_HANDLED;
}

+static const struct mtk_ir_data mt7623_data = {
+ .regs = mt7623_regs,
+ .fields = mt7623_fields,
+ .ok_count = 0xf,
+ .hw_period = 0xff,
+ .div = 4,
+};
+
+static const struct of_device_id mtk_ir_match[] = {
+ { .compatible = "mediatek,mt7623-cir", .data = &mt7623_data},
+ {},
+};
+MODULE_DEVICE_TABLE(of, mtk_ir_match);
+
static int mtk_ir_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *dn = dev->of_node;
+ const struct of_device_id *of_id =
+ of_match_device(mtk_ir_match, &pdev->dev);
struct resource *res;
struct mtk_ir *ir;
u32 val;
@@ -204,9 +291,7 @@ static int mtk_ir_probe(struct platform_device *pdev)
return -ENOMEM;

ir->dev = dev;
-
- if (!of_device_is_compatible(dn, "mediatek,mt7623-cir"))
- return -ENODEV;
+ ir->data = of_id->data;

ir->clk = devm_clk_get(dev, "clk");
if (IS_ERR(ir->clk)) {
@@ -214,6 +299,15 @@ static int mtk_ir_probe(struct platform_device *pdev)
return PTR_ERR(ir->clk);
}

+ ir->bus = devm_clk_get(dev, "bus");
+ if (IS_ERR(ir->bus)) {
+ /*
+ * For compatibility with older device trees try unnamed
+ * ir->bus uses the same clock as ir->clock.
+ */
+ ir->bus = ir->clk;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ir->base = devm_ioremap_resource(dev, res);
if (IS_ERR(ir->base)) {
@@ -256,40 +350,60 @@ static int mtk_ir_probe(struct platform_device *pdev)
return -ENODEV;
}

- /*
- * Enable interrupt after proper hardware
- * setup and IRQ handler registration
- */
if (clk_prepare_enable(ir->clk)) {
dev_err(dev, "try to enable ir_clk failed\n");
+ return -EINVAL;
+ }
+
+ if (clk_prepare_enable(ir->bus)) {
+ dev_err(dev, "try to enable ir_clk failed\n");
ret = -EINVAL;
goto exit_clkdisable_clk;
}

+ /*
+ * Enable interrupt after proper hardware
+ * setup and IRQ handler registration
+ */
mtk_irq_disable(ir, MTK_IRINT_EN);

ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
if (ret) {
dev_err(dev, "failed request irq\n");
- goto exit_clkdisable_clk;
+ goto exit_clkdisable_bus;
}

+ /*
+ * Setup software sample period as the reference of software decoder
+ */
+ val = (mtk_chk_period(ir) << ir->data->fields[MTK_CHK_PERIOD].offset) &
+ ir->data->fields[MTK_CHK_PERIOD].mask;
+ mtk_w32_mask(ir, val, ir->data->fields[MTK_CHK_PERIOD].mask,
+ ir->data->fields[MTK_CHK_PERIOD].reg);
+
+ /*
+ * Setup hardware sampling period used to setup the proper timeout for
+ * indicating end of IR receiving completion
+ */
+ val = (ir->data->hw_period << ir->data->fields[MTK_HW_PERIOD].offset) &
+ ir->data->fields[MTK_HW_PERIOD].mask;
+ mtk_w32_mask(ir, val, ir->data->fields[MTK_HW_PERIOD].mask,
+ ir->data->fields[MTK_HW_PERIOD].reg);
+
/* Enable IR and PWM */
val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
- val |= MTK_PWM_EN | MTK_IR_EN;
+ val |= MTK_OK_COUNT(ir->data->ok_count) | MTK_PWM_EN | MTK_IR_EN;
mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);

- /* Setting sample period */
- mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
- MTK_CONFIG_LOW_REG);
-
mtk_irq_enable(ir, MTK_IRINT_EN);

- dev_info(dev, "Initialized MT7623 IR driver, sample period = %luus\n",
+ dev_info(dev, "Initialized MT7623 IR driver, sample period = %dus\n",
DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));

return 0;

+exit_clkdisable_bus:
+ clk_disable_unprepare(ir->bus);
exit_clkdisable_clk:
clk_disable_unprepare(ir->clk);

@@ -308,17 +422,12 @@ static int mtk_ir_remove(struct platform_device *pdev)
mtk_irq_disable(ir, MTK_IRINT_EN);
synchronize_irq(ir->irq);

+ clk_disable_unprepare(ir->bus);
clk_disable_unprepare(ir->clk);

return 0;
}

-static const struct of_device_id mtk_ir_match[] = {
- { .compatible = "mediatek,mt7623-cir" },
- {},
-};
-MODULE_DEVICE_TABLE(of, mtk_ir_match);
-
static struct platform_driver mtk_ir_driver = {
.probe = mtk_ir_probe,
.remove = mtk_ir_remove,
--
2.7.4

2017-07-04 10:10:14

by Andi Shyti

[permalink] [raw]
Subject: Re: [PATCH v1 0/4] media: rc: add support for IR receiver on MT7622 SoC

Hi Sean,

> This patchset introduces Consumer IR (CIR) support for MT7622 SoC
> implements raw mode for more compatibility with different protocols
> as previously SoC did. Before adding support to MT7622 SoC, extra
> code refactor is done since there're major differences in register and
> field definition from the previous SoC.
>
> Sean Wang (4):
> dt-bindings: media: mtk-cir: Add support for MT7622 SoC
> media: rc: mtk-cir: add platform data to adapt into various hardware
> media: rc: mtk-cir: add support for MediaTek MT7622 SoC
> MAINTAINERS: add entry for MediaTek CIR driver

for the whole patchset:

Reviewed-by: Andi Shyti <[email protected]>

Andi

2017-07-06 18:56:32

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v1 1/4] dt-bindings: media: mtk-cir: Add support for MT7622 SoC

On Fri, Jun 30, 2017 at 02:03:04PM +0800, [email protected] wrote:
> From: Sean Wang <[email protected]>
>
> Document the devicetree bindings for CIR on MediaTek MT7622
> SoC.
>
> Signed-off-by: Sean Wang <[email protected]>
> ---
> Documentation/devicetree/bindings/media/mtk-cir.txt | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)

Acked-by: Rob Herring <[email protected]>

2017-08-02 02:24:13

by Sean Wang

[permalink] [raw]
Subject: Re: [PATCH v1 0/4] media: rc: add support for IR receiver on MT7622 SoC


Hi, Mauro and Sean

Just a gentle ping on the whole patchset porting MediaTek CIR to another
platform.

Sean


On Tue, 2017-07-04 at 19:10 +0900, Andi Shyti wrote:
> Hi Sean,
>
> > This patchset introduces Consumer IR (CIR) support for MT7622 SoC
> > implements raw mode for more compatibility with different protocols
> > as previously SoC did. Before adding support to MT7622 SoC, extra
> > code refactor is done since there're major differences in register and
> > field definition from the previous SoC.
> >
> > Sean Wang (4):
> > dt-bindings: media: mtk-cir: Add support for MT7622 SoC
> > media: rc: mtk-cir: add platform data to adapt into various hardware
> > media: rc: mtk-cir: add support for MediaTek MT7622 SoC
> > MAINTAINERS: add entry for MediaTek CIR driver
>
> for the whole patchset:
>
> Reviewed-by: Andi Shyti <[email protected]>
>
> Andi


2017-08-02 10:03:02

by Sean Young

[permalink] [raw]
Subject: Re: [PATCH v1 0/4] media: rc: add support for IR receiver on MT7622 SoC

Hi Sean,

On Wed, Aug 02, 2017 at 10:24:07AM +0800, Sean Wang wrote:
> Hi, Mauro and Sean
>
> Just a gentle ping on the whole patchset porting MediaTek CIR to another
> platform.

I'm creating the rc-core pull request, should be done by the end of the week.


Sean