Commit b671ae6b authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] cx25821: convert to vb2

This patch converts the cx25821 driver from the old videobuf framework to
the new vb2 framework.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 8d8e6d60
...@@ -2,7 +2,7 @@ config VIDEO_CX25821 ...@@ -2,7 +2,7 @@ config VIDEO_CX25821
tristate "Conexant cx25821 support" tristate "Conexant cx25821 support"
depends on VIDEO_DEV && PCI && I2C depends on VIDEO_DEV && PCI && I2C
select I2C_ALGOBIT select I2C_ALGOBIT
select VIDEOBUF_DMA_SG select VIDEOBUF2_DMA_SG
---help--- ---help---
This is a video4linux driver for Conexant 25821 based This is a video4linux driver for Conexant 25821 based
TV cards. TV cards.
......
...@@ -874,10 +874,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) ...@@ -874,10 +874,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
if (dev->pci->device != 0x8210) { if (dev->pci->device != 0x8210) {
pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
__func__, dev->pci->device); __func__, dev->pci->device);
return -1; return -ENODEV;
} else {
pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device);
} }
pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device);
/* Apply a sensible clock frequency for the PCIe bridge */ /* Apply a sensible clock frequency for the PCIe bridge */
dev->clk_freq = 28000000; dev->clk_freq = 28000000;
...@@ -1003,11 +1002,17 @@ EXPORT_SYMBOL(cx25821_riscmem_alloc); ...@@ -1003,11 +1002,17 @@ EXPORT_SYMBOL(cx25821_riscmem_alloc);
static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
unsigned int offset, u32 sync_line, unsigned int offset, u32 sync_line,
unsigned int bpl, unsigned int padding, unsigned int bpl, unsigned int padding,
unsigned int lines) unsigned int lines, bool jump)
{ {
struct scatterlist *sg; struct scatterlist *sg;
unsigned int line, todo; unsigned int line, todo;
if (jump) {
*(rp++) = cpu_to_le32(RISC_JUMP);
*(rp++) = cpu_to_le32(0);
*(rp++) = cpu_to_le32(0); /* bits 63-32 */
}
/* sync instruction */ /* sync instruction */
if (sync_line != NO_SYNC_LINE) if (sync_line != NO_SYNC_LINE)
*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
...@@ -1073,13 +1078,13 @@ int cx25821_risc_buffer(struct pci_dev *pci, struct cx25821_riscmem *risc, ...@@ -1073,13 +1078,13 @@ int cx25821_risc_buffer(struct pci_dev *pci, struct cx25821_riscmem *risc,
fields++; fields++;
/* estimate risc mem: worst case is one write per page border + /* estimate risc mem: worst case is one write per page border +
one write per scan line + syncs + jump (all 2 dwords). Padding one write per scan line + syncs + jump (all 3 dwords). Padding
can cause next bpl to start close to a page border. First DMA can cause next bpl to start close to a page border. First DMA
region may be smaller than PAGE_SIZE */ region may be smaller than PAGE_SIZE */
/* write and jump need and extra dword */ /* write and jump need and extra dword */
instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE +
lines); lines);
instructions += 2; instructions += 5;
rc = cx25821_riscmem_alloc(pci, risc, instructions * 12); rc = cx25821_riscmem_alloc(pci, risc, instructions * 12);
if (rc < 0) if (rc < 0)
...@@ -1090,17 +1095,17 @@ int cx25821_risc_buffer(struct pci_dev *pci, struct cx25821_riscmem *risc, ...@@ -1090,17 +1095,17 @@ int cx25821_risc_buffer(struct pci_dev *pci, struct cx25821_riscmem *risc,
if (UNSET != top_offset) { if (UNSET != top_offset) {
rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding, rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
lines); lines, true);
} }
if (UNSET != bottom_offset) { if (UNSET != bottom_offset) {
rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl, rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
padding, lines); padding, lines, UNSET == top_offset);
} }
/* save pointer to jmp instruction address */ /* save pointer to jmp instruction address */
risc->jmp = rp; risc->jmp = rp;
BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); BUG_ON((risc->jmp - risc->cpu + 3) * sizeof(*risc->cpu) > risc->size);
return 0; return 0;
} }
...@@ -1200,41 +1205,14 @@ int cx25821_risc_databuffer_audio(struct pci_dev *pci, ...@@ -1200,41 +1205,14 @@ int cx25821_risc_databuffer_audio(struct pci_dev *pci,
} }
EXPORT_SYMBOL(cx25821_risc_databuffer_audio); EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
int cx25821_risc_stopper(struct pci_dev *pci, struct cx25821_riscmem *risc, void cx25821_free_buffer(struct cx25821_dev *dev, struct cx25821_buffer *buf)
u32 reg, u32 mask, u32 value)
{ {
__le32 *rp;
int rc;
rc = cx25821_riscmem_alloc(pci, risc, 4 * 16);
if (rc < 0)
return rc;
/* write risc instructions */
rp = risc->cpu;
*(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
*(rp++) = cpu_to_le32(reg);
*(rp++) = cpu_to_le32(value);
*(rp++) = cpu_to_le32(mask);
*(rp++) = cpu_to_le32(RISC_JUMP);
*(rp++) = cpu_to_le32(risc->dma);
*(rp++) = cpu_to_le32(0); /* bits 63-32 */
return 0;
}
void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
{
struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
BUG_ON(in_interrupt()); BUG_ON(in_interrupt());
videobuf_waiton(q, &buf->vb, 0, 0); if (WARN_ON(buf->risc.size == 0))
videobuf_dma_unmap(q->dev, dma); return;
videobuf_dma_free(dma); pci_free_consistent(dev->pci,
pci_free_consistent(to_pci_dev(q->dev),
buf->risc.size, buf->risc.cpu, buf->risc.dma); buf->risc.size, buf->risc.cpu, buf->risc.dma);
buf->vb.state = VIDEOBUF_NEEDS_INIT; memset(&buf->risc, 0, sizeof(buf->risc));
} }
static irqreturn_t cx25821_irq(int irq, void *dev_id) static irqreturn_t cx25821_irq(int irq, void *dev_id)
...@@ -1319,14 +1297,15 @@ static int cx25821_initdev(struct pci_dev *pci_dev, ...@@ -1319,14 +1297,15 @@ static int cx25821_initdev(struct pci_dev *pci_dev,
goto fail_unregister_device; goto fail_unregister_device;
} }
dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev);
if (IS_ERR(dev->alloc_ctx)) {
err = PTR_ERR(dev->alloc_ctx);
goto fail_unregister_pci;
}
err = cx25821_dev_setup(dev); err = cx25821_dev_setup(dev);
if (err) { if (err)
if (err == -EBUSY) goto fail_free_ctx;
goto fail_unregister_device;
else
goto fail_unregister_pci;
}
/* print pci info */ /* print pci info */
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
...@@ -1356,6 +1335,8 @@ static int cx25821_initdev(struct pci_dev *pci_dev, ...@@ -1356,6 +1335,8 @@ static int cx25821_initdev(struct pci_dev *pci_dev,
pr_info("cx25821_initdev() can't get IRQ !\n"); pr_info("cx25821_initdev() can't get IRQ !\n");
cx25821_dev_unregister(dev); cx25821_dev_unregister(dev);
fail_free_ctx:
vb2_dma_sg_cleanup_ctx(dev->alloc_ctx);
fail_unregister_pci: fail_unregister_pci:
pci_disable_device(pci_dev); pci_disable_device(pci_dev);
fail_unregister_device: fail_unregister_device:
...@@ -1379,6 +1360,7 @@ static void cx25821_finidev(struct pci_dev *pci_dev) ...@@ -1379,6 +1360,7 @@ static void cx25821_finidev(struct pci_dev *pci_dev)
free_irq(pci_dev->irq, dev); free_irq(pci_dev->irq, dev);
cx25821_dev_unregister(dev); cx25821_dev_unregister(dev);
vb2_dma_sg_cleanup_ctx(dev->alloc_ctx);
v4l2_device_unregister(v4l2_dev); v4l2_device_unregister(v4l2_dev);
kfree(dev); kfree(dev);
} }
......
This diff is collapsed.
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/videobuf-dma-sg.h> #include <media/videobuf2-dma-sg.h>
#include "cx25821-reg.h" #include "cx25821-reg.h"
#include "cx25821-medusa-reg.h" #include "cx25821-medusa-reg.h"
...@@ -120,13 +120,13 @@ struct cx25821_riscmem { ...@@ -120,13 +120,13 @@ struct cx25821_riscmem {
/* buffer for one video frame */ /* buffer for one video frame */
struct cx25821_buffer { struct cx25821_buffer {
/* common v4l buffer stuff -- must be first */ /* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb; struct vb2_buffer vb;
struct list_head queue;
/* cx25821 specific */ /* cx25821 specific */
unsigned int bpl; unsigned int bpl;
struct cx25821_riscmem risc; struct cx25821_riscmem risc;
const struct cx25821_fmt *fmt; const struct cx25821_fmt *fmt;
u32 count;
}; };
enum port { enum port {
...@@ -165,17 +165,9 @@ struct cx25821_i2c { ...@@ -165,17 +165,9 @@ struct cx25821_i2c {
struct cx25821_dmaqueue { struct cx25821_dmaqueue {
struct list_head active; struct list_head active;
struct list_head queued;
struct timer_list timeout;
struct cx25821_riscmem stopper;
u32 count; u32 count;
}; };
struct cx25821_data {
struct cx25821_dev *dev;
const struct sram_channel *channel;
};
struct cx25821_dev; struct cx25821_dev;
struct cx25821_channel; struct cx25821_channel;
...@@ -213,18 +205,17 @@ struct cx25821_video_out_data { ...@@ -213,18 +205,17 @@ struct cx25821_video_out_data {
struct cx25821_channel { struct cx25821_channel {
unsigned id; unsigned id;
struct cx25821_dev *dev; struct cx25821_dev *dev;
struct v4l2_fh *streaming_fh;
struct v4l2_ctrl_handler hdl; struct v4l2_ctrl_handler hdl;
struct cx25821_data timeout_data;
struct video_device vdev; struct video_device vdev;
struct cx25821_dmaqueue dma_vidq; struct cx25821_dmaqueue dma_vidq;
struct videobuf_queue vidq; struct vb2_queue vidq;
const struct sram_channel *sram_channels; const struct sram_channel *sram_channels;
const struct cx25821_fmt *fmt; const struct cx25821_fmt *fmt;
unsigned field;
unsigned int width, height; unsigned int width, height;
int pixel_formats; int pixel_formats;
int use_cif_resolution; int use_cif_resolution;
...@@ -250,6 +241,7 @@ struct cx25821_dev { ...@@ -250,6 +241,7 @@ struct cx25821_dev {
int hwrevision; int hwrevision;
/* used by cx25821-alsa */ /* used by cx25821-alsa */
struct snd_card *card; struct snd_card *card;
void *alloc_ctx;
u32 clk_freq; u32 clk_freq;
...@@ -425,10 +417,8 @@ extern int cx25821_risc_databuffer_audio(struct pci_dev *pci, ...@@ -425,10 +417,8 @@ extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
struct scatterlist *sglist, struct scatterlist *sglist,
unsigned int bpl, unsigned int bpl,
unsigned int lines, unsigned int lpi); unsigned int lines, unsigned int lpi);
extern void cx25821_free_buffer(struct videobuf_queue *q, extern void cx25821_free_buffer(struct cx25821_dev *dev,
struct cx25821_buffer *buf); struct cx25821_buffer *buf);
extern int cx25821_risc_stopper(struct pci_dev *pci, struct cx25821_riscmem *risc,
u32 reg, u32 mask, u32 value);
extern void cx25821_sram_channel_dump(struct cx25821_dev *dev, extern void cx25821_sram_channel_dump(struct cx25821_dev *dev,
const struct sram_channel *ch); const struct sram_channel *ch);
extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
......
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