From: Zelong Dong <zelong.dong@xxxxxxxxxxx> Supports MMIO regmaps to access controller registers in Meson IR driver. Signed-off-by: Zelong Dong <zelong.dong@xxxxxxxxxxx> --- drivers/media/rc/Kconfig | 1 + drivers/media/rc/meson-ir.c | 72 +++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index ac4172feb6f9..24437ed64a27 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -271,6 +271,7 @@ config IR_MCEUSB config IR_MESON tristate "Amlogic Meson IR remote receiver" depends on ARCH_MESON || COMPILE_TEST + select REGMAP_MMIO help Say Y if you want to use the IR remote receiver available on Amlogic Meson SoCs. diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index a0ccde02bc08..d22d2578ec39 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/bitfield.h> +#include <linux/regmap.h> #include <media/rc-core.h> @@ -50,21 +51,16 @@ #define MESON_HW_TRATE 20 /* us */ struct meson_ir { - void __iomem *reg; + struct regmap *reg; struct rc_dev *rc; spinlock_t lock; }; -static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg, - u32 mask, u32 value) -{ - u32 data; - - data = readl(ir->reg + reg); - data &= ~mask; - data |= (value & mask); - writel(data, ir->reg + reg); -} +static struct regmap_config meson_ir_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; static irqreturn_t meson_ir_irq(int irqno, void *dev_id) { @@ -74,11 +70,11 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) spin_lock(&ir->lock); - duration = readl_relaxed(ir->reg + IR_DEC_REG1); + regmap_read(ir->reg, IR_DEC_REG1, &duration); duration = FIELD_GET(IR_DEC_REG1_TIME_IV, duration); rawir.duration = duration * MESON_RAW_TRATE; - status = readl_relaxed(ir->reg + IR_DEC_STATUS); + regmap_read(ir->reg, IR_DEC_STATUS, &status); rawir.pulse = !!(status & IR_DEC_STATUS_PULSE); ir_raw_event_store_with_timeout(ir->rc, &rawir); @@ -92,6 +88,7 @@ static int meson_ir_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; + void __iomem *res_start; const char *map_name; struct meson_ir *ir; int irq, ret; @@ -100,7 +97,12 @@ static int meson_ir_probe(struct platform_device *pdev) if (!ir) return -ENOMEM; - ir->reg = devm_platform_ioremap_resource(pdev, 0); + res_start = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(res_start)) + return PTR_ERR(res_start); + + ir->reg = devm_regmap_init_mmio(&pdev->dev, res_start, + &meson_ir_regmap_config); if (IS_ERR(ir->reg)) return PTR_ERR(ir->reg); @@ -143,27 +145,28 @@ static int meson_ir_probe(struct platform_device *pdev) } /* Reset the decoder */ - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_RESET, - IR_DEC_REG1_RESET); - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_RESET, 0); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_RESET, + IR_DEC_REG1_RESET); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_RESET, 0); /* Set general operation mode (= raw/software decoding) */ if (of_device_is_compatible(node, "amlogic,meson6-ir")) - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_MODE, - FIELD_PREP(IR_DEC_REG1_MODE, DEC_MODE_RAW)); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_MODE, + FIELD_PREP(IR_DEC_REG1_MODE, DEC_MODE_RAW)); else - meson_ir_set_mask(ir, IR_DEC_REG2, IR_DEC_REG2_MODE, - FIELD_PREP(IR_DEC_REG2_MODE, DEC_MODE_RAW)); + regmap_update_bits(ir->reg, IR_DEC_REG2, IR_DEC_REG2_MODE, + FIELD_PREP(IR_DEC_REG2_MODE, DEC_MODE_RAW)); /* Set rate */ - meson_ir_set_mask(ir, IR_DEC_REG0, IR_DEC_REG0_BASE_TIME, - MESON_RAW_TRATE - 1); + regmap_update_bits(ir->reg, IR_DEC_REG0, IR_DEC_REG0_BASE_TIME, + FIELD_PREP(IR_DEC_REG0_BASE_TIME, + MESON_RAW_TRATE - 1)); /* IRQ on rising and falling edges */ - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_IRQSEL, - FIELD_PREP(IR_DEC_REG1_IRQSEL, IRQSEL_RISE_FALL)); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_IRQSEL, + FIELD_PREP(IR_DEC_REG1_IRQSEL, IRQSEL_RISE_FALL)); /* Enable the decoder */ - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_ENABLE, - IR_DEC_REG1_ENABLE); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, + IR_DEC_REG1_ENABLE); dev_info(dev, "receiver initialized\n"); @@ -177,7 +180,7 @@ static void meson_ir_remove(struct platform_device *pdev) /* Disable the decoder */ spin_lock_irqsave(&ir->lock, flags); - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 0); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 0); spin_unlock_irqrestore(&ir->lock, flags); } @@ -195,15 +198,16 @@ static void meson_ir_shutdown(struct platform_device *pdev) * bootloader a chance to power the system back on */ if (of_device_is_compatible(node, "amlogic,meson6-ir")) - meson_ir_set_mask(ir, IR_DEC_REG1, IR_DEC_REG1_MODE, - FIELD_PREP(IR_DEC_REG1_MODE, DEC_MODE_NEC)); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_MODE, + FIELD_PREP(IR_DEC_REG1_MODE, DEC_MODE_NEC)); else - meson_ir_set_mask(ir, IR_DEC_REG2, IR_DEC_REG2_MODE, - FIELD_PREP(IR_DEC_REG2_MODE, DEC_MODE_NEC)); + regmap_update_bits(ir->reg, IR_DEC_REG2, IR_DEC_REG2_MODE, + FIELD_PREP(IR_DEC_REG2_MODE, DEC_MODE_NEC)); /* Set rate to default value */ - meson_ir_set_mask(ir, IR_DEC_REG0, IR_DEC_REG0_BASE_TIME, - MESON_HW_TRATE - 1); + regmap_update_bits(ir->reg, IR_DEC_REG0, IR_DEC_REG0_BASE_TIME, + FIELD_PREP(IR_DEC_REG0_BASE_TIME, + MESON_HW_TRATE - 1)); spin_unlock_irqrestore(&ir->lock, flags); } -- 2.35.1