diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 17:55:48 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 17:55:48 -0700 |
| commit | 5b4ca4447757019f11a601b0009534ef84bed801 (patch) | |
| tree | 09bc8445e61aea621580d7587c21ac3f2b0cafb4 /drivers/staging | |
| parent | 0db9723cacf4d62bc3685fb15179b39ee4e17679 (diff) | |
| parent | faebbd8f134f0c054f372982c8ddd1bbcc41b440 (diff) | |
| download | linux-5b4ca4447757019f11a601b0009534ef84bed801.tar.gz linux-5b4ca4447757019f11a601b0009534ef84bed801.tar.bz2 linux-5b4ca4447757019f11a601b0009534ef84bed801.zip | |
Merge tag 'media/v4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Lots of improvements at the DVB API DocBook documentation. Now, the
frontend and the network APIs are fully in sync with the Kernel and
looks more like the rest of the media documentation;
- New frontend driver: cx24120
- New driver for a PCI device: cobalt. This driver is actually not
sold in the market, but it is a good example of a multi-HDMI input
device;
- The dt3155 driver were promoted from staging;
- The mantis driver got remote controller support;
- New V4L2 driver for ST bdisp SoC chipsets;
- Make sparse and smatch happier: several bugs were solved by fixing
the issues reported by those static code analyzers.
- Lots of new device additions, new features, improvements and cleanups
at the existing drivers.
* tag 'media/v4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (553 commits)
[media] lmedm04: fix the range for relative measurements
[media] lmedm04: use u32 instead of u64 for relative stats
[media] omap3isp: remove unused var
[media] saa7134: fix page size on some archs
[media] use CONFIG_PM_SLEEP for suspend/resume
[media] tuner-i2c: be consistent with I2C declaration
[media] si470x: cleanup define namespace
[media] bdisp: prevent compiling on random arch
[media] vb2: Don't WARN when v4l2_buffer.bytesused is 0 for multiplanar buffers
[media] MAINTAINERS: Add entry for the Renesas VSP1 driver
[media] videodev2.h: fix copy-and-paste error in V4L2_MAP_XFER_FUNC_DEFAULT
[media] Revert "[media] vb2: Push mmap_sem down to memops"
[media] mantis: cleanup a warning
[media] bdisp-debug: don't try to divide by s64
[media] cx88: don't declare restart_video_queue if not used
[media] au0828: move dev->boards atribuition to happen earlier
[media] lmedm04: implement dvb v5 statistics
[media] bdisp: remove unused var
[media] bdisp: remove needless check
ts2020: fix compilation on i386
...
Diffstat (limited to 'drivers/staging')
21 files changed, 125 insertions, 1377 deletions
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 96498b7fc20e..14697686eea5 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -25,8 +25,6 @@ source "drivers/staging/media/cxd2099/Kconfig" source "drivers/staging/media/davinci_vpfe/Kconfig" -source "drivers/staging/media/dt3155v4l/Kconfig" - source "drivers/staging/media/mn88472/Kconfig" source "drivers/staging/media/mn88473/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index a9006bcb4472..34c557b4c6d6 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_I2C_BCM2048) += bcm2048/ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ -obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_DVB_MN88472) += mn88472/ diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index e9d0691b21d3..5e11a78ceef3 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2593,7 +2593,7 @@ static int bcm2048_i2c_driver_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bcm2048_device *bdev; - int err, skip_release = 0; + int err; bdev = kzalloc(sizeof(*bdev), GFP_KERNEL); if (!bdev) { @@ -2646,7 +2646,6 @@ free_sysfs: bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs)); free_registration: video_unregister_device(&bdev->videodev); - skip_release = 1; free_irq: if (client->irq) free_irq(client->irq, bdev); diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index b6498137de56..acb293ed9c91 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -321,6 +321,7 @@ static int resizer_configure_output_win(struct vpfe_resizer_device *resizer) outformat = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE]; + memset(&output_specs, 0x0, sizeof(struct vpfe_rsz_output_spec)); output_specs.vst_y = param->user_config.vst; if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) output_specs.vst_c = param->user_config.vst; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h index 2632a806c4a8..8ad8d743f4e0 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h @@ -67,8 +67,6 @@ struct vpfe_device { /* CCDC IRQs used when CCDC/ISIF output to SDRAM */ unsigned int ccdc_irq0; unsigned int ccdc_irq1; - /* maximum video memory that is available*/ - unsigned int video_limit; /* media device */ struct media_device media_dev; /* ccdc subdevice */ diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 06d48d5eb0a0..87048a14c34d 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -27,9 +27,6 @@ #include "vpfe.h" #include "vpfe_mc_capture.h" -/* minimum number of buffers needed in cont-mode */ -#define MIN_NUM_BUFFERS 3 - static int debug; /* get v4l2 subdev pointer to external subdev which is active */ @@ -473,7 +470,7 @@ void vpfe_video_process_buffer_complete(struct vpfe_video_device *video) { struct vpfe_pipeline *pipe = &video->pipe; - do_gettimeofday(&video->cur_frm->vb.v4l2_buf.timestamp); + v4l2_get_timestamp(&video->cur_frm->vb.v4l2_buf.timestamp); vb2_buffer_done(&video->cur_frm->vb, VB2_BUF_STATE_DONE); if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS) video->cur_frm = video->next_frm; @@ -1088,20 +1085,14 @@ vpfe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, struct vpfe_fh *fh = vb2_get_drv_priv(vq); struct vpfe_video_device *video = fh->video; struct vpfe_device *vpfe_dev = video->vpfe_dev; - struct vpfe_pipeline *pipe = &video->pipe; unsigned long size; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue_setup\n"); size = video->fmt.fmt.pix.sizeimage; - if (vpfe_dev->video_limit) { - while (size * *nbuffers > vpfe_dev->video_limit) - (*nbuffers)--; - } - if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS) { - if (*nbuffers < MIN_NUM_BUFFERS) - *nbuffers = MIN_NUM_BUFFERS; - } + if (vq->num_buffers + *nbuffers < 3) + *nbuffers = 3 - vq->num_buffers; + *nplanes = 1; sizes[0] = size; alloc_ctxs[0] = video->alloc_ctx; @@ -1346,6 +1337,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, q->ops = &video_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct vpfe_cap_buffer); + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) { diff --git a/drivers/staging/media/dt3155v4l/Kconfig b/drivers/staging/media/dt3155v4l/Kconfig deleted file mode 100644 index 2d496001b6e8..000000000000 --- a/drivers/staging/media/dt3155v4l/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -config VIDEO_DT3155 - tristate "DT3155 frame grabber, Video4Linux interface" - depends on PCI && VIDEO_DEV && VIDEO_V4L2 - depends on HAS_DMA - select VIDEOBUF2_DMA_CONTIG - default n - ---help--- - Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. - Say Y here if you have this hardware. - In doubt, say N. - - To compile this driver as a module, choose M here: the - module will be called dt3155v4l. - -config DT3155_CCIR - bool "Selects CCIR/50Hz vertical refresh" - depends on VIDEO_DT3155 - default y - ---help--- - Select it for CCIR/50Hz (European region), - or leave it unselected for RS-170/60Hz (North America). - -config DT3155_STREAMING - bool "Selects streaming capture method" - depends on VIDEO_DT3155 - default y - ---help--- - Select it if you want to use streaming of memory mapped buffers - or leave it unselected if you want to use read method (one copy more). diff --git a/drivers/staging/media/dt3155v4l/Makefile b/drivers/staging/media/dt3155v4l/Makefile deleted file mode 100644 index ce7a3ec2faf3..000000000000 --- a/drivers/staging/media/dt3155v4l/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l.o diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c deleted file mode 100644 index 52a8ffe560b1..000000000000 --- a/drivers/staging/media/dt3155v4l/dt3155v4l.c +++ /dev/null @@ -1,981 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006-2010 by Marin Mitov * - * mitov@issp.bas.bg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include <linux/module.h> -#include <linux/version.h> -#include <linux/stringify.h> -#include <linux/delay.h> -#include <linux/kthread.h> -#include <linux/slab.h> -#include <media/v4l2-dev.h> -#include <media/v4l2-ioctl.h> -#include <media/v4l2-common.h> -#include <media/videobuf2-dma-contig.h> - -#include "dt3155v4l.h" - -#define DT3155_DEVICE_ID 0x1223 - -/* DT3155_CHUNK_SIZE is 4M (2^22) 8 full size buffers */ -#define DT3155_CHUNK_SIZE (1U << 22) - -#define DT3155_COH_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN) - -#define DT3155_BUF_SIZE (768 * 576) - -#ifdef CONFIG_DT3155_STREAMING -#define DT3155_CAPTURE_METHOD V4L2_CAP_STREAMING -#else -#define DT3155_CAPTURE_METHOD V4L2_CAP_READWRITE -#endif - -/* global initializers (for all boards) */ -#ifdef CONFIG_DT3155_CCIR -static const u8 csr2_init = VT_50HZ; -#define DT3155_CURRENT_NORM V4L2_STD_625_50 -static const unsigned int img_width = 768; -static const unsigned int img_height = 576; -static const unsigned int frames_per_sec = 25; -static const struct v4l2_fmtdesc frame_std[] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = 0, - .description = "CCIR/50Hz 8 bits gray", - .pixelformat = V4L2_PIX_FMT_GREY, - }, -}; -#else -static const u8 csr2_init = VT_60HZ; -#define DT3155_CURRENT_NORM V4L2_STD_525_60 -static const unsigned int img_width = 640; -static const unsigned int img_height = 480; -static const unsigned int frames_per_sec = 30; -static const struct v4l2_fmtdesc frame_std[] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = 0, - .description = "RS-170/60Hz 8 bits gray", - .pixelformat = V4L2_PIX_FMT_GREY, - }, -}; -#endif - -#define NUM_OF_FORMATS ARRAY_SIZE(frame_std) - -static u8 config_init = ACQ_MODE_EVEN; - -/** - * read_i2c_reg - reads an internal i2c register - * - * @addr: dt3155 mmio base address - * @index: index (internal address) of register to read - * @data: pointer to byte the read data will be placed in - * - * returns: zero on success or error code - * - * This function starts reading the specified (by index) register - * and busy waits for the process to finish. The result is placed - * in a byte pointed by data. - */ -static int -read_i2c_reg(void __iomem *addr, u8 index, u8 *data) -{ - u32 tmp = index; - - iowrite32((tmp<<17) | IIC_READ, addr + IIC_CSR2); - mmiowb(); - udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - return -EIO; /* error: NEW_CYCLE not cleared */ - tmp = ioread32(addr + IIC_CSR1); - if (tmp & DIRECT_ABORT) { - /* reset DIRECT_ABORT bit */ - iowrite32(DIRECT_ABORT, addr + IIC_CSR1); - return -EIO; /* error: DIRECT_ABORT set */ - } - *data = tmp>>24; - return 0; -} - -/** - * write_i2c_reg - writes to an internal i2c register - * - * @addr: dt3155 mmio base address - * @index: index (internal address) of register to read - * @data: data to be written - * - * returns: zero on success or error code - * - * This function starts writting the specified (by index) register - * and busy waits for the process to finish. - */ -static int -write_i2c_reg(void __iomem *addr, u8 index, u8 data) -{ - u32 tmp = index; - - iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2); - mmiowb(); - udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - return -EIO; /* error: NEW_CYCLE not cleared */ - if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { - /* reset DIRECT_ABORT bit */ - iowrite32(DIRECT_ABORT, addr + IIC_CSR1); - return -EIO; /* error: DIRECT_ABORT set */ - } - return 0; -} - -/** - * write_i2c_reg_nowait - writes to an internal i2c register - * - * @addr: dt3155 mmio base address - * @index: index (internal address) of register to read - * @data: data to be written - * - * This function starts writting the specified (by index) register - * and then returns. - */ -static void write_i2c_reg_nowait(void __iomem *addr, u8 index, u8 data) -{ - u32 tmp = index; - - iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2); - mmiowb(); -} - -/** - * wait_i2c_reg - waits the read/write to finish - * - * @addr: dt3155 mmio base address - * - * returns: zero on success or error code - * - * This function waits reading/writting to finish. - */ -static int wait_i2c_reg(void __iomem *addr) -{ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - return -EIO; /* error: NEW_CYCLE not cleared */ - if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { - /* reset DIRECT_ABORT bit */ - iowrite32(DIRECT_ABORT, addr + IIC_CSR1); - return -EIO; /* error: DIRECT_ABORT set */ - } - return 0; -} - -static int -dt3155_start_acq(struct dt3155_priv *pd) -{ - struct vb2_buffer *vb = pd->curr_buf; - dma_addr_t dma_addr; - - dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); - iowrite32(dma_addr, pd->regs + EVEN_DMA_START); - iowrite32(dma_addr + img_width, pd->regs + ODD_DMA_START); - iowrite32(img_width, pd->regs + EVEN_DMA_STRIDE); - iowrite32(img_width, pd->regs + ODD_DMA_STRIDE); - /* enable interrupts, clear all irq flags */ - iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | - FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); - iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD, - pd->regs + CSR1); - wait_i2c_reg(pd->regs); - write_i2c_reg(pd->regs, CONFIG, pd->config); - write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); - write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); - - /* start the board */ - write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD); - return 0; /* success */ -} - -/* - * driver-specific callbacks (vb2_ops) - */ -static int -dt3155_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], void *alloc_ctxs[]) - -{ - struct dt3155_priv *pd = vb2_get_drv_priv(q); - void *ret; - - if (*num_buffers == 0) - *num_buffers = 1; - *num_planes = 1; - sizes[0] = img_width * img_height; - if (pd->q->alloc_ctx[0]) - return 0; - ret = vb2_dma_contig_init_ctx(&pd->pdev->dev); - if (IS_ERR(ret)) - return PTR_ERR(ret); - pd->q->alloc_ctx[0] = ret; - return 0; -} - -static void -dt3155_wait_prepare(struct vb2_queue *q) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(q); - - mutex_unlock(pd->vdev.lock); -} - -static void -dt3155_wait_finish(struct vb2_queue *q) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(q); - - mutex_lock(pd->vdev.lock); -} - -static int -dt3155_buf_prepare(struct vb2_buffer *vb) -{ - vb2_set_plane_payload(vb, 0, img_width * img_height); - return 0; -} - -static void -dt3155_stop_streaming(struct vb2_queue *q) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(q); - struct vb2_buffer *vb; - - spin_lock_irq(&pd->lock); - while (!list_empty(&pd->dmaq)) { - vb = list_first_entry(&pd->dmaq, typeof(*vb), done_entry); - list_del(&vb->done_entry); - vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); - } - spin_unlock_irq(&pd->lock); - msleep(45); /* irq hendler will stop the hardware */ -} - -static void -dt3155_buf_queue(struct vb2_buffer *vb) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue); - - /* pd->q->streaming = 1 when dt3155_buf_queue() is invoked */ - spin_lock_irq(&pd->lock); - if (pd->curr_buf) - list_add_tail(&vb->done_entry, &pd->dmaq); - else { - pd->curr_buf = vb; - dt3155_start_acq(pd); - } - spin_unlock_irq(&pd->lock); -} -/* - * end driver-specific callbacks - */ - -static const struct vb2_ops q_ops = { - .queue_setup = dt3155_queue_setup, - .wait_prepare = dt3155_wait_prepare, - .wait_finish = dt3155_wait_finish, - .buf_prepare = dt3155_buf_prepare, - .stop_streaming = dt3155_stop_streaming, - .buf_queue = dt3155_buf_queue, -}; - -static irqreturn_t -dt3155_irq_handler_even(int irq, void *dev_id) -{ - struct dt3155_priv *ipd = dev_id; - struct vb2_buffer *ivb; - dma_addr_t dma_addr; - u32 tmp; - - tmp = ioread32(ipd->regs + INT_CSR) & (FLD_START | FLD_END_ODD); - if (!tmp) - return IRQ_NONE; /* not our irq */ - if ((tmp & FLD_START) && !(tmp & FLD_END_ODD)) { - iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START, - ipd->regs + INT_CSR); - ipd->field_count++; - return IRQ_HANDLED; /* start of field irq */ - } - if ((tmp & FLD_START) && (tmp & FLD_END_ODD)) - ipd->stats.start_before_end++; - /* check for corrupted fields */ -/* write_i2c_reg(ipd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); */ -/* write_i2c_reg(ipd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); */ - tmp = ioread32(ipd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD); - if (tmp) { - ipd->stats.corrupted_fields++; - iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN | - CAP_CONT_EVEN | CAP_CONT_ODD, - ipd->regs + CSR1); - mmiowb(); - } - - spin_lock(&ipd->lock); - if (ipd->curr_buf) { - v4l2_get_timestamp(&ipd->curr_buf->v4l2_buf.timestamp); - ipd->curr_buf->v4l2_buf.sequence = (ipd->field_count) >> 1; - vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE); - } - - if (!ipd->q->streaming || list_empty(&ipd->dmaq)) - goto stop_dma; - ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry); - list_del(&ivb->done_entry); - ipd->curr_buf = ivb; - dma_addr = vb2_dma_contig_plane_dma_addr(ivb, 0); - iowrite32(dma_addr, ipd->regs + EVEN_DMA_START); - iowrite32(dma_addr + img_width, ipd->regs + ODD_DMA_START); - iowrite32(img_width, ipd->regs + EVEN_DMA_STRIDE); - iowrite32(img_width, ipd->regs + ODD_DMA_STRIDE); - mmiowb(); - /* enable interrupts, clear all irq flags */ - iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | - FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR); - spin_unlock(&ipd->lock); - return IRQ_HANDLED; - -stop_dma: - ipd->curr_buf = NULL; - /* stop the board */ - write_i2c_reg_nowait(ipd->regs, CSR2, ipd->csr2); - iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN, ipd->regs + CSR1); - /* disable interrupts, clear all irq flags */ - iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR); - spin_unlock(&ipd->lock); - return IRQ_HANDLED; -} - -static int -dt3155_open(struct file *filp) -{ - int ret = 0; - struct dt3155_priv *pd = video_drvdata(filp); - - if (mutex_lock_interruptible(&pd->mux)) - return -ERESTARTSYS; - if (!pd->users) { - pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL); - if (!pd->q) { - ret = -ENOMEM; - goto err_alloc_queue; - } - pd->q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - pd->q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - pd->q->io_modes = VB2_READ | VB2_MMAP; - pd->q->ops = &q_ops; - pd->q->mem_ops = &vb2_dma_contig_memops; - pd->q->drv_priv = pd; - pd->curr_buf = NULL; - pd->field_count = 0; - ret = vb2_queue_init(pd->q); - if (ret < 0) - goto err_request_irq; - INIT_LIST_HEAD(&pd->dmaq); - spin_lock_init(&pd->lock); - /* disable all irqs, clear all irq flags */ - iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, - pd->regs + INT_CSR); - ret = request_irq(pd->pdev->irq, dt3155_irq_handler_even, - IRQF_SHARED, DT3155_NAME, pd); - if (ret) - goto err_request_irq; - } - pd->users++; - mutex_unlock(&pd->mux); - return 0; /* success */ -err_request_irq: - kfree(pd->q); - pd->q = NULL; -err_alloc_queue: - mutex_unlock(&pd->mux); - return ret; -} - -static int -dt3155_release(struct file *filp) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - mutex_lock(&pd->mux); - pd->users--; - BUG_ON(pd->users < 0); - if (!pd->users) { - vb2_queue_release(pd->q); - free_irq(pd->pdev->irq, pd); - if (pd->q->alloc_ctx[0]) - vb2_dma_contig_cleanup_ctx(pd->q->alloc_ctx[0]); - kfree(pd->q); - pd->q = NULL; - } - mutex_unlock(&pd->mux); - return 0; -} - -static ssize_t -dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff) -{ - struct dt3155_priv *pd = video_drvdata(filp); - ssize_t res; - - if (mutex_lock_interruptible(&pd->mux)) - return -ERESTARTSYS; - res = vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK); - mutex_unlock(&pd->mux); - return res; -} - -static unsigned int -dt3155_poll(struct file *filp, struct poll_table_struct *polltbl) -{ - struct dt3155_priv *pd = video_drvdata(filp); - unsigned int res; - - mutex_lock(&pd->mux); - res = vb2_poll(pd->q, filp, polltbl); - mutex_unlock(&pd->mux); - return res; -} - -static int -dt3155_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct dt3155_priv *pd = video_drvdata(filp); - int res; - - if (mutex_lock_interruptible(&pd->mux)) - return -ERESTARTSYS; - res = vb2_mmap(pd->q, vma); - mutex_unlock(&pd->mux); - return res; -} - -static const struct v4l2_file_operations dt3155_fops = { - .owner = THIS_MODULE, - .open = dt3155_open, - .release = dt3155_release, - .read = dt3155_read, - .poll = dt3155_poll, - .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ - .mmap = dt3155_mmap, -}; - -static int -dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - return vb2_streamon(pd->q, type); -} - -static int -dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - return vb2_streamoff(pd->q, type); -} - -static int -dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - strcpy(cap->driver, DT3155_NAME); - strcpy(cap->card, DT3155_NAME " frame grabber"); - sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | - DT3155_CAPTURE_METHOD; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; -} - -static int -dt3155_ioc_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f) -{ - if (f->index >= NUM_OF_FORMATS) - return -EINVAL; - *f = frame_std[f->index]; - return 0; -} - -static int -dt3155_ioc_g_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) -{ - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - f->fmt.pix.width = img_width; - f->fmt.pix.height = img_height; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; - f->fmt.pix.field = V4L2_FIELD_NONE; - f->fmt.pix.bytesperline = f->fmt.pix.width; - f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height; - f->fmt.pix.colorspace = 0; - f->fmt.pix.priv = 0; - return 0; -} - -static int -dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) -{ - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (f->fmt.pix.width == img_width && - f->fmt.pix.height == img_height && - f->fmt.pix.pixelformat == V4L2_PIX_FMT_GREY && - f->fmt.pix.field == V4L2_FIELD_NONE && - f->fmt.pix.bytesperline == f->fmt.pix.width && - f->fmt.pix.sizeimage == f->fmt.pix.width * f->fmt.pix.height) - return 0; - else - return -EINVAL; -} - -static int -dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) -{ - return dt3155_ioc_g_fmt_vid_cap(filp, p, f); -} - -static int -dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - return vb2_reqbufs(pd->q, b); -} - -static int -dt3155_ioc_querybuf(struct file *filp, void *p, struct v4l2_buffer *b) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - return vb2_querybuf(pd->q, b); -} - -static int -dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - return vb2_qbuf(pd->q, b); -} - -static int -dt3155_ioc_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - return vb2_dqbuf(pd->q, b, filp->f_flags & O_NONBLOCK); -} - -static int -dt3155_ioc_querystd(struct file *filp, void *p, v4l2_std_id *norm) -{ - *norm = DT3155_CURRENT_NORM; - return 0; -} - -static int -dt3155_ioc_g_std(struct file *filp, void *p, v4l2_std_id *norm) -{ - *norm = DT3155_CURRENT_NORM; - return 0; -} - -static int -dt3155_ioc_s_std(struct file *filp, void *p, v4l2_std_id norm) -{ - if (norm & DT3155_CURRENT_NORM) - return 0; - return -EINVAL; -} - -static int -dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input) -{ - if (input->index) - return -EINVAL; - strcpy(input->name, "Coax in"); - input->type = V4L2_INPUT_TYPE_CAMERA; - /* - * FIXME: input->std = 0 according to v4l2 API - * VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD - * should return -EINVAL - */ - input->std = DT3155_CURRENT_NORM; - input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */ - return 0; -} - -static int -dt3155_ioc_g_input(struct file *filp, void *p, unsigned int *i) -{ - *i = 0; - return 0; -} - -static int -dt3155_ioc_s_input(struct file *filp, void *p, unsigned int i) -{ - if (i) |
