Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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.
+29 −47
Original line number Original line Diff line number Diff line
@@ -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);
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,
		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,


	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,
}
}
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,15 +1297,16 @@ 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);
	err = cx25821_dev_setup(dev);
	if (IS_ERR(dev->alloc_ctx)) {
	if (err) {
		err = PTR_ERR(dev->alloc_ctx);
		if (err == -EBUSY)
			goto fail_unregister_device;
		else
		goto fail_unregister_pci;
		goto fail_unregister_pci;
	}
	}


	err = cx25821_dev_setup(dev);
	if (err)
		goto fail_free_ctx;

	/* 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);
	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
@@ -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)
		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);
}
}
+170 −512

File changed.

Preview size limit exceeded, changes collapsed.

+7 −17
Original line number Original line Diff line number Diff line
@@ -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 {
/* 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 {


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 {
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 {
	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,
					 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,