Commit 7102b773 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

V4L/DVB (7250): Clean up pxa-camera driver, remove non-functional and never tested pm-support

This patch addresses most issues pointed out by Russell and Erik, moves
recently introduced into pxa-regs.h camera-specific defines into
pxa_camera.c, removes dummy power-management functions, improves
function-naming, etc.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Acked-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent bb55de3b
...@@ -10,10 +10,9 @@ ...@@ -10,10 +10,9 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <asm/io.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -42,6 +41,26 @@ ...@@ -42,6 +41,26 @@
#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
#define PXA_CAM_DRV_NAME "pxa27x-camera" #define PXA_CAM_DRV_NAME "pxa27x-camera"
#define CICR0_SIM_MP (0 << 24)
#define CICR0_SIM_SP (1 << 24)
#define CICR0_SIM_MS (2 << 24)
#define CICR0_SIM_EP (3 << 24)
#define CICR0_SIM_ES (4 << 24)
#define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */
#define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */
#define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */
#define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */
#define CICR2_HSW_VAL(x) (((x) << 10) & CICR2_HSW) /* Horizontal sync pulse width */
#define CICR2_BFPW_VAL(x) (((x) << 3) & CICR2_BFPW) /* Beginning-of-frame pixel clock wait count */
#define CICR2_FSW_VAL(x) (((x) << 0) & CICR2_FSW) /* Frame stabilization wait count */
#define CICR3_BFW_VAL(x) (((x) << 24) & CICR3_BFW) /* Beginning-of-frame line clock wait count */
#define CICR3_EFW_VAL(x) (((x) << 16) & CICR3_EFW) /* End-of-frame line clock wait count */
#define CICR3_VSW_VAL(x) (((x) << 11) & CICR3_VSW) /* Vertical sync pulse width */
#define CICR3_LPF_VAL(x) (((x) << 0) & CICR3_LPF) /* Lines per frame */
#define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \ #define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \
CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \ CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
CICR0_EOFM | CICR0_FOM) CICR0_EOFM | CICR0_FOM)
...@@ -83,8 +102,6 @@ struct pxa_camera_dev { ...@@ -83,8 +102,6 @@ struct pxa_camera_dev {
void __iomem *base; void __iomem *base;
unsigned int dma_chan_y; unsigned int dma_chan_y;
enum v4l2_buf_type type;
struct pxacamera_platform_data *pdata; struct pxacamera_platform_data *pdata;
struct resource *res; struct resource *res;
unsigned long platform_flags; unsigned long platform_flags;
...@@ -94,8 +111,6 @@ struct pxa_camera_dev { ...@@ -94,8 +111,6 @@ struct pxa_camera_dev {
spinlock_t lock; spinlock_t lock;
int dma_running;
struct pxa_buffer *active; struct pxa_buffer *active;
}; };
...@@ -106,8 +121,7 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ ...@@ -106,8 +121,7 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
/* /*
* Videobuf operations * Videobuf operations
*/ */
static int static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size) unsigned int *size)
{ {
struct soc_camera_device *icd = vq->priv_data; struct soc_camera_device *icd = vq->priv_data;
...@@ -151,9 +165,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) ...@@ -151,9 +165,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
buf->vb.state = VIDEOBUF_NEEDS_INIT; buf->vb.state = VIDEOBUF_NEEDS_INIT;
} }
static int static int pxa_videobuf_prepare(struct videobuf_queue *vq,
pxa_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, struct videobuf_buffer *vb, enum v4l2_field field)
enum v4l2_field field)
{ {
struct soc_camera_device *icd = vq->priv_data; struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = struct soc_camera_host *ici =
...@@ -255,15 +268,15 @@ out: ...@@ -255,15 +268,15 @@ out:
return ret; return ret;
} }
static void static void pxa_videobuf_queue(struct videobuf_queue *vq,
pxa_videobuf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) struct videobuf_buffer *vb)
{ {
struct soc_camera_device *icd = vq->priv_data; struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = struct soc_camera_host *ici =
to_soc_camera_host(icd->dev.parent); to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv; struct pxa_camera_dev *pcdev = ici->priv;
struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
struct pxa_buffer *active = pcdev->active; struct pxa_buffer *active;
struct videobuf_dmabuf *dma = videobuf_to_dma(vb); struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
int nents = dma->sglen; int nents = dma->sglen;
unsigned long flags; unsigned long flags;
...@@ -275,8 +288,9 @@ pxa_videobuf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) ...@@ -275,8 +288,9 @@ pxa_videobuf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
list_add_tail(&vb->queue, &pcdev->capture); list_add_tail(&vb->queue, &pcdev->capture);
vb->state = VIDEOBUF_ACTIVE; vb->state = VIDEOBUF_ACTIVE;
active = pcdev->active;
if (!pcdev->active) { if (!active) {
CIFR |= CIFR_RESET_F; CIFR |= CIFR_RESET_F;
DDADR(pcdev->dma_chan_y) = buf->sg_dma; DDADR(pcdev->dma_chan_y) = buf->sg_dma;
DCSR(pcdev->dma_chan_y) = DCSR_RUN; DCSR(pcdev->dma_chan_y) = DCSR_RUN;
...@@ -373,22 +387,21 @@ static void pxa_camera_dma_irq_y(int channel, void *data) ...@@ -373,22 +387,21 @@ static void pxa_camera_dma_irq_y(int channel, void *data)
spin_lock_irqsave(&pcdev->lock, flags); spin_lock_irqsave(&pcdev->lock, flags);
status = DCSR(pcdev->dma_chan_y); status = DCSR(pcdev->dma_chan_y);
DCSR(pcdev->dma_chan_y) = status;
if (status & DCSR_BUSERR) { if (status & DCSR_BUSERR) {
dev_err(pcdev->dev, "%s: Bus Error\n", __FUNCTION__); dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
DCSR(pcdev->dma_chan_y) |= DCSR_BUSERR;
goto out; goto out;
} }
if (!(status & DCSR_ENDINTR)) { if (!(status & DCSR_ENDINTR)) {
dev_err(pcdev->dev, "%s: unknown dma interrupt source. " dev_err(pcdev->dev, "Unknown DMA IRQ source, "
"status: 0x%08x\n", __FUNCTION__, status); "status: 0x%08x\n", status);
goto out; goto out;
} }
DCSR(pcdev->dma_chan_y) |= DCSR_ENDINTR;
if (!pcdev->active) { if (!pcdev->active) {
dev_err(pcdev->dev, "%s: no active buf\n", __FUNCTION__); dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n");
goto out; goto out;
} }
...@@ -398,7 +411,7 @@ static void pxa_camera_dma_irq_y(int channel, void *data) ...@@ -398,7 +411,7 @@ static void pxa_camera_dma_irq_y(int channel, void *data)
dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__,
vb, vb->baddr, vb->bsize); vb, vb->baddr, vb->bsize);
/* _init is used to debug races, see comment in pxa_is_reqbufs() */ /* _init is used to debug races, see comment in pxa_camera_reqbufs() */
list_del_init(&vb->queue); list_del_init(&vb->queue);
vb->state = VIDEOBUF_DONE; vb->state = VIDEOBUF_DONE;
do_gettimeofday(&vb->ts); do_gettimeofday(&vb->ts);
...@@ -419,7 +432,7 @@ out: ...@@ -419,7 +432,7 @@ out:
spin_unlock_irqrestore(&pcdev->lock, flags); spin_unlock_irqrestore(&pcdev->lock, flags);
} }
static struct videobuf_queue_ops pxa_video_ops = { static struct videobuf_queue_ops pxa_videobuf_ops = {
.buf_setup = pxa_videobuf_setup, .buf_setup = pxa_videobuf_setup,
.buf_prepare = pxa_videobuf_prepare, .buf_prepare = pxa_videobuf_prepare,
.buf_queue = pxa_videobuf_queue, .buf_queue = pxa_videobuf_queue,
...@@ -444,7 +457,7 @@ static int mclk_get_divisor(struct pxa_camera_dev *pcdev) ...@@ -444,7 +457,7 @@ static int mclk_get_divisor(struct pxa_camera_dev *pcdev)
return div; return div;
} }
static void pxa_is_activate(struct pxa_camera_dev *pcdev) static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
{ {
struct pxacamera_platform_data *pdata = pcdev->pdata; struct pxacamera_platform_data *pdata = pcdev->pdata;
u32 cicr4 = 0; u32 cicr4 = 0;
...@@ -486,7 +499,7 @@ static void pxa_is_activate(struct pxa_camera_dev *pcdev) ...@@ -486,7 +499,7 @@ static void pxa_is_activate(struct pxa_camera_dev *pcdev)
clk_enable(pcdev->clk); clk_enable(pcdev->clk);
} }
static void pxa_is_deactivate(struct pxa_camera_dev *pcdev) static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
{ {
struct pxacamera_platform_data *board = pcdev->pdata; struct pxacamera_platform_data *board = pcdev->pdata;
...@@ -518,7 +531,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) ...@@ -518,7 +531,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
/* The following two functions absolutely depend on the fact, that /* The following two functions absolutely depend on the fact, that
* there can be only one camera on PXA quick capture interface */ * there can be only one camera on PXA quick capture interface */
static int pxa_is_add_device(struct soc_camera_device *icd) static int pxa_camera_add_device(struct soc_camera_device *icd)
{ {
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv; struct pxa_camera_dev *pcdev = ici->priv;
...@@ -534,7 +547,7 @@ static int pxa_is_add_device(struct soc_camera_device *icd) ...@@ -534,7 +547,7 @@ static int pxa_is_add_device(struct soc_camera_device *icd)
dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n", dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n",
icd->devnum); icd->devnum);
pxa_is_activate(pcdev); pxa_camera_activate(pcdev);
ret = icd->ops->init(icd); ret = icd->ops->init(icd);
if (!ret) if (!ret)
...@@ -546,7 +559,7 @@ ebusy: ...@@ -546,7 +559,7 @@ ebusy:
return ret; return ret;
} }
static void pxa_is_remove_device(struct soc_camera_device *icd) static void pxa_camera_remove_device(struct soc_camera_device *icd)
{ {
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv; struct pxa_camera_dev *pcdev = ici->priv;
...@@ -563,12 +576,12 @@ static void pxa_is_remove_device(struct soc_camera_device *icd) ...@@ -563,12 +576,12 @@ static void pxa_is_remove_device(struct soc_camera_device *icd)
icd->ops->release(icd); icd->ops->release(icd);
pxa_is_deactivate(pcdev); pxa_camera_deactivate(pcdev);
pcdev->icd = NULL; pcdev->icd = NULL;
} }
static int pxa_is_set_capture_format(struct soc_camera_device *icd, static int pxa_camera_set_capture_format(struct soc_camera_device *icd,
__u32 pixfmt, struct v4l2_rect *rect) __u32 pixfmt, struct v4l2_rect *rect)
{ {
struct soc_camera_host *ici = struct soc_camera_host *ici =
...@@ -652,13 +665,13 @@ static int pxa_is_set_capture_format(struct soc_camera_device *icd, ...@@ -652,13 +665,13 @@ static int pxa_is_set_capture_format(struct soc_camera_device *icd,
/* CIF interrupts are not used, only DMA */ /* CIF interrupts are not used, only DMA */
CICR0 = (pcdev->platform_flags & PXA_CAMERA_MASTER ? CICR0 = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
0 : (CICR0_SL_CAP_EN | CICR0_SIM_SP)) | CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP)) |
CICR0_DMAEN | CICR0_IRQ_MASK | (cicr0 & CICR0_ENB); CICR0_DMAEN | CICR0_IRQ_MASK | (cicr0 & CICR0_ENB);
return 0; return 0;
} }
static int pxa_is_try_fmt_cap(struct soc_camera_host *ici, static int pxa_camera_try_fmt_cap(struct soc_camera_host *ici,
struct v4l2_format *f) struct v4l2_format *f)
{ {
/* limit to pxa hardware capabilities */ /* limit to pxa hardware capabilities */
...@@ -675,7 +688,7 @@ static int pxa_is_try_fmt_cap(struct soc_camera_host *ici, ...@@ -675,7 +688,7 @@ static int pxa_is_try_fmt_cap(struct soc_camera_host *ici,
return 0; return 0;
} }
static int pxa_is_reqbufs(struct soc_camera_file *icf, static int pxa_camera_reqbufs(struct soc_camera_file *icf,
struct v4l2_requestbuffers *p) struct v4l2_requestbuffers *p)
{ {
int i; int i;
...@@ -694,7 +707,7 @@ static int pxa_is_reqbufs(struct soc_camera_file *icf, ...@@ -694,7 +707,7 @@ static int pxa_is_reqbufs(struct soc_camera_file *icf,
return 0; return 0;
} }
static unsigned int pxa_is_poll(struct file *file, poll_table *pt) static unsigned int pxa_camera_poll(struct file *file, poll_table *pt)
{ {
struct soc_camera_file *icf = file->private_data; struct soc_camera_file *icf = file->private_data;
struct pxa_buffer *buf; struct pxa_buffer *buf;
...@@ -711,7 +724,7 @@ static unsigned int pxa_is_poll(struct file *file, poll_table *pt) ...@@ -711,7 +724,7 @@ static unsigned int pxa_is_poll(struct file *file, poll_table *pt)
return 0; return 0;
} }
static int pxa_is_querycap(struct soc_camera_host *ici, static int pxa_camera_querycap(struct soc_camera_host *ici,
struct v4l2_capability *cap) struct v4l2_capability *cap)
{ {
/* cap->name is set by the firendly caller:-> */ /* cap->name is set by the firendly caller:-> */
...@@ -725,15 +738,15 @@ static int pxa_is_querycap(struct soc_camera_host *ici, ...@@ -725,15 +738,15 @@ static int pxa_is_querycap(struct soc_camera_host *ici,
/* Should beallocated dynamically too, but we have only one. */ /* Should beallocated dynamically too, but we have only one. */
static struct soc_camera_host pxa_soc_camera_host = { static struct soc_camera_host pxa_soc_camera_host = {
.drv_name = PXA_CAM_DRV_NAME, .drv_name = PXA_CAM_DRV_NAME,
.vbq_ops = &pxa_video_ops, .vbq_ops = &pxa_videobuf_ops,
.add = pxa_is_add_device, .add = pxa_camera_add_device,
.remove = pxa_is_remove_device, .remove = pxa_camera_remove_device,
.msize = sizeof(struct pxa_buffer), .msize = sizeof(struct pxa_buffer),
.set_capture_format = pxa_is_set_capture_format, .set_capture_format = pxa_camera_set_capture_format,
.try_fmt_cap = pxa_is_try_fmt_cap, .try_fmt_cap = pxa_camera_try_fmt_cap,
.reqbufs = pxa_is_reqbufs, .reqbufs = pxa_camera_reqbufs,
.poll = pxa_is_poll, .poll = pxa_camera_poll,
.querycap = pxa_is_querycap, .querycap = pxa_camera_querycap,
}; };
static int pxa_camera_probe(struct platform_device *pdev) static int pxa_camera_probe(struct platform_device *pdev)
...@@ -753,8 +766,7 @@ static int pxa_camera_probe(struct platform_device *pdev) ...@@ -753,8 +766,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
if (!pcdev) { if (!pcdev) {
dev_err(&pdev->dev, "%s: Could not allocate pcdev\n", dev_err(&pdev->dev, "Could not allocate pcdev\n");
__FUNCTION__);
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
...@@ -871,51 +883,17 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev) ...@@ -871,51 +883,17 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev)
kfree(pcdev); kfree(pcdev);
dev_info(&pdev->dev, "%s: PXA Camera driver unloaded\n", __FUNCTION__); dev_info(&pdev->dev, "PXA Camera driver unloaded\n");
return 0;
}
/*
* Suspend the Camera Module.
*/
static int pxa_camera_suspend(struct platform_device *pdev, pm_message_t level)
{
struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev);
dev_info(&pdev->dev, "camera suspend\n");
disable_irq(pcdev->irq);
return 0;
}
/*
* Resume the Camera Module.
*/
static int pxa_camera_resume(struct platform_device *pdev)
{
struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev);
dev_info(&pdev->dev, "camera resume\n");
enable_irq(pcdev->irq);
/* if (pcdev) { */ /* FIXME: dev in use? */
/* DRCMR68 = pcdev->dma_chan_y | DRCMR_MAPVLD; */
/* DRCMR69 = pcdev->dma_chan_cb | DRCMR_MAPVLD; */
/* DRCMR70 = pcdev->dma_chan_cr | DRCMR_MAPVLD; */
/* } */
return 0; return 0;
} }
static struct platform_driver pxa_camera_driver = { static struct platform_driver pxa_camera_driver = {
.driver = { .driver = {
.name = PXA_CAM_DRV_NAME, .name = PXA_CAM_DRV_NAME,
}, },
.probe = pxa_camera_probe, .probe = pxa_camera_probe,
.remove = __exit_p(pxa_camera_remove), .remove = __exit_p(pxa_camera_remove),
.suspend = pxa_camera_suspend,
.resume = pxa_camera_resume,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment