From d9b811e183d9cae753929cb55e627a29c6a971a8 Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Wed, 30 Aug 2017 14:44:29 +0300 Subject: [PATCH] LVDS: ar0132 use context swwitch This enabled context-A-B switch on every frame Signed-off-by: Vladimir Barinov --- drivers/media/i2c/soc_camera/ar0132.c | 19 +++++++++++++++++++ drivers/media/platform/soc_camera/rcar_vin.c | 23 ++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c index 284c522..2c21fa9 100644 --- a/drivers/media/i2c/soc_camera/ar0132.c +++ b/drivers/media/i2c/soc_camera/ar0132.c @@ -238,11 +238,30 @@ static int ar0132_s_register(struct v4l2_subdev *sd, } #endif +static int ar0132_isr(struct v4l2_subdev *sd, u32 status, bool *handled) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); +#if 1 + u16 frame_count = 0; + /* read frame counter from sensor */ + reg16_read16(client, 0x303a, &frame_count); +#else + static int frame_count = 0; + /* get cached frame counter */ + frame_count++; +#endif + /* odd frame -> Mode A, even frame -> Mode B */ + reg16_write16(client, 0x30b0, frame_count & 1 ? 0x2 : 0x2002); + + return 0; +}; + static struct v4l2_subdev_core_ops ar0132_core_ops = { #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ar0132_g_register, .s_register = ar0132_s_register, #endif + .interrupt_service_routine = ar0132_isr, }; static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl) diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index c39fe63..9ab6f00 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1292,13 +1292,24 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq) .wait_finish = vb2_ops_wait_finish, }; +static irqreturn_t rcar_vin_threaded_irq(int irq, void *data) +{ + struct rcar_vin_priv *priv = data; + struct soc_camera_device *icd = priv->ici.icd; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + v4l2_subdev_call(sd, core, interrupt_service_routine, 0, NULL); + + return IRQ_HANDLED; +}; + static irqreturn_t rcar_vin_irq(int irq, void *data) { struct rcar_vin_priv *priv = data; u32 int_status; bool can_run = false, hw_stopped; int slot; - unsigned int handled = 0; + unsigned int handled = IRQ_NONE; int vin_ovr_cnt = 0; spin_lock(&priv->lock); @@ -1309,7 +1320,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data) /* ack interrupts */ iowrite32(int_status, priv->base + VNINTS_REG); - handled = 1; + handled = IRQ_HANDLED; /* overflow occurs */ if (vin_debug && (int_status & VNINTS_FOS)) { @@ -1342,6 +1353,8 @@ static irqreturn_t rcar_vin_irq(int irq, void *data) priv->queue_buf[slot] = NULL; can_run = rcar_vin_fill_hw_slot(priv); + + handled = IRQ_WAKE_THREAD; } if (is_continuous_transfer(priv)) { @@ -1370,7 +1383,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data) done: spin_unlock(&priv->lock); - return IRQ_RETVAL(handled); + return handled; } static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev) @@ -2930,8 +2943,8 @@ static int rcar_vin_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED, - dev_name(&pdev->dev), priv); + ret = devm_request_threaded_irq(&pdev->dev, irq, rcar_vin_irq, rcar_vin_threaded_irq, + IRQF_SHARED, dev_name(&pdev->dev), priv); if (ret) return ret; -- 1.9.1