aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb-core/demux.h619
-rw-r--r--drivers/media/dvb-core/dmxdev.c10
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.h99
-rw-r--r--drivers/media/dvb-core/dvb_demux.c11
-rw-r--r--drivers/media/dvb-core/dvb_net.c5
-rw-r--r--drivers/media/dvb-core/dvbdev.h4
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c3
-rw-r--r--drivers/media/dvb-frontends/horus3a.h4
-rw-r--r--drivers/media/dvb-frontends/lnbh25.h2
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.c73
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.c23
-rw-r--r--drivers/media/dvb-frontends/si2168.c4
-rw-r--r--drivers/media/i2c/ml86v7667.c11
-rw-r--r--drivers/media/i2c/ov9650.c2
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c2
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-spi.c2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c1
-rw-r--r--drivers/media/i2c/tvp5150.c14
-rw-r--r--drivers/media/media-entity.c4
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c5
-rw-r--r--drivers/media/pci/cobalt/Kconfig2
-rw-r--r--drivers/media/pci/cobalt/cobalt-cpld.c8
-rw-r--r--drivers/media/pci/cobalt/cobalt-driver.h6
-rw-r--r--drivers/media/pci/cobalt/cobalt-irq.c7
-rw-r--r--drivers/media/pci/cobalt/cobalt-v4l2.c24
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-417.c13
-rw-r--r--drivers/media/pci/cx23885/cx23885-core.c28
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c11
-rw-r--r--drivers/media/pci/cx23885/cx23885-vbi.c18
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c29
-rw-r--r--drivers/media/pci/cx23885/cx23885.h2
-rw-r--r--drivers/media/pci/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/media/pci/cx25821/cx25821-core.c3
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c24
-rw-r--r--drivers/media/pci/cx25821/cx25821.h3
-rw-r--r--drivers/media/pci/cx88/cx88-alsa.c6
-rw-r--r--drivers/media/pci/cx88/cx88-blackbird.c15
-rw-r--r--drivers/media/pci/cx88/cx88-core.c8
-rw-r--r--drivers/media/pci/cx88/cx88-dvb.c13
-rw-r--r--drivers/media/pci/cx88/cx88-mpeg.c17
-rw-r--r--drivers/media/pci/cx88/cx88-vbi.c19
-rw-r--r--drivers/media/pci/cx88/cx88-video.c25
-rw-r--r--drivers/media/pci/cx88/cx88.h2
-rw-r--r--drivers/media/pci/dt3155/dt3155.c20
-rw-r--r--drivers/media/pci/dt3155/dt3155.h3
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-main.c14
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.c12
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb.h4
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_ci.c10
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c37
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c2
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_spi.c16
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c43
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c18
-rw-r--r--drivers/media/pci/saa7134/saa7134-input.c7
-rw-r--r--drivers/media/pci/saa7134/saa7134-ts.c16
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c12
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c23
-rw-r--r--drivers/media/pci/saa7134/saa7134.h5
-rw-r--r--drivers/media/pci/saa7164/Kconfig1
-rw-r--r--drivers/media/pci/saa7164/saa7164-core.c4
-rw-r--r--drivers/media/pci/saa7164/saa7164-encoder.c653
-rw-r--r--drivers/media/pci/saa7164/saa7164-vbi.c629
-rw-r--r--drivers/media/pci/saa7164/saa7164.h26
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c50
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2.c23
-rw-r--r--drivers/media/pci/solo6x10/solo6x10.h4
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c28
-rw-r--r--drivers/media/pci/ttpci/av7110.c9
-rw-r--r--drivers/media/pci/ttpci/av7110_av.c6
-rw-r--r--drivers/media/pci/tw68/tw68-core.c4
-rw-r--r--drivers/media/pci/tw68/tw68-video.c24
-rw-r--r--drivers/media/pci/tw68/tw68.h3
-rw-r--r--drivers/media/platform/Kconfig2
-rw-r--r--drivers/media/platform/am437x/am437x-vpfe.c43
-rw-r--r--drivers/media/platform/am437x/am437x-vpfe.h3
-rw-r--r--drivers/media/platform/blackfin/bfin_capture.c37
-rw-r--r--drivers/media/platform/coda/coda-bit.c135
-rw-r--r--drivers/media/platform/coda/coda-common.c26
-rw-r--r--drivers/media/platform/coda/coda-jpeg.c6
-rw-r--r--drivers/media/platform/coda/coda.h8
-rw-r--r--drivers/media/platform/coda/trace.h18
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c34
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c33
-rw-r--r--drivers/media/platform/davinci/vpif_capture.h2
-rw-r--r--drivers/media/platform/davinci/vpif_display.c42
-rw-r--r--drivers/media/platform/davinci/vpif_display.h2
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.h4
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-m2m.c25
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c33
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.h4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.h2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp-video.c18
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp-video.h2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.h4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c25
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.h4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-m2m.c23
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c3
-rw-r--r--drivers/media/platform/m2m-deinterlace.c25
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.c46
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.h2
-rw-r--r--drivers/media/platform/mx2_emmaprp.c17
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c5
-rw-r--r--drivers/media/platform/omap3isp/ispstat.h2
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c27
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.h4
-rw-r--r--drivers/media/platform/rcar_jpu.c68
-rw-r--r--drivers/media/platform/s3c-camif/camif-capture.c26
-rw-r--r--drivers/media/platform/s3c-camif/camif-core.c2
-rw-r--r--drivers/media/platform/s3c-camif/camif-core.h4
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c19
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c475
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h41
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c80
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h11
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-regs.h85
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c106
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h4
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c40
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c75
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c46
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c68
-rw-r--r--drivers/media/platform/s5p-tv/mixer.h4
-rw-r--r--drivers/media/platform/s5p-tv/mixer_grp_layer.c2
-rw-r--r--drivers/media/platform/s5p-tv/mixer_reg.c2
-rw-r--r--drivers/media/platform/s5p-tv/mixer_video.c13
-rw-r--r--drivers/media/platform/s5p-tv/mixer_vp_layer.c5
-rw-r--r--drivers/media/platform/sh_veu.c22
-rw-r--r--drivers/media/platform/sh_vou.c29
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c153
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.h128
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c24
-rw-r--r--drivers/media/platform/soc_camera/mx3_camera.c30
-rw-r--r--drivers/media/platform/soc_camera/rcar_vin.c64
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c63
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c4
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-v4l2.c26
-rw-r--r--drivers/media/platform/sti/c8sectpfe/Kconfig1
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c11
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c44
-rw-r--r--drivers/media/platform/vim2m.c57
-rw-r--r--drivers/media/platform/vivid/Kconfig8
-rw-r--r--drivers/media/platform/vivid/vivid-core.c7
-rw-r--r--drivers/media/platform/vivid/vivid-core.h6
-rw-r--r--drivers/media/platform/vivid/vivid-ctrls.c55
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-cap.c73
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-out.c34
-rw-r--r--drivers/media/platform/vivid/vivid-osd.c1
-rw-r--r--drivers/media/platform/vivid/vivid-sdr-cap.c83
-rw-r--r--drivers/media/platform/vivid/vivid-tpg-colors.c328
-rw-r--r--drivers/media/platform/vivid/vivid-tpg-colors.h4
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.c91
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-cap.c40
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-out.c20
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c18
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c56
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.c18
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c4
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c23
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.h8
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c4
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.c29
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.h2
-rw-r--r--drivers/media/rc/ir-hix5hd2.c2
-rw-r--r--drivers/media/tuners/msi001.c1
-rw-r--r--drivers/media/tuners/si2157.c4
-rw-r--r--drivers/media/usb/airspy/airspy.c26
-rw-r--r--drivers/media/usb/au0828/au0828-vbi.c10
-rw-r--r--drivers/media/usb/au0828/au0828-video.c48
-rw-r--r--drivers/media/usb/au0828/au0828.h3
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c3
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvbsky.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c17
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.h2
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c10
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c37
-rw-r--r--drivers/media/usb/em28xx/em28xx.h3
-rw-r--r--drivers/media/usb/go7007/go7007-driver.c29
-rw-r--r--drivers/media/usb/go7007/go7007-fw.c6
-rw-r--r--drivers/media/usb/go7007/go7007-priv.h4
-rw-r--r--drivers/media/usb/go7007/go7007-v4l2.c22
-rw-r--r--drivers/media/usb/gspca/gspca.c4
-rw-r--r--drivers/media/usb/hackrf/hackrf.c1086
-rw-r--r--drivers/media/usb/msi2500/msi2500.c19
-rw-r--r--drivers/media/usb/pwc/pwc-if.c35
-rw-r--r--drivers/media/usb/pwc/pwc-uncompress.c6
-rw-r--r--drivers/media/usb/pwc/pwc.h4
-rw-r--r--drivers/media/usb/s2255/s2255drv.c29
-rw-r--r--drivers/media/usb/stk1160/stk1160-v4l.c17
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c12
-rw-r--r--drivers/media/usb/stk1160/stk1160.h4
-rw-r--r--drivers/media/usb/tm6000/tm6000-alsa.c2
-rw-r--r--drivers/media/usb/ttusb-dec/ttusb_dec.c12
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c24
-rw-r--r--drivers/media/usb/usbtv/usbtv.h3
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c3
-rw-r--r--drivers/media/usb/uvc/uvc_queue.c29
-rw-r--r--drivers/media/usb/uvc/uvc_video.c23
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h7
-rw-r--r--drivers/media/v4l2-core/Kconfig2
-rw-r--r--drivers/media/v4l2-core/Makefile4
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c51
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c14
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c14
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c51
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c33
-rw-r--r--drivers/media/v4l2-core/v4l2-trace.c10
-rw-r--r--drivers/media/v4l2-core/vb2-trace.c9
-rw-r--r--drivers/media/v4l2-core/videobuf-core.c4
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c2014
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c7
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-sg.c7
-rw-r--r--drivers/media/v4l2-core/videobuf2-internal.h161
-rw-r--r--drivers/media/v4l2-core/videobuf2-memops.c2
-rw-r--r--drivers/media/v4l2-core/videobuf2-v4l2.c1661
-rw-r--r--drivers/media/v4l2-core/videobuf2-vmalloc.c2
220 files changed, 6819 insertions, 5081 deletions
diff --git a/drivers/media/dvb-core/demux.h b/drivers/media/dvb-core/demux.h
index 833191bcd810..ccc1f43cb9a9 100644
--- a/drivers/media/dvb-core/demux.h
+++ b/drivers/media/dvb-core/demux.h
@@ -32,9 +32,9 @@
#include <linux/time.h>
#include <linux/dvb/dmx.h>
-/*--------------------------------------------------------------------------*/
-/* Common definitions */
-/*--------------------------------------------------------------------------*/
+/*
+ * Common definitions
+ */
/*
* DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
@@ -45,7 +45,8 @@
#endif
/*
- * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
+ * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed
+ * filter.
*/
#ifndef DMX_MAX_SECTION_SIZE
@@ -55,139 +56,296 @@
#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
#endif
-
/*
- * enum dmx_success: Success codes for the Demux Callback API.
+ * TS packet reception
*/
-enum dmx_success {
- DMX_OK = 0, /* Received Ok */
- DMX_LENGTH_ERROR, /* Incorrect length */
- DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
- DMX_CRC_ERROR, /* Incorrect CRC */
- DMX_FRAME_ERROR, /* Frame alignment error */
- DMX_FIFO_ERROR, /* Receiver FIFO overrun */
- DMX_MISSED_ERROR /* Receiver missed packet */
-} ;
-
-/*--------------------------------------------------------------------------*/
-/* TS packet reception */
-/*--------------------------------------------------------------------------*/
-
-/* TS filter type for set() */
-
-#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
-#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
- payload (<=184 bytes per packet) to callback */
-#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
-#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to
- the demux device, not to the dvr device */
+/**
+ * enum ts_filter_type - filter type bitmap for dmx_ts_feed.set()
+ *
+ * @TS_PACKET: Send TS packets (188 bytes) to callback (default).
+ * @TS_PAYLOAD_ONLY: In case TS_PACKET is set, only send the TS payload
+ * (<=184 bytes per packet) to callback
+ * @TS_DECODER: Send stream to built-in decoder (if present).
+ * @TS_DEMUX: In case TS_PACKET is set, send the TS to the demux
+ * device, not to the dvr device
+ */
+enum ts_filter_type {
+ TS_PACKET = 1,
+ TS_PAYLOAD_ONLY = 2,
+ TS_DECODER = 4,
+ TS_DEMUX = 8,
+};
+/**
+ * struct dmx_ts_feed - Structure that contains a TS feed filter
+ *
+ * @is_filtering: Set to non-zero when filtering in progress
+ * @parent: pointer to struct dmx_demux
+ * @priv: pointer to private data of the API client
+ * @set: sets the TS filter
+ * @start_filtering: starts TS filtering
+ * @stop_filtering: stops TS filtering
+ *
+ * A TS feed is typically mapped to a hardware PID filter on the demux chip.
+ * Using this API, the client can set the filtering properties to start/stop
+ * filtering TS packets on a particular TS feed.
+ */
struct dmx_ts_feed {
- int is_filtering; /* Set to non-zero when filtering in progress */
- struct dmx_demux *parent; /* Back-pointer */
- void *priv; /* Pointer to private data of the API client */
- int (*set) (struct dmx_ts_feed *feed,
- u16 pid,
- int type,
- enum dmx_ts_pes pes_type,
- size_t circular_buffer_size,
- struct timespec timeout);
- int (*start_filtering) (struct dmx_ts_feed* feed);
- int (*stop_filtering) (struct dmx_ts_feed* feed);
+ int is_filtering;
+ struct dmx_demux *parent;
+ void *priv;
+ int (*set)(struct dmx_ts_feed *feed,
+ u16 pid,
+ int type,
+ enum dmx_ts_pes pes_type,
+ size_t circular_buffer_size,
+ struct timespec timeout);
+ int (*start_filtering)(struct dmx_ts_feed *feed);
+ int (*stop_filtering)(struct dmx_ts_feed *feed);
};
-/*--------------------------------------------------------------------------*/
-/* Section reception */
-/*--------------------------------------------------------------------------*/
+/*
+ * Section reception
+ */
+/**
+ * struct dmx_section_filter - Structure that describes a section filter
+ *
+ * @filter_value: Contains up to 16 bytes (128 bits) of the TS section header
+ * that will be matched by the section filter
+ * @filter_mask: Contains a 16 bytes (128 bits) filter mask with the bits
+ * specified by @filter_value that will be used on the filter
+ * match logic.
+ * @filter_mode: Contains a 16 bytes (128 bits) filter mode.
+ * @parent: Pointer to struct dmx_section_feed.
+ * @priv: Pointer to private data of the API client.
+ *
+ *
+ * The @filter_mask controls which bits of @filter_value are compared with
+ * the section headers/payload. On a binary value of 1 in filter_mask, the
+ * corresponding bits are compared. The filter only accepts sections that are
+ * equal to filter_value in all the tested bit positions.
+ */
struct dmx_section_filter {
- u8 filter_value [DMX_MAX_FILTER_SIZE];
- u8 filter_mask [DMX_MAX_FILTER_SIZE];
- u8 filter_mode [DMX_MAX_FILTER_SIZE];
- struct dmx_section_feed* parent; /* Back-pointer */
- void* priv; /* Pointer to private data of the API client */
+ u8 filter_value[DMX_MAX_FILTER_SIZE];
+ u8 filter_mask[DMX_MAX_FILTER_SIZE];
+ u8 filter_mode[DMX_MAX_FILTER_SIZE];
+ struct dmx_section_feed *parent; /* Back-pointer */
+ void *priv; /* Pointer to private data of the API client */
};
+/**
+ * struct dmx_section_feed - Structure that contains a section feed filter
+ *
+ * @is_filtering: Set to non-zero when filtering in progress
+ * @parent: pointer to struct dmx_demux
+ * @priv: pointer to private data of the API client
+ * @check_crc: If non-zero, check the CRC values of filtered sections.
+ * @set: sets the section filter
+ * @allocate_filter: This function is used to allocate a section filter on
+ * the demux. It should only be called when no filtering
+ * is in progress on this section feed. If a filter cannot
+ * be allocated, the function fails with -ENOSPC.
+ * @release_filter: This function releases all the resources of a
+ * previously allocated section filter. The function
+ * should not be called while filtering is in progress
+ * on this section feed. After calling this function,
+ * the caller should not try to dereference the filter
+ * pointer.
+ * @start_filtering: starts section filtering
+ * @stop_filtering: stops section filtering
+ *
+ * A TS feed is typically mapped to a hardware PID filter on the demux chip.
+ * Using this API, the client can set the filtering properties to start/stop
+ * filtering TS packets on a particular TS feed.
+ */
struct dmx_section_feed {
- int is_filtering; /* Set to non-zero when filtering in progress */
- struct dmx_demux* parent; /* Back-pointer */
- void* priv; /* Pointer to private data of the API client */
+ int is_filtering;
+ struct dmx_demux *parent;
+ void *priv;
int check_crc;
+
+ /* private: Used internally at dvb_demux.c */
u32 crc_val;
u8 *secbuf;
u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
u16 secbufp, seclen, tsfeedp;
- int (*set) (struct dmx_section_feed* feed,
- u16 pid,
- size_t circular_buffer_size,
- int check_crc);
- int (*allocate_filter) (struct dmx_section_feed* feed,
- struct dmx_section_filter** filter);
- int (*release_filter) (struct dmx_section_feed* feed,
- struct dmx_section_filter* filter);
- int (*start_filtering) (struct dmx_section_feed* feed);
- int (*stop_filtering) (struct dmx_section_feed* feed);
+ /* public: */
+ int (*set)(struct dmx_section_feed *feed,
+ u16 pid,
+ size_t circular_buffer_size,
+ int check_crc);
+ int (*allocate_filter)(struct dmx_section_feed *feed,
+ struct dmx_section_filter **filter);
+ int (*release_filter)(struct dmx_section_feed *feed,
+ struct dmx_section_filter *filter);
+ int (*start_filtering)(struct dmx_section_feed *feed);
+ int (*stop_filtering)(struct dmx_section_feed *feed);
};
-/*--------------------------------------------------------------------------*/
-/* Callback functions */
-/*--------------------------------------------------------------------------*/
-
-typedef int (*dmx_ts_cb) ( const u8 * buffer1,
- size_t buffer1_length,
- const u8 * buffer2,
- size_t buffer2_length,
- struct dmx_ts_feed* source,
- enum dmx_success success);
+/*
+ * Callback functions
+ */
-typedef int (*dmx_section_cb) ( const u8 * buffer1,
- size_t buffer1_len,
- const u8 * buffer2,
- size_t buffer2_len,
- struct dmx_section_filter * source,
- enum dmx_success success);
+/**
+ * typedef dmx_ts_cb - DVB demux TS filter callback function prototype
+ *
+ * @buffer1: Pointer to the start of the filtered TS packets.
+ * @buffer1_length: Length of the TS data in buffer1.
+ * @buffer2: Pointer to the tail of the filtered TS packets, or NULL.
+ * @buffer2_length: Length of the TS data in buffer2.
+ * @source: Indicates which TS feed is the source of the callback.
+ *
+ * This function callback prototype, provided by the client of the demux API,
+ * is called from the demux code. The function is only called when filtering
+ * on ae TS feed has been enabled using the start_filtering() function at
+ * the &dmx_demux.
+ * Any TS packets that match the filter settings are copied to a circular
+ * buffer. The filtered TS packets are delivered to the client using this
+ * callback function. The size of the circular buffer is controlled by the
+ * circular_buffer_size parameter of the &dmx_ts_feed.@set function.
+ * It is expected that the @buffer1 and @buffer2 callback parameters point to
+ * addresses within the circular buffer, but other implementations are also
+ * possible. Note that the called party should not try to free the memory
+ * the @buffer1 and @buffer2 parameters point to.
+ *
+ * When this function is called, the @buffer1 parameter typically points to
+ * the start of the first undelivered TS packet within a circular buffer.
+ * The @buffer2 buffer parameter is normally NULL, except when the received
+ * TS packets have crossed the last address of the circular buffer and
+ * ”wrapped” to the beginning of the buffer. In the latter case the @buffer1
+ * parameter would contain an address within the circular buffer, while the
+ * @buffer2 parameter would contain the first address of the circular buffer.
+ * The number of bytes delivered with this function (i.e. @buffer1_length +
+ * @buffer2_length) is usually equal to the value of callback_length parameter
+ * given in the set() function, with one exception: if a timeout occurs before
+ * receiving callback_length bytes of TS data, any undelivered packets are
+ * immediately delivered to the client by calling this function. The timeout
+ * duration is controlled by the set() function in the TS Feed API.
+ *
+ * If a TS packet is received with errors that could not be fixed by the
+ * TS-level forward error correction (FEC), the Transport_error_indicator
+ * flag of the TS packet header should be set. The TS packet should not be
+ * discarded, as the error can possibly be corrected by a higher layer
+ * protocol. If the called party is slow in processing the callback, it
+ * is possible that the circular buffer eventually fills up. If this happens,
+ * the demux driver should discard any TS packets received while the buffer
+ * is full and return -EOVERFLOW.
+ *
+ * The type of data returned to the callback can be selected by the
+ * &dmx_ts_feed.@set function. The type parameter decides if the raw
+ * TS packet (TS_PACKET) or just the payload (TS_PACKET|TS_PAYLOAD_ONLY)
+ * should be returned. If additionally the TS_DECODER bit is set the stream
+ * will also be sent to the hardware MPEG decoder.
+ *
+ * Return:
+ * 0, on success;
+ * -EOVERFLOW, on buffer overflow.
+ */
+typedef int (*dmx_ts_cb)(const u8 *buffer1,
+ size_t buffer1_length,
+ const u8 *buffer2,
+ size_t buffer2_length,
+ struct dmx_ts_feed *source);
+
+/**
+ * typedef dmx_section_cb - DVB demux TS filter callback function prototype
+ *
+ * @buffer1: Pointer to the start of the filtered section, e.g.
+ * within the circular buffer of the demux driver.
+ * @buffer1_len: Length of the filtered section data in @buffer1,
+ * including headers and CRC.
+ * @buffer2: Pointer to the tail of the filtered section data,
+ * or NULL. Useful to handle the wrapping of a
+ * circular buffer.
+ * @buffer2_len: Length of the filtered section data in @buffer2,
+ * including headers and CRC.
+ * @source: Indicates which section feed is the source of the
+ * callback.
+ *
+ * This function callback prototype, provided by the client of the demux API,
+ * is called from the demux code. The function is only called when
+ * filtering of sections has been enabled using the function
+ * &dmx_ts_feed.@start_filtering. When the demux driver has received a
+ * complete section that matches at least one section filter, the client
+ * is notified via this callback function. Normally this function is called
+ * for each received section; however, it is also possible to deliver
+ * multiple sections with one callback, for example when the system load
+ * is high. If an error occurs while receiving a section, this
+ * function should be called with the corresponding error type set in the
+ * success field, whether or not there is data to deliver. The Section Feed
+ * implementation should maintain a circular buffer for received sections.
+ * However, this is not necessary if the Section Feed API is implemented as
+ * a client of the TS Feed API, because the TS Feed implementation then
+ * buffers the received data. The size of the circular buffer can be
+ * configured using the &dmx_ts_feed.@set function in the Section Feed API.
+ * If there is no room in the circular buffer when a new section is received,
+ * the section must be discarded. If this happens, the value of the success
+ * parameter should be DMX_OVERRUN_ERROR on the next callback.
+ */
+typedef int (*dmx_section_cb)(const u8 *buffer1,
+ size_t buffer1_len,
+ const u8 *buffer2,
+ size_t buffer2_len,
+ struct dmx_section_filter *source);
/*--------------------------------------------------------------------------*/
/* DVB Front-End */
/*--------------------------------------------------------------------------*/
+/**
+ * enum dmx_frontend_source - Used to identify the type of frontend
+ *
+ * @DMX_MEMORY_FE: The source of the demux is memory. It means that
+ * the MPEG-TS to be filtered comes from userspace,
+ * via write() syscall.
+ *
+ * @DMX_FRONTEND_0: The source of the demux is a frontend connected
+ * to the demux.
+ */
enum dmx_frontend_source {
DMX_MEMORY_FE,
DMX_FRONTEND_0,
- DMX_FRONTEND_1,
- DMX_FRONTEND_2,
- DMX_FRONTEND_3,
- DMX_STREAM_0, /* external stream input, e.g. LVDS */
- DMX_STREAM_1,
- DMX_STREAM_2,
- DMX_STREAM_3
};
+/**
+ * struct dmx_frontend - Structure that lists the frontends associated with
+ * a demux
+ *
+ * @connectivity_list: List of front-ends that can be connected to a
+ * particular demux;
+ * @source: Type of the frontend.
+ *
+ * FIXME: this structure should likely be replaced soon by some
+ * media-controller based logic.
+ */
struct dmx_frontend {
- struct list_head connectivity_list; /* List of front-ends that can
- be connected to a particular
- demux */
+ struct list_head connectivity_list;
enum dmx_frontend_source source;
};
-/*--------------------------------------------------------------------------*/
-/* MPEG-2 TS Demux */
-/*--------------------------------------------------------------------------*/
-
/*
- * Flags OR'ed in the capabilities field of struct dmx_demux.
+ * MPEG-2 TS Demux
*/
-#define DMX_TS_FILTERING 1
-#define DMX_PES_FILTERING 2
-#define DMX_SECTION_FILTERING 4
-#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
-#define DMX_CRC_CHECKING 16
-#define DMX_TS_DESCRAMBLING 32
+/**
+ * enum dmx_demux_caps - MPEG-2 TS Demux capabilities bitmap
+ *
+ * @DMX_TS_FILTERING: set if TS filtering is supported;
+ * @DMX_SECTION_FILTERING: set if section filtering is supported;
+ * @DMX_MEMORY_BASED_FILTERING: set if write() available.
+ *
+ * Those flags are OR'ed in the &dmx_demux.&capabilities field
+ */
+enum dmx_demux_caps {
+ DMX_TS_FILTERING = 1,
+ DMX_SECTION_FILTERING = 4,
+ DMX_MEMORY_BASED_FILTERING = 8,
+};
/*
* Demux resource type identifier.
@@ -200,42 +358,241 @@ struct dmx_frontend {
*.
*/
-#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
+#define DMX_FE_ENTRY(list) \
+ list_entry(list, struct dmx_frontend, connectivity_list)
+
+/**
+ * struct dmx_demux - Structure that contains the demux capabilities and
+ * callbacks.
+ *
+ * @capabilities: Bitfield of capability flags.
+ *
+ * @frontend: Front-end connected to the demux
+ *
+ * @priv: Pointer to private data of the API client
+ *
+ * @open: This function reserves the demux for use by the caller and, if
+ * necessary, initializes the demux. When the demux is no longer needed,
+ * the function @close should be called. It should be possible for
+ * multiple clients to access the demux at the same time. Thus, the
+ * function implementation should increment the demux usage count when
+ * @open is called and decrement it when @close is called.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -EUSERS, if maximum usage count was reached;
+ * -EINVAL, on bad parameter.
+ *
+ * @close: This function reserves the demux for use by the caller and, if
+ * necessary, initializes the demux. When the demux is no longer needed,
+ * the function @close should be called. It should be possible for
+ * multiple clients to access the demux at the same time. Thus, the
+ * function implementation should increment the demux usage count when
+ * @open is called and decrement it when @close is called.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -ENODEV, if demux was not in use (e. g. no users);
+ * -EINVAL, on bad parameter.
+ *
+ * @write: This function provides the demux driver with a memory buffer
+ * containing TS packets. Instead of receiving TS packets from the DVB
+ * front-end, the demux driver software will read packets from memory.
+ * Any clients of this demux with active TS, PES or Section filters will
+ * receive filtered data via the Demux callback API (see 0). The function
+ * returns when all the data in the buffer has been consumed by the demux.
+ * Demux hardware typically cannot read TS from memory. If this is the
+ * case, memory-based filtering has to be implemented entirely in software.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @buf function parameter contains a pointer to the TS data in
+ * kernel-space memory.
+ * The @count function parameter contains the length of the TS data.
+ * It returns
+ * 0 on success;
+ * -ERESTARTSYS, if mutex lock was interrupted;
+ * -EINTR, if a signal handling is pending;
+ * -ENODEV, if demux was removed;
+ * -EINVAL, on bad parameter.
+ *
+ * @allocate_ts_feed: Allocates a new TS feed, which is used to filter the TS
+ * packets carrying a certain PID. The TS feed normally corresponds to a
+ * hardware PID filter on the demux chip.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @feed function parameter contains a pointer to the TS feed API and
+ * instance data.
+ * The @callback function parameter contains a pointer to the callback
+ * function for passing received TS packet.
+ * It returns
+ * 0 on success;
+ * -ERESTARTSYS, if mutex lock was interrupted;
+ * -EBUSY, if no more TS feeds is available;
+ * -EINVAL, on bad parameter.
+ *
+ * @release_ts_feed: Releases the resources allocated with @allocate_ts_feed.
+ * Any filtering in progress on the TS feed should be stopped before
+ * calling this function.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @feed function parameter contains a pointer to the TS feed API and
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -EINVAL on bad parameter.
+ *
+ * @allocate_section_feed: Allocates a new section feed, i.e. a demux resource
+ * for filtering and receiving sections. On platforms with hardware
+ * support for section filtering, a section feed is directly mapped to
+ * the demux HW. On other platforms, TS packets are first PID filtered in
+ * hardware and a hardware section filter then emulated in software. The
+ * caller obtains an API pointer of type dmx_section_feed_t as an out
+ * parameter. Using this API the caller can set filtering parameters and
+ * start receiving sections.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @feed function parameter contains a pointer to the TS feed API and
+ * instance data.
+ * The @callback function parameter contains a pointer to the callback
+ * function for passing received TS packet.
+ * It returns
+ * 0 on success;
+ * -EBUSY, if no more TS feeds is available;
+ * -EINVAL, on bad parameter.
+ *
+ * @release_section_feed: Releases the resources allocated with
+ * @allocate_section_feed, including allocated filters. Any filtering in
+ * progress on the section feed should be stopped before calling this
+ * function.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @feed function parameter contains a pointer to the TS feed API and
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -EINVAL, on bad parameter.
+ *
+ * @add_frontend: Registers a connectivity between a demux and a front-end,
+ * i.e., indicates that the demux can be connected via a call to
+ * @connect_frontend to use the given front-end as a TS source. The
+ * client of this function has to allocate dynamic or static memory for
+ * the frontend structure and initialize its fields before calling this
+ * function. This function is normally called during the driver
+ * initialization. The caller must not free the memory of the frontend
+ * struct before successfully calling @remove_frontend.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @frontend function parameter contains a pointer to the front-end
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -EINVAL, on bad parameter.
+ *
+ * @remove_frontend: Indicates that the given front-end, registered by a call
+ * to @add_frontend, can no longer be connected as a TS source by this
+ * demux. The function should be called when a front-end driver or a demux
+ * driver is removed from the system. If the front-end is in use, the
+ * function fails with the return value of -EBUSY. After successfully
+ * calling this function, the caller can free the memory of the frontend
+ * struct if it was dynamically allocated before the @add_frontend
+ * operation.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @frontend function parameter contains a pointer to the front-end
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -ENODEV, if the front-end was not found,
+ * -EINVAL, on bad parameter.
+ *
+ * @get_frontends: Provides the APIs of the front-ends that have been
+ * registered for this demux. Any of the front-ends obtained with this
+ * call can be used as a parameter for @connect_frontend. The include
+ * file demux.h contains the macro DMX_FE_ENTRY() for converting an
+ * element of the generic type struct &list_head * to the type
+ * struct &dmx_frontend *. The caller must not free the memory of any of
+ * the elements obtained via this function call.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * It returns a struct list_head pointer to the list of front-end
+ * interfaces, or NULL in the case of an empty list.
+ *
+ * @connect_frontend: Connects the TS output of the front-end to the input of
+ * the demux. A demux can only be connected to a front-end registered to
+ * the demux with the function @add_frontend. It may or may not be
+ * possible to connect multiple demuxes to the same front-end, depending
+ * on the capabilities of the HW platform. When not used, the front-end
+ * should be released by calling @disconnect_frontend.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @frontend function parameter contains a pointer to the front-end
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -EINVAL, on bad parameter.
+ *
+ * @disconnect_frontend: Disconnects the demux and a front-end previously
+ * connected by a @connect_frontend call.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * It returns
+ * 0 on success;
+ * -EINVAL on bad parameter.
+ *
+ * @get_pes_pids: Get the PIDs for DMX_PES_AUDIO0, DMX_PES_VIDEO0,
+ * DMX_PES_TELETEXT0, DMX_PES_SUBTITLE0 and DMX_PES_PCR0.
+ * The @demux function parameter contains a pointer to the demux API and
+ * instance data.
+ * The @pids function parameter contains an array with five u16 elements
+ * where the PIDs will be stored.
+ * It returns
+ * 0 on success;
+ * -EINVAL on bad parameter.
+ */
struct dmx_demux {
- u32 capabilities; /* Bitfield of capability flags */
- struct dmx_frontend* frontend; /* Front-end connected to the demux */
- void* priv; /* Pointer to private data of the API client */
- int (*open) (struct dmx_demux* demux);
- int (*close) (struct dmx_demux* demux);
- int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count);
- int (*allocate_ts_feed) (struct dmx_demux* demux,
- struct dmx_ts_feed** feed,
- dmx_ts_cb callback);
- int (*release_ts_feed) (struct dmx_demux* demux,
- struct dmx_ts_feed* feed);
- int (*allocate_section_feed) (struct dmx_demux* demux,
- struct dmx_section_feed** feed,
- dmx_section_cb callback);
- int (*release_section_feed) (struct dmx_demux* demux,
- struct dmx_section_feed* feed);
- int (*add_frontend) (struct dmx_demux* demux,
- struct dmx_frontend* frontend);
- int (*remove_frontend) (struct dmx_demux* demux,
- struct dmx_frontend* frontend);
- struct list_head* (*get_frontends) (struct dmx_demux* demux);
- int (*connect_frontend) (struct dmx_demux* demux,
- struct dmx_frontend* frontend);
- int (*disconnect_frontend) (struct dmx_demux* demux);
-
- int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
-
- int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
-
- int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
-
- int (*get_stc) (struct dmx_demux* demux, unsigned int num,
- u64 *stc, unsigned int *base);
+ enum dmx_demux_caps capabilities;
+ struct dmx_frontend *frontend;
+ void *priv;
+ int (*open)(struct dmx_demux *demux);
+ int (*close)(struct dmx_demux *demux);
+ int (*write)(struct dmx_demux *demux, const char __user *buf,
+ size_t count);
+ int (*allocate_ts_feed)(struct dmx_demux *demux,
+ struct dmx_ts_feed **feed,
+ dmx_ts_cb callback);
+ int (*release_ts_feed)(struct dmx_demux *demux,
+ struct dmx_ts_feed *feed);
+ int (*allocate_section_feed)(struct dmx_demux *demux,
+ struct dmx_section_feed **feed,
+ dmx_section_cb callback);
+ int (*release_section_feed)(struct dmx_demux *demux,
+ struct dmx_section_feed *feed);
+ int (*add_frontend)(struct dmx_demux *demux,
+ struct dmx_frontend *frontend);
+ int (*remove_frontend)(struct dmx_demux *demux,
+ struct dmx_frontend *frontend);
+ struct list_head *(*get_frontends)(struct dmx_demux *demux);
+ int (*connect_frontend)(struct dmx_demux *demux,
+ struct dmx_frontend *frontend);
+ int (*disconnect_frontend)(struct dmx_demux *demux);
+
+ int (*get_pes_pids)(struct dmx_demux *demux, u16 *pids);
+
+ /* private: Not used upstream and never documented */
+#if 0
+ int (*get_caps)(struct dmx_demux *demux, struct dmx_caps *caps);
+ int (*set_source)(struct dmx_demux *demux, const dmx_source_t *src);
+#endif
+ /*
+ * private: Only used at av7110, to read some data from firmware.
+ * As this was never documented, we have no clue about what's
+ * there, and its usage on other drivers aren't encouraged.
+ */
+ int (*get_stc)(struct dmx_demux *demux, unsigned int num,
+ u64 *stc, unsigned int *base);
};
#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index d0e3f9d85f34..ea9abde902e9 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -352,8 +352,7 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
- struct dmx_section_filter *filter,
- enum dmx_success success)
+ struct dmx_section_filter *filter)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
int ret;
@@ -386,8 +385,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
- struct dmx_ts_feed *feed,
- enum dmx_success success)
+ struct dmx_ts_feed *feed)
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
@@ -1023,6 +1021,9 @@ static int dvb_demux_do_ioctl(struct file *file,
dmxdev->demux->get_pes_pids(dmxdev->demux, parg);
break;
+#if 0
+ /* Not used upstream and never documented */
+
case DMX_GET_CAPS:
if (!dmxdev->demux->get_caps) {
ret = -EINVAL;
@@ -1038,6 +1039,7 @@ static int dvb_demux_do_ioctl(struct file *file,
}
ret = dmxdev->demux->set_source(dmxdev->demux, parg);
break;
+#endif
case DMX_GET_STC:
if (!dmxdev->demux->get_stc) {
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index c117fb3b4aff..0a46580b5376 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -257,6 +257,7 @@
#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
#define USB_PID_TERRATEC_H7 0x10b4
#define USB_PID_TERRATEC_H7_2 0x10a3
+#define USB_PID_TERRATEC_H7_3 0x10a5
#define USB_PID_TERRATEC_T3 0x10a0
#define USB_PID_TERRATEC_T5 0x10a1
#define USB_PID_NOXON_DAB_STICK 0x00b3
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb-core/dvb_ca_en50221.h
index aba3b4fbd704..1e4bbbd34d91 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb-core/dvb_ca_en50221.h
@@ -12,10 +12,6 @@
* 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 Lesser 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.
*/
#ifndef _DVB_CA_EN50221_H_
@@ -37,50 +33,53 @@
#define DVB_CA_EN50221_CAMCHANGE_REMOVED 0
#define DVB_CA_EN50221_CAMCHANGE_INSERTED 1
-
-
-/* Structure describing a CA interface */
+/**
+ * struct dvb_ca_en50221- Structure describing a CA interface
+ *
+ * @owner: the module owning this structure
+ * @read_attribute_mem: function for reading attribute memory on the CAM
+ * @write_attribute_mem: function for writing attribute memory on the CAM
+ * @read_cam_control: function for reading the control interface on the CAM
+ * @write_cam_control: function for reading the control interface on the CAM
+ * @slot_reset: function to reset the CAM slot
+ * @slot_shutdown: function to shutdown a CAM slot
+ * @slot_ts_enable: function to enable the Transport Stream on a CAM slot
+ * @poll_slot_status: function to poll slot status. Only necessary if
+ * DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set.
+ * @data: private data, used by caller.
+ * @private: Opaque data used by the dvb_ca core. Do not modify!
+ *
+ * NOTE: the read_*, write_* and poll_slot_status functions will be
+ * called for different slots concurrently and need to use locks where
+ * and if appropriate. There will be no concurrent access to one slot.
+ */
struct dvb_ca_en50221 {
+ struct module *owner;
- /* the module owning this structure */
- struct module* owner;
-
- /* NOTE: the read_*, write_* and poll_slot_status functions will be
- * called for different slots concurrently and need to use locks where
- * and if appropriate. There will be no concurrent access to one slot.
- */
+ int (*read_attribute_mem)(struct dvb_ca_en50221 *ca,
+ int slot, int address);
+ int (*write_attribute_mem)(struct dvb_ca_en50221 *ca,
+ int slot, int address, u8 value);
- /* functions for accessing attribute memory on the CAM */
- int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
- int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value);
+ int (*read_cam_control)(struct dvb_ca_en50221 *ca,
+ int slot, u8 address);
+ int (*write_cam_control)(struct dvb_ca_en50221 *ca,
+ int slot, u8 address, u8 value);
- /* functions for accessing the control interface on the CAM */
- int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address);
- int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value);
+ int (*slot_reset)(struct dvb_ca_en50221 *ca, int slot);
+ int (*slot_shutdown)(struct dvb_ca_en50221 *ca, int slot);
+ int (*slot_ts_enable)(struct dvb_ca_en50221 *ca, int slot);
- /* Functions for controlling slots */
- int (*slot_reset)(struct dvb_ca_en50221* ca, int slot);
- int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot);
- int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot);
+ int (*poll_slot_status)(struct dvb_ca_en50221 *ca, int slot, int open);
- /*
- * Poll slot status.
- * Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set
- */
- int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open);
+ void *data;
- /* private data, used by caller */
- void* data;
-
- /* Opaque data used by the dvb_ca core. Do not modify! */
- void* private;
+ void *private;
};
-
-
-
-/* ******************************************************************************** */
-/* Functions for reporting IRQ events */
+/*
+ * Functions for reporting IRQ events
+ */
/**
* dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
@@ -89,7 +88,8 @@ struct dvb_ca_en50221 {
* @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values
*/
-void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
+void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot,
+ int change_type);
/**
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
@@ -97,7 +97,7 @@ void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int ch
* @pubca: CA instance.
* @slot: Slot concerned.
*/
-void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
+void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot);
/**
* dvb_ca_en50221_frda_irq - An FR or a DA IRQ has occurred.
@@ -105,12 +105,11 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
* @ca: CA instance.
* @slot: Slot concerned.
*/
-void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
-
+void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *ca, int slot);
-
-/* ******************************************************************************** */
-/* Initialisation/shutdown functions */
+/*
+ * Initialisation/shutdown functions
+ */
/**
* dvb_ca_en50221_init - Initialise a new DVB CA device.
@@ -122,15 +121,15 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
*
* @return 0 on success, nonzero on failure
*/
-extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
+extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
+ struct dvb_ca_en50221 *ca, int flags,
+ int slot_count);
/**
* dvb_ca_en50221_release - Release a DVB CA device.
*
* @ca: The associated dvb_ca instance.
*/
-extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);
-
-
+extern void dvb_ca_en50221_release(struct dvb_ca_en50221 *ca);
#endif
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index 6c7ff0cdcd32..0cc5e935166c 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -130,7 +130,7 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
feed->peslen += count;
- return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
+ return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts);
}
static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
@@ -152,7 +152,7 @@ static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
return 0;
return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
- NULL, 0, &f->filter, DMX_OK);
+ NULL, 0, &f->filter);
}
static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
@@ -367,8 +367,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
if (feed->ts_type & TS_PAYLOAD_ONLY)
dvb_dmx_swfilter_payload(feed, buf);
else
- feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
- DMX_OK);
+ feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
}
if (feed->ts_type & TS_DECODER)
if (feed->demux->write_to_decoder)
@@ -469,7 +468,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
if (feed->pid == pid)
dvb_dmx_swfilter_packet_type(feed, buf);
else if (feed->pid == 0x2000)
- feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
+ feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
}
}
@@ -588,7 +587,7 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
spin_lock_irqsave(&demux->lock, flags);
- demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK);
+ demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts);
spin_unlock_irqrestore(&demux->lock, flags);
}
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index b81e026edab3..ce4332e80a91 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -761,7 +761,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
- struct dmx_ts_feed *feed, enum dmx_success success)
+ struct dmx_ts_feed *feed)
{
struct net_device *dev = feed->priv;
@@ -870,8 +870,7 @@ static void dvb_net_sec(struct net_device *dev,
static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
- struct dmx_section_filter *filter,
- enum dmx_success success)
+ struct dmx_section_filter *filter)
{
struct net_device *dev = filter->priv;
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index c61a4f03a66f..1069a776bbdb 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -184,10 +184,6 @@ int dvb_unregister_adapter(struct dvb_adapter *adap);
* @pdvbdev: pointer to the place where the new struct dvb_device will be
* stored
* @template: Template used to create &pdvbdev;
- * @device: pointer to struct device that corresponds to the device driver
- * @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
- * to select among them. Typically, initialized with:
- * DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
* @priv: private data
* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index 34b9441840da..445a15c2714f 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -2950,10 +2950,9 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config,
{
struct drxd_state *state = NULL;
- state = kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return NULL;
- memset(state, 0, sizeof(*state));
state->ops = drxd_ops;
state->dev = dev;
diff --git a/drivers/media/dvb-frontends/horus3a.h b/drivers/media/dvb-frontends/horus3a.h
index b055319d532e..c1e2d1834b78 100644
--- a/drivers/media/dvb-frontends/horus3a.h
+++ b/drivers/media/dvb-frontends/horus3a.h
@@ -46,8 +46,8 @@ extern struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
const struct horus3a_config *config,
struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend *horus3a_attach(
- const struct cxd2820r_config *config,
+static inline struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
+ const struct horus3a_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb-frontends/lnbh25.h b/drivers/media/dvb-frontends/lnbh25.h
index 69f30e21f6b3..1f329ef05acc 100644
--- a/drivers/media/dvb-frontends/lnbh25.h
+++ b/drivers/media/dvb-frontends/lnbh25.h
@@ -43,7 +43,7 @@ struct dvb_frontend *lnbh25_attach(
struct lnbh25_config *cfg,
struct i2c_adapter *i2c);
#else
-static inline dvb_frontend *lnbh25_attach(
+static inline struct dvb_frontend *lnbh25_attach(
struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index ff31e7a01ca9..feeeb70d841e 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -18,6 +18,27 @@
static struct dvb_frontend_ops m88ds3103_ops;
+/* write single register with mask */
+static int m88ds3103_update_bits(struct m88ds3103_dev *dev,
+ u8 reg, u8 mask, u8 val)
+{
+ int ret;
+ u8 tmp;
+
+ /* no need for read if whole reg is written */
+ if (mask != 0xff) {
+ ret = regmap_bulk_read(dev->regmap, reg, &tmp, 1);
+ if (ret)
+ return ret;
+
+ val &= mask;
+ tmp &= ~mask;
+ val |= tmp;
+ }
+
+ return regmap_bulk_write(dev->regmap, reg, &val, 1);
+}
+
/* write reg val table using reg addr auto increment */
static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev,
const struct m88ds3103_reg_val *tab, int tab_len)
@@ -394,10 +415,10 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
u8tmp2 = 0x00; /* 0b00 */
break;
}
- ret = regmap_update_bits(dev->regmap, 0x22, 0xc0, u8tmp1 << 6);
+ ret = m88ds3103_update_bits(dev, 0x22, 0xc0, u8tmp1 << 6);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x24, 0xc0, u8tmp2 << 6);
+ ret = m88ds3103_update_bits(dev, 0x24, 0xc0, u8tmp2 << 6);
if (ret)
goto err;
}
@@ -455,13 +476,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
}
- ret = regmap_update_bits(dev->regmap, 0x9d, 0x08, 0x08);
+ ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);
if (ret)
goto err;
ret = regmap_write(dev->regmap, 0xf1, 0x01);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x30, 0x80, 0x80);
+ ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
if (ret)
goto err;
}
@@ -498,7 +519,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
switch (dev->cfg->ts_mode) {
case M88DS3103_TS_SERIAL:
case M88DS3103_TS_SERIAL_D7:
- ret = regmap_update_bits(dev->regmap, 0x29, 0x20, u8tmp1);
+ ret = m88ds3103_update_bits(dev, 0x29, 0x20, u8tmp1);
if (ret)
goto err;
u8tmp1 = 0;
@@ -567,11 +588,11 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x4d, 0x02, dev->cfg->spec_inv << 1);
+ ret = m88ds3103_update_bits(dev, 0x4d, 0x02, dev->cfg->spec_inv << 1);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x30, 0x10, dev->cfg->agc_inv << 4);
+ ret = m88ds3103_update_bits(dev, 0x30, 0x10, dev->cfg->agc_inv << 4);
if (ret)
goto err;
@@ -625,13 +646,13 @@ static int m88ds3103_init(struct dvb_frontend *fe)
dev->warm = false;
/* wake up device from sleep */
- ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x01);
+ ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x01);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x00);
+ ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x00);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x00);
+ ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x00);
if (ret)
goto err;
@@ -749,18 +770,18 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
utmp = 0x29;
else
utmp = 0x27;
- ret = regmap_update_bits(dev->regmap, utmp, 0x01, 0x00);
+ ret = m88ds3103_update_bits(dev, utmp, 0x01, 0x00);
if (ret)
goto err;
/* sleep */
- ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00);
+ ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01);
+ ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
if (ret)
goto err;
- ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10);
+ ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
if (ret)
goto err;
@@ -992,12 +1013,12 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
}
utmp = tone << 7 | dev->cfg->envelope_mode << 5;
- ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+ ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
if (ret)
goto err;
utmp = 1 << 2;
- ret = regmap_update_bits(dev->regmap, 0xa1, reg_a1_mask, utmp);
+ ret = m88ds3103_update_bits(dev, 0xa1, reg_a1_mask, utmp);
if (ret)
goto err;
@@ -1047,7 +1068,7 @@ static int m88ds3103_set_voltage(struct dvb_frontend *fe,
voltage_dis ^= dev->cfg->lnb_en_pol;
utmp = voltage_dis << 1 | voltage_sel << 0;
- ret = regmap_update_bits(dev->regmap, 0xa2, 0x03, utmp);
+ ret = m88ds3103_update_bits(dev, 0xa2, 0x03, utmp);
if (ret)
goto err;
@@ -1080,7 +1101,7 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
}
utmp = dev->cfg->envelope_mode << 5;
- ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+ ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
if (ret)
goto err;
@@ -1115,12 +1136,12 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
} else {
dev_dbg(&client->dev, "diseqc tx timeout\n");
- ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40);
+ ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
if (ret)
goto err;
}
- ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80);
+ ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
if (ret)
goto err;
@@ -1152,7 +1173,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
}
utmp = dev->cfg->envelope_mode << 5;
- ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+ ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
if (ret)
goto err;
@@ -1194,12 +1215,12 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
} else {
dev_dbg(&client->dev, "diseqc tx timeout\n");
- ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40);
+ ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
if (ret)
goto err;
}
- ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80);
+ ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
if (ret)
goto err;
@@ -1435,13 +1456,13 @@ static int m88ds3103_probe(struct i2c_client *client,
goto err_kfree;
/* sleep */
- ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00);
+ ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
if (ret)
goto err_kfree;
- ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01);
+ ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
if (ret)
goto err_kfree;
- ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10);
+ ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
if (ret)
goto err_kfree;
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index d5b994f17612..dcd8d94c1037 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -29,6 +29,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <linux/platform_device.h>
@@ -107,7 +108,8 @@ static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
/* intermediate buffers with raw data from the USB device */
struct rtl2832_sdr_frame_buf {
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -304,13 +306,13 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
}
/* fill framebuffer */
- ptr = vb2_plane_vaddr(&fbuf->vb, 0);
+ ptr = vb2_plane_vaddr(&fbuf->vb.vb2_buf, 0);
len = rtl2832_sdr_convert_stream(dev, ptr, urb->transfer_buffer,
urb->actual_length);
- vb2_set_plane_payload(&fbuf->vb, 0, len);
- v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);
- fbuf->vb.v4l2_buf.sequence = dev->sequence++;
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len);
+ v4l2_get_timestamp(&fbuf->vb.timestamp);
+ fbuf->vb.sequence = dev->sequence++;
+ vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
skip:
usb_submit_urb(urb, GFP_ATOMIC);
@@ -464,7 +466,7 @@ static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_dev *dev)
buf = list_entry(dev->queued_bufs.next,
struct rtl2832_sdr_frame_buf, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);
}
@@ -488,7 +490,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
/* Videobuf2 operations */
static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbuffers,
+ const void *parg, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
struct rtl2832_sdr_dev *dev = vb2_get_drv_priv(vq);
@@ -518,14 +520,15 @@ static int rtl2832_sdr_buf_prepare(struct vb2_buffer *vb)
static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct rtl2832_sdr_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
struct rtl2832_sdr_frame_buf *buf =
- container_of(vb, struct rtl2832_sdr_frame_buf, vb);
+ container_of(vbuf, struct rtl2832_sdr_frame_buf, vb);
unsigned long flags;
/* Check the device has not disconnected between prep and queuing */
if (!dev->udev) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
return;
}
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 81788c5a44d8..821a8f481507 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -502,6 +502,10 @@ static int si2168_init(struct dvb_frontend *fe)
/* firmware is in the new format */
for (remaining = fw->size; remaining > 0; remaining -= 17) {
len = fw->data[fw->size - remaining];
+ if (len > SI2168_ARGLEN) {
+ ret = -EINVAL;
+ break;
+ }
memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
cmd.wlen = len;
cmd.rlen = 1;
diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c
index af5eaf2db2a0..38a20fe181ee 100644
--- a/drivers/media/i2c/ml86v7667.c
+++ b/drivers/media/i2c/ml86v7667.c
@@ -233,6 +233,15 @@ static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd,
return 0;
}
+static int ml86v7667_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+ *std = priv->std;
+
+ return 0;
+}
+
static int ml86v7667_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct ml86v7667_priv *priv = to_ml86v7667(sd);
@@ -282,6 +291,7 @@ static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
};
static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
+ .g_std = ml86v7667_g_std,
.s_std = ml86v7667_s_std,
.querystd = ml86v7667_querystd,
.g_input_status = ml86v7667_g_input_status,
@@ -427,7 +437,6 @@ MODULE_DEVICE_TABLE(i2c, ml86v7667_id);
static struct i2c_driver ml86v7667_i2c_driver = {
.driver = {
.name = DRV_NAME,
- .owner = THIS_MODULE,
},
.probe = ml86v7667_probe,
.remove = ml86v7667_remove,
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index e691bba1945b..1ee6a5527c38 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1133,7 +1133,7 @@ static int __ov965x_set_frame_interval(struct ov965x *ov965x,
if (mbus_fmt->width != iv->size.width ||
mbus_fmt->height != iv->size.height)
continue;
- err = abs64((u64)(iv->interval.numerator * 10000) /
+ err = abs((u64)(iv->interval.numerator * 10000) /
iv->interval.denominator - req_int);
if (err < min_err) {
fiv = iv;
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 53c5ea89f0b9..51b26010403c 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -167,7 +167,7 @@ static int s5c73m3_i2c_read(struct i2c_client *client, u16 addr, u16 *data)
*/
ret = i2c_transfer(client->adapter, msg, 2);
if (ret == 2) {
- *data = be16_to_cpup((u16 *)rbuf);
+ *data = be16_to_cpup((__be16 *)rbuf);
v4l2_dbg(4, s5c73m3_dbg, client,
"%s: addr: 0x%04x, data: 0x%04x\n",
__func__, addr, *data);
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
index fa4a5ebda6b2..72ef9f936e6c 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
@@ -31,6 +31,7 @@ static const struct of_device_id s5c73m3_spi_ids[] = {
{ .compatible = "samsung,s5c73m3" },
{ }
};
+MODULE_DEVICE_TABLE(of, s5c73m3_spi_ids);
enum spi_direction {
SPI_DIR_RX,
@@ -149,7 +150,6 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
spidrv->remove = s5c73m3_spi_remove;
spidrv->probe = s5c73m3_spi_probe;
spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
- spidrv->driver.owner = THIS_MODULE;
spidrv->driver.of_match_table = s5c73m3_spi_ids;
return spi_register_driver(spidrv);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 636ebd6fe5dc..fb39dfd55e75 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -3131,6 +3131,7 @@ static const struct of_device_id smiapp_of_table[] = {
{ .compatible = "nokia,smia" },
{ },
};
+MODULE_DEVICE_TABLE(of, smiapp_of_table);
static const struct i2c_device_id smiapp_id_table[] = {
{ SMIAPP_NAME, 0 },
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 522a865c5c60..3c5fb2509c47 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -10,6 +10,7 @@
#include <linux/videodev2.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/tvp5150.h>
#include <media/v4l2-ctrls.h>
@@ -1172,8 +1173,7 @@ static int tvp5150_probe(struct i2c_client *c,
sd->ctrl_handler = &core->hdl;
if (core->hdl.error) {
res = core->hdl.error;
- v4l2_ctrl_handler_free(&core->hdl);
- return res;
+ goto err;
}
v4l2_ctrl_handler_setup(&core->hdl);
@@ -1186,9 +1186,17 @@ static int tvp5150_probe(struct i2c_client *c,
core->rect.left = 0;
core->rect.width = TVP5150_H_MAX;
+ res = v4l2_async_register_subdev(sd);
+ if (res < 0)
+ goto err;
+
if (debug > 1)
tvp5150_log_status(sd);
return 0;
+
+err:
+ v4l2_ctrl_handler_free(&core->hdl);
+ return res;
}
static int tvp5150_remove(struct i2c_client *c)
@@ -1200,7 +1208,7 @@ static int tvp5150_remove(struct i2c_client *c)
"tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
c->addr << 1);
- v4l2_device_unregister_subdev(sd);
+ v4l2_async_unregister_subdev(sd);
v4l2_ctrl_handler_free(&decoder->hdl);
return 0;
}
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 153a46469814..767fe55ba08e 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -235,8 +235,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
media_entity_graph_walk_start(&graph, entity);
while ((entity = media_entity_graph_walk_next(&graph))) {
- DECLARE_BITMAP(active, entity->num_pads);
- DECLARE_BITMAP(has_no_links, entity->num_pads);
+ DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
+ DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
unsigned int i;
entity->stream_count++;
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 3632958f2158..15a4ebc2844d 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3625,13 +3625,10 @@ static void
bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
unsigned int state)
{
- struct timeval ts;
-
if (NULL == wakeup)
return;
- v4l2_get_timestamp(&ts);
- wakeup->vb.ts = ts;
+ v4l2_get_timestamp(&wakeup->vb.ts);
wakeup->vb.field_count = btv->field_count;
wakeup->vb.state = state;
wake_up(&wakeup->vb.done);
diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig
index 1f88ccc174da..a01f0cc745cc 100644
--- a/drivers/media/pci/cobalt/Kconfig
+++ b/drivers/media/pci/cobalt/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_COBALT
tristate "Cisco Cobalt support"
- depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER
+ depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
depends on PCI_MSI && MTD_COMPLEX_MAPPINGS
depends on GPIOLIB || COMPILE_TEST
depends on SND
diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c
index e83f5c9f7e7d..23c875fc173e 100644
--- a/drivers/media/pci/cobalt/cobalt-cpld.c
+++ b/drivers/media/pci/cobalt/cobalt-cpld.c
@@ -290,8 +290,8 @@ bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out)
0x01, 0xc7, 0xfc, 0x7f, 0x53, 0x62).
*/
- cobalt_dbg(1, "%u: %02x %02x %02x %02x %02x %02x\n", f_out,
- regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]);
+ cobalt_dbg(1, "%u: %6ph\n", f_out, regs);
+
while (retries--) {
u8 read_regs[6];
@@ -330,9 +330,7 @@ bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out)
if (!memcmp(read_regs, regs, sizeof(read_regs)))
break;
- cobalt_dbg(1, "retry: %02x %02x %02x %02x %02x %02x\n",
- read_regs[0], read_regs[1], read_regs[2],
- read_regs[3], read_regs[4], read_regs[5]);
+ cobalt_dbg(1, "retry: %6ph\n", read_regs);
}
if (2 - retries)
cobalt_info("Needed %d retries\n", 2 - retries);
diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h
index c206df930669..b2f08e4a68bf 100644
--- a/drivers/media/pci/cobalt/cobalt-driver.h
+++ b/drivers/media/pci/cobalt/cobalt-driver.h
@@ -35,6 +35,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fh.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-sg.h>
#include "m00233_video_measure_memmap_package.h"
@@ -206,11 +207,12 @@ struct sg_dma_desc_info {
#define COBALT_STREAM_FL_ADV_IRQ 1
struct cobalt_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
-static inline struct cobalt_buffer *to_cobalt_buffer(struct vb2_buffer *vb2)
+static inline
+struct cobalt_buffer *to_cobalt_buffer(struct vb2_v4l2_buffer *vb2)
{
return container_of(vb2, struct cobalt_buffer, vb);
}
diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c
index d1f5898d11ba..3de26d0714b5 100644
--- a/drivers/media/pci/cobalt/cobalt-irq.c
+++ b/drivers/media/pci/cobalt/cobalt-irq.c
@@ -134,11 +134,12 @@ done:
skip = true;
s->skip_first_frames--;
}
- v4l2_get_timestamp(&cb->vb.v4l2_buf.timestamp);
+ v4l2_get_timestamp(&cb->vb.timestamp);
/* TODO: the sequence number should be read from the FPGA so we
also know about dropped frames. */
- cb->vb.v4l2_buf.sequence = s->sequence++;
- vb2_buffer_done(&cb->vb, (skip || s->unstable_frame) ?
+ cb->vb.sequence = s->sequence++;
+ vb2_buffer_done(&cb->vb.vb2_buf,
+ (skip || s->unstable_frame) ?
VB2_BUF_STATE_REQUEUEING : VB2_BUF_STATE_DONE);
}
diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c
index 9756fd3e8af5..ff46e424262f 100644
--- a/drivers/media/pci/cobalt/cobalt-v4l2.c
+++ b/drivers/media/pci/cobalt/cobalt-v4l2.c
@@ -43,11 +43,11 @@ static const struct v4l2_dv_timings cea1080p60 = V4L2_DV_BT_CEA_1920X1080P60;
/* vb2 DMA streaming ops */
-static int cobalt_queue_setup(struct vb2_queue *q,
- const struct v4l2_format *fmt,
+static int cobalt_queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct cobalt_stream *s = q->drv_priv;
unsigned size = s->stride * s->height;
@@ -75,7 +75,7 @@ static int cobalt_buf_init(struct vb2_buffer *vb)
const size_t bytes =
COBALT_MAX_HEIGHT * max_pages_per_line * 0x20;
const size_t audio_bytes = ((1920 * 4) / PAGE_SIZE + 1) * 0x20;
- struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->v4l2_buf.index];
+ struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->index];
struct sg_table *sg_desc = vb2_dma_sg_plane_desc(vb, 0);
unsigned size;
int ret;
@@ -105,17 +105,18 @@ static int cobalt_buf_init(struct vb2_buffer *vb)
static void cobalt_buf_cleanup(struct vb2_buffer *vb)
{
struct cobalt_stream *s = vb->vb2_queue->drv_priv;
- struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->v4l2_buf.index];
+ struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->index];
descriptor_list_free(desc);
}
static int cobalt_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cobalt_stream *s = vb->vb2_queue->drv_priv;
vb2_set_plane_payload(vb, 0, s->stride * s->height);
- vb->v4l2_buf.field = V4L2_FIELD_NONE;
+ vbuf->field = V4L2_FIELD_NONE;
return 0;
}
@@ -128,7 +129,7 @@ static void chain_all_buffers(struct cobalt_stream *s)
list_for_each(p, &s->bufs) {
cb = list_entry(p, struct cobalt_buffer, list);
- desc[i] = &s->dma_desc_info[cb->vb.v4l2_buf.index];
+ desc[i] = &s->dma_desc_info[cb->vb.vb2_buf.index];
if (i > 0)
descriptor_list_chain(desc[i-1], desc[i]);
i++;
@@ -137,10 +138,11 @@ static void chain_all_buffers(struct cobalt_stream *s)
static void cobalt_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *q = vb->vb2_queue;
struct cobalt_stream *s = q->drv_priv;
- struct cobalt_buffer *cb = to_cobalt_buffer(vb);
- struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->v4l2_buf.index];
+ struct cobalt_buffer *cb = to_cobalt_buffer(vbuf);
+ struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->index];
unsigned long flags;
/* Prepare new buffer */
@@ -284,7 +286,7 @@ static void cobalt_dma_start_streaming(struct cobalt_stream *s)
&vo->control);
}
cb = list_first_entry(&s->bufs, struct cobalt_buffer, list);
- omni_sg_dma_start(s, &s->dma_desc_info[cb->vb.v4l2_buf.index]);
+ omni_sg_dma_start(s, &s->dma_desc_info[cb->vb.vb2_buf.index]);
spin_unlock_irqrestore(&s->irqlock, flags);
}
@@ -381,7 +383,7 @@ static void cobalt_dma_stop_streaming(struct cobalt_stream *s)
spin_lock_irqsave(&s->irqlock, flags);
list_for_each(p, &s->bufs) {
cb = list_entry(p, struct cobalt_buffer, list);
- desc = &s->dma_desc_info[cb->vb.v4l2_buf.index];
+ desc = &s->dma_desc_info[cb->vb.vb2_buf.index];
/* Stop DMA after this descriptor chain */
descriptor_list_end_of_chain(desc);
}
@@ -416,7 +418,7 @@ static void cobalt_stop_streaming(struct vb2_queue *q)
list_for_each_safe(p, safe, &s->bufs) {
cb = list_entry(p, struct cobalt_buffer, list);
list_del(&cb->list);
- vb2_buffer_done(&cb->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&cb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&s->irqlock, flags);
diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
index eabf00c6351b..1f8aa9a749a1 100644
--- a/drivers/media/pci/cx18/cx18-mailbox.c
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
@@ -202,7 +202,7 @@ static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
}
if (dispatch) {
- vb_buf->vb.ts = ktime_to_timeval(ktime_get());
+ v4l2_get_timestamp(&vb_buf->vb.ts);
list_del(&vb_buf->vb.queue);
vb_buf->vb.state = VIDEOBUF_DONE;
wake_up(&vb_buf->vb.done);
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 63c0ee5d0bf5..88a3afb66d10 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1138,7 +1138,7 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -1155,17 +1155,19 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
+ container_of(vbuf, struct cx23885_buffer, vb);
return cx23885_buf_prepare(buf, &dev->ts1);
}
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
- struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_free_buffer(dev, buf);
@@ -1173,8 +1175,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
- struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_buf_queue(&dev->ts1, buf);
@@ -1201,7 +1204,7 @@ static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
struct cx23885_buffer, queue);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
}
spin_unlock_irqrestore(&dev->slock, flags);
return ret;
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 7aee76af7a85..e8f847226a19 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -427,12 +427,13 @@ static void cx23885_wakeup(struct cx23885_tsport *port,
buf = list_entry(q->active.next,
struct cx23885_buffer, queue);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.sequence = q->count++;
- dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.sequence = q->count++;
+ dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
+ buf->vb.vb2_buf.index,
count, q->count);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
int cx23885_sram_channel_setup(struct cx23885_dev *dev,
@@ -1453,12 +1454,12 @@ int cx23885_buf_prepare(struct cx23885_buffer *buf, struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
int size = port->ts_packet_size * port->ts_packet_count;
- struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0);
dprintk(1, "%s: %p\n", __func__, buf);
- if (vb2_plane_size(&buf->vb, 0) < size)
+ if (vb2_plane_size(&buf->vb.vb2_buf, 0) < size)
return -EINVAL;
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
cx23885_risc_databuffer(dev->pci, &buf->risc,
sgt->sgl,
@@ -1503,7 +1504,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
if (list_empty(&cx88q->active)) {
list_add_tail(&buf->queue, &cx88q->active);
dprintk(1, "[%p/%d] %s - first active\n",
- buf, buf->vb.v4l2_buf.index, __func__);
+ buf, buf->vb.vb2_buf.index, __func__);
} else {
buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
@@ -1511,7 +1512,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
list_add_tail(&buf->queue, &cx88q->active);
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk(1, "[%p/%d] %s - append to active\n",
- buf, buf->vb.v4l2_buf.index, __func__);
+ buf, buf->vb.vb2_buf.index, __func__);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
@@ -1530,9 +1531,10 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason)
buf = list_entry(q->active.next, struct cx23885_buffer,
queue);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(1, "[%p/%d] %s - dma=0x%08lx\n",
- buf, buf->vb.v4l2_buf.index, reason, (unsigned long)buf->risc.dma);
+ buf, buf->vb.vb2_buf.index, reason,
+ (unsigned long)buf->risc.dma);
}
spin_unlock_irqrestore(&port->slock, flags);
}
@@ -1990,9 +1992,9 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
(unsigned long long)pci_resource_start(pci_dev, 0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+ err = pci_set_dma_mask(pci_dev, 0xffffffff);
+ if (err) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
goto fail_context;
}
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 6e8c24cdb2cd..c4307ad8594c 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -92,7 +92,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -110,18 +110,20 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
+ container_of(vbuf, struct cx23885_buffer, vb);
return cx23885_buf_prepare(buf, port);
}
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
struct cx23885_dev *dev = port->dev;
- struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_free_buffer(dev, buf);
@@ -129,8 +131,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
- struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_buf_queue(port, buf);
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index d362d3838c84..cf3cb1324c55 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -121,7 +121,7 @@ static int cx23885_start_vbi_dma(struct cx23885_dev *dev,
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -138,8 +138,9 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
- struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
unsigned lines = VBI_PAL_LINE_COUNT;
@@ -161,7 +162,8 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb)
{
- struct cx23885_buffer *buf = container_of(vb,
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
@@ -190,8 +192,10 @@ static void buffer_finish(struct vb2_buffer *vb)
*/
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
- struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb);
+ struct cx23885_buffer *buf = container_of(vbuf,
+ struct cx23885_buffer, vb);
struct cx23885_buffer *prev;
struct cx23885_dmaqueue *q = &dev->vbiq;
unsigned long flags;
@@ -206,7 +210,7 @@ static void buffer_queue(struct vb2_buffer *vb)
list_add_tail(&buf->queue, &q->active);
spin_unlock_irqrestore(&dev->slock, flags);
dprintk(2, "[%p/%d] vbi_queue - first active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
} else {
buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
@@ -217,7 +221,7 @@ static void buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&dev->slock, flags);
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk(2, "[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
}
@@ -245,7 +249,7 @@ static void cx23885_stop_streaming(struct vb2_queue *q)
struct cx23885_buffer, queue);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ec76470d12a4..71a80e2b842c 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -104,12 +104,12 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
buf = list_entry(q->active.next,
struct cx23885_buffer, queue);
- buf->vb.v4l2_buf.sequence = q->count++;
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
- count, q->count);
+ buf->vb.sequence = q->count++;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
+ buf->vb.vb2_buf.index, count, q->count);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
@@ -315,7 +315,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
return 0;
}
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -329,9 +329,10 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf =
- container_of(vb, struct cx23885_buffer, vb);
+ container_of(vbuf, struct cx23885_buffer, vb);
u32 line0_offset, line1_offset;
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
int field_tff;
@@ -401,7 +402,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
BUG();
}
dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
- buf, buf->vb.v4l2_buf.index,
+ buf, buf->vb.vb2_buf.index,
dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
(unsigned long)buf->risc.dma);
return 0;
@@ -409,7 +410,8 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb)
{
- struct cx23885_buffer *buf = container_of(vb,
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
@@ -438,8 +440,9 @@ static void buffer_finish(struct vb2_buffer *vb)
*/
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
- struct cx23885_buffer *buf = container_of(vb,
+ struct cx23885_buffer *buf = container_of(vbuf,
struct cx23885_buffer, vb);
struct cx23885_buffer *prev;
struct cx23885_dmaqueue *q = &dev->vidq;
@@ -455,7 +458,7 @@ static void buffer_queue(struct vb2_buffer *vb)
if (list_empty(&q->active)) {
list_add_tail(&buf->queue, &q->active);
dprintk(2, "[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
} else {
buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
prev = list_entry(q->active.prev, struct cx23885_buffer,
@@ -463,7 +466,7 @@ static void buffer_queue(struct vb2_buffer *vb)
list_add_tail(&buf->queue, &q->active);
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk(2, "[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
@@ -492,7 +495,7 @@ static void cx23885_stop_streaming(struct vb2_queue *q)
struct cx23885_buffer, queue);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 027ead438194..c5ba0833f47a 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -170,7 +170,7 @@ struct cx23885_riscmem {
/* buffer for one video frame */
struct cx23885_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head queue;
/* cx23885 specific */
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index 24f964bcc53a..b602eba2b601 100644
--- a/drivers/media/pci/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
@@ -102,7 +102,7 @@ struct cx25821_audio_dev {
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = { 1, [1 ... (SNDRV_CARDS - 1)] = 1 };
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index 559f8293c53a..0042803a9de7 100644
--- a/drivers/media/pci/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
@@ -1319,7 +1319,8 @@ static int cx25821_initdev(struct pci_dev *pci_dev,
dev->pci_lat, (unsigned long long)dev->base_io_addr);
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+ err = pci_set_dma_mask(pci_dev, 0xffffffff);
+ if (err) {
pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
err = -EIO;
goto fail_irq;
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index 7bc495e4ece2..26e3e296d615 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -130,10 +130,10 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
buf = list_entry(dmaq->active.next,
struct cx25821_buffer, queue);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.sequence = dmaq->count++;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.sequence = dmaq->count++;
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
spin_unlock(&dev->slock);
handled++;
@@ -141,10 +141,11 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
return handled;
}
-static int cx25821_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int cx25821_queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct cx25821_channel *chan = q->drv_priv;
unsigned size = (chan->fmt->depth * chan->width * chan->height) >> 3;
@@ -159,10 +160,11 @@ static int cx25821_queue_setup(struct vb2_queue *q, const struct v4l2_format *fm
static int cx25821_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx25821_channel *chan = vb->vb2_queue->drv_priv;
struct cx25821_dev *dev = chan->dev;
struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
+ container_of(vbuf, struct cx25821_buffer, vb);
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
u32 line0_offset;
int bpl_local = LINE_SIZE_D1;
@@ -176,7 +178,7 @@ static int cx25821_buffer_prepare(struct vb2_buffer *vb)
if (vb2_plane_size(vb, 0) < chan->height * buf->bpl)
return -EINVAL;
vb2_set_plane_payload(vb, 0, chan->height * buf->bpl);
- buf->vb.v4l2_buf.field = chan->field;
+ buf->vb.field = chan->field;
if (chan->pixel_formats == PIXEL_FRMT_411) {
bpl_local = buf->bpl;
@@ -231,7 +233,7 @@ static int cx25821_buffer_prepare(struct vb2_buffer *vb)
}
dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
- buf, buf->vb.v4l2_buf.index, chan->width, chan->height,
+ buf, buf->vb.vb2_buf.index, chan->width, chan->height,
chan->fmt->depth, chan->fmt->name,
(unsigned long)buf->risc.dma);
@@ -240,8 +242,9 @@ static int cx25821_buffer_prepare(struct vb2_buffer *vb)
static void cx25821_buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
+ container_of(vbuf, struct cx25821_buffer, vb);
struct cx25821_channel *chan = vb->vb2_queue->drv_priv;
struct cx25821_dev *dev = chan->dev;
@@ -250,8 +253,9 @@ static void cx25821_buffer_finish(struct vb2_buffer *vb)
static void cx25821_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
+ container_of(vbuf, struct cx25821_buffer, vb);
struct cx25821_channel *chan = vb->vb2_queue->drv_priv;
struct cx25821_dev *dev = chan->dev;
struct cx25821_buffer *prev;
@@ -300,7 +304,7 @@ static void cx25821_stop_streaming(struct vb2_queue *q)
struct cx25821_buffer, queue);
list_del(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h
index d81a08a2df4f..a513b68be0fa 100644
--- a/drivers/media/pci/cx25821/cx25821.h
+++ b/drivers/media/pci/cx25821/cx25821.h
@@ -34,6 +34,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-sg.h>
#include "cx25821-reg.h"
@@ -127,7 +128,7 @@ struct cx25821_riscmem {
/* buffer for one video frame */
struct cx25821_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head queue;
/* cx25821 specific */
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c
index 7f8dc60028d5..1b5268f9bb24 100644
--- a/drivers/media/pci/cx88/cx88-alsa.c
+++ b/drivers/media/pci/cx88/cx88-alsa.c
@@ -101,7 +101,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
@@ -890,9 +890,9 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci,
return err;
}
- if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) {
+ err = pci_set_dma_mask(pci,DMA_BIT_MASK(32));
+ if (err) {
dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
- err = -EIO;
cx88_core_put(core, pci);
return err;
}
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index 24216efa56e7..8b889135be8a 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -637,7 +637,7 @@ static int blackbird_stop_codec(struct cx8802_dev *dev)
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -653,16 +653,18 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
return cx8802_buf_prepare(vb->vb2_queue, dev, buf);
}
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct cx88_riscmem *risc = &buf->risc;
if (risc->cpu)
@@ -672,8 +674,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
cx8802_buf_queue(dev, buf);
}
@@ -721,7 +724,7 @@ fail:
struct cx88_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
}
spin_unlock_irqrestore(&dev->slock, flags);
return err;
@@ -749,7 +752,7 @@ static void stop_streaming(struct vb2_queue *q)
struct cx88_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index aab7cf4c9825..9a43c7826b60 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -518,11 +518,11 @@ void cx88_wakeup(struct cx88_core *core,
buf = list_entry(q->active.next,
struct cx88_buffer, list);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.field = core->field;
- buf->vb.v4l2_buf.sequence = q->count++;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.field = core->field;
+ buf->vb.sequence = q->count++;
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
void cx88_shutdown(struct cx88_core *core)
diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c
index 9dfa5ee32a8f..f04835073844 100644
--- a/drivers/media/pci/cx88/cx88-dvb.c
+++ b/drivers/media/pci/cx88/cx88-dvb.c
@@ -82,7 +82,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -99,16 +99,18 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
return cx8802_buf_prepare(vb->vb2_queue, dev, buf);
}
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct cx88_riscmem *risc = &buf->risc;
if (risc->cpu)
@@ -118,8 +120,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
cx8802_buf_queue(dev, buf);
}
@@ -149,7 +152,7 @@ static void stop_streaming(struct vb2_queue *q)
struct cx88_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c
index 34f505744477..f34c229f9b37 100644
--- a/drivers/media/pci/cx88/cx88-mpeg.c
+++ b/drivers/media/pci/cx88/cx88-mpeg.c
@@ -214,7 +214,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
buf = list_entry(q->active.next, struct cx88_buffer, list);
dprintk(2,"restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
cx8802_start_dma(dev, q, buf);
return 0;
}
@@ -225,13 +225,13 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev,
struct cx88_buffer *buf)
{
int size = dev->ts_packet_size * dev->ts_packet_count;
- struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0);
struct cx88_riscmem *risc = &buf->risc;
int rc;
- if (vb2_plane_size(&buf->vb, 0) < size)
+ if (vb2_plane_size(&buf->vb.vb2_buf, 0) < size)
return -EINVAL;
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
rc = cx88_risc_databuffer(dev->pci, risc, sgt->sgl,
dev->ts_packet_size, dev->ts_packet_count, 0);
@@ -259,7 +259,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
dprintk( 1, "queue is empty - first active\n" );
list_add_tail(&buf->list, &cx88q->active);
dprintk(1,"[%p/%d] %s - first active\n",
- buf, buf->vb.v4l2_buf.index, __func__);
+ buf, buf->vb.vb2_buf.index, __func__);
} else {
buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
@@ -268,7 +268,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
list_add_tail(&buf->list, &cx88q->active);
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk( 1, "[%p/%d] %s - append to active\n",
- buf, buf->vb.v4l2_buf.index, __func__);
+ buf, buf->vb.vb2_buf.index, __func__);
}
}
@@ -284,7 +284,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev)
while (!list_empty(&q->active)) {
buf = list_entry(q->active.next, struct cx88_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock,flags);
}
@@ -393,7 +393,8 @@ static int cx8802_init_common(struct cx8802_dev *dev)
if (pci_enable_device(dev->pci))
return -EIO;
pci_set_master(dev->pci);
- if (!pci_dma_supported(dev->pci,DMA_BIT_MASK(32))) {
+ err = pci_set_dma_mask(dev->pci,DMA_BIT_MASK(32));
+ if (err) {
printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
return -EIO;
}
diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
index 7510e80eb2ff..007a5eee8e5e 100644
--- a/drivers/media/pci/cx88/cx88-vbi.c
+++ b/drivers/media/pci/cx88/cx88-vbi.c
@@ -100,14 +100,14 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
buf = list_entry(q->active.next, struct cx88_buffer, list);
dprintk(2,"restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
cx8800_start_vbi_dma(dev, q, buf);
return 0;
}
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -125,8 +125,9 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
unsigned int lines;
unsigned int size;
@@ -149,8 +150,9 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct cx88_riscmem *risc = &buf->risc;
if (risc->cpu)
@@ -160,8 +162,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct cx88_buffer *prev;
struct cx88_dmaqueue *q = &dev->vbiq;
@@ -174,7 +177,7 @@ static void buffer_queue(struct vb2_buffer *vb)
list_add_tail(&buf->list, &q->active);
cx8800_start_vbi_dma(dev, q, buf);
dprintk(2,"[%p/%d] vbi_queue - first active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
} else {
buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
@@ -182,7 +185,7 @@ static void buffer_queue(struct vb2_buffer *vb)
list_add_tail(&buf->list, &q->active);
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk(2,"[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
}
@@ -213,7 +216,7 @@ static void stop_streaming(struct vb2_queue *q)
struct cx88_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index 400e5caefd58..aef9acf351f6 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -420,7 +420,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
if (!list_empty(&q->active)) {
buf = list_entry(q->active.next, struct cx88_buffer, list);
dprintk(2,"restart_queue [%p/%d]: restart dma\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
start_video_dma(dev, q, buf);
}
return 0;
@@ -429,7 +429,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
/* ------------------------------------------------------------------ */
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -444,9 +444,10 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
struct cx88_core *core = dev->core;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
buf->bpl = core->width * dev->fmt->depth >> 3;
@@ -489,7 +490,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
break;
}
dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
- buf, buf->vb.v4l2_buf.index,
+ buf, buf->vb.vb2_buf.index,
core->width, core->height, dev->fmt->depth, dev->fmt->name,
(unsigned long)buf->risc.dma);
return 0;
@@ -497,8 +498,9 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct cx88_riscmem *risc = &buf->risc;
if (risc->cpu)
@@ -508,8 +510,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
- struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
+ struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
struct cx88_buffer *prev;
struct cx88_core *core = dev->core;
struct cx88_dmaqueue *q = &dev->vidq;
@@ -522,7 +525,7 @@ static void buffer_queue(struct vb2_buffer *vb)
if (list_empty(&q->active)) {
list_add_tail(&buf->list, &q->active);
dprintk(2,"[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
} else {
buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
@@ -530,7 +533,7 @@ static void buffer_queue(struct vb2_buffer *vb)
list_add_tail(&buf->list, &q->active);
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk(2, "[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
}
@@ -560,7 +563,7 @@ static void stop_streaming(struct vb2_queue *q)
struct cx88_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
@@ -1311,9 +1314,9 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev,DMA_BIT_MASK(32))) {
+ err = pci_set_dma_mask(pci_dev,DMA_BIT_MASK(32));
+ if (err) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
- err = -EIO;
goto fail_core;
}
dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev);
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 785fe2e0d702..2996eb3ea1fc 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -321,7 +321,7 @@ struct cx88_riscmem {
/* buffer for one video frame */
struct cx88_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
/* cx88 specific */
diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c
index 8df634518927..d84abde5ea29 100644
--- a/drivers/media/pci/dt3155/dt3155.c
+++ b/drivers/media/pci/dt3155/dt3155.c
@@ -131,11 +131,12 @@ static int wait_i2c_reg(void __iomem *addr)
}
static int
-dt3155_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+dt3155_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct dt3155_priv *pd = vb2_get_drv_priv(vq);
unsigned size = pd->width * pd->height;
@@ -160,7 +161,7 @@ static int dt3155_buf_prepare(struct vb2_buffer *vb)
static int dt3155_start_streaming(struct vb2_queue *q, unsigned count)
{
struct dt3155_priv *pd = vb2_get_drv_priv(q);
- struct vb2_buffer *vb = pd->curr_buf;
+ struct vb2_buffer *vb = &pd->curr_buf->vb2_buf;
dma_addr_t dma_addr;
pd->sequence = 0;
@@ -208,7 +209,7 @@ static void dt3155_stop_streaming(struct vb2_queue *q)
spin_lock_irq(&pd->lock);
if (pd->curr_buf) {
- vb2_buffer_done(pd->curr_buf, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&pd->curr_buf->vb2_buf, VB2_BUF_STATE_ERROR);
pd->curr_buf = NULL;
}
@@ -222,6 +223,7 @@ static void dt3155_stop_streaming(struct vb2_queue *q)
static void dt3155_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue);
/* pd->vidq.streaming = 1 when dt3155_buf_queue() is invoked */
@@ -229,7 +231,7 @@ static void dt3155_buf_queue(struct vb2_buffer *vb)
if (pd->curr_buf)
list_add_tail(&vb->done_entry, &pd->dmaq);
else
- pd->curr_buf = vb;
+ pd->curr_buf = vbuf;
spin_unlock_irq(&pd->lock);
}
@@ -269,14 +271,14 @@ static irqreturn_t dt3155_irq_handler_even(int irq, void *dev_id)
spin_lock(&ipd->lock);
if (ipd->curr_buf && !list_empty(&ipd->dmaq)) {
- v4l2_get_timestamp(&ipd->curr_buf->v4l2_buf.timestamp);
- ipd->curr_buf->v4l2_buf.sequence = ipd->sequence++;
- ipd->curr_buf->v4l2_buf.field = V4L2_FIELD_NONE;
- vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&ipd->curr_buf->timestamp);
+ ipd->curr_buf->sequence = ipd->sequence++;
+ ipd->curr_buf->field = V4L2_FIELD_NONE;
+ vb2_buffer_done(&ipd->curr_buf->vb2_buf, VB2_BUF_STATE_DONE);
ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry);
list_del(&ivb->done_entry);
- ipd->curr_buf = ivb;
+ ipd->curr_buf = to_vb2_v4l2_buffer(ivb);
dma_addr = vb2_dma_contig_plane_dma_addr(ivb, 0);
iowrite32(dma_addr, ipd->regs + EVEN_DMA_START);
iowrite32(dma_addr + ipd->width, ipd->regs + ODD_DMA_START);
diff --git a/drivers/media/pci/dt3155/dt3155.h b/drivers/media/pci/dt3155/dt3155.h
index 4e1f4d598d57..b3531e0bc733 100644
--- a/drivers/media/pci/dt3155/dt3155.h
+++ b/drivers/media/pci/dt3155/dt3155.h
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
+#include <media/videobuf2-v4l2.h>
#define DT3155_NAME "dt3155"
#define DT3155_VER_MAJ 2
@@ -181,7 +182,7 @@ struct dt3155_priv {
struct pci_dev *pdev;
struct vb2_queue vidq;
struct vb2_alloc_ctx *alloc_ctx;
- struct vb2_buffer *curr_buf;
+ struct vb2_v4l2_buffer *curr_buf;
struct mutex mux;
struct list_head dmaq;
spinlock_t lock;
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c
index 41fa21534edf..8a86b61a896d 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-main.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
@@ -41,6 +41,7 @@
#include "ivtv-alsa-pcm.h"
int ivtv_alsa_debug;
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
#define IVTV_DEBUG_ALSA_INFO(fmt, arg...) \
do { \
@@ -54,6 +55,10 @@ MODULE_PARM_DESC(debug,
"\t\t\t 1/0x0001: warning\n"
"\t\t\t 2/0x0002: info\n");
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index,
+ "Index value for IVTV ALSA capture interface(s).\n");
+
MODULE_AUTHOR("Andy Walls");
MODULE_DESCRIPTION("CX23415/CX23416 ALSA Interface");
MODULE_SUPPORTED_DEVICE("CX23415/CX23416 MPEG2 encoder");
@@ -137,7 +142,7 @@ static int snd_ivtv_init(struct v4l2_device *v4l2_dev)
struct ivtv *itv = to_ivtv(v4l2_dev);
struct snd_card *sc = NULL;
struct snd_ivtv_card *itvsc;
- int ret;
+ int ret, idx;
/* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
@@ -145,8 +150,10 @@ static int snd_ivtv_init(struct v4l2_device *v4l2_dev)
/* This is a no-op for us. We'll use the itv->instance */
/* (2) Create a card instance */
+ /* use first available id if not specified otherwise*/
+ idx = index[itv->instance] == -1 ? SNDRV_DEFAULT_IDX1 : index[itv->instance];
ret = snd_card_new(&itv->pdev->dev,
- SNDRV_DEFAULT_IDX1, /* use first available id */
+ idx,
SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
THIS_MODULE, 0, &sc);
if (ret) {
@@ -196,6 +203,9 @@ static int snd_ivtv_init(struct v4l2_device *v4l2_dev)
goto err_exit_free;
}
+ IVTV_ALSA_INFO("%s: Instance %d registered as ALSA card %d\n",
+ __func__, itv->instance, sc->number);
+
return 0;
err_exit_free:
diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
index 2ad65eb29832..2b8e7b2f2b86 100644
--- a/drivers/media/pci/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -75,15 +75,15 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
ivtv_udma_get_page_info (&uv_dma, (unsigned long)args->uv_source, 360 * uv_decode_height);
/* Get user pages for DMA Xfer */
- down_read(&current->mm->mmap_sem);
- y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
+ y_pages = get_user_pages_unlocked(current, current->mm,
+ y_dma.uaddr, y_dma.page_count, 0, 1,
+ &dma->map[0]);
uv_pages = 0; /* silence gcc. value is set and consumed only if: */
if (y_pages == y_dma.page_count) {
- uv_pages = get_user_pages(current, current->mm,
- uv_dma.uaddr, uv_dma.page_count, 0, 1,
- &dma->map[y_pages], NULL);
+ uv_pages = get_user_pages_unlocked(current, current->mm,
+ uv_dma.uaddr, uv_dma.page_count, 0, 1,
+ &dma->map[y_pages]);
}
- up_read(&current->mm->mmap_sem);
if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
int rc = -EFAULT;
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb.h b/drivers/media/pci/netup_unidvb/netup_unidvb.h
index fa951102d7fb..a67b28111905 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb.h
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb.h
@@ -54,7 +54,7 @@ struct netup_dma {
u8 num;
spinlock_t lock;
struct netup_unidvb_dev *ndev;
- struct netup_dma_regs *regs;
+ struct netup_dma_regs __iomem *regs;
u32 ring_buffer_size;
u8 *addr_virt;
dma_addr_t addr_phys;
@@ -82,7 +82,7 @@ struct netup_i2c {
wait_queue_head_t wq;
struct i2c_adapter adap;
struct netup_unidvb_dev *dev;
- struct netup_i2c_regs *regs;
+ struct netup_i2c_regs __iomem *regs;
struct i2c_msg *msg;
enum netup_i2c_state state;
u32 xmit_size;
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c b/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c
index 751b51b03593..f46ffac66ee9 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c
@@ -147,7 +147,7 @@ static int netup_unidvb_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
{
struct netup_ci_state *state = en50221->data;
struct netup_unidvb_dev *dev = state->dev;
- u8 val = state->membase8_config[addr];
+ u8 val = *((u8 __force *)state->membase8_io + addr);
dev_dbg(&dev->pci_dev->dev,
"%s(): addr=0x%x val=0x%x\n", __func__, addr, val);
@@ -162,7 +162,7 @@ static int netup_unidvb_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
dev_dbg(&dev->pci_dev->dev,
"%s(): addr=0x%x data=0x%x\n", __func__, addr, data);
- state->membase8_config[addr] = data;
+ *((u8 __force *)state->membase8_io + addr) = data;
return 0;
}
@@ -171,7 +171,7 @@ static int netup_unidvb_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
{
struct netup_ci_state *state = en50221->data;
struct netup_unidvb_dev *dev = state->dev;
- u8 val = state->membase8_io[addr];
+ u8 val = *((u8 __force *)state->membase8_io + addr);
dev_dbg(&dev->pci_dev->dev,
"%s(): addr=0x%x val=0x%x\n", __func__, addr, val);
@@ -186,7 +186,7 @@ static int netup_unidvb_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221,
dev_dbg(&dev->pci_dev->dev,
"%s(): addr=0x%x data=0x%x\n", __func__, addr, data);
- state->membase8_io[addr] = data;
+ *((u8 __force *)state->membase8_io + addr) = data;
return 0;
}
@@ -226,7 +226,7 @@ int netup_unidvb_ci_register(struct netup_unidvb_dev *dev,
__func__, result);
return result;
}
- writew(NETUP_UNIDVB_IRQ_CI, (u16 *)(dev->bmmio0 + REG_IMASK_SET));
+ writew(NETUP_UNIDVB_IRQ_CI, dev->bmmio0 + REG_IMASK_SET);
dev_info(&pci_dev->dev,
"%s(): CI adapter %d init done\n", __func__, num);
return 0;
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 6d8bf6277647..3fdbd81b5580 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/list.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include "netup_unidvb.h"
@@ -110,7 +111,7 @@ struct netup_dma_regs {
} __packed __aligned(1);
struct netup_unidvb_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
u32 size;
};
@@ -189,12 +190,10 @@ static void netup_unidvb_dma_enable(struct netup_dma *dma, int enable)
"%s(): DMA%d enable %d\n", __func__, dma->num, enable);
if (enable) {
writel(BIT_DMA_RUN, &dma->regs->ctrlstat_set);
- writew(irq_mask,
- (u16 *)(dma->ndev->bmmio0 + REG_IMASK_SET));
+ writew(irq_mask, dma->ndev->bmmio0 + REG_IMASK_SET);
} else {
writel(BIT_DMA_RUN, &dma->regs->ctrlstat_clear);
- writew(irq_mask,
- (u16 *)(dma->ndev->bmmio0 + REG_IMASK_CLEAR));
+ writew(irq_mask, dma->ndev->bmmio0 + REG_IMASK_CLEAR);
}
}
@@ -278,7 +277,7 @@ static irqreturn_t netup_unidvb_isr(int irq, void *dev_id)
}
static int netup_unidvb_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers,
unsigned int *nplanes,
unsigned int sizes[],
@@ -300,7 +299,8 @@ static int netup_unidvb_queue_setup(struct vb2_queue *vq,
static int netup_unidvb_buf_prepare(struct vb2_buffer *vb)
{
struct netup_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
- struct netup_unidvb_buffer *buf = container_of(vb,
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct netup_unidvb_buffer *buf = container_of(vbuf,
struct netup_unidvb_buffer, vb);
dev_dbg(&dma->ndev->pci_dev->dev, "%s(): buf 0x%p\n", __func__, buf);
@@ -312,7 +312,8 @@ static void netup_unidvb_buf_queue(struct vb2_buffer *vb)
{
unsigned long flags;
struct netup_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
- struct netup_unidvb_buffer *buf = container_of(vb,
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct netup_unidvb_buffer *buf = container_of(vbuf,
struct netup_unidvb_buffer, vb);
dev_dbg(&dma->ndev->pci_dev->dev, "%s(): %p\n", __func__, buf);
@@ -509,7 +510,7 @@ static int netup_unidvb_ring_copy(struct netup_dma *dma,
{
u32 copy_bytes, ring_bytes;
u32 buff_bytes = NETUP_DMA_PACKETS_COUNT * 188 - buf->size;
- u8 *p = vb2_plane_vaddr(&buf->vb, 0);
+ u8 *p = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
struct netup_unidvb_dev *ndev = dma->ndev;
if (p == NULL) {
@@ -522,7 +523,7 @@ static int netup_unidvb_ring_copy(struct netup_dma *dma,
ring_bytes = dma->ring_buffer_size - dma->data_offset;
copy_bytes = (ring_bytes > buff_bytes) ?
buff_bytes : ring_bytes;
- memcpy_fromio(p, dma->addr_virt + dma->data_offset, copy_bytes);
+ memcpy_fromio(p, (u8 __iomem *)(dma->addr_virt + dma->data_offset), copy_bytes);
p += copy_bytes;
buf->size += copy_bytes;
buff_bytes -= copy_bytes;
@@ -535,7 +536,7 @@ static int netup_unidvb_ring_copy(struct netup_dma *dma,
ring_bytes = dma->data_size;
copy_bytes = (ring_bytes > buff_bytes) ?
buff_bytes : ring_bytes;
- memcpy_fromio(p, dma->addr_virt + dma->data_offset, copy_bytes);
+ memcpy_fromio(p, (u8 __iomem *)(dma->addr_virt + dma->data_offset), copy_bytes);
buf->size += copy_bytes;
dma->data_size -= copy_bytes;
dma->data_offset += copy_bytes;
@@ -579,9 +580,9 @@ static void netup_unidvb_dma_worker(struct work_struct *work)
dev_dbg(&ndev->pci_dev->dev,
"%s(): buffer %p done, size %d\n",
__func__, buf, buf->size);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- vb2_set_plane_payload(&buf->vb, 0, buf->size);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
}
work_done:
@@ -599,7 +600,7 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma)
buf = list_first_entry(&dma->free_buffers,
struct netup_unidvb_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dma->lock, flags);
}
@@ -641,10 +642,10 @@ static int netup_unidvb_dma_init(struct netup_unidvb_dev *ndev, int num)
__func__, num, dma->addr_virt,
(unsigned long long)dma->addr_phys,
dma->ring_buffer_size);
- memset_io(dma->addr_virt, 0, dma->ring_buffer_size);
+ memset_io((u8 __iomem *)dma->addr_virt, 0, dma->ring_buffer_size);
dma->addr_last = dma->addr_phys;
dma->high_addr = (u32)(dma->addr_phys & 0xC0000000);
- dma->regs = (struct netup_dma_regs *)(num == 0 ?
+ dma->regs = (struct netup_dma_regs __iomem *)(num == 0 ?
ndev->bmmio0 + NETUP_DMA0_ADDR :
ndev->bmmio0 + NETUP_DMA1_ADDR);
writel((NETUP_DMA_BLOCKS_COUNT << 24) |
@@ -809,7 +810,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
"%s(): board vendor 0x%x, revision 0x%x\n",
__func__, board_vendor, board_revision);
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+ if (pci_set_dma_mask(pci_dev, 0xffffffff) < 0) {
dev_err(&pci_dev->dev,
"%s(): 32bit PCI DMA is not supported\n", __func__);
goto pci_detect_err;
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c b/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c
index eaaa2d0a5fba..c09c52bc6eab 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c
@@ -320,7 +320,7 @@ static int netup_i2c_init(struct netup_unidvb_dev *ndev, int bus_num)
i2c = &ndev->i2c[bus_num];
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wq);
- i2c->regs = (struct netup_i2c_regs *)(ndev->bmmio0 +
+ i2c->regs = (struct netup_i2c_regs __iomem *)(ndev->bmmio0 +
(bus_num == 0 ? NETUP_I2C_BUS0_ADDR : NETUP_I2C_BUS1_ADDR));
netup_i2c_reset(i2c);
i2c->adap = netup_i2c_adapter;
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c b/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c
index f55b3276f28d..f33c0de3e849 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c
@@ -45,7 +45,7 @@ struct netup_spi_regs {
struct netup_spi {
struct device *dev;
struct spi_master *master;
- struct netup_spi_regs *regs;
+ struct netup_spi_regs __iomem *regs;
u8 __iomem *mmio;
spinlock_t lock;
wait_queue_head_t waitq;
@@ -80,11 +80,9 @@ irqreturn_t netup_spi_interrupt(struct netup_spi *spi)
u16 reg;
unsigned long flags;
- if (!spi) {
- dev_dbg(&spi->master->dev,
- "%s(): SPI not initialized\n", __func__);
+ if (!spi)
return IRQ_NONE;
- }
+
spin_lock_irqsave(&spi->lock, flags);
reg = readw(&spi->regs->control_stat);
if (!(reg & NETUP_SPI_CTRL_IRQ)) {
@@ -202,7 +200,7 @@ int netup_spi_init(struct netup_unidvb_dev *ndev)
spin_lock_init(&nspi->lock);
init_waitqueue_head(&nspi->waitq);
nspi->master = master;
- nspi->regs = (struct netup_spi_regs *)(ndev->bmmio0 + 0x4000);
+ nspi->regs = (struct netup_spi_regs __iomem *)(ndev->bmmio0 + 0x4000);
writew(2, &nspi->regs->clock_divider);
writew(NETUP_UNIDVB_IRQ_SPI, ndev->bmmio0 + REG_IMASK_SET);
ndev->spi = nspi;
@@ -234,11 +232,9 @@ void netup_spi_release(struct netup_unidvb_dev *ndev)
unsigned long flags;
struct netup_spi *spi = ndev->spi;
- if (!spi) {
- dev_dbg(&spi->master->dev,
- "%s(): SPI not initialized\n", __func__);
+ if (!spi)
return;
- }
+
spin_lock_irqsave(&spi->lock, flags);
reg = readw(&spi->regs->control_stat);
writew(reg | NETUP_SPI_CTRL_IRQ, &spi->regs->control_stat);
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index c7405766609c..29d2094c42a0 100644
--- a/drivers/media/pci/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
@@ -5884,6 +5884,42 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},
},
+ [SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM] = {
+ .name = "Leadtek Winfast TV2100 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_TNF_5335MF,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x0d,
+ .inputs = {{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE1,
+ .gpio = 0x00,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ .gpio = 0x08,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ .gpio = 0x08,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x04,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ .gpio = 0x08,
+ },
+ },
};
@@ -7149,6 +7185,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0xa10a,
.driver_data = SAA7134_BOARD_AVERMEDIA_505,
}, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
+ .subvendor = 0x107d,
+ .subdevice = 0x6f3a,
+ .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM,
+ }, {
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -7545,6 +7587,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
+ case SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM:
dev->has_remote = SAA7134_REMOTE_GPIO;
break;
case SAA7134_BOARD_FLYDVBS_LR300:
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index 72d7f992375e..f720cea80e28 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -216,13 +216,14 @@ int saa7134_buffer_count(unsigned int size, unsigned int count)
int saa7134_buffer_startpage(struct saa7134_buf *buf)
{
- return saa7134_buffer_pages(vb2_plane_size(&buf->vb2, 0)) * buf->vb2.v4l2_buf.index;
+ return saa7134_buffer_pages(vb2_plane_size(&buf->vb2.vb2_buf, 0))
+ * buf->vb2.vb2_buf.index;
}
unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
{
unsigned long base;
- struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
+ struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2.vb2_buf, 0);
base = saa7134_buffer_startpage(buf) * 4096;
base += dma->sgl[0].offset;
@@ -308,9 +309,9 @@ void saa7134_buffer_finish(struct saa7134_dev *dev,
core_dbg("buffer_finish %p\n", q->curr);
/* finish current buffer */
- v4l2_get_timestamp(&q->curr->vb2.v4l2_buf.timestamp);
- q->curr->vb2.v4l2_buf.sequence = q->seq_nr++;
- vb2_buffer_done(&q->curr->vb2, state);
+ v4l2_get_timestamp(&q->curr->vb2.timestamp);
+ q->curr->vb2.sequence = q->seq_nr++;
+ vb2_buffer_done(&q->curr->vb2.vb2_buf, state);
q->curr = NULL;
}
@@ -375,7 +376,8 @@ void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q)
if (!list_empty(&q->queue)) {
list_for_each_safe(pos, n, &q->queue) {
tmp = list_entry(pos, struct saa7134_buf, entry);
- vb2_buffer_done(&tmp->vb2, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&tmp->vb2.vb2_buf,
+ VB2_BUF_STATE_ERROR);
list_del(pos);
tmp = NULL;
}
@@ -949,9 +951,9 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) {
+ err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
+ if (err) {
pr_warn("%s: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
goto fail1;
}
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 11a172000291..69d32d3fa32c 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -835,6 +835,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keycode = 0xffff;
raw_decode = true;
break;
+ case SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM:
+ ir_codes = RC_MAP_LEADTEK_Y04G0051;
+ mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
+ mask_keyup = 0x0040000;
+ mask_keycode = 0xffff;
+ raw_decode = true;
+ break;
}
if (NULL == ir_codes) {
pr_err("Oops: IR config error [card=%d]\n", dev->board);
diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c
index 4b202fa5fbc4..7fb5ee7e20ac 100644
--- a/drivers/media/pci/saa7134/saa7134-ts.c
+++ b/drivers/media/pci/saa7134/saa7134-ts.c
@@ -79,8 +79,9 @@ static int buffer_activate(struct saa7134_dev *dev,
int saa7134_ts_buffer_init(struct vb2_buffer *vb2)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
- struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
dmaq->curr = NULL;
buf->activate = buffer_activate;
@@ -91,9 +92,10 @@ EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init);
int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
- struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
unsigned int lines, llength, size;
@@ -107,14 +109,14 @@ int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2)
return -EINVAL;
vb2_set_plane_payload(vb2, 0, size);
- vb2->v4l2_buf.field = dev->field;
+ vbuf->field = dev->field;
return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
saa7134_buffer_startpage(buf));
}
EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare);
-int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+int saa7134_ts_queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -148,10 +150,12 @@ int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count)
list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) {
list_del(&buf->entry);
- vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb2.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
if (dmaq->curr) {
- vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&dmaq->curr->vb2.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
dmaq->curr = NULL;
}
return -EBUSY;
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index 4d36586ad752..6271b0eb0265 100644
--- a/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -83,7 +83,7 @@ static int buffer_activate(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next)
{
- struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;
+ struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_buf.vb2_queue->drv_priv;
unsigned long control, base;
vbi_dbg("buffer_activate [%p]\n", buf);
@@ -119,8 +119,9 @@ static int buffer_prepare(struct vb2_buffer *vb2)
{
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
- struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
- struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
+ struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
unsigned int size;
if (dma->sgl->offset) {
@@ -137,7 +138,7 @@ static int buffer_prepare(struct vb2_buffer *vb2)
saa7134_buffer_startpage(buf));
}
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -161,7 +162,8 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
static int buffer_init(struct vb2_buffer *vb2)
{
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
- struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
dmaq->curr = NULL;
buf->activate = buffer_activate;
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 035039cfae6d..518086c7aed5 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -791,7 +791,7 @@ static int buffer_activate(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next)
{
- struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;
+ struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_buf.vb2_queue->drv_priv;
unsigned long base,control,bpl;
unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
@@ -872,7 +872,8 @@ static int buffer_activate(struct saa7134_dev *dev,
static int buffer_init(struct vb2_buffer *vb2)
{
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
- struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
dmaq->curr = NULL;
buf->activate = buffer_activate;
@@ -883,8 +884,9 @@ static int buffer_prepare(struct vb2_buffer *vb2)
{
struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
- struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
- struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
+ struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
unsigned int size;
if (dma->sgl->offset) {
@@ -896,13 +898,13 @@ static int buffer_prepare(struct vb2_buffer *vb2)
return -EINVAL;
vb2_set_plane_payload(vb2, 0, size);
- vb2->v4l2_buf.field = dev->field;
+ vbuf->field = dev->field;
return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
saa7134_buffer_startpage(buf));
}
-static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -932,7 +934,8 @@ void saa7134_vb2_buffer_queue(struct vb2_buffer *vb)
{
struct saa7134_dmaqueue *dmaq = vb->vb2_queue->drv_priv;
struct saa7134_dev *dev = dmaq->dev;
- struct saa7134_buf *buf = container_of(vb, struct saa7134_buf, vb2);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct saa7134_buf *buf = container_of(vbuf, struct saa7134_buf, vb2);
saa7134_buffer_queue(dev, dmaq, buf);
}
@@ -953,10 +956,12 @@ int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) {
list_del(&buf->entry);
- vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb2.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
if (dmaq->curr) {
- vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&dmaq->curr->vb2.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
dmaq->curr = NULL;
}
return -EBUSY;
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 6b5f6f45d285..6b6d234f5cab 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -342,6 +342,7 @@ struct saa7134_card_ir {
#define SAA7134_BOARD_AVERMEDIA_A706 192
#define SAA7134_BOARD_WIS_VOYAGER 193
#define SAA7134_BOARD_AVERMEDIA_505 194
+#define SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM 195
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
@@ -459,7 +460,7 @@ struct saa7134_thread {
/* buffer for one video/vbi/ts frame */
struct saa7134_buf {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb2;
+ struct vb2_v4l2_buffer vb2;
/* saa7134 specific */
unsigned int top_seen;
@@ -819,7 +820,7 @@ void saa7134_video_fini(struct saa7134_dev *dev);
int saa7134_ts_buffer_init(struct vb2_buffer *vb2);
int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2);
-int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+int saa7134_ts_queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[]);
int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count);
diff --git a/drivers/media/pci/saa7164/Kconfig b/drivers/media/pci/saa7164/Kconfig
index a53db7d1c96e..9098ef5feca4 100644
--- a/drivers/media/pci/saa7164/Kconfig
+++ b/drivers/media/pci/saa7164/Kconfig
@@ -5,7 +5,6 @@ config VIDEO_SAA7164
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
- select VIDEOBUF_DVB
select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 3206a826b80d..8bbd092fbe1d 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -1264,9 +1264,9 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
pci_set_master(pci_dev);
/* TODO */
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+ err = pci_set_dma_mask(pci_dev, 0xffffffff);
+ if (err) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
goto fail_irq;
}
diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
index 4434e0f28c26..1b184c39ba97 100644
--- a/drivers/media/pci/saa7164/saa7164-encoder.c
+++ b/drivers/media/pci/saa7164/saa7164-encoder.c
@@ -25,6 +25,18 @@
#define ENCODER_MIN_BITRATE 1000000
#define ENCODER_DEF_BITRATE 5000000
+/*
+ * This is a dummy non-zero value for the sizeimage field of v4l2_pix_format.
+ * It is not actually used for anything since this driver does not support
+ * stream I/O, only read(), and because this driver produces an MPEG stream
+ * and not discrete frames. But the V4L2 spec doesn't allow for this value
+ * to be 0, so set it to 0x10000 instead.
+ *
+ * If we ever change this driver to support stream I/O, then this field
+ * will be the size of the streaming buffers.
+ */
+#define SAA7164_SIZEIMAGE (0x10000)
+
static struct saa7164_tvnorm saa7164_tvnorms[] = {
{
.name = "NTSC-M",
@@ -35,24 +47,6 @@ static struct saa7164_tvnorm saa7164_tvnorms[] = {
}
};
-static const u32 saa7164_v4l2_ctrls[] = {
- V4L2_CID_BRIGHTNESS,
- V4L2_CID_CONTRAST,
- V4L2_CID_SATURATION,
- V4L2_CID_HUE,
- V4L2_CID_AUDIO_VOLUME,
- V4L2_CID_SHARPNESS,
- V4L2_CID_MPEG_STREAM_TYPE,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_CID_MPEG_VIDEO_B_FRAMES,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- V4L2_CID_MPEG_AUDIO_MUTE,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
- 0
-};
-
/* Take the encoder configuration form the port struct and
* flush it to the hardware.
*/
@@ -211,10 +205,8 @@ static int saa7164_encoder_initialize(struct saa7164_port *port)
}
/* -- V4L2 --------------------------------------------------------- */
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
+int saa7164_s_std(struct saa7164_port *port, v4l2_std_id id)
{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
unsigned int i;
@@ -240,22 +232,33 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
return 0;
}
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
{
struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
+ return saa7164_s_std(fh->port, id);
+}
+
+int saa7164_g_std(struct saa7164_port *port, v4l2_std_id *id)
+{
*id = port->std;
return 0;
}
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
{
- int n;
+ struct saa7164_encoder_fh *fh = file->private_data;
+
+ return saa7164_g_std(fh->port, id);
+}
- char *inputs[] = { "tuner", "composite", "svideo", "aux",
- "composite 2", "svideo 2", "aux 2" };
+int saa7164_enum_input(struct file *file, void *priv, struct v4l2_input *i)
+{
+ static const char * const inputs[] = {
+ "tuner", "composite", "svideo", "aux",
+ "composite 2", "svideo 2", "aux 2"
+ };
+ int n;
if (i->index >= 7)
return -EINVAL;
@@ -273,10 +276,8 @@ static int vidioc_enum_input(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+int saa7164_g_input(struct saa7164_port *port, unsigned int *i)
{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
if (saa7164_api_get_videomux(port) != SAA_OK)
@@ -289,10 +290,15 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
return 0;
}
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
+
+ return saa7164_g_input(fh->port, i);
+}
+
+int saa7164_s_input(struct saa7164_port *port, unsigned int i)
+{
struct saa7164_dev *dev = port->dev;
dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i);
@@ -308,8 +314,14 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
return 0;
}
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ struct saa7164_encoder_fh *fh = file->private_data;
+
+ return saa7164_s_input(fh->port, i);
+}
+
+int saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
{
struct saa7164_encoder_fh *fh = file->private_data;
struct saa7164_port *port = fh->port;
@@ -319,38 +331,45 @@ static int vidioc_g_tuner(struct file *file, void *priv,
return -EINVAL;
strcpy(t->name, "tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
+ t->rangelow = SAA7164_TV_MIN_FREQ;
+ t->rangehigh = SAA7164_TV_MAX_FREQ;
dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
return 0;
}
-static int vidioc_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *t)
+int saa7164_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *t)
{
+ if (0 != t->index)
+ return -EINVAL;
+
/* Update the A/V core */
return 0;
}
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
+int saa7164_g_frequency(struct saa7164_port *port, struct v4l2_frequency *f)
{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
+ if (f->tuner)
+ return -EINVAL;
- f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = port->freq;
-
return 0;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *f)
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
{
struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
+
+ return saa7164_g_frequency(fh->port, f);
+}
+
+int saa7164_s_frequency(struct saa7164_port *port,
+ const struct v4l2_frequency *f)
+{
struct saa7164_dev *dev = port->dev;
struct saa7164_port *tsport;
struct dvb_frontend *fe;
@@ -370,16 +389,13 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (f->tuner != 0)
return -EINVAL;
- if (f->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
-
- port->freq = f->frequency;
+ port->freq = clamp(f->frequency,
+ SAA7164_TV_MIN_FREQ, SAA7164_TV_MAX_FREQ);
/* Update the hardware */
if (port->nr == SAA7164_PORT_ENC1)
tsport = &dev->ports[SAA7164_PORT_TS1];
- else
- if (port->nr == SAA7164_PORT_ENC2)
+ else if (port->nr == SAA7164_PORT_ENC2)
tsport = &dev->ports[SAA7164_PORT_TS2];
else
BUG();
@@ -396,253 +412,54 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
+static int vidioc_s_frequency(struct file *file, void *priv,
+ const struct v4l2_frequency *f)
{
struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctl->value = port->ctl_brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctl->value = port->ctl_contrast;
- break;
- case V4L2_CID_SATURATION:
- ctl->value = port->ctl_saturation;
- break;
- case V4L2_CID_HUE:
- ctl->value = port->ctl_hue;
- break;
- case V4L2_CID_SHARPNESS:
- ctl->value = port->ctl_sharpness;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- ctl->value = port->ctl_volume;
- break;
- default:
- return -EINVAL;
- }
- return 0;
+ return saa7164_s_frequency(fh->port, f);
}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
+static int saa7164_s_ctrl(struct v4l2_ctrl *ctrl)
{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
+ struct saa7164_port *port =
+ container_of(ctrl->handler, struct saa7164_port, ctrl_handler);
+ struct saa7164_encoder_params *params = &port->encoder_params;
int ret = 0;
- dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
+ switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_brightness = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_BRIGHTNESS_CONTROL);
- } else
- ret = -EINVAL;
+ port->ctl_brightness = ctrl->val;
+ saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL);
break;
case V4L2_CID_CONTRAST:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_contrast = ctl->value;
- saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
- } else
- ret = -EINVAL;
+ port->ctl_contrast = ctrl->val;
+ saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
break;
case V4L2_CID_SATURATION:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_saturation = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_SATURATION_CONTROL);
- } else
- ret = -EINVAL;
+ port->ctl_saturation = ctrl->val;
+ saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL);
break;
case V4L2_CID_HUE:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_hue = ctl->value;
- saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
- } else
- ret = -EINVAL;
+ port->ctl_hue = ctrl->val;
+ saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
break;
case V4L2_CID_SHARPNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_sharpness = ctl->value;
- saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
- } else
- ret = -EINVAL;
+ port->ctl_sharpness = ctrl->val;
+ saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
break;
case V4L2_CID_AUDIO_VOLUME:
- if ((ctl->value >= -83) && (ctl->value <= 24)) {
- port->ctl_volume = ctl->value;
- saa7164_api_set_audio_volume(port, port->ctl_volume);
- } else
- ret = -EINVAL;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int saa7164_get_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_encoder_params *params = &port->encoder_params;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctrl->value = params->bitrate;
- break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = params->stream_type;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- ctrl->value = params->ctl_mute;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->ctl_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctrl->value = params->bitrate_mode;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- ctrl->value = params->refdist;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- ctrl->value = params->bitrate_peak;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- ctrl->value = params->gop_size;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_get_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
-{
- int ret = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
- (ctrl->value <= ENCODER_MAX_BITRATE))
- ret = 0;
+ port->ctl_volume = ctrl->val;
+ saa7164_api_set_audio_volume(port, port->ctl_volume);
break;
- case V4L2_CID_MPEG_STREAM_TYPE:
- if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
- (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
- ret = 0;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 1))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
- (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 255))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ||
- (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- if ((ctrl->value >= 1) &&
- (ctrl->value <= 3))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
- (ctrl->value <= ENCODER_MAX_BITRATE))
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
- }
-
- return -EINVAL;
-}
-
-static int saa7164_set_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_encoder_params *params = &port->encoder_params;
- int ret = 0;
-
- switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_BITRATE:
- params->bitrate = ctrl->value;
+ params->bitrate = ctrl->val;
break;
case V4L2_CID_MPEG_STREAM_TYPE:
- params->stream_type = ctrl->value;
+ params->stream_type = ctrl->val;
break;
case V4L2_CID_MPEG_AUDIO_MUTE:
- params->ctl_mute = ctrl->value;
+ params->ctl_mute = ctrl->val;
ret = saa7164_api_audio_mute(port, params->ctl_mute);
if (ret != SAA_OK) {
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
@@ -651,7 +468,7 @@ static int saa7164_set_ctrl(struct saa7164_port *port,
}
break;
case V4L2_CID_MPEG_VIDEO_ASPECT:
- params->ctl_aspect = ctrl->value;
+ params->ctl_aspect = ctrl->val;
ret = saa7164_api_set_aspect_ratio(port);
if (ret != SAA_OK) {
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
@@ -660,55 +477,24 @@ static int saa7164_set_ctrl(struct saa7164_port *port,
}
break;
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- params->bitrate_mode = ctrl->value;
+ params->bitrate_mode = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- params->refdist = ctrl->value;
+ params->refdist = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- params->bitrate_peak = ctrl->value;
+ params->bitrate_peak = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- params->gop_size = ctrl->value;
+ params->gop_size = ctrl->val;
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
- /* TODO: Update the hardware */
-
return ret;
}
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- err = saa7164_set_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@@ -745,145 +531,22 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+static int vidioc_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7164_encoder_fh *fh = file->private_data;
struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
+ f->fmt.pix.sizeimage = SAA7164_SIZEIMAGE;
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.width = port->width;
f->fmt.pix.height = port->height;
-
- dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n",
- port->width, port->height);
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
- port->width, port->height);
return 0;
}
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
-
- dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
-
- return 0;
-}
-
-static int fill_queryctrl(struct saa7164_encoder_params *params,
- struct v4l2_queryctrl *c)
-{
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(c,
- ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
- 100000, ENCODER_DEF_BITRATE);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
- 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100,
- 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
- 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(c,
- 1, 3, 1, 1);
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- return v4l2_ctrl_query_fill(c,
- ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
- 100000, ENCODER_DEF_BITRATE);
- default:
- return -EINVAL;
- }
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct saa7164_encoder_fh *fh = priv;
- struct saa7164_port *port = fh->port;
- int i, next;
- u32 id = c->id;
-
- memset(c, 0, sizeof(*c));
-
- next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
- c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
-
- for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
- if (next) {
- if (c->id < saa7164_v4l2_ctrls[i])
- c->id = saa7164_v4l2_ctrls[i];
- else
- continue;
- }
-
- if (c->id == saa7164_v4l2_ctrls[i])
- return fill_queryctrl(&port->encoder_params, c);
-
- if (c->id < saa7164_v4l2_ctrls[i])
- break;
- }
-
- return -EINVAL;
-}
-
static int saa7164_encoder_stop_port(struct saa7164_port *port)
{
struct saa7164_dev *dev = port->dev;
@@ -1084,8 +747,10 @@ static int fops_open(struct file *file)
if (NULL == fh)
return -ENOMEM;
- file->private_data = fh;
fh->port = port;
+ v4l2_fh_init(&fh->fh, video_devdata(file));
+ v4l2_fh_add(&fh->fh);
+ file->private_data = fh;
return 0;
}
@@ -1106,7 +771,8 @@ static int fops_release(struct file *file)
}
}
- file->private_data = NULL;
+ v4l2_fh_del(&fh->fh);
+ v4l2_fh_exit(&fh->fh);
kfree(fh);
return 0;
@@ -1250,10 +916,11 @@ err:
static unsigned int fops_poll(struct file *file, poll_table *wait)
{
+ unsigned long req_events = poll_requested_events(wait);
struct saa7164_encoder_fh *fh =
(struct saa7164_encoder_fh *)file->private_data;
struct saa7164_port *port = fh->port;
- unsigned int mask = 0;
+ unsigned int mask = v4l2_ctrl_poll(file, wait);
port->last_poll_msecs_diff = port->last_poll_msecs;
port->last_poll_msecs = jiffies_to_msecs(jiffies);
@@ -1263,26 +930,18 @@ static unsigned int fops_poll(struct file *file, poll_table *wait)
saa7164_histogram_update(&port->poll_interval,
port->last_poll_msecs_diff);
- if (!video_is_registered(port->v4l_device))
- return -EIO;
+ if (!(req_events & (POLLIN | POLLRDNORM)))
+ return mask;
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
if (atomic_inc_return(&port->v4l_reader_count) == 1) {
if (saa7164_encoder_initialize(port) < 0)
- return -EINVAL;
+ return mask | POLLERR;
saa7164_encoder_start_streaming(port);
msleep(200);
}
}
- /* blocking wait for buffer */
- if ((file->f_flags & O_NONBLOCK) == 0) {
- if (wait_event_interruptible(port->wait_read,
- saa7164_enc_next_buf(port))) {
- return -ERESTARTSYS;
- }
- }
-
/* Pull the first buffer from the used list */
if (!list_empty(&port->list_buf_used.list))
mask |= POLLIN | POLLRDNORM;
@@ -1290,6 +949,10 @@ static unsigned int fops_poll(struct file *file, poll_table *wait)
return mask;
}
+static const struct v4l2_ctrl_ops saa7164_ctrl_ops = {
+ .s_ctrl = saa7164_s_ctrl,
+};
+
static const struct v4l2_file_operations mpeg_fops = {
.owner = THIS_MODULE,
.open = fops_open,
@@ -1302,24 +965,21 @@ static const struct v4l2_file_operations mpeg_fops = {
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.vidioc_s_std = vidioc_s_std,
.vidioc_g_std = vidioc_g_std,
- .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_enum_input = saa7164_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_tuner = saa7164_g_tuner,
+ .vidioc_s_tuner = saa7164_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_fmt_vid_cap = vidioc_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_fmt_vid_cap,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
static struct video_device saa7164_mpeg_template = {
@@ -1357,6 +1017,7 @@ static struct video_device *saa7164_encoder_alloc(
int saa7164_encoder_register(struct saa7164_port *port)
{
struct saa7164_dev *dev = port->dev;
+ struct v4l2_ctrl_handler *hdl = &port->ctrl_handler;
int result = -ENODEV;
dprintk(DBGLVL_ENC, "%s()\n", __func__);
@@ -1381,19 +1042,52 @@ int saa7164_encoder_register(struct saa7164_port *port)
port->video_format = EU_VIDEO_FORMAT_MPEG_2;
port->audio_format = 0;
port->video_resolution = 0;
- port->ctl_brightness = 127;
- port->ctl_contrast = 66;
- port->ctl_hue = 128;
- port->ctl_saturation = 62;
- port->ctl_sharpness = 8;
- port->encoder_params.bitrate = ENCODER_DEF_BITRATE;
- port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE;
- port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
- port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
- port->encoder_params.ctl_mute = 0;
- port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
- port->encoder_params.refdist = 1;
- port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
+ port->freq = SAA7164_TV_MIN_FREQ;
+
+ v4l2_ctrl_handler_init(hdl, 14);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_CONTRAST, 0, 255, 1, 66);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_SATURATION, 0, 255, 1, 62);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_HUE, 0, 255, 1, 128);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_SHARPNESS, 0x0, 0x0f, 1, 8);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_AUDIO_MUTE, 0x0, 0x01, 1, 0);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_AUDIO_VOLUME, -83, 24, 1, 20);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
+ 100000, ENCODER_DEF_BITRATE);
+ v4l2_ctrl_new_std_menu(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_STREAM_TYPE,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 0,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
+ v4l2_ctrl_new_std_menu(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_ASPECT,
+ V4L2_MPEG_VIDEO_ASPECT_221x100, 0,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 255, 1, 15);
+ v4l2_ctrl_new_std_menu(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_B_FRAMES, 1, 3, 1, 1);
+ v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
+ 100000, ENCODER_DEF_BITRATE);
+ if (hdl->error) {
+ result = hdl->error;
+ goto failed;
+ }
+
port->std = V4L2_STD_NTSC_M;
if (port->encodernorm.id & V4L2_STD_525_60)
@@ -1412,6 +1106,8 @@ int saa7164_encoder_register(struct saa7164_port *port)
goto failed;
}
+ port->v4l_device->ctrl_handler = hdl;
+ v4l2_ctrl_handler_setup(hdl);
video_set_drvdata(port->v4l_device, port);
result = video_register_device(port->v4l_device,
VFL_TYPE_GRABBER, -1);
@@ -1466,6 +1162,7 @@ void saa7164_encoder_unregister(struct saa7164_port *port)
port->v4l_device = NULL;
}
+ v4l2_ctrl_handler_free(&port->ctrl_handler);
dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
}
diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c
index 859fd03d82f9..ee54491459a6 100644
--- a/drivers/media/pci/saa7164/saa7164-vbi.c
+++ b/drivers/media/pci/saa7164/saa7164-vbi.c
@@ -21,20 +21,6 @@
#include "saa7164.h"
-static struct saa7164_tvnorm saa7164_tvnorms[] = {
- {
- .name = "NTSC-M",
- .id = V4L2_STD_NTSC_M,
- }, {
- .name = "NTSC-JP",
- .id = V4L2_STD_NTSC_M_JP,
- }
-};
-
-static const u32 saa7164_v4l2_ctrls[] = {
- 0
-};
-
/* Take the encoder configuration from the port struct and
* flush it to the hardware.
*/
@@ -43,23 +29,13 @@ static void saa7164_vbi_configure(struct saa7164_port *port)
struct saa7164_dev *dev = port->dev;
dprintk(DBGLVL_VBI, "%s()\n", __func__);
- port->vbi_params.width = port->width;
- port->vbi_params.height = port->height;
+ port->vbi_params.width = port->enc_port->width;
+ port->vbi_params.height = port->enc_port->height;
port->vbi_params.is_50hz =
- (port->encodernorm.id & V4L2_STD_625_50) != 0;
+ (port->enc_port->encodernorm.id & V4L2_STD_625_50) != 0;
/* Set up the DIF (enable it) for analog mode by default */
saa7164_api_initialize_dif(port);
-
- /* Configure the correct video standard */
-#if 0
- saa7164_api_configure_dif(port, port->encodernorm.id);
-#endif
-
-#if 0
- /* Ensure the audio decoder is correct configured */
- saa7164_api_set_audio_std(port);
-#endif
dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
}
@@ -186,468 +162,50 @@ static int saa7164_vbi_initialize(struct saa7164_port *port)
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
{
struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- unsigned int i;
- dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)id);
-
- for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
- if (id & saa7164_tvnorms[i].id)
- break;
- }
- if (i == ARRAY_SIZE(saa7164_tvnorms))
- return -EINVAL;
-
- port->encodernorm = saa7164_tvnorms[i];
- port->std = id;
-
- /* Update the audio decoder while is not running in
- * auto detect mode.
- */
- saa7164_api_set_audio_std(port);
-
- dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)id);
-
- return 0;
+ return saa7164_s_std(fh->port->enc_port, id);
}
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
{
struct saa7164_encoder_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- *id = port->std;
- return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- int n;
-
- char *inputs[] = { "tuner", "composite", "svideo", "aux",
- "composite 2", "svideo 2", "aux 2" };
-
- if (i->index >= 7)
- return -EINVAL;
-
- strcpy(i->name, inputs[i->index]);
-
- if (i->index == 0)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
- i->std |= saa7164_tvnorms[n].id;
-
- return 0;
+ return saa7164_g_std(fh->port->enc_port, id);
}
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- if (saa7164_api_get_videomux(port) != SAA_OK)
- return -EIO;
-
- *i = (port->mux_input - 1);
-
- dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i);
- return 0;
+ return saa7164_g_input(fh->port->enc_port, i);
}
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i);
-
- if (i >= 7)
- return -EINVAL;
-
- port->mux_input = i + 1;
- if (saa7164_api_set_videomux(port) != SAA_OK)
- return -EIO;
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- if (0 != t->index)
- return -EINVAL;
-
- strcpy(t->name, "tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
-
- dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
-
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *t)
-{
- /* Update the A/V core */
- return 0;
+ return saa7164_s_input(fh->port->enc_port, i);
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = port->freq;
-
- return 0;
+ return saa7164_g_frequency(fh->port->enc_port, f);
}
static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- struct saa7164_port *tsport;
- struct dvb_frontend *fe;
-
- /* TODO: Pull this for the std */
- struct analog_parameters params = {
- .mode = V4L2_TUNER_ANALOG_TV,
- .audmode = V4L2_TUNER_MODE_STEREO,
- .std = port->encodernorm.id,
- .frequency = f->frequency
- };
-
- /* Stop the encoder */
- dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__,
- f->frequency, f->tuner);
-
- if (f->tuner != 0)
- return -EINVAL;
-
- if (f->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
-
- port->freq = f->frequency;
-
- /* Update the hardware */
- if (port->nr == SAA7164_PORT_VBI1)
- tsport = &dev->ports[SAA7164_PORT_TS1];
- else
- if (port->nr == SAA7164_PORT_VBI2)
- tsport = &dev->ports[SAA7164_PORT_TS2];
- else
- BUG();
-
- fe = tsport->dvb.frontend;
-
- if (fe && fe->ops.tuner_ops.set_analog_params)
- fe->ops.tuner_ops.set_analog_params(fe, &params);
- else
- printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
-
- saa7164_vbi_initialize(port);
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctl->value = port->ctl_brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctl->value = port->ctl_contrast;
- break;
- case V4L2_CID_SATURATION:
- ctl->value = port->ctl_saturation;
- break;
- case V4L2_CID_HUE:
- ctl->value = port->ctl_hue;
- break;
- case V4L2_CID_SHARPNESS:
- ctl->value = port->ctl_sharpness;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- ctl->value = port->ctl_volume;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
- int ret = 0;
-
- dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
- ctl->id, ctl->value);
-
- switch (ctl->id) {
- case V4L2_CID_BRIGHTNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_brightness = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_BRIGHTNESS_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_CONTRAST:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_contrast = ctl->value;
- saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_SATURATION:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_saturation = ctl->value;
- saa7164_api_set_usercontrol(port,
- PU_SATURATION_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_HUE:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_hue = ctl->value;
- saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_SHARPNESS:
- if ((ctl->value >= 0) && (ctl->value <= 255)) {
- port->ctl_sharpness = ctl->value;
- saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
- } else
- ret = -EINVAL;
- break;
- case V4L2_CID_AUDIO_VOLUME:
- if ((ctl->value >= -83) && (ctl->value <= 24)) {
- port->ctl_volume = ctl->value;
- saa7164_api_set_audio_volume(port, port->ctl_volume);
- } else
- ret = -EINVAL;
- break;
- default:
- ret = -EINVAL;
- }
+ int ret = saa7164_s_frequency(fh->port->enc_port, f);
+ if (ret == 0)
+ saa7164_vbi_initialize(fh->port);
return ret;
}
-static int saa7164_get_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_vbi_params *params = &port->vbi_params;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = params->stream_type;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- ctrl->value = params->ctl_mute;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->ctl_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- ctrl->value = params->refdist;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- ctrl->value = params->gop_size;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_get_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
-static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
-{
- int ret = -EINVAL;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
- (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
- ret = 0;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 1))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
- (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- if ((ctrl->value >= 0) &&
- (ctrl->value <= 255))
- ret = 0;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- if ((ctrl->value >= 1) &&
- (ctrl->value <= 3))
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
- }
-
- return -EINVAL;
-}
-
-static int saa7164_set_ctrl(struct saa7164_port *port,
- struct v4l2_ext_control *ctrl)
-{
- struct saa7164_vbi_params *params = &port->vbi_params;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- params->stream_type = ctrl->value;
- break;
- case V4L2_CID_MPEG_AUDIO_MUTE:
- params->ctl_mute = ctrl->value;
- ret = saa7164_api_audio_mute(port, params->ctl_mute);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
- ret = -EIO;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- params->ctl_aspect = ctrl->value;
- ret = saa7164_api_set_aspect_ratio(port);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
- ret);
- ret = -EIO;
- }
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- params->refdist = ctrl->value;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- params->gop_size = ctrl->value;
- break;
- default:
- return -EINVAL;
- }
-
- /* TODO: Update the hardware */
-
- return ret;
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrls)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- int i, err = 0;
-
- if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- for (i = 0; i < ctrls->count; i++) {
- struct v4l2_ext_control *ctrl = ctrls->controls + i;
-
- err = saa7164_try_ctrl(ctrl, 0);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- err = saa7164_set_ctrl(port, ctrl);
- if (err) {
- ctrls->error_idx = i;
- break;
- }
- }
- return err;
-
- }
-
- return -EINVAL;
-}
-
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@@ -672,144 +230,6 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (f->index != 0)
- return -EINVAL;
-
- strlcpy(f->description, "VBI", sizeof(f->description));
- f->pixelformat = V4L2_PIX_FMT_MPEG;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = port->width;
- f->fmt.pix.height = port->height;
-
- dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
- port->width, port->height);
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
- port->width, port->height);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct saa7164_vbi_fh *fh = file->private_data;
- struct saa7164_port *port = fh->port;
- struct saa7164_dev *dev = port->dev;
-
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- port->ts_packet_size * port->ts_packet_count;
- f->fmt.pix.colorspace = 0;
-
- dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
-
- return 0;
-}
-
-static int fill_queryctrl(struct saa7164_vbi_params *params,
- struct v4l2_queryctrl *c)
-{
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
- 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100,
- 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(c,
- 1, 3, 1, 1);
- default:
- return -EINVAL;
- }
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *c)
-{
- struct saa7164_vbi_fh *fh = priv;
- struct saa7164_port *port = fh->port;
- int i, next;
- u32 id = c->id;
-
- memset(c, 0, sizeof(*c));
-
- next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
- c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
-
- for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
- if (next) {
- if (c->id < saa7164_v4l2_ctrls[i])
- c->id = saa7164_v4l2_ctrls[i];
- else
- continue;
- }
-
- if (c->id == saa7164_v4l2_ctrls[i])
- return fill_queryctrl(&port->vbi_params, c);
-
- if (c->id < saa7164_v4l2_ctrls[i])
- break;
- }
-
- return -EINVAL;
-}
-
static int saa7164_vbi_stop_port(struct saa7164_port *port)
{
struct saa7164_dev *dev = port->dev;
@@ -999,7 +419,6 @@ static int saa7164_vbi_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
/* ntsc */
- f->fmt.vbi.samples_per_line = 1600;
f->fmt.vbi.samples_per_line = 1440;
f->fmt.vbi.sampling_rate = 27000000;
f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
@@ -1009,6 +428,7 @@ static int saa7164_vbi_fmt(struct file *file, void *priv,
f->fmt.vbi.count[0] = 18;
f->fmt.vbi.start[1] = 263 + 10 + 1;
f->fmt.vbi.count[1] = 18;
+ memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved));
return 0;
}
@@ -1031,8 +451,10 @@ static int fops_open(struct file *file)
if (NULL == fh)
return -ENOMEM;
- file->private_data = fh;
fh->port = port;
+ v4l2_fh_init(&fh->fh, video_devdata(file));
+ v4l2_fh_add(&fh->fh);
+ file->private_data = fh;
return 0;
}
@@ -1053,7 +475,8 @@ static int fops_release(struct file *file)
}
}
- file->private_data = NULL;
+ v4l2_fh_del(&fh->fh);
+ v4l2_fh_exit(&fh->fh);
kfree(fh);
return 0;
@@ -1248,24 +671,14 @@ static const struct v4l2_file_operations vbi_fops = {
static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
.vidioc_s_std = vidioc_s_std,
.vidioc_g_std = vidioc_g_std,
- .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_enum_input = saa7164_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_tuner = saa7164_g_tuner,
+ .vidioc_s_tuner = saa7164_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
- .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
- .vidioc_queryctrl = vidioc_queryctrl,
.vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt,
@@ -1335,7 +748,7 @@ int saa7164_vbi_register(struct saa7164_port *port)
goto failed;
}
- port->std = V4L2_STD_NTSC_M;
+ port->enc_port = &dev->ports[port->nr - 2];
video_set_drvdata(port->v4l_device, port);
result = video_register_device(port->v4l_device,
VFL_TYPE_VBI, -1);
diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index 18906e0c80e1..8337524bfb8c 100644
--- a/drivers/media/pci/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -54,8 +54,6 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
#include <dvb_demux.h>
#include <dvb_frontend.h>
#include <dvb_net.h>
@@ -64,6 +62,8 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
#include "saa7164-reg.h"
#include "saa7164-types.h"
@@ -117,7 +117,11 @@
#define DBGLVL_CPU 8192
#define SAA7164_NORMS \
- (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
+ (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP)
+
+/* TV frequency range copied from tuner-core.c */
+#define SAA7164_TV_MIN_FREQ (44U * 16U)
+#define SAA7164_TV_MAX_FREQ (958U * 16U)
enum port_t {
SAA7164_MPEG_UNDEFINED = 0,
@@ -185,11 +189,13 @@ struct saa7164_subid {
};
struct saa7164_encoder_fh {
+ struct v4l2_fh fh;
struct saa7164_port *port;
atomic_t v4l_reading;
};
struct saa7164_vbi_fh {
+ struct v4l2_fh fh;
struct saa7164_port *port;
atomic_t v4l_reading;
};
@@ -381,12 +387,11 @@ struct saa7164_port {
/* Encoder */
/* Defaults established in saa7164-encoder.c */
struct saa7164_tvnorm encodernorm;
+ struct v4l2_ctrl_handler ctrl_handler;
v4l2_std_id std;
u32 height;
u32 width;
u32 freq;
- u32 ts_packet_size;
- u32 ts_packet_count;
u8 mux_input;
u8 encoder_profile;
u8 video_format;
@@ -419,6 +424,7 @@ struct saa7164_port {
/* V4L VBI */
struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc;
struct saa7164_vbi_params vbi_params;
+ struct saa7164_port *enc_port;
/* Debug */
u32 sync_errors;
@@ -594,6 +600,16 @@ extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i);
/* ----------------------------------------------------------- */
/* saa7164-encoder.c */
+int saa7164_s_std(struct saa7164_port *port, v4l2_std_id id);
+int saa7164_g_std(struct saa7164_port *port, v4l2_std_id *id);
+int saa7164_enum_input(struct file *file, void *priv, struct v4l2_input *i);
+int saa7164_g_input(struct saa7164_port *port, unsigned int *i);
+int saa7164_s_input(struct saa7164_port *port, unsigned int i);
+int saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
+int saa7164_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t);
+int saa7164_g_frequency(struct saa7164_port *port, struct v4l2_frequency *f);
+int saa7164_s_frequency(struct saa7164_port *port,
+ const struct v4l2_frequency *f);
int saa7164_encoder_register(struct saa7164_port *port);
void saa7164_encoder_unregister(struct saa7164_port *port);
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 53fff5425c13..4432fd69b7cb 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -458,11 +458,12 @@ static inline u32 vop_usec(const vop_header *vh)
static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
struct vb2_buffer *vb, const vop_header *vh)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct solo_dev *solo_dev = solo_enc->solo_dev;
- struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
int frame_size;
- vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+ vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len)
return -EIO;
@@ -470,7 +471,7 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN);
vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len);
- return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf,
+ return solo_send_desc(solo_enc, solo_enc->jpeg_len, sgt,
vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev),
frame_size, SOLO_JPEG_EXT_ADDR(solo_dev),
SOLO_JPEG_EXT_SIZE(solo_dev));
@@ -479,8 +480,9 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
struct vb2_buffer *vb, const vop_header *vh)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct solo_dev *solo_dev = solo_enc->solo_dev;
- struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
int frame_off, frame_size;
int skip = 0;
@@ -488,15 +490,15 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
return -EIO;
/* If this is a key frame, add extra header */
- vb->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME |
+ vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME |
V4L2_BUF_FLAG_BFRAME);
if (!vop_type(vh)) {
skip = solo_enc->vop_len;
- vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+ vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh) +
solo_enc->vop_len);
} else {
- vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
+ vbuf->flags |= V4L2_BUF_FLAG_PFRAME;
vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh));
}
@@ -505,7 +507,7 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
sizeof(*vh)) % SOLO_MP4E_EXT_SIZE(solo_dev);
frame_size = ALIGN(vop_mpeg_size(vh) + skip, DMA_ALIGN);
- return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size,
+ return solo_send_desc(solo_enc, skip, sgt, frame_off, frame_size,
SOLO_MP4E_EXT_ADDR(solo_dev),
SOLO_MP4E_EXT_SIZE(solo_dev));
}
@@ -513,6 +515,7 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
struct vb2_buffer *vb, struct solo_enc_buf *enc_buf)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
const vop_header *vh = enc_buf->vh;
int ret;
@@ -527,17 +530,18 @@ static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
}
if (!ret) {
- vb->v4l2_buf.sequence = solo_enc->sequence++;
- vb->v4l2_buf.timestamp.tv_sec = vop_sec(vh);
- vb->v4l2_buf.timestamp.tv_usec = vop_usec(vh);
+ vbuf->sequence = solo_enc->sequence++;
+ vbuf->timestamp.tv_sec = vop_sec(vh);
+ vbuf->timestamp.tv_usec = vop_usec(vh);
/* Check for motion flags */
if (solo_is_motion_on(solo_enc) && enc_buf->motion) {
struct v4l2_event ev = {
.type = V4L2_EVENT_MOTION_DET,
.u.motion_det = {
- .flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
- .frame_sequence = vb->v4l2_buf.sequence,
+ .flags
+ = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
+ .frame_sequence = vbuf->sequence,
.region_mask = enc_buf->motion ? 1 : 0,
},
};
@@ -571,7 +575,7 @@ static void solo_enc_handle_one(struct solo_enc_dev *solo_enc,
list_del(&vb->list);
spin_unlock_irqrestore(&solo_enc->av_lock, flags);
- solo_enc_fillbuf(solo_enc, &vb->vb, enc_buf);
+ solo_enc_fillbuf(solo_enc, &vb->vb.vb2_buf, enc_buf);
unlock:
mutex_unlock(&solo_enc->lock);
}
@@ -659,7 +663,7 @@ static int solo_ring_thread(void *data)
}
static int solo_enc_queue_setup(struct vb2_queue *q,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *num_buffers,
unsigned int *num_planes, unsigned int sizes[],
void *alloc_ctxs[])
@@ -678,10 +682,11 @@ static int solo_enc_queue_setup(struct vb2_queue *q,
static void solo_enc_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vq);
struct solo_vb2_buf *solo_vb =
- container_of(vb, struct solo_vb2_buf, vb);
+ container_of(vbuf, struct solo_vb2_buf, vb);
spin_lock(&solo_enc->av_lock);
list_add_tail(&solo_vb->list, &solo_enc->vidq_active);
@@ -734,25 +739,26 @@ static void solo_enc_stop_streaming(struct vb2_queue *q)
struct solo_vb2_buf, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&solo_enc->av_lock, flags);
}
static void solo_enc_buf_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vb->vb2_queue);
- struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0);
+ struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
switch (solo_enc->fmt) {
case V4L2_PIX_FMT_MPEG4:
case V4L2_PIX_FMT_H264:
- if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
- sg_copy_from_buffer(vbuf->sgl, vbuf->nents,
+ if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+ sg_copy_from_buffer(sgt->sgl, sgt->nents,
solo_enc->vop, solo_enc->vop_len);
break;
default: /* V4L2_PIX_FMT_MJPEG */
- sg_copy_from_buffer(vbuf->sgl, vbuf->nents,
+ sg_copy_from_buffer(sgt->sgl, sgt->nents,
solo_enc->jpeg_header, solo_enc->jpeg_len);
break;
}
@@ -1291,7 +1297,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
solo_enc->vidq.ops = &solo_enc_video_qops;
solo_enc->vidq.mem_ops = &vb2_dma_sg_memops;
solo_enc->vidq.drv_priv = solo_enc;
- solo_enc->vidq.gfp_flags = __GFP_DMA32;
+ solo_enc->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM;
solo_enc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
solo_enc->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
solo_enc->vidq.lock = &solo_enc->lock;
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
index 63ae8a61f603..f7ce493b1fee 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
@@ -26,6 +26,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "solo6x10.h"
@@ -191,13 +192,14 @@ static int solo_v4l2_set_ch(struct solo_dev *solo_dev, u8 ch)
static void solo_fillbuf(struct solo_dev *solo_dev,
struct vb2_buffer *vb)
{
- dma_addr_t vbuf;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ dma_addr_t addr;
unsigned int fdma_addr;
int error = -1;
int i;
- vbuf = vb2_dma_contig_plane_dma_addr(vb, 0);
- if (!vbuf)
+ addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (!addr)
goto finish_buf;
if (erase_off(solo_dev)) {
@@ -213,7 +215,7 @@ static void solo_fillbuf(struct solo_dev *solo_dev,
fdma_addr = SOLO_DISP_EXT_ADDR + (solo_dev->old_write *
(SOLO_HW_BPL * solo_vlines(solo_dev)));
- error = solo_p2m_dma_t(solo_dev, 0, vbuf, fdma_addr,
+ error = solo_p2m_dma_t(solo_dev, 0, addr, fdma_addr,
solo_bytesperline(solo_dev),
solo_vlines(solo_dev), SOLO_HW_BPL);
}
@@ -222,8 +224,8 @@ finish_buf:
if (!error) {
vb2_set_plane_payload(vb, 0,
solo_vlines(solo_dev) * solo_bytesperline(solo_dev));
- vb->v4l2_buf.sequence = solo_dev->sequence++;
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
+ vbuf->sequence = solo_dev->sequence++;
+ v4l2_get_timestamp(&vbuf->timestamp);
}
vb2_buffer_done(vb, error ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
@@ -256,7 +258,7 @@ static void solo_thread_try(struct solo_dev *solo_dev)
spin_unlock(&solo_dev->slock);
- solo_fillbuf(solo_dev, &vb->vb);
+ solo_fillbuf(solo_dev, &vb->vb.vb2_buf);
}
assert_spin_locked(&solo_dev->slock);
@@ -311,7 +313,7 @@ static void solo_stop_thread(struct solo_dev *solo_dev)
solo_dev->kthread = NULL;
}
-static int solo_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int solo_queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -345,10 +347,11 @@ static void solo_stop_streaming(struct vb2_queue *q)
static void solo_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct solo_dev *solo_dev = vb2_get_drv_priv(vq);
struct solo_vb2_buf *solo_vb =
- container_of(vb, struct solo_vb2_buf, vb);
+ container_of(vbuf, struct solo_vb2_buf, vb);
spin_lock(&solo_dev->slock);
list_add_tail(&solo_vb->list, &solo_dev->vidq_active);
@@ -675,7 +678,7 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
solo_dev->vidq.mem_ops = &vb2_dma_contig_memops;
solo_dev->vidq.drv_priv = solo_dev;
solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- solo_dev->vidq.gfp_flags = __GFP_DMA32;
+ solo_dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM;
solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
solo_dev->vidq.lock = &solo_dev->lock;
ret = vb2_queue_init(&solo_dev->vidq);
diff --git a/drivers/media/pci/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h
index 27423d7f5410..4ab6586c0467 100644
--- a/drivers/media/pci/solo6x10/solo6x10.h
+++ b/drivers/media/pci/solo6x10/solo6x10.h
@@ -35,7 +35,7 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "solo6x10-regs.h"
@@ -135,7 +135,7 @@ struct solo_p2m_dev {
#define OSD_TEXT_MAX 44
struct solo_vb2_buf {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index 59b3a36a3639..6367b455a7e7 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -88,11 +88,11 @@
struct vip_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
dma_addr_t dma;
};
-static inline struct vip_buffer *to_vip_buffer(struct vb2_buffer *vb2)
+static inline struct vip_buffer *to_vip_buffer(struct vb2_v4l2_buffer *vb2)
{
return container_of(vb2, struct vip_buffer, vb);
}
@@ -265,7 +265,7 @@ static void vip_active_buf_next(struct sta2x11_vip *vip)
/* Videobuf2 Operations */
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -287,7 +287,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
};
static int buffer_init(struct vb2_buffer *vb)
{
- struct vip_buffer *vip_buf = to_vip_buffer(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vip_buffer *vip_buf = to_vip_buffer(vbuf);
vip_buf->dma = vb2_dma_contig_plane_dma_addr(vb, 0);
INIT_LIST_HEAD(&vip_buf->list);
@@ -296,8 +297,9 @@ static int buffer_init(struct vb2_buffer *vb)
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
- struct vip_buffer *vip_buf = to_vip_buffer(vb);
+ struct vip_buffer *vip_buf = to_vip_buffer(vbuf);
unsigned long size;
size = vip->format.sizeimage;
@@ -307,14 +309,15 @@ static int buffer_prepare(struct vb2_buffer *vb)
return -EINVAL;
}
- vb2_set_plane_payload(&vip_buf->vb, 0, size);
+ vb2_set_plane_payload(&vip_buf->vb.vb2_buf, 0, size);
return 0;
}
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
- struct vip_buffer *vip_buf = to_vip_buffer(vb);
+ struct vip_buffer *vip_buf = to_vip_buffer(vbuf);
spin_lock(&vip->lock);
list_add_tail(&vip_buf->list, &vip->buffer_list);
@@ -329,8 +332,9 @@ static void buffer_queue(struct vb2_buffer *vb)
}
static void buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
- struct vip_buffer *vip_buf = to_vip_buffer(vb);
+ struct vip_buffer *vip_buf = to_vip_buffer(vbuf);
/* Buffer handled, remove it from the list */
spin_lock(&vip->lock);
@@ -370,7 +374,7 @@ static void stop_streaming(struct vb2_queue *vq)
/* Release all active buffers */
spin_lock(&vip->lock);
list_for_each_entry_safe(vip_buf, node, &vip->buffer_list, list) {
- vb2_buffer_done(&vip_buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&vip_buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&vip_buf->list);
}
spin_unlock(&vip->lock);
@@ -813,9 +817,9 @@ static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
/* Disable acquisition */
reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA);
/* Remove the active buffer from the list */
- v4l2_get_timestamp(&vip->active->vb.v4l2_buf.timestamp);
- vip->active->vb.v4l2_buf.sequence = vip->sequence++;
- vb2_buffer_done(&vip->active->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vip->active->vb.timestamp);
+ vip->active->vb.sequence = vip->sequence++;
+ vb2_buffer_done(&vip->active->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
return IRQ_HANDLED;
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
index 3f24fce74fc1..f89364951ebd 100644
--- a/drivers/media/pci/ttpci/av7110.c
+++ b/drivers/media/pci/ttpci/av7110.c
@@ -303,7 +303,6 @@ static int arm_thread(void *data)
static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
u8 *buffer2, size_t buffer2_len,
struct dvb_demux_filter *dvbdmxfilter,
- enum dmx_success success,
struct av7110 *av7110)
{
if (!dvbdmxfilter->feed->demux->dmx.frontend)
@@ -329,16 +328,14 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
}
return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
buffer2, buffer2_len,
- &dvbdmxfilter->filter,
- DMX_OK);
+ &dvbdmxfilter->filter);
case DMX_TYPE_TS:
if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
return 0;
if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
buffer2, buffer2_len,
- &dvbdmxfilter->feed->feed.ts,
- DMX_OK);
+ &dvbdmxfilter->feed->feed.ts);
else
av7110_p2t_write(buffer1, buffer1_len,
dvbdmxfilter->feed->pid,
@@ -422,7 +419,7 @@ static void debiirq(unsigned long cookie)
DvbDmxFilterCallback((u8 *)av7110->debi_virt,
av7110->debilen, NULL, 0,
av7110->handle2filter[handle],
- DMX_OK, av7110);
+ av7110);
xfer = RX_BUFF;
break;
diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c
index 9544cfc06601..9ed1ec7d3551 100644
--- a/drivers/media/pci/ttpci/av7110_av.c
+++ b/drivers/media/pci/ttpci/av7110_av.c
@@ -102,7 +102,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
buf[4] = buf[5] = 0;
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
- &dvbdmxfeed->feed.ts, DMX_OK);
+ &dvbdmxfeed->feed.ts);
else
return dvb_filter_pes2ts(p2t, buf, len, 1);
}
@@ -112,7 +112,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
dvbdmxfeed->cb.ts(data, 188, NULL, 0,
- &dvbdmxfeed->feed.ts, DMX_OK);
+ &dvbdmxfeed->feed.ts);
return 0;
}
@@ -815,7 +815,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
memcpy(obuf + l, buf + c, TS_SIZE - l);
c = length;
}
- feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
+ feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts);
pes_start = 0;
}
}
diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c
index 04706cc9b818..4e77618fbb2b 100644
--- a/drivers/media/pci/tw68/tw68-core.c
+++ b/drivers/media/pci/tw68/tw68-core.c
@@ -257,9 +257,9 @@ static int tw68_initdev(struct pci_dev *pci_dev,
dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
dev->pci_lat, (u64)pci_resource_start(pci_dev, 0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) {
+ err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
+ if (err) {
pr_info("%s: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
goto fail1;
}
diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c
index 8355e55b4e8e..46642ef9151b 100644
--- a/drivers/media/pci/tw68/tw68-video.c
+++ b/drivers/media/pci/tw68/tw68-video.c
@@ -376,10 +376,11 @@ static int tw68_buffer_count(unsigned int size, unsigned int count)
/* ------------------------------------------------------------- */
/* vb2 queue operations */
-static int tw68_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+static int tw68_queue_setup(struct vb2_queue *q, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct tw68_dev *dev = vb2_get_drv_priv(q);
unsigned tot_bufs = q->num_buffers + *num_buffers;
@@ -423,9 +424,10 @@ static int tw68_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
*/
static void tw68_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct tw68_dev *dev = vb2_get_drv_priv(vq);
- struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
+ struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
struct tw68_buf *prev;
unsigned long flags;
@@ -457,9 +459,10 @@ static void tw68_buf_queue(struct vb2_buffer *vb)
*/
static int tw68_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct tw68_dev *dev = vb2_get_drv_priv(vq);
- struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
+ struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0);
unsigned size, bpl;
@@ -499,9 +502,10 @@ static int tw68_buf_prepare(struct vb2_buffer *vb)
static void tw68_buf_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct tw68_dev *dev = vb2_get_drv_priv(vq);
- struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
+ struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
pci_free_consistent(dev->pci, buf->size, buf->cpu, buf->dma);
}
@@ -528,7 +532,7 @@ static void tw68_stop_streaming(struct vb2_queue *q)
container_of(dev->active.next, struct tw68_buf, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
}
@@ -975,7 +979,7 @@ int tw68_video_init2(struct tw68_dev *dev, int video_nr)
dev->vidq.ops = &tw68_video_qops;
dev->vidq.mem_ops = &vb2_dma_sg_memops;
dev->vidq.drv_priv = dev;
- dev->vidq.gfp_flags = __GFP_DMA32;
+ dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM;
dev->vidq.buf_struct_size = sizeof(struct tw68_buf);
dev->vidq.lock = &dev->lock;
dev->vidq.min_buffers_needed = 2;
@@ -1012,10 +1016,10 @@ void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status)
buf = list_entry(dev->active.next, struct tw68_buf, list);
list_del(&buf->list);
spin_unlock(&dev->slock);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.field = dev->field;
- buf->vb.v4l2_buf.sequence = dev->seqnr++;
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.field = dev->field;
+ buf->vb.sequence = dev->seqnr++;
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
status &= ~(TW68_DMAPI);
if (0 == status)
return;
diff --git a/drivers/media/pci/tw68/tw68.h b/drivers/media/pci/tw68/tw68.h
index ef51e4d48866..6c7dcb300f34 100644
--- a/drivers/media/pci/tw68/tw68.h
+++ b/drivers/media/pci/tw68/tw68.h
@@ -36,6 +36,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-sg.h>
#include "tw68-reg.h"
@@ -118,7 +119,7 @@ struct tw68_dev; /* forward delclaration */
/* buffer for one video/vbi/ts frame */
struct tw68_buf {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
unsigned int size;
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index dc75694ac12d..ccbc9742cb7a 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -233,7 +233,7 @@ config VIDEO_SH_VEU
config VIDEO_RENESAS_JPU
tristate "Renesas JPEG Processing Unit"
- depends on VIDEO_DEV && VIDEO_V4L2
+ depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
depends on ARCH_SHMOBILE || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index c8447fa3fd91..f0480d687f17 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -307,7 +307,8 @@ static inline struct vpfe_device *to_vpfe(struct vpfe_ccdc *ccdc)
return container_of(ccdc, struct vpfe_device, ccdc);
}
-static inline struct vpfe_cap_buffer *to_vpfe_buffer(struct vb2_buffer *vb)
+static inline
+struct vpfe_cap_buffer *to_vpfe_buffer(struct vb2_v4l2_buffer *vb)
{
return container_of(vb, struct vpfe_cap_buffer, vb);
}
@@ -1257,14 +1258,14 @@ static inline void vpfe_schedule_next_buffer(struct vpfe_device *vpfe)
list_del(&vpfe->next_frm->list);
vpfe_set_sdr_addr(&vpfe->ccdc,
- vb2_dma_contig_plane_dma_addr(&vpfe->next_frm->vb, 0));
+ vb2_dma_contig_plane_dma_addr(&vpfe->next_frm->vb.vb2_buf, 0));
}
static inline void vpfe_schedule_bottom_field(struct vpfe_device *vpfe)
{
unsigned long addr;
- addr = vb2_dma_contig_plane_dma_addr(&vpfe->next_frm->vb, 0) +
+ addr = vb2_dma_contig_plane_dma_addr(&vpfe->next_frm->vb.vb2_buf, 0) +
vpfe->field_off;
vpfe_set_sdr_addr(&vpfe->ccdc, addr);
@@ -1280,10 +1281,10 @@ static inline void vpfe_schedule_bottom_field(struct vpfe_device *vpfe)
*/
static inline void vpfe_process_buffer_complete(struct vpfe_device *vpfe)
{
- v4l2_get_timestamp(&vpfe->cur_frm->vb.v4l2_buf.timestamp);
- vpfe->cur_frm->vb.v4l2_buf.field = vpfe->fmt.fmt.pix.field;
- vpfe->cur_frm->vb.v4l2_buf.sequence = vpfe->sequence++;
- vb2_buffer_done(&vpfe->cur_frm->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vpfe->cur_frm->vb.timestamp);
+ vpfe->cur_frm->vb.field = vpfe->fmt.fmt.pix.field;
+ vpfe->cur_frm->vb.sequence = vpfe->sequence++;
+ vb2_buffer_done(&vpfe->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
vpfe->cur_frm = vpfe->next_frm;
}
@@ -1907,10 +1908,11 @@ static void vpfe_calculate_offsets(struct vpfe_device *vpfe)
* the buffer count and buffer size
*/
static int vpfe_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct vpfe_device *vpfe = vb2_get_drv_priv(vq);
if (fmt && fmt->fmt.pix.sizeimage < vpfe->fmt.fmt.pix.sizeimage)
@@ -1942,6 +1944,7 @@ static int vpfe_queue_setup(struct vb2_queue *vq,
*/
static int vpfe_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vpfe_device *vpfe = vb2_get_drv_priv(vb->vb2_queue);
vb2_set_plane_payload(vb, 0, vpfe->fmt.fmt.pix.sizeimage);
@@ -1949,7 +1952,7 @@ static int vpfe_buffer_prepare(struct vb2_buffer *vb)
if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
return -EINVAL;
- vb->v4l2_buf.field = vpfe->fmt.fmt.pix.field;
+ vbuf->field = vpfe->fmt.fmt.pix.field;
return 0;
}
@@ -1960,8 +1963,9 @@ static int vpfe_buffer_prepare(struct vb2_buffer *vb)
*/
static void vpfe_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vpfe_device *vpfe = vb2_get_drv_priv(vb->vb2_queue);
- struct vpfe_cap_buffer *buf = to_vpfe_buffer(vb);
+ struct vpfe_cap_buffer *buf = to_vpfe_buffer(vbuf);
unsigned long flags = 0;
/* add the buffer to the DMA queue */
@@ -2006,7 +2010,7 @@ static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count)
list_del(&vpfe->cur_frm->list);
spin_unlock_irqrestore(&vpfe->dma_queue_lock, flags);
- addr = vb2_dma_contig_plane_dma_addr(&vpfe->cur_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&vpfe->cur_frm->vb.vb2_buf, 0);
vpfe_set_sdr_addr(&vpfe->ccdc, (unsigned long)(addr));
@@ -2023,7 +2027,7 @@ static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count)
err:
list_for_each_entry_safe(buf, tmp, &vpfe->dma_queue, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
}
return ret;
@@ -2055,13 +2059,14 @@ static void vpfe_stop_streaming(struct vb2_queue *vq)
/* release all active buffers */
spin_lock_irqsave(&vpfe->dma_queue_lock, flags);
if (vpfe->cur_frm == vpfe->next_frm) {
- vb2_buffer_done(&vpfe->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&vpfe->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
} else {
if (vpfe->cur_frm != NULL)
- vb2_buffer_done(&vpfe->cur_frm->vb,
+ vb2_buffer_done(&vpfe->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
if (vpfe->next_frm != NULL)
- vb2_buffer_done(&vpfe->next_frm->vb,
+ vb2_buffer_done(&vpfe->next_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
}
@@ -2069,7 +2074,8 @@ static void vpfe_stop_streaming(struct vb2_queue *vq)
vpfe->next_frm = list_entry(vpfe->dma_queue.next,
struct vpfe_cap_buffer, list);
list_del(&vpfe->next_frm->list);
- vb2_buffer_done(&vpfe->next_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&vpfe->next_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&vpfe->dma_queue_lock, flags);
}
@@ -2546,11 +2552,12 @@ static int vpfe_probe(struct platform_device *pdev)
if (IS_ERR(ccdc->ccdc_cfg.base_addr))
return PTR_ERR(ccdc->ccdc_cfg.base_addr);
- vpfe->irq = platform_get_irq(pdev, 0);
- if (vpfe->irq <= 0) {
+ ret = platform_get_irq(pdev, 0);
+ if (ret <= 0) {
dev_err(&pdev->dev, "No IRQ resource\n");
return -ENODEV;
}
+ vpfe->irq = ret;
ret = devm_request_irq(vpfe->pdev, vpfe->irq, vpfe_isr, 0,
"vpfe_capture0", vpfe);
diff --git a/drivers/media/platform/am437x/am437x-vpfe.h b/drivers/media/platform/am437x/am437x-vpfe.h
index 5bfb35649a39..777bf97fea57 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.h
+++ b/drivers/media/platform/am437x/am437x-vpfe.h
@@ -31,6 +31,7 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "am437x-vpfe_regs.h"
@@ -104,7 +105,7 @@ struct vpfe_config {
};
struct vpfe_cap_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index b7e70fb05eb8..7764b9c482ef 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -54,7 +54,7 @@ struct bcap_format {
};
struct bcap_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -149,7 +149,7 @@ static const struct bcap_format bcap_formats[] = {
static irqreturn_t bcap_isr(int irq, void *dev_id);
-static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb)
+static struct bcap_buffer *to_bcap_vb(struct vb2_v4l2_buffer *vb)
{
return container_of(vb, struct bcap_buffer, vb);
}
@@ -202,10 +202,11 @@ static void bcap_free_sensor_formats(struct bcap_device *bcap_dev)
}
static int bcap_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
if (fmt && fmt->fmt.pix.sizeimage < bcap_dev->fmt.sizeimage)
@@ -223,6 +224,7 @@ static int bcap_queue_setup(struct vb2_queue *vq,
static int bcap_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
unsigned long size = bcap_dev->fmt.sizeimage;
@@ -233,15 +235,16 @@ static int bcap_buffer_prepare(struct vb2_buffer *vb)
}
vb2_set_plane_payload(vb, 0, size);
- vb->v4l2_buf.field = bcap_dev->fmt.field;
+ vbuf->field = bcap_dev->fmt.field;
return 0;
}
static void bcap_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
- struct bcap_buffer *buf = to_bcap_vb(vb);
+ struct bcap_buffer *buf = to_bcap_vb(vbuf);
unsigned long flags;
spin_lock_irqsave(&bcap_dev->lock, flags);
@@ -251,8 +254,9 @@ static void bcap_buffer_queue(struct vb2_buffer *vb)
static void bcap_buffer_cleanup(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
- struct bcap_buffer *buf = to_bcap_vb(vb);
+ struct bcap_buffer *buf = to_bcap_vb(vbuf);
unsigned long flags;
spin_lock_irqsave(&bcap_dev->lock, flags);
@@ -333,7 +337,8 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
struct bcap_buffer, list);
/* remove buffer from the dma queue */
list_del_init(&bcap_dev->cur_frm->list);
- addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb.vb2_buf,
+ 0);
/* update DMA address */
ppi->ops->update_addr(ppi, (unsigned long)addr);
/* enable ppi */
@@ -344,7 +349,7 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
err:
list_for_each_entry_safe(buf, tmp, &bcap_dev->dma_queue, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
}
return ret;
@@ -367,13 +372,15 @@ static void bcap_stop_streaming(struct vb2_queue *vq)
/* release all active buffers */
if (bcap_dev->cur_frm)
- vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&bcap_dev->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
while (!list_empty(&bcap_dev->dma_queue)) {
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
struct bcap_buffer, list);
list_del_init(&bcap_dev->cur_frm->list);
- vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&bcap_dev->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
}
}
@@ -392,18 +399,19 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
{
struct ppi_if *ppi = dev_id;
struct bcap_device *bcap_dev = ppi->priv;
- struct vb2_buffer *vb = &bcap_dev->cur_frm->vb;
+ struct vb2_v4l2_buffer *vbuf = &bcap_dev->cur_frm->vb;
+ struct vb2_buffer *vb = &vbuf->vb2_buf;
dma_addr_t addr;
spin_lock(&bcap_dev->lock);
if (!list_empty(&bcap_dev->dma_queue)) {
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
+ v4l2_get_timestamp(&vbuf->timestamp);
if (ppi->err) {
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
ppi->err = false;
} else {
- vb->v4l2_buf.sequence = bcap_dev->sequence++;
+ vbuf->sequence = bcap_dev->sequence++;
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
}
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
@@ -420,7 +428,8 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
if (bcap_dev->stop) {
complete(&bcap_dev->comp);
} else {
- addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(
+ &bcap_dev->cur_frm->vb.vb2_buf, 0);
ppi->ops->update_addr(ppi, (unsigned long)addr);
ppi->ops->start(ppi);
}
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index fd7819d8922d..654e964f84a2 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -25,7 +25,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
@@ -179,31 +179,32 @@ static void coda_kfifo_sync_to_device_write(struct coda_ctx *ctx)
}
static int coda_bitstream_queue(struct coda_ctx *ctx,
- struct vb2_buffer *src_buf)
+ struct vb2_v4l2_buffer *src_buf)
{
- u32 src_size = vb2_get_plane_payload(src_buf, 0);
+ u32 src_size = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
u32 n;
- n = kfifo_in(&ctx->bitstream_fifo, vb2_plane_vaddr(src_buf, 0),
- src_size);
+ n = kfifo_in(&ctx->bitstream_fifo,
+ vb2_plane_vaddr(&src_buf->vb2_buf, 0), src_size);
if (n < src_size)
return -ENOSPC;
- src_buf->v4l2_buf.sequence = ctx->qsequence++;
+ src_buf->sequence = ctx->qsequence++;
return 0;
}
static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
- struct vb2_buffer *src_buf)
+ struct vb2_v4l2_buffer *src_buf)
{
int ret;
if (coda_get_bitstream_payload(ctx) +
- vb2_get_plane_payload(src_buf, 0) + 512 >= ctx->bitstream.size)
+ vb2_get_plane_payload(&src_buf->vb2_buf, 0) + 512 >=
+ ctx->bitstream.size)
return false;
- if (vb2_plane_vaddr(src_buf, 0) == NULL) {
+ if (vb2_plane_vaddr(&src_buf->vb2_buf, 0) == NULL) {
v4l2_err(&ctx->dev->v4l2_dev, "trying to queue empty buffer\n");
return true;
}
@@ -224,7 +225,7 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
{
- struct vb2_buffer *src_buf;
+ struct vb2_v4l2_buffer *src_buf;
struct coda_buffer_meta *meta;
unsigned long flags;
u32 start;
@@ -257,7 +258,7 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
}
/* Dump empty buffers */
- if (!vb2_get_plane_payload(src_buf, 0)) {
+ if (!vb2_get_plane_payload(&src_buf->vb2_buf, 0)) {
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
continue;
@@ -276,9 +277,9 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
meta = kmalloc(sizeof(*meta), GFP_KERNEL);
if (meta) {
- meta->sequence = src_buf->v4l2_buf.sequence;
- meta->timecode = src_buf->v4l2_buf.timecode;
- meta->timestamp = src_buf->v4l2_buf.timestamp;
+ meta->sequence = src_buf->sequence;
+ meta->timecode = src_buf->timecode;
+ meta->timestamp = src_buf->timestamp;
meta->start = start;
meta->end = ctx->bitstream_fifo.kfifo.in &
ctx->bitstream_fifo.kfifo.mask;
@@ -483,20 +484,21 @@ err:
return ret;
}
-static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
+static int coda_encode_header(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
int header_code, u8 *header, int *size)
{
+ struct vb2_buffer *vb = &buf->vb2_buf;
struct coda_dev *dev = ctx->dev;
size_t bufsize;
int ret;
int i;
if (dev->devtype->product == CODA_960)
- memset(vb2_plane_vaddr(buf, 0), 0, 64);
+ memset(vb2_plane_vaddr(vb, 0), 0, 64);
- coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(vb, 0),
CODA_CMD_ENC_HEADER_BB_START);
- bufsize = vb2_plane_size(buf, 0);
+ bufsize = vb2_plane_size(vb, 0);
if (dev->devtype->product == CODA_960)
bufsize /= 1024;
coda_write(dev, bufsize, CODA_CMD_ENC_HEADER_BB_SIZE);
@@ -509,14 +511,14 @@ static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
if (dev->devtype->product == CODA_960) {
for (i = 63; i > 0; i--)
- if (((char *)vb2_plane_vaddr(buf, 0))[i] != 0)
+ if (((char *)vb2_plane_vaddr(vb, 0))[i] != 0)
break;
*size = i + 1;
} else {
*size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)) -
coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
}
- memcpy(header, vb2_plane_vaddr(buf, 0), *size);
+ memcpy(header, vb2_plane_vaddr(vb, 0), *size);
return 0;
}
@@ -799,7 +801,7 @@ static int coda_start_encoding(struct coda_ctx *ctx)
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
struct coda_q_data *q_data_src, *q_data_dst;
u32 bitstream_buf, bitstream_size;
- struct vb2_buffer *buf;
+ struct vb2_v4l2_buffer *buf;
int gamma, ret, value;
u32 dst_fourcc;
int num_fb;
@@ -810,7 +812,7 @@ static int coda_start_encoding(struct coda_ctx *ctx)
dst_fourcc = q_data_dst->fourcc;
buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
- bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
+ bitstream_buf = vb2_dma_contig_plane_dma_addr(&buf->vb2_buf, 0);
bitstream_size = q_data_dst->sizeimage;
if (!coda_is_initialized(dev)) {
@@ -1185,7 +1187,7 @@ out:
static int coda_prepare_encode(struct coda_ctx *ctx)
{
struct coda_q_data *q_data_src, *q_data_dst;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
struct coda_dev *dev = ctx->dev;
int force_ipicture;
int quant_param = 0;
@@ -1200,8 +1202,8 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
dst_fourcc = q_data_dst->fourcc;
- src_buf->v4l2_buf.sequence = ctx->osequence;
- dst_buf->v4l2_buf.sequence = ctx->osequence;
+ src_buf->sequence = ctx->osequence;
+ dst_buf->sequence = ctx->osequence;
ctx->osequence++;
/*
@@ -1209,12 +1211,12 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
* frame as IDR. This is a problem for some decoders that can't
* recover when a frame is lost.
*/
- if (src_buf->v4l2_buf.sequence % ctx->params.gop_size) {
- src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
- src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
+ if (src_buf->sequence % ctx->params.gop_size) {
+ src_buf->flags |= V4L2_BUF_FLAG_PFRAME;
+ src_buf->flags &= ~V4L2_BUF_FLAG_KEYFRAME;
} else {
- src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
- src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
+ src_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+ src_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
}
if (dev->devtype->product == CODA_960)
@@ -1224,9 +1226,9 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
* Copy headers at the beginning of the first frame for H.264 only.
* In MPEG4 they are already copied by the coda.
*/
- if (src_buf->v4l2_buf.sequence == 0) {
+ if (src_buf->sequence == 0) {
pic_stream_buffer_addr =
- vb2_dma_contig_plane_dma_addr(dst_buf, 0) +
+ vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0) +
ctx->vpu_header_size[0] +
ctx->vpu_header_size[1] +
ctx->vpu_header_size[2];
@@ -1234,20 +1236,21 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
ctx->vpu_header_size[0] -
ctx->vpu_header_size[1] -
ctx->vpu_header_size[2];
- memcpy(vb2_plane_vaddr(dst_buf, 0),
+ memcpy(vb2_plane_vaddr(&dst_buf->vb2_buf, 0),
&ctx->vpu_header[0][0], ctx->vpu_header_size[0]);
- memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0],
- &ctx->vpu_header[1][0], ctx->vpu_header_size[1]);
- memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0] +
- ctx->vpu_header_size[1], &ctx->vpu_header[2][0],
- ctx->vpu_header_size[2]);
+ memcpy(vb2_plane_vaddr(&dst_buf->vb2_buf, 0)
+ + ctx->vpu_header_size[0], &ctx->vpu_header[1][0],
+ ctx->vpu_header_size[1]);
+ memcpy(vb2_plane_vaddr(&dst_buf->vb2_buf, 0)
+ + ctx->vpu_header_size[0] + ctx->vpu_header_size[1],
+ &ctx->vpu_header[2][0], ctx->vpu_header_size[2]);
} else {
pic_stream_buffer_addr =
- vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
pic_stream_buffer_size = q_data_dst->sizeimage;
}
- if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
+ if (src_buf->flags & V4L2_BUF_FLAG_KEYFRAME) {
force_ipicture = 1;
switch (dst_fourcc) {
case V4L2_PIX_FMT_H264:
@@ -1324,7 +1327,7 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
static void coda_finish_encode(struct coda_ctx *ctx)
{
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
struct coda_dev *dev = ctx->dev;
u32 wr_ptr, start_ptr;
@@ -1338,13 +1341,13 @@ static void coda_finish_encode(struct coda_ctx *ctx)
wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
/* Calculate bytesused field */
- if (dst_buf->v4l2_buf.sequence == 0) {
- vb2_set_plane_payload(dst_buf, 0, wr_ptr - start_ptr +
+ if (dst_buf->sequence == 0) {
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
ctx->vpu_header_size[0] +
ctx->vpu_header_size[1] +
ctx->vpu_header_size[2]);
} else {
- vb2_set_plane_payload(dst_buf, 0, wr_ptr - start_ptr);
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr);
}
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, "frame size = %u\n",
@@ -1354,18 +1357,18 @@ static void coda_finish_encode(struct coda_ctx *ctx)
coda_read(dev, CODA_RET_ENC_PIC_FLAG);
if (coda_read(dev, CODA_RET_ENC_PIC_TYPE) == 0) {
- dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
+ dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+ dst_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
} else {
- dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
+ dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
+ dst_buf->flags &= ~V4L2_BUF_FLAG_KEYFRAME;
}
- dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_buf->v4l2_buf.flags |=
- src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
+ dst_buf->timestamp = src_buf->timestamp;
+ dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_buf->flags |=
+ src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_buf->timecode = src_buf->timecode;
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
@@ -1378,8 +1381,8 @@ static void coda_finish_encode(struct coda_ctx *ctx)
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
"job finished: encoding frame (%d) (%s)\n",
- dst_buf->v4l2_buf.sequence,
- (dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
+ dst_buf->sequence,
+ (dst_buf->flags & V4L2_BUF_FLAG_KEYFRAME) ?
"KEYFRAME" : "PFRAME");
}
@@ -1716,7 +1719,7 @@ static int coda_start_decoding(struct coda_ctx *ctx)
static int coda_prepare_decode(struct coda_ctx *ctx)
{
- struct vb2_buffer *dst_buf;
+ struct vb2_v4l2_buffer *dst_buf;
struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data_dst;
struct coda_buffer_meta *meta;
@@ -1763,7 +1766,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
* well as the rotator buffer output.
* ROT_INDEX needs to be < 0x40, but > ctx->num_internal_frames.
*/
- coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->v4l2_buf.index,
+ coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->vb2_buf.index,
CODA9_CMD_DEC_PIC_ROT_INDEX);
reg_addr = CODA9_CMD_DEC_PIC_ROT_ADDR_Y;
@@ -1838,7 +1841,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data_src;
struct coda_q_data *q_data_dst;
- struct vb2_buffer *dst_buf;
+ struct vb2_v4l2_buffer *dst_buf;
struct coda_buffer_meta *meta;
unsigned long payload;
unsigned long flags;
@@ -2029,15 +2032,15 @@ static void coda_finish_decode(struct coda_ctx *ctx)
if (ctx->display_idx >= 0 &&
ctx->display_idx < ctx->num_internal_frames) {
dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
- dst_buf->v4l2_buf.sequence = ctx->osequence++;
+ dst_buf->sequence = ctx->osequence++;
- dst_buf->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
+ dst_buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
V4L2_BUF_FLAG_PFRAME |
V4L2_BUF_FLAG_BFRAME);
- dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx];
+ dst_buf->flags |= ctx->frame_types[ctx->display_idx];
meta = &ctx->frame_metas[ctx->display_idx];
- dst_buf->v4l2_buf.timecode = meta->timecode;
- dst_buf->v4l2_buf.timestamp = meta->timestamp;
+ dst_buf->timecode = meta->timecode;
+ dst_buf->timestamp = meta->timestamp;
trace_coda_dec_rot_done(ctx, dst_buf, meta);
@@ -2052,15 +2055,15 @@ static void coda_finish_decode(struct coda_ctx *ctx)
payload = width * height * 2;
break;
}
- vb2_set_plane_payload(dst_buf, 0, payload);
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
coda_m2m_buf_done(ctx, dst_buf, ctx->frame_errors[display_idx] ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
"job finished: decoding frame (%d) (%s)\n",
- dst_buf->v4l2_buf.sequence,
- (dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
+ dst_buf->sequence,
+ (dst_buf->flags & V4L2_BUF_FLAG_KEYFRAME) ?
"KEYFRAME" : "PFRAME");
} else {
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index a4654e0c104d..15516a6e3a39 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -36,7 +36,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
@@ -84,9 +84,9 @@ unsigned int coda_read(struct coda_dev *dev, u32 reg)
}
void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data,
- struct vb2_buffer *buf, unsigned int reg_y)
+ struct vb2_v4l2_buffer *buf, unsigned int reg_y)
{
- u32 base_y = vb2_dma_contig_plane_dma_addr(buf, 0);
+ u32 base_y = vb2_dma_contig_plane_dma_addr(&buf->vb2_buf, 0);
u32 base_cb, base_cr;
switch (q_data->fourcc) {
@@ -684,17 +684,17 @@ static int coda_qbuf(struct file *file, void *priv,
}
static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx,
- struct vb2_buffer *buf)
+ struct vb2_v4l2_buffer *buf)
{
struct vb2_queue *src_vq;
src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
return ((ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) &&
- (buf->v4l2_buf.sequence == (ctx->qsequence - 1)));
+ (buf->sequence == (ctx->qsequence - 1)));
}
-void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_buffer *buf,
+void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
enum vb2_buffer_state state)
{
const struct v4l2_event eos_event = {
@@ -702,7 +702,7 @@ void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_buffer *buf,
};
if (coda_buf_is_end_of_stream(ctx, buf)) {
- buf->v4l2_buf.flags |= V4L2_BUF_FLAG_LAST;
+ buf->flags |= V4L2_BUF_FLAG_LAST;
v4l2_event_queue_fh(&ctx->fh, &eos_event);
}
@@ -1131,8 +1131,7 @@ static void set_default_params(struct coda_ctx *ctx)
/*
* Queue operations
*/
-static int coda_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+static int coda_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -1175,6 +1174,7 @@ static int coda_buf_prepare(struct vb2_buffer *vb)
static void coda_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_queue *vq = vb->vb2_queue;
struct coda_q_data *q_data;
@@ -1193,12 +1193,12 @@ static void coda_buf_queue(struct vb2_buffer *vb)
if (vb2_get_plane_payload(vb, 0) == 0)
coda_bit_stream_end_flag(ctx);
mutex_lock(&ctx->bitstream_mutex);
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
if (vb2_is_streaming(vb->vb2_queue))
coda_fill_bitstream(ctx, true);
mutex_unlock(&ctx->bitstream_mutex);
} else {
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
}
@@ -1247,7 +1247,7 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
struct coda_q_data *q_data_src, *q_data_dst;
- struct vb2_buffer *buf;
+ struct vb2_v4l2_buffer *buf;
int ret = 0;
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
@@ -1338,7 +1338,7 @@ static void coda_stop_streaming(struct vb2_queue *q)
{
struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct coda_dev *dev = ctx->dev;
- struct vb2_buffer *buf;
+ struct vb2_v4l2_buffer *buf;
unsigned long flags;
bool stop;
diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
index 11e734bc2cbd..96cd42a0baaf 100644
--- a/drivers/media/platform/coda/coda-jpeg.c
+++ b/drivers/media/platform/coda/coda-jpeg.c
@@ -178,12 +178,12 @@ int coda_jpeg_write_tables(struct coda_ctx *ctx)
return 0;
}
-bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
+bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_v4l2_buffer *vb)
{
- void *vaddr = vb2_plane_vaddr(vb, 0);
+ void *vaddr = vb2_plane_vaddr(&vb->vb2_buf, 0);
u16 soi = be16_to_cpup((__be16 *)vaddr);
u16 eoi = be16_to_cpup((__be16 *)(vaddr +
- vb2_get_plane_payload(vb, 0) - 2));
+ vb2_get_plane_payload(&vb->vb2_buf, 0) - 2));
return soi == SOI_MARKER && eoi == EOI_MARKER;
}
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 59b2af9c7749..96532b06bd9e 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -24,7 +24,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "coda_regs.h"
@@ -243,7 +243,7 @@ extern int coda_debug;
void coda_write(struct coda_dev *dev, u32 data, u32 reg);
unsigned int coda_read(struct coda_dev *dev, u32 reg);
void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data,
- struct vb2_buffer *buf, unsigned int reg_y);
+ struct vb2_v4l2_buffer *buf, unsigned int reg_y);
int coda_alloc_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf,
size_t size, const char *name, struct dentry *parent);
@@ -284,12 +284,12 @@ static inline unsigned int coda_get_bitstream_payload(struct coda_ctx *ctx)
void coda_bit_stream_end_flag(struct coda_ctx *ctx);
-void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_buffer *buf,
+void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
enum vb2_buffer_state state);
int coda_h264_padding(int size, char *p);
-bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb);
+bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_v4l2_buffer *vb);
int coda_jpeg_write_tables(struct coda_ctx *ctx);
void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality);
diff --git a/drivers/media/platform/coda/trace.h b/drivers/media/platform/coda/trace.h
index d9099a0f7c32..f20666a4aa89 100644
--- a/drivers/media/platform/coda/trace.h
+++ b/drivers/media/platform/coda/trace.h
@@ -5,7 +5,7 @@
#define __CODA_TRACE_H__
#include <linux/tracepoint.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "coda.h"
@@ -49,7 +49,7 @@ TRACE_EVENT(coda_bit_done,
);
DECLARE_EVENT_CLASS(coda_buf_class,
- TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf),
+ TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
TP_ARGS(ctx, buf),
@@ -61,7 +61,7 @@ DECLARE_EVENT_CLASS(coda_buf_class,
TP_fast_assign(
__entry->minor = ctx->fh.vdev->minor;
- __entry->index = buf->v4l2_buf.index;
+ __entry->index = buf->vb2_buf.index;
__entry->ctx = ctx->idx;
),
@@ -70,17 +70,17 @@ DECLARE_EVENT_CLASS(coda_buf_class,
);
DEFINE_EVENT(coda_buf_class, coda_enc_pic_run,
- TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf),
+ TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
TP_ARGS(ctx, buf)
);
DEFINE_EVENT(coda_buf_class, coda_enc_pic_done,
- TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf),
+ TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
TP_ARGS(ctx, buf)
);
DECLARE_EVENT_CLASS(coda_buf_meta_class,
- TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf,
+ TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
struct coda_buffer_meta *meta),
TP_ARGS(ctx, buf, meta),
@@ -95,7 +95,7 @@ DECLARE_EVENT_CLASS(coda_buf_meta_class,
TP_fast_assign(
__entry->minor = ctx->fh.vdev->minor;
- __entry->index = buf->v4l2_buf.index;
+ __entry->index = buf->vb2_buf.index;
__entry->start = meta->start;
__entry->end = meta->end;
__entry->ctx = ctx->idx;
@@ -107,7 +107,7 @@ DECLARE_EVENT_CLASS(coda_buf_meta_class,
);
DEFINE_EVENT(coda_buf_meta_class, coda_bit_queue,
- TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf,
+ TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
struct coda_buffer_meta *meta),
TP_ARGS(ctx, buf, meta)
);
@@ -146,7 +146,7 @@ DEFINE_EVENT(coda_meta_class, coda_dec_pic_done,
);
DEFINE_EVENT(coda_buf_meta_class, coda_dec_rot_done,
- TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf,
+ TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
struct coda_buffer_meta *meta),
TP_ARGS(ctx, buf, meta)
);
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index f69cdd7da10c..6d91422c4e4c 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -74,8 +74,8 @@ static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
if (layer->cur_frm == layer->next_frm)
return;
- v4l2_get_timestamp(&layer->cur_frm->vb.v4l2_buf.timestamp);
- vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&layer->cur_frm->vb.timestamp);
+ vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
/* Make cur_frm pointing to next_frm */
layer->cur_frm = layer->next_frm;
}
@@ -104,8 +104,8 @@ static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
list_del(&layer->next_frm->list);
spin_unlock(&disp_obj->dma_queue_lock);
/* Mark state of the frame to active */
- layer->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
- addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb, 0);
+ layer->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
+ addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb.vb2_buf, 0);
osd_device->ops.start_layer(osd_device,
layer->layer_info.id,
addr,
@@ -228,11 +228,12 @@ static int vpbe_buffer_prepare(struct vb2_buffer *vb)
* This function allocates memory for the buffers
*/
static int
-vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+vpbe_buffer_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
/* Get the file handle object and layer object */
struct vpbe_layer *layer = vb2_get_drv_priv(vq);
struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
@@ -259,8 +260,9 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
*/
static void vpbe_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
/* Get the file handle object and layer object */
- struct vpbe_disp_buffer *buf = container_of(vb,
+ struct vpbe_disp_buffer *buf = container_of(vbuf,
struct vpbe_disp_buffer, vb);
struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
struct vpbe_display *disp = layer->disp_dev;
@@ -290,7 +292,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
/* Remove buffer from the buffer queue */
list_del(&layer->cur_frm->list);
/* Mark state of the current frame to active */
- layer->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+ layer->cur_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
/* Initialize field_id and started member */
layer->field_id = 0;
@@ -299,10 +301,12 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
if (ret < 0) {
struct vpbe_disp_buffer *buf, *tmp;
- vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
return ret;
@@ -332,13 +336,14 @@ static void vpbe_stop_streaming(struct vb2_queue *vq)
/* release all active buffers */
spin_lock_irqsave(&disp->dma_queue_lock, flags);
if (layer->cur_frm == layer->next_frm) {
- vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
} else {
if (layer->cur_frm != NULL)
- vb2_buffer_done(&layer->cur_frm->vb,
+ vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
if (layer->next_frm != NULL)
- vb2_buffer_done(&layer->next_frm->vb,
+ vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
}
@@ -346,7 +351,8 @@ static void vpbe_stop_streaming(struct vb2_queue *vq)
layer->next_frm = list_entry(layer->dma_queue.next,
struct vpbe_disp_buffer, list);
list_del(&layer->next_frm->list);
- vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
}
@@ -383,7 +389,7 @@ static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
unsigned long addr;
int ret;
- addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb.vb2_buf, 0);
/* Set address in the display registers */
osd_device->ops.start_layer(osd_device,
layer->layer_info.id,
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index a5f548138b91..c1e573b7cc6f 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -57,7 +57,8 @@ static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} };
/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
static int ycmux_mode;
-static inline struct vpif_cap_buffer *to_vpif_buffer(struct vb2_buffer *vb)
+static inline
+struct vpif_cap_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)
{
return container_of(vb, struct vpif_cap_buffer, vb);
}
@@ -72,6 +73,7 @@ static inline struct vpif_cap_buffer *to_vpif_buffer(struct vb2_buffer *vb)
*/
static int vpif_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *q = vb->vb2_queue;
struct channel_obj *ch = vb2_get_drv_priv(q);
struct common_obj *common;
@@ -85,7 +87,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
return -EINVAL;
- vb->v4l2_buf.field = common->fmt.fmt.pix.field;
+ vbuf->field = common->fmt.fmt.pix.field;
addr = vb2_dma_contig_plane_dma_addr(vb, 0);
if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
@@ -112,10 +114,11 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
* the buffer count and buffer size
*/
static int vpif_buffer_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct channel_obj *ch = vb2_get_drv_priv(vq);
struct common_obj *common;
@@ -145,8 +148,9 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
*/
static void vpif_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
- struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
+ struct vpif_cap_buffer *buf = to_vpif_buffer(vbuf);
struct common_obj *common;
unsigned long flags;
@@ -214,7 +218,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
list_del(&common->cur_frm->list);
spin_unlock_irqrestore(&common->irqlock, flags);
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
common->set_addr(addr + common->ytop_off,
addr + common->ybtm_off,
@@ -243,7 +247,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
err:
list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
}
spin_unlock_irqrestore(&common->irqlock, flags);
@@ -286,13 +290,14 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
/* release all active buffers */
spin_lock_irqsave(&common->irqlock, flags);
if (common->cur_frm == common->next_frm) {
- vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
} else {
if (common->cur_frm != NULL)
- vb2_buffer_done(&common->cur_frm->vb,
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
if (common->next_frm != NULL)
- vb2_buffer_done(&common->next_frm->vb,
+ vb2_buffer_done(&common->next_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
}
@@ -300,7 +305,8 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
common->next_frm = list_entry(common->dma_queue.next,
struct vpif_cap_buffer, list);
list_del(&common->next_frm->list);
- vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&common->next_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&common->irqlock, flags);
}
@@ -325,9 +331,8 @@ static struct vb2_ops video_qops = {
*/
static void vpif_process_buffer_complete(struct common_obj *common)
{
- v4l2_get_timestamp(&common->cur_frm->vb.v4l2_buf.timestamp);
- vb2_buffer_done(&common->cur_frm->vb,
- VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&common->cur_frm->vb.timestamp);
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
/* Make curFrm pointing to nextFrm */
common->cur_frm = common->next_frm;
}
@@ -350,7 +355,7 @@ static void vpif_schedule_next_buffer(struct common_obj *common)
/* Remove that buffer from the buffer queue */
list_del(&common->next_frm->list);
spin_unlock(&common->irqlock);
- addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);
/* Set top and bottom field addresses in VPIF registers */
common->set_addr(addr + common->ytop_off,
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index 8b8a663f6b22..4a7600929b61 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -52,7 +52,7 @@ struct video_obj {
};
struct vpif_cap_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 682e5d578bf7..fd2780306c17 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -53,7 +53,8 @@ static struct device *vpif_dev;
static void vpif_calculate_offsets(struct channel_obj *ch);
static void vpif_config_addr(struct channel_obj *ch, int muxmode);
-static inline struct vpif_disp_buffer *to_vpif_buffer(struct vb2_buffer *vb)
+static inline
+struct vpif_disp_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)
{
return container_of(vb, struct vpif_disp_buffer, vb);
}
@@ -68,6 +69,7 @@ static inline struct vpif_disp_buffer *to_vpif_buffer(struct vb2_buffer *vb)
*/
static int vpif_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
struct common_obj *common;
@@ -77,7 +79,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
return -EINVAL;
- vb->v4l2_buf.field = common->fmt.fmt.pix.field;
+ vbuf->field = common->fmt.fmt.pix.field;
if (vb->vb2_queue->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
unsigned long addr = vb2_dma_contig_plane_dma_addr(vb, 0);
@@ -107,10 +109,11 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
* the buffer count and buffer size
*/
static int vpif_buffer_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct channel_obj *ch = vb2_get_drv_priv(vq);
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
@@ -138,7 +141,8 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
*/
static void vpif_buffer_queue(struct vb2_buffer *vb)
{
- struct vpif_disp_buffer *buf = to_vpif_buffer(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vpif_disp_buffer *buf = to_vpif_buffer(vbuf);
struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
struct common_obj *common;
unsigned long flags;
@@ -197,7 +201,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
list_del(&common->cur_frm->list);
spin_unlock_irqrestore(&common->irqlock, flags);
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
common->set_addr((addr + common->ytop_off),
(addr + common->ybtm_off),
(addr + common->ctop_off),
@@ -229,7 +233,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
err:
list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
}
spin_unlock_irqrestore(&common->irqlock, flags);
@@ -264,13 +268,14 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
/* release all active buffers */
spin_lock_irqsave(&common->irqlock, flags);
if (common->cur_frm == common->next_frm) {
- vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
} else {
if (common->cur_frm != NULL)
- vb2_buffer_done(&common->cur_frm->vb,
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
if (common->next_frm != NULL)
- vb2_buffer_done(&common->next_frm->vb,
+ vb2_buffer_done(&common->next_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
}
@@ -278,7 +283,8 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
common->next_frm = list_entry(common->dma_queue.next,
struct vpif_disp_buffer, list);
list_del(&common->next_frm->list);
- vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&common->next_frm->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&common->irqlock, flags);
}
@@ -306,7 +312,7 @@ static void process_progressive_mode(struct common_obj *common)
spin_unlock(&common->irqlock);
/* Set top and bottom field addrs in VPIF registers */
- addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);
common->set_addr(addr + common->ytop_off,
addr + common->ybtm_off,
addr + common->ctop_off,
@@ -324,10 +330,10 @@ static void process_interlaced_mode(int fid, struct common_obj *common)
/* one frame is displayed If next frame is
* available, release cur_frm and move on */
/* Copy frame display time */
- v4l2_get_timestamp(&common->cur_frm->vb.v4l2_buf.timestamp);
+ v4l2_get_timestamp(&common->cur_frm->vb.timestamp);
/* Change status of the cur_frm */
- vb2_buffer_done(&common->cur_frm->vb,
- VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_DONE);
/* Make cur_frm pointing to next_frm */
common->cur_frm = common->next_frm;
@@ -380,10 +386,10 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
if (!channel_first_int[i][channel_id]) {
/* Mark status of the cur_frm to
* done and unlock semaphore on it */
- v4l2_get_timestamp(&common->cur_frm->vb.
- v4l2_buf.timestamp);
- vb2_buffer_done(&common->cur_frm->vb,
- VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(
+ &common->cur_frm->vb.timestamp);
+ vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+ VB2_BUF_STATE_DONE);
/* Make cur_frm pointing to next_frm */
common->cur_frm = common->next_frm;
}
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index 849e0e385f18..e7a1723a1b7a 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -62,7 +62,7 @@ struct video_obj {
};
struct vpif_disp_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h
index fa572aacdb3f..e93a2336cfa2 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.h
+++ b/drivers/media/platform/exynos-gsc/gsc-core.h
@@ -19,7 +19,7 @@
#include <linux/videodev2.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h>
@@ -136,7 +136,7 @@ struct gsc_fmt {
* @idx : index of G-Scaler input buffer
*/
struct gsc_input_buf {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
int idx;
};
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
index d5cffef2e227..d82e717acba7 100644
--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
+++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
@@ -77,7 +77,7 @@ static void gsc_m2m_stop_streaming(struct vb2_queue *q)
void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
{
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
if (!ctx || !ctx->m2m_ctx)
return;
@@ -86,11 +86,11 @@ void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
if (src_vb && dst_vb) {
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
- dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
- dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.flags |=
- src_vb->v4l2_buf.flags
+ dst_vb->timestamp = src_vb->timestamp;
+ dst_vb->timecode = src_vb->timecode;
+ dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_vb->flags |=
+ src_vb->flags
& V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
v4l2_m2m_buf_done(src_vb, vb_state);
@@ -109,23 +109,23 @@ static void gsc_m2m_job_abort(void *priv)
static int gsc_get_bufs(struct gsc_ctx *ctx)
{
struct gsc_frame *s_frame, *d_frame;
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
int ret;
s_frame = &ctx->s_frame;
d_frame = &ctx->d_frame;
src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- ret = gsc_prepare_addr(ctx, src_vb, s_frame, &s_frame->addr);
+ ret = gsc_prepare_addr(ctx, &src_vb->vb2_buf, s_frame, &s_frame->addr);
if (ret)
return ret;
dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- ret = gsc_prepare_addr(ctx, dst_vb, d_frame, &d_frame->addr);
+ ret = gsc_prepare_addr(ctx, &dst_vb->vb2_buf, d_frame, &d_frame->addr);
if (ret)
return ret;
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
+ dst_vb->timestamp = src_vb->timestamp;
return 0;
}
@@ -212,7 +212,7 @@ put_device:
}
static int gsc_m2m_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *allocators[])
{
@@ -255,12 +255,13 @@ static int gsc_m2m_buf_prepare(struct vb2_buffer *vb)
static void gsc_m2m_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct gsc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
pr_debug("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
if (ctx->m2m_ctx)
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
}
static struct vb2_ops gsc_m2m_qops = {
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index cfebf292e15a..99e57320e6f7 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -24,7 +24,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "common.h"
@@ -103,7 +103,7 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
/* Release unused buffers */
while (!suspend && !list_empty(&cap->pending_buf_q)) {
buf = fimc_pending_queue_pop(cap);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
/* If suspending put unused buffers onto pending queue */
while (!list_empty(&cap->active_buf_q)) {
@@ -111,7 +111,7 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
if (suspend)
fimc_pending_queue_add(cap, buf);
else
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
fimc_hw_reset(fimc);
@@ -183,8 +183,6 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
struct fimc_frame *f = &cap->ctx->d_frame;
struct fimc_vid_buffer *v_buf;
- struct timeval *tv;
- struct timespec ts;
if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
wake_up(&fimc->irq_queue);
@@ -193,16 +191,12 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
if (!list_empty(&cap->active_buf_q) &&
test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
- ktime_get_real_ts(&ts);
-
v_buf = fimc_active_queue_pop(cap);
- tv = &v_buf->vb.v4l2_buf.timestamp;
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
- v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
+ v4l2_get_timestamp(&v_buf->vb.timestamp);
+ v_buf->vb.sequence = cap->frame_count++;
- vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&v_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
if (!list_empty(&cap->pending_buf_q)) {
@@ -233,7 +227,7 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
list_for_each_entry(v_buf, &cap->active_buf_q, list) {
if (v_buf->index != index)
continue;
- vaddr = vb2_plane_vaddr(&v_buf->vb, plane);
+ vaddr = vb2_plane_vaddr(&v_buf->vb.vb2_buf, plane);
v4l2_subdev_call(csis, video, s_rx_buffer,
vaddr, &size);
break;
@@ -338,16 +332,17 @@ int fimc_capture_resume(struct fimc_dev *fimc)
if (list_empty(&vid_cap->pending_buf_q))
break;
buf = fimc_pending_queue_pop(vid_cap);
- buffer_queue(&buf->vb);
+ buffer_queue(&buf->vb.vb2_buf);
}
return 0;
}
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *allocators[])
{
+ const struct v4l2_format *pfmt = parg;
const struct v4l2_pix_format_mplane *pixm = NULL;
struct fimc_ctx *ctx = vq->drv_priv;
struct fimc_frame *frame = &ctx->d_frame;
@@ -410,8 +405,9 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct fimc_vid_buffer *buf
- = container_of(vb, struct fimc_vid_buffer, vb);
+ = container_of(vbuf, struct fimc_vid_buffer, vb);
struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct fimc_dev *fimc = ctx->fimc_dev;
struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
@@ -420,7 +416,7 @@ static void buffer_queue(struct vb2_buffer *vb)
int min_bufs;
spin_lock_irqsave(&fimc->slock, flags);
- fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
+ fimc_prepare_addr(ctx, &buf->vb.vb2_buf, &ctx->d_frame, &buf->paddr);
if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
!test_bit(ST_CAPT_STREAM, &fimc->state) &&
@@ -1472,7 +1468,8 @@ void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
if (!list_empty(&fimc->vid_cap.active_buf_q)) {
buf = list_entry(fimc->vid_cap.active_buf_q.next,
struct fimc_vid_buffer, list);
- vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0,
+ *((u32 *)arg));
}
fimc_capture_irq_handler(fimc, 1);
fimc_deactivate_capture(fimc);
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index 1101c41ac117..cef2a7f07cdb 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -27,7 +27,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "fimc-core.h"
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
index 7328f0845065..d336fa2916df 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/exynos4-is/fimc-core.h
@@ -22,7 +22,7 @@
#include <linux/sizes.h>
#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h>
@@ -224,7 +224,7 @@ struct fimc_addr {
* @index: buffer index for the output DMA engine
*/
struct fimc_vid_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
struct fimc_addr paddr;
int index;
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
index e0be691af2d3..386eb49ece7e 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.h
+++ b/drivers/media/platform/exynos4-is/fimc-is.h
@@ -22,7 +22,7 @@
#include <linux/sizes.h>
#include <linux/spinlock.h>
#include <linux/types.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-ctrls.h>
#include "fimc-isp.h"
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 76b6b4d14616..6e6648446f00 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -28,7 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/exynos-fimc.h>
@@ -39,10 +39,11 @@
#include "fimc-is-param.h"
static int isp_video_capture_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *pfmt,
+ const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *allocators[])
{
+ const struct v4l2_format *pfmt = parg;
struct fimc_isp *isp = vb2_get_drv_priv(vq);
struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt;
const struct v4l2_pix_format_mplane *pixm = NULL;
@@ -194,10 +195,11 @@ static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb)
static void isp_video_capture_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
struct fimc_is_video *video = &isp->video_capture;
struct fimc_is *is = fimc_isp_to_is(isp);
- struct isp_video_buf *ivb = to_isp_video_buf(vb);
+ struct isp_video_buf *ivb = to_isp_video_buf(vbuf);
unsigned long flags;
unsigned int i;
@@ -220,7 +222,7 @@ static void isp_video_capture_buffer_queue(struct vb2_buffer *vb)
isp_dbg(2, &video->ve.vdev,
"dma_buf %pad (%d/%d/%d) addr: %pad\n",
- &buf_index, ivb->index, i, vb->v4l2_buf.index,
+ &buf_index, ivb->index, i, vb->index,
&ivb->dma_addr[i]);
}
@@ -242,7 +244,7 @@ static void isp_video_capture_buffer_queue(struct vb2_buffer *vb)
void fimc_isp_video_irq_handler(struct fimc_is *is)
{
struct fimc_is_video *video = &is->isp.video_capture;
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vbuf;
int buf_index;
/* TODO: Ensure the DMA is really stopped in stop_streaming callback */
@@ -250,10 +252,10 @@ void fimc_isp_video_irq_handler(struct fimc_is *is)
return;
buf_index = (is->i2h_cmd.args[1] - 1) % video->buf_count;
- vb = &video->buffers[buf_index]->vb;
+ vbuf = &video->buffers[buf_index]->vb;
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vbuf->timestamp);
+ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
video->buf_mask &= ~BIT(buf_index);
fimc_is_hw_set_isp_buf_mask(is, video->buf_mask);
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.h b/drivers/media/platform/exynos4-is/fimc-isp-video.h
index 98c662654bb6..f79a1b348aa6 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.h
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.h
@@ -11,7 +11,7 @@
#ifndef FIMC_ISP_VIDEO__
#define FIMC_ISP_VIDEO__
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "fimc-isp.h"
#ifdef CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
index b99be09b49fc..c2d25df85db9 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.h
+++ b/drivers/media/platform/exynos4-is/fimc-isp.h
@@ -21,7 +21,7 @@
#include <linux/videodev2.h>
#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
#include <media/exynos-fimc.h>
@@ -102,7 +102,7 @@ struct fimc_isp_ctrls {
};
struct isp_video_buf {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
dma_addr_t dma_addr[FIMC_ISP_MAX_PLANES];
unsigned int index;
};
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index ca6261a86a5f..60660c3a5de0 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -28,7 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/exynos-fimc.h>
@@ -200,7 +200,7 @@ static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
/* Release unused buffers */
while (!suspend && !list_empty(&fimc->pending_buf_q)) {
buf = fimc_lite_pending_queue_pop(fimc);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
/* If suspending put unused buffers onto pending queue */
while (!list_empty(&fimc->active_buf_q)) {
@@ -208,7 +208,7 @@ static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
if (suspend)
fimc_lite_pending_queue_add(fimc, buf);
else
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&fimc->slock, flags);
@@ -254,8 +254,6 @@ static irqreturn_t flite_irq_handler(int irq, void *priv)
struct fimc_lite *fimc = priv;
struct flite_buffer *vbuf;
unsigned long flags;
- struct timeval *tv;
- struct timespec ts;
u32 intsrc;
spin_lock_irqsave(&fimc->slock, flags);
@@ -294,13 +292,10 @@ static irqreturn_t flite_irq_handler(int irq, void *priv)
test_bit(ST_FLITE_RUN, &fimc->state) &&
!list_empty(&fimc->active_buf_q)) {
vbuf = fimc_lite_active_queue_pop(fimc);
- ktime_get_ts(&ts);
- tv = &vbuf->vb.v4l2_buf.timestamp;
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
- vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
+ v4l2_get_timestamp(&vbuf->vb.timestamp);
+ vbuf->vb.sequence = fimc->frame_count++;
flite_hw_mask_dma_buffer(fimc, vbuf->index);
- vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&vbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
if (test_bit(ST_FLITE_CONFIG, &fimc->state))
@@ -360,10 +355,11 @@ static void stop_streaming(struct vb2_queue *q)
fimc_lite_stop_capture(fimc, false);
}
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *allocators[])
{
+ const struct v4l2_format *pfmt = parg;
const struct v4l2_pix_format_mplane *pixm = NULL;
struct fimc_lite *fimc = vq->drv_priv;
struct flite_frame *frame = &fimc->out_frame;
@@ -422,8 +418,9 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct flite_buffer *buf
- = container_of(vb, struct flite_buffer, vb);
+ = container_of(vbuf, struct flite_buffer, vb);
struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
unsigned long flags;
@@ -1637,7 +1634,7 @@ static int fimc_lite_resume(struct device *dev)
if (list_empty(&fimc->pending_buf_q))
break;
buf = fimc_lite_pending_queue_pop(fimc);
- buffer_queue(&buf->vb);
+ buffer_queue(&buf->vb.vb2_buf);
}
return 0;
}
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
index ea19dc7be63e..b302305dedbe 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite.h
@@ -19,7 +19,7 @@
#include <linux/videodev2.h>
#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
@@ -100,7 +100,7 @@ struct flite_frame {
* @index: DMA start address register's index
*/
struct flite_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
dma_addr_t paddr;
unsigned short index;
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index d2bfe7c2a6b4..4d1d64a46b21 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "common.h"
@@ -42,7 +42,7 @@ static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
{
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
if (!ctx || !ctx->fh.m2m_ctx)
return;
@@ -99,7 +99,7 @@ static void stop_streaming(struct vb2_queue *q)
static void fimc_device_run(void *priv)
{
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
struct fimc_ctx *ctx = priv;
struct fimc_frame *sf, *df;
struct fimc_dev *fimc;
@@ -123,19 +123,19 @@ static void fimc_device_run(void *priv)
}
src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- ret = fimc_prepare_addr(ctx, src_vb, sf, &sf->paddr);
+ ret = fimc_prepare_addr(ctx, &src_vb->vb2_buf, sf, &sf->paddr);
if (ret)
goto dma_unlock;
dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
- ret = fimc_prepare_addr(ctx, dst_vb, df, &df->paddr);
+ ret = fimc_prepare_addr(ctx, &dst_vb->vb2_buf, df, &df->paddr);
if (ret)
goto dma_unlock;
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
- dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.flags |=
- src_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_vb->timestamp = src_vb->timestamp;
+ dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_vb->flags |=
+ src_vb->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
/* Reconfigure hardware if the context has changed. */
if (fimc->m2m.ctx != ctx) {
@@ -176,7 +176,7 @@ static void fimc_job_abort(void *priv)
fimc_m2m_shutdown(priv);
}
-static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int fimc_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *allocators[])
{
@@ -220,8 +220,9 @@ static int fimc_buf_prepare(struct vb2_buffer *vb)
static void fimc_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
static struct vb2_ops fimc_qops = {
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index d74e1bec3d86..4b85105dc159 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -706,7 +706,8 @@ static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
else
offset = S5PCSIS_PKTDATA_ODD;
- memcpy(pktbuf->data, state->regs + offset, pktbuf->len);
+ memcpy(pktbuf->data, (u8 __force *)state->regs + offset,
+ pktbuf->len);
pktbuf->data = NULL;
rmb();
}
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index c07f367aa436..29973f9bf8db 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -200,18 +200,18 @@ static void dma_callback(void *data)
{
struct deinterlace_ctx *curr_ctx = data;
struct deinterlace_dev *pcdev = curr_ctx->dev;
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
atomic_set(&pcdev->busy, 0);
src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
- dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.flags |=
- src_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
+ dst_vb->timestamp = src_vb->timestamp;
+ dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_vb->flags |=
+ src_vb->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_vb->timecode = src_vb->timecode;
v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
@@ -225,7 +225,7 @@ static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op,
int do_callback)
{
struct deinterlace_q_data *s_q_data;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
struct deinterlace_dev *pcdev = ctx->dev;
struct dma_chan *chan = pcdev->dma_chan;
struct dma_device *dmadev = chan->device;
@@ -243,8 +243,9 @@ static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op,
s_height = s_q_data->height;
s_size = s_width * s_height;
- p_in = (dma_addr_t)vb2_dma_contig_plane_dma_addr(src_buf, 0);
- p_out = (dma_addr_t)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ p_in = (dma_addr_t)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+ p_out = (dma_addr_t)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf,
+ 0);
if (!p_in || !p_out) {
v4l2_err(&pcdev->v4l2_dev,
"Acquiring kernel pointers to buffers failed\n");
@@ -797,7 +798,7 @@ struct vb2_dc_conf {
};
static int deinterlace_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -849,8 +850,10 @@ static int deinterlace_buf_prepare(struct vb2_buffer *vb)
static void deinterlace_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
}
static struct vb2_ops deinterlace_qops = {
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index 5e2b4df48b3c..aa2b44041d3f 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -201,18 +201,18 @@ struct mcam_dma_desc {
/*
* Our buffer type for working with videobuf2. Note that the vb2
- * developers have decreed that struct vb2_buffer must be at the
+ * developers have decreed that struct vb2_v4l2_buffer must be at the
* beginning of this structure.
*/
struct mcam_vb_buffer {
- struct vb2_buffer vb_buf;
+ struct vb2_v4l2_buffer vb_buf;
struct list_head queue;
struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */
dma_addr_t dma_desc_pa; /* Descriptor physical address */
int dma_desc_nent; /* Number of mapped descriptors */
};
-static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb)
+static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_v4l2_buffer *vb)
{
return container_of(vb, struct mcam_vb_buffer, vb_buf);
}
@@ -221,14 +221,14 @@ static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb)
* Hand a completed buffer back to user space.
*/
static void mcam_buffer_done(struct mcam_camera *cam, int frame,
- struct vb2_buffer *vbuf)
+ struct vb2_v4l2_buffer *vbuf)
{
- vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage;
- vbuf->v4l2_buf.sequence = cam->buf_seq[frame];
- vbuf->v4l2_buf.field = V4L2_FIELD_NONE;
- v4l2_get_timestamp(&vbuf->v4l2_buf.timestamp);
- vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage);
- vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE);
+ vbuf->vb2_buf.planes[0].bytesused = cam->pix_format.sizeimage;
+ vbuf->sequence = cam->buf_seq[frame];
+ vbuf->field = V4L2_FIELD_NONE;
+ v4l2_get_timestamp(&vbuf->timestamp);
+ vb2_set_plane_payload(&vbuf->vb2_buf, 0, cam->pix_format.sizeimage);
+ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
}
@@ -482,7 +482,8 @@ static void mcam_frame_tasklet(unsigned long data)
* Drop the lock during the big copy. This *should* be safe...
*/
spin_unlock_irqrestore(&cam->dev_lock, flags);
- memcpy(vb2_plane_vaddr(&buf->vb_buf, 0), cam->dma_bufs[bufno],
+ memcpy(vb2_plane_vaddr(&buf->vb_buf.vb2_buf, 0),
+ cam->dma_bufs[bufno],
cam->pix_format.sizeimage);
mcam_buffer_done(cam, bufno, &buf->vb_buf);
spin_lock_irqsave(&cam->dev_lock, flags);
@@ -548,7 +549,7 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)
{
struct mcam_vb_buffer *buf;
dma_addr_t dma_handle;
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vb;
/*
* If there are no available buffers, go into single mode
@@ -570,7 +571,7 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)
cam->vb_bufs[frame] = buf;
vb = &buf->vb_buf;
- dma_handle = vb2_dma_contig_plane_dma_addr(vb, 0);
+ dma_handle = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
mcam_write_yuv_bases(cam, frame, dma_handle);
}
@@ -1048,10 +1049,11 @@ static int mcam_read_setup(struct mcam_camera *cam)
*/
static int mcam_vb_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbufs,
+ const void *parg, unsigned int *nbufs,
unsigned int *num_planes, unsigned int sizes[],
void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct mcam_camera *cam = vb2_get_drv_priv(vq);
int minbufs = (cam->buffer_mode == B_DMA_contig) ? 3 : 2;
@@ -1071,7 +1073,8 @@ static int mcam_vb_queue_setup(struct vb2_queue *vq,
static void mcam_vb_buf_queue(struct vb2_buffer *vb)
{
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
unsigned long flags;
int start;
@@ -1096,14 +1099,14 @@ static void mcam_vb_requeue_bufs(struct vb2_queue *vq,
spin_lock_irqsave(&cam->dev_lock, flags);
list_for_each_entry_safe(buf, node, &cam->buffers, queue) {
- vb2_buffer_done(&buf->vb_buf, state);
+ vb2_buffer_done(&buf->vb_buf.vb2_buf, state);
list_del(&buf->queue);
}
for (i = 0; i < MAX_DMA_BUFS; i++) {
buf = cam->vb_bufs[i];
if (buf) {
- vb2_buffer_done(&buf->vb_buf, state);
+ vb2_buffer_done(&buf->vb_buf.vb2_buf, state);
cam->vb_bufs[i] = NULL;
}
}
@@ -1198,7 +1201,8 @@ static const struct vb2_ops mcam_vb2_ops = {
*/
static int mcam_vb_sg_buf_init(struct vb2_buffer *vb)
{
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
@@ -1214,7 +1218,8 @@ static int mcam_vb_sg_buf_init(struct vb2_buffer *vb)
static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
{
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
struct mcam_dma_desc *desc = mvb->dma_desc;
struct scatterlist *sg;
@@ -1230,8 +1235,9 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
- struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+ struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc),
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h
index 97167f6ffd1e..35cd9e5aedf8 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.h
+++ b/drivers/media/platform/marvell-ccic/mcam-core.h
@@ -10,7 +10,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dev.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
/*
* Create our own symbols for the supported buffer modes, but, for now,
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index 87314b743f55..03a1b606655d 100644
--- a/drivers/media/platform/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -351,7 +351,7 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data)
{
struct emmaprp_dev *pcdev = data;
struct emmaprp_ctx *curr_ctx;
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
unsigned long flags;
u32 irqst;
@@ -375,13 +375,13 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data)
src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
- dst_vb->v4l2_buf.flags &=
+ dst_vb->timestamp = src_vb->timestamp;
+ dst_vb->flags &=
~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.flags |=
- src_vb->v4l2_buf.flags
+ dst_vb->flags |=
+ src_vb->flags
& V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
+ dst_vb->timecode = src_vb->timecode;
spin_lock_irqsave(&pcdev->irqlock, flags);
v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
@@ -689,7 +689,7 @@ static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = {
* Queue operations
*/
static int emmaprp_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -742,8 +742,9 @@ static int emmaprp_buf_prepare(struct vb2_buffer *vb)
static void emmaprp_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
}
static struct vb2_ops emmaprp_qops = {
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 20434e83e801..94d4c295d3d0 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -235,7 +235,7 @@ static int isp_stat_buf_queue(struct ispstat *stat)
if (!stat->active_buf)
return STAT_NO_BUF;
- ktime_get_ts(&stat->active_buf->ts);
+ v4l2_get_timestamp(&stat->active_buf->ts);
stat->active_buf->buf_size = stat->buf_size;
if (isp_stat_buf_check_magic(stat, stat->active_buf)) {
@@ -496,8 +496,7 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
return PTR_ERR(buf);
}
- data->ts.tv_sec = buf->ts.tv_sec;
- data->ts.tv_usec = buf->ts.tv_nsec / NSEC_PER_USEC;
+ data->ts = buf->ts;
data->config_counter = buf->config_counter;
data->frame_number = buf->frame_number;
data->buf_size = buf->buf_size;
diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h
index b79380d83fcf..6d9b0244f320 100644
--- a/drivers/media/platform/omap3isp/ispstat.h
+++ b/drivers/media/platform/omap3isp/ispstat.h
@@ -39,7 +39,7 @@ struct ispstat_buffer {
struct sg_table sgt;
void *virt_addr;
dma_addr_t dma_addr;
- struct timespec ts;
+ struct timeval ts;
u32 buf_size;
u32 frame_number;
u16 config_counter;
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 41bb8df91f72..f4f591652432 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -320,7 +320,7 @@ isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
*/
static int isp_video_queue_setup(struct vb2_queue *queue,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *count, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -342,8 +342,9 @@ static int isp_video_queue_setup(struct vb2_queue *queue,
static int isp_video_buffer_prepare(struct vb2_buffer *buf)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(buf);
struct isp_video_fh *vfh = vb2_get_drv_priv(buf->vb2_queue);
- struct isp_buffer *buffer = to_isp_buffer(buf);
+ struct isp_buffer *buffer = to_isp_buffer(vbuf);
struct isp_video *video = vfh->video;
dma_addr_t addr;
@@ -363,7 +364,8 @@ static int isp_video_buffer_prepare(struct vb2_buffer *buf)
return -EINVAL;
}
- vb2_set_plane_payload(&buffer->vb, 0, vfh->format.fmt.pix.sizeimage);
+ vb2_set_plane_payload(&buffer->vb.vb2_buf, 0,
+ vfh->format.fmt.pix.sizeimage);
buffer->dma = addr;
return 0;
@@ -380,8 +382,9 @@ static int isp_video_buffer_prepare(struct vb2_buffer *buf)
*/
static void isp_video_buffer_queue(struct vb2_buffer *buf)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(buf);
struct isp_video_fh *vfh = vb2_get_drv_priv(buf->vb2_queue);
- struct isp_buffer *buffer = to_isp_buffer(buf);
+ struct isp_buffer *buffer = to_isp_buffer(vbuf);
struct isp_video *video = vfh->video;
struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
enum isp_pipeline_state state;
@@ -392,7 +395,7 @@ static void isp_video_buffer_queue(struct vb2_buffer *buf)
spin_lock_irqsave(&video->irqlock, flags);
if (unlikely(video->error)) {
- vb2_buffer_done(&buffer->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buffer->vb.vb2_buf, VB2_BUF_STATE_ERROR);
spin_unlock_irqrestore(&video->irqlock, flags);
return;
}
@@ -464,7 +467,7 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
list_del(&buf->irqlist);
spin_unlock_irqrestore(&video->irqlock, flags);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ v4l2_get_timestamp(&buf->vb.timestamp);
/* Do frame number propagation only if this is the output video node.
* Frame number either comes from the CSI receivers or it gets
@@ -473,15 +476,15 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
* first, so the input number might lag behind by 1 in some cases.
*/
if (video == pipe->output && !pipe->do_propagation)
- buf->vb.v4l2_buf.sequence =
+ buf->vb.sequence =
atomic_inc_return(&pipe->frame_number);
else
- buf->vb.v4l2_buf.sequence = atomic_read(&pipe->frame_number);
+ buf->vb.sequence = atomic_read(&pipe->frame_number);
if (pipe->field != V4L2_FIELD_NONE)
- buf->vb.v4l2_buf.sequence /= 2;
+ buf->vb.sequence /= 2;
- buf->vb.v4l2_buf.field = pipe->field;
+ buf->vb.field = pipe->field;
/* Report pipeline errors to userspace on the capture device side. */
if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
@@ -491,7 +494,7 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
state = VB2_BUF_STATE_DONE;
}
- vb2_buffer_done(&buf->vb, state);
+ vb2_buffer_done(&buf->vb.vb2_buf, state);
spin_lock_irqsave(&video->irqlock, flags);
@@ -546,7 +549,7 @@ void omap3isp_video_cancel_stream(struct isp_video *video)
buf = list_first_entry(&video->dmaqueue,
struct isp_buffer, irqlist);
list_del(&buf->irqlist);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
video->error = true;
diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h
index 4071dd7060ea..bcf0e0acc8f3 100644
--- a/drivers/media/platform/omap3isp/ispvideo.h
+++ b/drivers/media/platform/omap3isp/ispvideo.h
@@ -20,7 +20,7 @@
#include <media/media-entity.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#define ISP_VIDEO_DRIVER_NAME "ispvideo"
#define ISP_VIDEO_DRIVER_VERSION "0.0.2"
@@ -122,7 +122,7 @@ static inline int isp_pipeline_ready(struct isp_pipeline *pipe)
* @dma: DMA address
*/
struct isp_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head irqlist;
dma_addr_t dma;
};
diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c
index 2973f070d328..f8e3e83c52a2 100644
--- a/drivers/media/platform/rcar_jpu.c
+++ b/drivers/media/platform/rcar_jpu.c
@@ -37,7 +37,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
@@ -471,7 +471,7 @@ static const char *error_to_text[16] = {
"Unknown"
};
-static struct jpu_buffer *vb2_to_jpu_buffer(struct vb2_buffer *vb)
+static struct jpu_buffer *vb2_to_jpu_buffer(struct vb2_v4l2_buffer *vb)
{
struct v4l2_m2m_buffer *b =
container_of(vb, struct v4l2_m2m_buffer, vb);
@@ -1015,10 +1015,11 @@ error_free:
* ============================================================================
*/
static int jpu_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
struct jpu_q_data *q_data;
unsigned int i;
@@ -1044,6 +1045,7 @@ static int jpu_queue_setup(struct vb2_queue *vq,
static int jpu_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct jpu_q_data *q_data;
unsigned int i;
@@ -1051,9 +1053,9 @@ static int jpu_buf_prepare(struct vb2_buffer *vb)
q_data = jpu_get_q_data(ctx, vb->vb2_queue->type);
if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
- if (vb->v4l2_buf.field == V4L2_FIELD_ANY)
- vb->v4l2_buf.field = V4L2_FIELD_NONE;
- if (vb->v4l2_buf.field != V4L2_FIELD_NONE) {
+ if (vbuf->field == V4L2_FIELD_ANY)
+ vbuf->field = V4L2_FIELD_NONE;
+ if (vbuf->field != V4L2_FIELD_NONE) {
dev_err(ctx->jpu->dev, "%s field isn't supported\n",
__func__);
return -EINVAL;
@@ -1080,10 +1082,11 @@ static int jpu_buf_prepare(struct vb2_buffer *vb)
static void jpu_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
if (!ctx->encoder && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
- struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vb);
+ struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf);
struct jpu_q_data *q_data, adjust;
void *buffer = vb2_plane_vaddr(vb, 0);
unsigned long buf_size = vb2_get_plane_payload(vb, 0);
@@ -1117,7 +1120,7 @@ static void jpu_buf_queue(struct vb2_buffer *vb)
}
if (ctx->fh.m2m_ctx)
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
return;
@@ -1128,14 +1131,15 @@ format_error:
static void jpu_buf_finish(struct vb2_buffer *vb)
{
- struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct jpu_buffer *jpu_buf = vb2_to_jpu_buffer(vbuf);
struct jpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct jpu_q_data *q_data = &ctx->out_q;
enum v4l2_buf_type type = vb->vb2_queue->type;
u8 *buffer;
if (vb->state == VB2_BUF_STATE_DONE)
- vb->v4l2_buf.sequence = jpu_get_q_data(ctx, type)->sequence++;
+ vbuf->sequence = jpu_get_q_data(ctx, type)->sequence++;
if (!ctx->encoder || vb->state != VB2_BUF_STATE_DONE ||
V4L2_TYPE_IS_OUTPUT(type))
@@ -1144,9 +1148,9 @@ static void jpu_buf_finish(struct vb2_buffer *vb)
buffer = vb2_plane_vaddr(vb, 0);
memcpy(buffer, jpeg_hdrs[jpu_buf->compr_quality], JPU_JPEG_HDR_SIZE);
- *(u16 *)(buffer + JPU_JPEG_HEIGHT_OFFSET) =
+ *(__be16 *)(buffer + JPU_JPEG_HEIGHT_OFFSET) =
cpu_to_be16(q_data->format.height);
- *(u16 *)(buffer + JPU_JPEG_WIDTH_OFFSET) =
+ *(__be16 *)(buffer + JPU_JPEG_WIDTH_OFFSET) =
cpu_to_be16(q_data->format.width);
*(buffer + JPU_JPEG_SUBS_OFFSET) = q_data->fmtinfo->subsampling;
}
@@ -1163,7 +1167,7 @@ static int jpu_start_streaming(struct vb2_queue *vq, unsigned count)
static void jpu_stop_streaming(struct vb2_queue *vq)
{
struct jpu_ctx *ctx = vb2_get_drv_priv(vq);
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vb;
unsigned long flags;
for (;;) {
@@ -1327,7 +1331,7 @@ static const struct v4l2_file_operations jpu_fops = {
static void jpu_cleanup(struct jpu_ctx *ctx, bool reset)
{
/* remove current buffers and finish job */
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
unsigned long flags;
spin_lock_irqsave(&ctx->jpu->lock, flags);
@@ -1353,7 +1357,7 @@ static void jpu_device_run(void *priv)
struct jpu *jpu = ctx->jpu;
struct jpu_buffer *jpu_buf;
struct jpu_q_data *q_data;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
unsigned int w, h, bpl;
unsigned char num_planes, subsampling;
unsigned long flags;
@@ -1389,10 +1393,12 @@ static void jpu_device_run(void *priv)
unsigned long src_1_addr, src_2_addr, dst_addr;
unsigned int redu, inft;
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
- src_1_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+ src_1_addr =
+ vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
if (num_planes > 1)
- src_2_addr = vb2_dma_contig_plane_dma_addr(src_buf, 1);
+ src_2_addr = vb2_dma_contig_plane_dma_addr(
+ &src_buf->vb2_buf, 1);
else
src_2_addr = src_1_addr + w * h;
@@ -1453,10 +1459,12 @@ static void jpu_device_run(void *priv)
return;
}
- src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
- dst_1_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+ dst_1_addr =
+ vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
if (q_data->fmtinfo->num_planes > 1)
- dst_2_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+ dst_2_addr = vb2_dma_contig_plane_dma_addr(
+ &dst_buf->vb2_buf, 1);
else
dst_2_addr = dst_1_addr + w * h;
@@ -1511,7 +1519,7 @@ static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
{
struct jpu *jpu = dev_id;
struct jpu_ctx *curr_ctx;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
unsigned int int_status;
int_status = jpu_read(jpu, JINTS);
@@ -1547,18 +1555,18 @@ static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
unsigned long payload_size = jpu_read(jpu, JCDTCU) << 16
| jpu_read(jpu, JCDTCM) << 8
| jpu_read(jpu, JCDTCD);
- vb2_set_plane_payload(dst_buf, 0,
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
payload_size + JPU_JPEG_HDR_SIZE);
}
- dst_buf->v4l2_buf.field = src_buf->v4l2_buf.field;
- dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
- if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TIMECODE)
- dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_buf->v4l2_buf.flags |= src_buf->v4l2_buf.flags &
+ dst_buf->field = src_buf->field;
+ dst_buf->timestamp = src_buf->timestamp;
+ if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE)
+ dst_buf->timecode = src_buf->timecode;
+ dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_buf->flags |= src_buf->flags &
V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_buf->v4l2_buf.flags = src_buf->v4l2_buf.flags &
+ dst_buf->flags = src_buf->flags &
(V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME |
V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 76e6289a5612..537b858cb94a 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -34,7 +34,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "camif-core.h"
@@ -164,12 +164,12 @@ static int camif_reinitialize(struct camif_vp *vp)
/* Release unused buffers */
while (!list_empty(&vp->pending_buf_q)) {
buf = camif_pending_queue_pop(vp);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
while (!list_empty(&vp->active_buf_q)) {
buf = camif_active_queue_pop(vp);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&camif->slock, flags);
@@ -328,25 +328,19 @@ irqreturn_t s3c_camif_irq_handler(int irq, void *priv)
!list_empty(&vp->active_buf_q)) {
unsigned int index;
struct camif_buffer *vbuf;
- struct timeval *tv;
- struct timespec ts;
/*
* Get previous DMA write buffer index:
* 0 => DMA buffer 0, 2;
* 1 => DMA buffer 1, 3.
*/
index = (CISTATUS_FRAMECNT(status) + 2) & 1;
-
- ktime_get_ts(&ts);
vbuf = camif_active_queue_peek(vp, index);
if (!WARN_ON(vbuf == NULL)) {
/* Dequeue a filled buffer */
- tv = &vbuf->vb.v4l2_buf.timestamp;
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
- vbuf->vb.v4l2_buf.sequence = vp->frame_sequence++;
- vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vbuf->vb.timestamp);
+ vbuf->vb.sequence = vp->frame_sequence++;
+ vb2_buffer_done(&vbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
/* Set up an empty buffer at the DMA engine */
vbuf = camif_pending_queue_pop(vp);
@@ -441,10 +435,11 @@ static void stop_streaming(struct vb2_queue *vq)
camif_stop_capture(vp);
}
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *allocators[])
{
+ const struct v4l2_format *pfmt = parg;
const struct v4l2_pix_format *pix = NULL;
struct camif_vp *vp = vb2_get_drv_priv(vq);
struct camif_dev *camif = vp->camif;
@@ -496,13 +491,14 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
- struct camif_buffer *buf = container_of(vb, struct camif_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct camif_buffer *buf = container_of(vbuf, struct camif_buffer, vb);
struct camif_vp *vp = vb2_get_drv_priv(vb->vb2_queue);
struct camif_dev *camif = vp->camif;
unsigned long flags;
spin_lock_irqsave(&camif->slock, flags);
- WARN_ON(camif_prepare_addr(vp, &buf->vb, &buf->paddr));
+ WARN_ON(camif_prepare_addr(vp, &buf->vb.vb2_buf, &buf->paddr));
if (!(vp->state & ST_VP_STREAMING) && vp->active_buffers < 2) {
/* Schedule an empty buffer in H/W */
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..1ba9bb08f5da 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -32,7 +32,7 @@
#include <media/media-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "camif-core.h"
diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h
index 35d2fcdc0036..adaf1969ef63 100644
--- a/drivers/media/platform/s3c-camif/camif-core.h
+++ b/drivers/media/platform/s3c-camif/camif-core.h
@@ -25,7 +25,7 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/s3c_camif.h>
#define S3C_CAMIF_DRIVER_NAME "s3c-camif"
@@ -322,7 +322,7 @@ struct camif_addr {
* @index: an identifier of this buffer at the DMA engine
*/
struct camif_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
struct camif_addr paddr;
unsigned int index;
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 421a7c3b595b..e1936d9d27da 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -23,7 +23,7 @@
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "g2d.h"
@@ -101,7 +101,7 @@ static struct g2d_frame *get_frame(struct g2d_ctx *ctx,
}
}
-static int g2d_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int g2d_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -134,8 +134,9 @@ static int g2d_buf_prepare(struct vb2_buffer *vb)
static void g2d_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
static struct vb2_ops g2d_qops = {
@@ -537,7 +538,7 @@ static irqreturn_t g2d_isr(int irq, void *prv)
{
struct g2d_dev *dev = prv;
struct g2d_ctx *ctx = dev->curr;
- struct vb2_buffer *src, *dst;
+ struct vb2_v4l2_buffer *src, *dst;
g2d_clear_int(dev);
clk_disable(dev->gate);
@@ -550,11 +551,11 @@ static irqreturn_t g2d_isr(int irq, void *prv)
BUG_ON(src == NULL);
BUG_ON(dst == NULL);
- dst->v4l2_buf.timecode = src->v4l2_buf.timecode;
- dst->v4l2_buf.timestamp = src->v4l2_buf.timestamp;
- dst->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst->v4l2_buf.flags |=
- src->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst->timecode = src->timecode;
+ dst->timestamp = src->timestamp;
+ dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst->flags |=
+ src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 9690f9dcb0ca..4a608cbe0fdb 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -26,7 +26,7 @@
#include <linux/string.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "jpeg-core.h"
@@ -626,6 +626,7 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
return exynos3250_decoded_subsampling[ctx->subsampling];
case SJPEG_EXYNOS4:
+ case SJPEG_EXYNOS5433:
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
return exynos4x12_decoded_subsampling[ctx->subsampling];
@@ -750,6 +751,208 @@ static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
ARRAY_SIZE(hactblg0));
}
+static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
+{
+ /*
+ * class: 0 - DC, 1 - AC
+ * id: 0 - Y, 1 - Cb/Cr
+ */
+ if (class) {
+ if (id)
+ return lenval ? EXYNOS4_HUFF_TBL_HACCL :
+ EXYNOS4_HUFF_TBL_HACCV;
+ return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
+
+ }
+ /* class == 0 */
+ if (id)
+ return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
+
+ return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
+}
+
+static inline int exynos4_huff_tbl_len(int class, int id)
+{
+ return __exynos4_huff_tbl(class, id, true);
+}
+
+static inline int exynos4_huff_tbl_val(int class, int id)
+{
+ return __exynos4_huff_tbl(class, id, false);
+}
+
+static int get_byte(struct s5p_jpeg_buffer *buf);
+static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
+static void skip(struct s5p_jpeg_buffer *buf, long len);
+
+static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
+{
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ struct s5p_jpeg_buffer jpeg_buffer;
+ unsigned int word;
+ int c, x, components;
+
+ jpeg_buffer.size = 2; /* Ls */
+ jpeg_buffer.data =
+ (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sos + 2;
+ jpeg_buffer.curr = 0;
+
+ word = 0;
+
+ if (get_word_be(&jpeg_buffer, &word))
+ return;
+ jpeg_buffer.size = (long)word - 2;
+ jpeg_buffer.data += 2;
+ jpeg_buffer.curr = 0;
+
+ components = get_byte(&jpeg_buffer);
+ if (components == -1)
+ return;
+ while (components--) {
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ x = get_byte(&jpeg_buffer);
+ if (x == -1)
+ return;
+ exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
+ (((x >> 4) & 0x1) << 1) | (x & 0x1));
+ }
+
+}
+
+static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
+{
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ struct s5p_jpeg_buffer jpeg_buffer;
+ unsigned int word;
+ int c, i, n, j;
+
+ for (j = 0; j < ctx->out_q.dht.n; ++j) {
+ jpeg_buffer.size = ctx->out_q.dht.len[j];
+ jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
+ ctx->out_q.dht.marker[j];
+ jpeg_buffer.curr = 0;
+
+ word = 0;
+ while (jpeg_buffer.curr < jpeg_buffer.size) {
+ char id, class;
+
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ id = c & 0xf;
+ class = (c >> 4) & 0xf;
+ n = 0;
+ for (i = 0; i < 16; ++i) {
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ word |= c << ((i % 4) * 8);
+ if ((i + 1) % 4 == 0) {
+ writel(word, jpeg->regs +
+ exynos4_huff_tbl_len(class, id) +
+ (i / 4) * 4);
+ word = 0;
+ }
+ n += c;
+ }
+ word = 0;
+ for (i = 0; i < n; ++i) {
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ word |= c << ((i % 4) * 8);
+ if ((i + 1) % 4 == 0) {
+ writel(word, jpeg->regs +
+ exynos4_huff_tbl_val(class, id) +
+ (i / 4) * 4);
+ word = 0;
+ }
+ }
+ if (i % 4) {
+ writel(word, jpeg->regs +
+ exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
+ }
+ word = 0;
+ }
+ }
+}
+
+static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
+{
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ struct s5p_jpeg_buffer jpeg_buffer;
+ int c, x, components;
+
+ jpeg_buffer.size = ctx->out_q.sof_len;
+ jpeg_buffer.data =
+ (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sof;
+ jpeg_buffer.curr = 0;
+
+ skip(&jpeg_buffer, 5); /* P, Y, X */
+ components = get_byte(&jpeg_buffer);
+ if (components == -1)
+ return;
+
+ exynos4_jpeg_set_dec_components(jpeg->regs, components);
+
+ while (components--) {
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ skip(&jpeg_buffer, 1);
+ x = get_byte(&jpeg_buffer);
+ if (x == -1)
+ return;
+ exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
+ }
+}
+
+static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
+{
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ struct s5p_jpeg_buffer jpeg_buffer;
+ unsigned int word;
+ int c, i, j;
+
+ for (j = 0; j < ctx->out_q.dqt.n; ++j) {
+ jpeg_buffer.size = ctx->out_q.dqt.len[j];
+ jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
+ ctx->out_q.dqt.marker[j];
+ jpeg_buffer.curr = 0;
+
+ word = 0;
+ while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
+ char id;
+
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ id = c & 0xf;
+ /* nonzero means extended mode - not supported */
+ if ((c >> 4) & 0xf)
+ return;
+ for (i = 0; i < 64; ++i) {
+ c = get_byte(&jpeg_buffer);
+ if (c == -1)
+ return;
+ word |= c << ((i % 4) * 8);
+ if ((i + 1) % 4 == 0) {
+ writel(word, jpeg->regs +
+ EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4);
+ word = 0;
+ }
+ }
+ word = 0;
+ }
+ }
+}
+
/*
* ============================================================================
* Device file operations
@@ -894,8 +1097,11 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
unsigned long buffer, unsigned long size,
struct s5p_jpeg_ctx *ctx)
{
- int c, components = 0, notfound;
- unsigned int height, width, word, subsampling = 0;
+ int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
+ unsigned int height, width, word, subsampling = 0, sos = 0, sof = 0,
+ sof_len = 0;
+ unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER],
+ dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
long length;
struct s5p_jpeg_buffer jpeg_buffer;
@@ -904,7 +1110,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
jpeg_buffer.curr = 0;
notfound = 1;
- while (notfound) {
+ while (notfound || !sos) {
c = get_byte(&jpeg_buffer);
if (c == -1)
return false;
@@ -923,6 +1129,11 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
case SOF0:
if (get_word_be(&jpeg_buffer, &word))
break;
+ length = (long)word - 2;
+ if (!length)
+ return false;
+ sof = jpeg_buffer.curr; /* after 0xffc0 */
+ sof_len = length;
if (get_byte(&jpeg_buffer) == -1)
break;
if (get_word_be(&jpeg_buffer, &height))
@@ -932,7 +1143,6 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
components = get_byte(&jpeg_buffer);
if (components == -1)
break;
- notfound = 0;
if (components == 1) {
subsampling = 0x33;
@@ -941,8 +1151,40 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
subsampling = get_byte(&jpeg_buffer);
skip(&jpeg_buffer, 1);
}
-
+ if (components > 3)
+ return false;
skip(&jpeg_buffer, components * 2);
+ notfound = 0;
+ break;
+
+ case DQT:
+ if (get_word_be(&jpeg_buffer, &word))
+ break;
+ length = (long)word - 2;
+ if (!length)
+ return false;
+ if (n_dqt >= S5P_JPEG_MAX_MARKER)
+ return false;
+ dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
+ dqt_len[n_dqt++] = length;
+ skip(&jpeg_buffer, length);
+ break;
+
+ case DHT:
+ if (get_word_be(&jpeg_buffer, &word))
+ break;
+ length = (long)word - 2;
+ if (!length)
+ return false;
+ if (n_dht >= S5P_JPEG_MAX_MARKER)
+ return false;
+ dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
+ dht_len[n_dht++] = length;
+ skip(&jpeg_buffer, length);
+ break;
+
+ case SOS:
+ sos = jpeg_buffer.curr - 2; /* 0xffda */
break;
/* skip payload-less markers */
@@ -963,7 +1205,20 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
}
result->w = width;
result->h = height;
- result->size = components;
+ result->sos = sos;
+ result->dht.n = n_dht;
+ while (n_dht--) {
+ result->dht.marker[n_dht] = dht[n_dht];
+ result->dht.len[n_dht] = dht_len[n_dht];
+ }
+ result->dqt.n = n_dqt;
+ while (n_dqt--) {
+ result->dqt.marker[n_dqt] = dqt[n_dqt];
+ result->dqt.len[n_dqt] = dqt_len[n_dqt];
+ }
+ result->sof = sof;
+ result->sof_len = sof_len;
+ result->size = result->components = components;
switch (subsampling) {
case 0x11:
@@ -982,7 +1237,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
return false;
}
- return !notfound;
+ return !notfound && sos;
}
static int s5p_jpeg_querycap(struct file *file, void *priv,
@@ -1226,8 +1481,7 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL;
}
- if ((ctx->jpeg->variant->version != SJPEG_EXYNOS4) ||
- (ctx->mode != S5P_JPEG_DECODE))
+ if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
goto exit;
/*
@@ -1350,7 +1604,7 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
* the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
* page fault calculate proper buffer size in such a case.
*/
- if (ct->jpeg->variant->version == SJPEG_EXYNOS4 &&
+ if (ct->jpeg->variant->hw_ex4_compat &&
f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
f,
@@ -1889,9 +2143,36 @@ static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
+ ctx->mode == S5P_JPEG_DECODE)
+ jpeg_addr += ctx->out_q.sos;
exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
}
+static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
+ unsigned int img_fmt)
+{
+ __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
+}
+
+static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
+ unsigned int img_fmt)
+{
+ __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
+}
+
+static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
+ unsigned int out_fmt)
+{
+ __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
+}
+
+static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
+ unsigned int out_fmt)
+{
+ __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
+}
+
static void exynos4_jpeg_device_run(void *priv)
{
struct s5p_jpeg_ctx *ctx = priv;
@@ -1899,11 +2180,11 @@ static void exynos4_jpeg_device_run(void *priv)
unsigned int bitstream_size;
unsigned long flags;
- spin_lock_irqsave(&ctx->jpeg->slock, flags);
+ spin_lock_irqsave(&jpeg->slock, flags);
if (ctx->mode == S5P_JPEG_ENCODE) {
exynos4_jpeg_sw_reset(jpeg->regs);
- exynos4_jpeg_set_interrupt(jpeg->regs);
+ exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
exynos4_jpeg_set_huff_tbl(jpeg->regs);
@@ -1920,27 +2201,56 @@ static void exynos4_jpeg_device_run(void *priv)
exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
ctx->cap_q.h);
- exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
- exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
+ if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
+ exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
+ ctx->subsampling);
+ exynos4_jpeg_set_img_fmt(jpeg->regs,
+ ctx->out_q.fmt->fourcc);
+ } else {
+ exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
+ ctx->subsampling);
+ exynos5433_jpeg_set_img_fmt(jpeg->regs,
+ ctx->out_q.fmt->fourcc);
+ }
exynos4_jpeg_set_img_addr(ctx);
exynos4_jpeg_set_jpeg_addr(ctx);
exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
ctx->out_q.fmt->fourcc);
} else {
exynos4_jpeg_sw_reset(jpeg->regs);
- exynos4_jpeg_set_interrupt(jpeg->regs);
+ exynos4_jpeg_set_interrupt(jpeg->regs,
+ jpeg->variant->version);
exynos4_jpeg_set_img_addr(ctx);
exynos4_jpeg_set_jpeg_addr(ctx);
- exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
- bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
+ if (jpeg->variant->version == SJPEG_EXYNOS5433) {
+ exynos4_jpeg_parse_huff_tbl(ctx);
+ exynos4_jpeg_parse_decode_h_tbl(ctx);
+
+ exynos4_jpeg_parse_q_tbl(ctx);
+ exynos4_jpeg_parse_decode_q_tbl(ctx);
+
+ exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
+
+ exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
+ ctx->cap_q.h);
+ exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
+ ctx->subsampling);
+ exynos5433_jpeg_set_img_fmt(jpeg->regs,
+ ctx->cap_q.fmt->fourcc);
+ bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
+ } else {
+ exynos4_jpeg_set_img_fmt(jpeg->regs,
+ ctx->cap_q.fmt->fourcc);
+ bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
+ }
exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
}
exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
- spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
+ spin_unlock_irqrestore(&jpeg->slock, flags);
}
static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
@@ -2120,7 +2430,7 @@ static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
*/
static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -2170,6 +2480,7 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
if (ctx->mode == S5P_JPEG_DECODE &&
@@ -2187,13 +2498,24 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
q_data = &ctx->out_q;
q_data->w = tmp.w;
q_data->h = tmp.h;
+ q_data->sos = tmp.sos;
+ memcpy(q_data->dht.marker, tmp.dht.marker,
+ sizeof(tmp.dht.marker));
+ memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
+ q_data->dht.n = tmp.dht.n;
+ memcpy(q_data->dqt.marker, tmp.dqt.marker,
+ sizeof(tmp.dqt.marker));
+ memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
+ q_data->dqt.n = tmp.dqt.n;
+ q_data->sof = tmp.sof;
+ q_data->sof_len = tmp.sof_len;
q_data = &ctx->cap_q;
q_data->w = tmp.w;
q_data->h = tmp.h;
}
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
@@ -2264,7 +2586,7 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
{
struct s5p_jpeg *jpeg = dev_id;
struct s5p_jpeg_ctx *curr_ctx;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
unsigned long payload_size = 0;
enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
bool enc_jpeg_too_large = false;
@@ -2298,15 +2620,15 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
payload_size = s5p_jpeg_compressed_size(jpeg->regs);
}
- dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
- dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_buf->v4l2_buf.flags |=
- src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_buf->timecode = src_buf->timecode;
+ dst_buf->timestamp = src_buf->timestamp;
+ dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_buf->flags |=
+ src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
v4l2_m2m_buf_done(src_buf, state);
if (curr_ctx->mode == S5P_JPEG_ENCODE)
- vb2_set_plane_payload(dst_buf, 0, payload_size);
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
v4l2_m2m_buf_done(dst_buf, state);
v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
@@ -2321,7 +2643,7 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
{
unsigned int int_status;
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
struct s5p_jpeg *jpeg = priv;
struct s5p_jpeg_ctx *curr_ctx;
unsigned long payload_size = 0;
@@ -2363,7 +2685,8 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
if (jpeg->irq_ret == OK_ENC_OR_DEC) {
if (curr_ctx->mode == S5P_JPEG_ENCODE) {
payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
- vb2_set_plane_payload(dst_vb, 0, payload_size);
+ vb2_set_plane_payload(&dst_vb->vb2_buf,
+ 0, payload_size);
}
v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
@@ -2373,7 +2696,8 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
}
v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
- curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
+ if (jpeg->variant->version == SJPEG_EXYNOS4)
+ curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
spin_unlock(&jpeg->slock);
return IRQ_HANDLED;
@@ -2383,7 +2707,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
{
struct s5p_jpeg *jpeg = dev_id;
struct s5p_jpeg_ctx *curr_ctx;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
unsigned long payload_size = 0;
enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
bool interrupt_timeout = false;
@@ -2427,12 +2751,12 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
- dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
- dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
+ dst_buf->timecode = src_buf->timecode;
+ dst_buf->timestamp = src_buf->timestamp;
v4l2_m2m_buf_done(src_buf, state);
if (curr_ctx->mode == S5P_JPEG_ENCODE)
- vb2_set_plane_payload(dst_buf, 0, payload_size);
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
v4l2_m2m_buf_done(dst_buf, state);
v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
@@ -2455,7 +2779,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
{
struct s5p_jpeg *jpeg;
struct resource *res;
- int ret;
+ int i, ret;
/* JPEG IP abstraction struct */
jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
@@ -2490,23 +2814,21 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
}
/* clocks */
- jpeg->clk = clk_get(&pdev->dev, "jpeg");
- if (IS_ERR(jpeg->clk)) {
- dev_err(&pdev->dev, "cannot get clock\n");
- ret = PTR_ERR(jpeg->clk);
- return ret;
+ for (i = 0; i < jpeg->variant->num_clocks; i++) {
+ jpeg->clocks[i] = devm_clk_get(&pdev->dev,
+ jpeg->variant->clk_names[i]);
+ if (IS_ERR(jpeg->clocks[i])) {
+ dev_err(&pdev->dev, "failed to get clock: %s\n",
+ jpeg->variant->clk_names[i]);
+ return PTR_ERR(jpeg->clocks[i]);
+ }
}
- dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
-
- jpeg->sclk = clk_get(&pdev->dev, "sclk");
- if (IS_ERR(jpeg->sclk))
- dev_info(&pdev->dev, "sclk clock not available\n");
/* v4l2 device */
ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to register v4l2 device\n");
- goto clk_get_rollback;
+ return ret;
}
/* mem2mem device */
@@ -2603,17 +2925,13 @@ m2m_init_rollback:
device_register_rollback:
v4l2_device_unregister(&jpeg->v4l2_dev);
-clk_get_rollback:
- clk_put(jpeg->clk);
- if (!IS_ERR(jpeg->sclk))
- clk_put(jpeg->sclk);
-
return ret;
}
static int s5p_jpeg_remove(struct platform_device *pdev)
{
struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
+ int i;
pm_runtime_disable(jpeg->dev);
@@ -2624,15 +2942,10 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
v4l2_device_unregister(&jpeg->v4l2_dev);
if (!pm_runtime_status_suspended(&pdev->dev)) {
- clk_disable_unprepare(jpeg->clk);
- if (!IS_ERR(jpeg->sclk))
- clk_disable_unprepare(jpeg->sclk);
+ for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
+ clk_disable_unprepare(jpeg->clocks[i]);
}
- clk_put(jpeg->clk);
- if (!IS_ERR(jpeg->sclk))
- clk_put(jpeg->sclk);
-
return 0;
}
@@ -2640,10 +2953,10 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
static int s5p_jpeg_runtime_suspend(struct device *dev)
{
struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
+ int i;
- clk_disable_unprepare(jpeg->clk);
- if (!IS_ERR(jpeg->sclk))
- clk_disable_unprepare(jpeg->sclk);
+ for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
+ clk_disable_unprepare(jpeg->clocks[i]);
return 0;
}
@@ -2652,16 +2965,15 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
{
struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
unsigned long flags;
- int ret;
+ int i, ret;
- ret = clk_prepare_enable(jpeg->clk);
- if (ret < 0)
- return ret;
-
- if (!IS_ERR(jpeg->sclk)) {
- ret = clk_prepare_enable(jpeg->sclk);
- if (ret < 0)
+ for (i = 0; i < jpeg->variant->num_clocks; i++) {
+ ret = clk_prepare_enable(jpeg->clocks[i]);
+ if (ret) {
+ while (--i > 0)
+ clk_disable_unprepare(jpeg->clocks[i]);
return ret;
+ }
}
spin_lock_irqsave(&jpeg->slock, flags);
@@ -2715,6 +3027,8 @@ static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
.jpeg_irq = s5p_jpeg_irq,
.m2m_ops = &s5p_jpeg_m2m_ops,
.fmt_ver_flag = SJPEG_FMT_FLAG_S5P,
+ .clk_names = {"jpeg"},
+ .num_clocks = 1,
};
static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
@@ -2723,6 +3037,8 @@ static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
.m2m_ops = &exynos3250_jpeg_m2m_ops,
.fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250,
.hw3250_compat = 1,
+ .clk_names = {"jpeg", "sclk"},
+ .num_clocks = 2,
};
static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
@@ -2731,6 +3047,9 @@ static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
.m2m_ops = &exynos4_jpeg_m2m_ops,
.fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
.htbl_reinit = 1,
+ .clk_names = {"jpeg"},
+ .num_clocks = 1,
+ .hw_ex4_compat = 1,
};
static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
@@ -2740,6 +3059,19 @@ static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
.fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */
.hw3250_compat = 1,
.htbl_reinit = 1,
+ .clk_names = {"jpeg"},
+ .num_clocks = 1,
+};
+
+static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
+ .version = SJPEG_EXYNOS5433,
+ .jpeg_irq = exynos4_jpeg_irq,
+ .m2m_ops = &exynos4_jpeg_m2m_ops,
+ .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
+ .htbl_reinit = 1,
+ .clk_names = {"pclk", "aclk", "aclk_xiu", "sclk"},
+ .num_clocks = 4,
+ .hw_ex4_compat = 1,
};
static const struct of_device_id samsung_jpeg_match[] = {
@@ -2758,6 +3090,9 @@ static const struct of_device_id samsung_jpeg_match[] = {
}, {
.compatible = "samsung,exynos5420-jpeg",
.data = &exynos5420_jpeg_drvdata,
+ }, {
+ .compatible = "samsung,exynos5433-jpeg",
+ .data = &exynos5433_jpeg_drvdata,
},
{},
};
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 7d9a9ed19cea..9b1db0934909 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -20,6 +20,8 @@
#define S5P_JPEG_M2M_NAME "s5p-jpeg"
+#define JPEG_MAX_CLOCKS 4
+
/* JPEG compression quality setting */
#define S5P_JPEG_COMPR_QUAL_BEST 0
#define S5P_JPEG_COMPR_QUAL_WORST 3
@@ -40,9 +42,12 @@
/* a selection of JPEG markers */
#define TEM 0x01
#define SOF0 0xc0
+#define DHT 0xc4
#define RST 0xd0
#define SOI 0xd8
#define EOI 0xd9
+#define SOS 0xda
+#define DQT 0xdb
#define DHP 0xde
/* Flags that indicate a format can be used for capture/output */
@@ -66,12 +71,15 @@
#define SJPEG_SUBSAMPLING_422 0x21
#define SJPEG_SUBSAMPLING_420 0x22
+#define S5P_JPEG_MAX_MARKER 4
+
/* Version numbers */
enum sjpeg_version {
SJPEG_S5P,
SJPEG_EXYNOS3250,
SJPEG_EXYNOS4,
SJPEG_EXYNOS5420,
+ SJPEG_EXYNOS5433,
};
enum exynos4_jpeg_result {
@@ -100,8 +108,7 @@ enum exynos4_jpeg_img_quality_level {
* @m2m_dev: v4l2 mem2mem device data
* @regs: JPEG IP registers mapping
* @irq: JPEG IP irq
- * @clk: JPEG IP clock
- * @sclk: Exynos3250 JPEG IP special clock
+ * @clocks: JPEG IP clock(s)
* @dev: JPEG IP struct device
* @alloc_ctx: videobuf2 memory allocator's context
* @variant: driver variant to be used
@@ -121,8 +128,7 @@ struct s5p_jpeg {
void __iomem *regs;
unsigned int irq;
enum exynos4_jpeg_result irq_ret;
- struct clk *clk;
- struct clk *sclk;
+ struct clk *clocks[JPEG_MAX_CLOCKS];
struct device *dev;
void *alloc_ctx;
struct s5p_jpeg_variant *variant;
@@ -134,8 +140,11 @@ struct s5p_jpeg_variant {
unsigned int fmt_ver_flag;
unsigned int hw3250_compat:1;
unsigned int htbl_reinit:1;
+ unsigned int hw_ex4_compat:1;
struct v4l2_m2m_ops *m2m_ops;
irqreturn_t (*jpeg_irq)(int irq, void *priv);
+ const char *clk_names[JPEG_MAX_CLOCKS];
+ int num_clocks;
};
/**
@@ -161,16 +170,40 @@ struct s5p_jpeg_fmt {
};
/**
+ * s5p_jpeg_marker - collection of markers from jpeg header
+ * @marker: markers' positions relative to the buffer beginning
+ * @len: markers' payload lengths (without length field)
+ * @n: number of markers in collection
+ */
+struct s5p_jpeg_marker {
+ u32 marker[S5P_JPEG_MAX_MARKER];
+ u32 len[S5P_JPEG_MAX_MARKER];
+ u32 n;
+};
+
+/**
* s5p_jpeg_q_data - parameters of one queue
* @fmt: driver-specific format of this queue
* @w: image width
* @h: image height
+ * @sos: SOS marker's position relative to the buffer beginning
+ * @dht: DHT markers' positions relative to the buffer beginning
+ * @dqt: DQT markers' positions relative to the buffer beginning
+ * @sof: SOF0 marker's postition relative to the buffer beginning
+ * @sof_len: SOF0 marker's payload length (without length field itself)
+ * @components: number of image components
* @size: image buffer size in bytes
*/
struct s5p_jpeg_q_data {
struct s5p_jpeg_fmt *fmt;
u32 w;
u32 h;
+ u32 sos;
+ struct s5p_jpeg_marker dht;
+ struct s5p_jpeg_marker dqt;
+ u32 sof;
+ u32 sof_len;
+ u32 components;
u32 size;
};
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
index ab6d6f43c96f..0912d0a892e2 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
@@ -45,9 +45,20 @@ void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode)
}
}
-void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt)
+void __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt,
+ unsigned int version)
{
unsigned int reg;
+ unsigned int exynos4_swap_chroma_cbcr;
+ unsigned int exynos4_swap_chroma_crcb;
+
+ if (version == SJPEG_EXYNOS4) {
+ exynos4_swap_chroma_cbcr = EXYNOS4_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_crcb = EXYNOS4_SWAP_CHROMA_CRCB;
+ } else {
+ exynos4_swap_chroma_cbcr = EXYNOS5433_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_crcb = EXYNOS5433_SWAP_CHROMA_CRCB;
+ }
reg = readl(base + EXYNOS4_IMG_FMT_REG) &
EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */
@@ -67,48 +78,48 @@ void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt)
case V4L2_PIX_FMT_NV24:
reg = reg | EXYNOS4_ENC_YUV_444_IMG |
EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
- EXYNOS4_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_cbcr;
break;
case V4L2_PIX_FMT_NV42:
reg = reg | EXYNOS4_ENC_YUV_444_IMG |
EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
- EXYNOS4_SWAP_CHROMA_CRCB;
+ exynos4_swap_chroma_crcb;
break;
case V4L2_PIX_FMT_YUYV:
reg = reg | EXYNOS4_DEC_YUV_422_IMG |
EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
- EXYNOS4_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_cbcr;
break;
case V4L2_PIX_FMT_YVYU:
reg = reg | EXYNOS4_DEC_YUV_422_IMG |
EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
- EXYNOS4_SWAP_CHROMA_CRCB;
+ exynos4_swap_chroma_crcb;
break;
case V4L2_PIX_FMT_NV16:
reg = reg | EXYNOS4_DEC_YUV_422_IMG |
EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
- EXYNOS4_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_cbcr;
break;
case V4L2_PIX_FMT_NV61:
reg = reg | EXYNOS4_DEC_YUV_422_IMG |
EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
- EXYNOS4_SWAP_CHROMA_CRCB;
+ exynos4_swap_chroma_crcb;
break;
case V4L2_PIX_FMT_NV12:
reg = reg | EXYNOS4_DEC_YUV_420_IMG |
EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
- EXYNOS4_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_cbcr;
break;
case V4L2_PIX_FMT_NV21:
reg = reg | EXYNOS4_DEC_YUV_420_IMG |
EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
- EXYNOS4_SWAP_CHROMA_CRCB;
+ exynos4_swap_chroma_crcb;
break;
case V4L2_PIX_FMT_YUV420:
reg = reg | EXYNOS4_DEC_YUV_420_IMG |
EXYNOS4_YUV_420_IP_YUV_420_3P_IMG |
- EXYNOS4_SWAP_CHROMA_CBCR;
+ exynos4_swap_chroma_cbcr;
break;
default:
break;
@@ -118,12 +129,14 @@ void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt)
writel(reg, base + EXYNOS4_IMG_FMT_REG);
}
-void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt)
+void __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt,
+ unsigned int version)
{
unsigned int reg;
reg = readl(base + EXYNOS4_IMG_FMT_REG) &
- ~EXYNOS4_ENC_FMT_MASK; /* clear enc format */
+ ~(version == SJPEG_EXYNOS4 ? EXYNOS4_ENC_FMT_MASK :
+ EXYNOS5433_ENC_FMT_MASK); /* clear enc format */
switch (out_fmt) {
case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
@@ -149,9 +162,18 @@ void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt)
writel(reg, base + EXYNOS4_IMG_FMT_REG);
}
-void exynos4_jpeg_set_interrupt(void __iomem *base)
+void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version)
{
- writel(EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
+ unsigned int reg;
+
+ if (version == SJPEG_EXYNOS4) {
+ reg = readl(base + EXYNOS4_INT_EN_REG) & ~EXYNOS4_INT_EN_MASK;
+ writel(reg | EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
+ } else {
+ reg = readl(base + EXYNOS4_INT_EN_REG) &
+ ~EXYNOS5433_INT_EN_MASK;
+ writel(reg | EXYNOS5433_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
+ }
}
unsigned int exynos4_jpeg_get_int_status(void __iomem *base)
@@ -234,6 +256,36 @@ void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
writel(reg, base + EXYNOS4_TBL_SEL_REG);
}
+void exynos4_jpeg_set_dec_components(void __iomem *base, int n)
+{
+ unsigned int reg;
+
+ reg = readl(base + EXYNOS4_TBL_SEL_REG);
+
+ reg |= EXYNOS4_NF(n);
+ writel(reg, base + EXYNOS4_TBL_SEL_REG);
+}
+
+void exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x)
+{
+ unsigned int reg;
+
+ reg = readl(base + EXYNOS4_TBL_SEL_REG);
+
+ reg |= EXYNOS4_Q_TBL_COMP(c, x);
+ writel(reg, base + EXYNOS4_TBL_SEL_REG);
+}
+
+void exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x)
+{
+ unsigned int reg;
+
+ reg = readl(base + EXYNOS4_TBL_SEL_REG);
+
+ reg |= EXYNOS4_HUFF_TBL_COMP(c, x);
+ writel(reg, base + EXYNOS4_TBL_SEL_REG);
+}
+
void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt)
{
if (fmt == V4L2_PIX_FMT_GREY)
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h
index c228d28a4bc7..cf6ec055d63a 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h
@@ -15,10 +15,12 @@
void exynos4_jpeg_sw_reset(void __iomem *base);
void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode);
-void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt);
-void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt);
+void __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt,
+ unsigned int version);
+void __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt,
+ unsigned int version);
void exynos4_jpeg_set_enc_tbl(void __iomem *base);
-void exynos4_jpeg_set_interrupt(void __iomem *base);
+void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version);
unsigned int exynos4_jpeg_get_int_status(void __iomem *base);
void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value);
void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value);
@@ -30,6 +32,9 @@ void exynos4_jpeg_set_frame_buf_address(void __iomem *base,
struct s5p_jpeg_addr *jpeg_addr);
void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
enum exynos4_jpeg_img_quality_level level);
+void exynos4_jpeg_set_dec_components(void __iomem *base, int n);
+void exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x);
+void exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x);
void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt);
void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size);
unsigned int exynos4_jpeg_get_stream_size(void __iomem *base);
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
index 050fc440248f..1870400468b2 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
@@ -231,12 +231,14 @@
/* JPEG INT Register bit */
#define EXYNOS4_INT_EN_MASK (0x1f << 0)
+#define EXYNOS5433_INT_EN_MASK (0x1ff << 0)
#define EXYNOS4_PROT_ERR_INT_EN (1 << 0)
#define EXYNOS4_IMG_COMPLETION_INT_EN (1 << 1)
#define EXYNOS4_DEC_INVALID_FORMAT_EN (1 << 2)
#define EXYNOS4_MULTI_SCAN_ERROR_EN (1 << 3)
#define EXYNOS4_FRAME_ERR_EN (1 << 4)
#define EXYNOS4_INT_EN_ALL (0x1f << 0)
+#define EXYNOS5433_INT_EN_ALL (0x1b6 << 0)
#define EXYNOS4_MOD_REG_PROC_ENC (0 << 3)
#define EXYNOS4_MOD_REG_PROC_DEC (1 << 3)
@@ -296,6 +298,8 @@
#define EXYNOS4_ENC_FMT_SHIFT 24
#define EXYNOS4_ENC_FMT_MASK (3 << EXYNOS4_ENC_FMT_SHIFT)
+#define EXYNOS5433_ENC_FMT_MASK (7 << EXYNOS4_ENC_FMT_SHIFT)
+
#define EXYNOS4_ENC_FMT_GRAY (0 << EXYNOS4_ENC_FMT_SHIFT)
#define EXYNOS4_ENC_FMT_YUV_444 (1 << EXYNOS4_ENC_FMT_SHIFT)
#define EXYNOS4_ENC_FMT_YUV_422 (2 << EXYNOS4_ENC_FMT_SHIFT)
@@ -305,6 +309,8 @@
#define EXYNOS4_SWAP_CHROMA_CRCB (1 << 26)
#define EXYNOS4_SWAP_CHROMA_CBCR (0 << 26)
+#define EXYNOS5433_SWAP_CHROMA_CRCB (1 << 27)
+#define EXYNOS5433_SWAP_CHROMA_CBCR (0 << 27)
/* JPEG HUFF count Register bit */
#define EXYNOS4_HUFF_COUNT_MASK 0xffff
@@ -316,35 +322,56 @@
#define EXYNOS4_DECODED_IMG_FMT_MASK 0x3
/* JPEG TBL SEL Register bit */
-#define EXYNOS4_Q_TBL_COMP1_0 (0 << 0)
-#define EXYNOS4_Q_TBL_COMP1_1 (1 << 0)
-#define EXYNOS4_Q_TBL_COMP1_2 (2 << 0)
-#define EXYNOS4_Q_TBL_COMP1_3 (3 << 0)
-
-#define EXYNOS4_Q_TBL_COMP2_0 (0 << 2)
-#define EXYNOS4_Q_TBL_COMP2_1 (1 << 2)
-#define EXYNOS4_Q_TBL_COMP2_2 (2 << 2)
-#define EXYNOS4_Q_TBL_COMP2_3 (3 << 2)
-
-#define EXYNOS4_Q_TBL_COMP3_0 (0 << 4)
-#define EXYNOS4_Q_TBL_COMP3_1 (1 << 4)
-#define EXYNOS4_Q_TBL_COMP3_2 (2 << 4)
-#define EXYNOS4_Q_TBL_COMP3_3 (3 << 4)
-
-#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_0 (0 << 6)
-#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 (1 << 6)
-#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_0 (2 << 6)
-#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_1 (3 << 6)
-
-#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 (0 << 8)
-#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_1 (1 << 8)
-#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_0 (2 << 8)
-#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_1 (3 << 8)
-
-#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_0 (0 << 10)
-#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_1 (1 << 10)
-#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_0 (2 << 10)
-#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1 (3 << 10)
+#define EXYNOS4_Q_TBL_COMP(c, n) ((n) << (((c) - 1) << 1))
+
+#define EXYNOS4_Q_TBL_COMP1_0 EXYNOS4_Q_TBL_COMP(1, 0)
+#define EXYNOS4_Q_TBL_COMP1_1 EXYNOS4_Q_TBL_COMP(1, 1)
+#define EXYNOS4_Q_TBL_COMP1_2 EXYNOS4_Q_TBL_COMP(1, 2)
+#define EXYNOS4_Q_TBL_COMP1_3 EXYNOS4_Q_TBL_COMP(1, 3)
+
+#define EXYNOS4_Q_TBL_COMP2_0 EXYNOS4_Q_TBL_COMP(2, 0)
+#define EXYNOS4_Q_TBL_COMP2_1 EXYNOS4_Q_TBL_COMP(2, 1)
+#define EXYNOS4_Q_TBL_COMP2_2 EXYNOS4_Q_TBL_COMP(2, 2)
+#define EXYNOS4_Q_TBL_COMP2_3 EXYNOS4_Q_TBL_COMP(2, 3)
+
+#define EXYNOS4_Q_TBL_COMP3_0 EXYNOS4_Q_TBL_COMP(3, 0)
+#define EXYNOS4_Q_TBL_COMP3_1 EXYNOS4_Q_TBL_COMP(3, 1)
+#define EXYNOS4_Q_TBL_COMP3_2 EXYNOS4_Q_TBL_COMP(3, 2)
+#define EXYNOS4_Q_TBL_COMP3_3 EXYNOS4_Q_TBL_COMP(3, 3)
+
+#define EXYNOS4_HUFF_TBL_COMP(c, n) ((n) << ((((c) - 1) << 1) + 6))
+
+#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_0 \
+ EXYNOS4_HUFF_TBL_COMP(1, 0)
+#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 \
+ EXYNOS4_HUFF_TBL_COMP(1, 1)
+#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_0 \
+ EXYNOS4_HUFF_TBL_COMP(1, 2)
+#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_1 \
+ EXYNOS4_HUFF_TBL_COMP(1, 3)
+
+#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 \
+ EXYNOS4_HUFF_TBL_COMP(2, 0)
+#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_1 \
+ EXYNOS4_HUFF_TBL_COMP(2, 1)
+#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_0 \
+ EXYNOS4_HUFF_TBL_COMP(2, 2)
+#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_1 \
+ EXYNOS4_HUFF_TBL_COMP(2, 3)
+
+#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_0 \
+ EXYNOS4_HUFF_TBL_COMP(3, 0)
+#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_1 \
+ EXYNOS4_HUFF_TBL_COMP(3, 1)
+#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_0 \
+ EXYNOS4_HUFF_TBL_COMP(3, 2)
+#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1 \
+ EXYNOS4_HUFF_TBL_COMP(3, 3)
+
+#define EXYNOS4_NF_SHIFT 16
+#define EXYNOS4_NF_MASK 0xff
+#define EXYNOS4_NF(x) \
+ (((x) << EXYNOS4_NF_SHIFT) & EXYNOS4_NF_MASK)
/* JPEG quantizer table register */
#define EXYNOS4_QTBL_CONTENT(n) (0x100 + (n) * 0x40)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 8de61dc1e142..3ffe2ecfd5ef 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,7 +22,7 @@
#include <media/v4l2-event.h>
#include <linux/workqueue.h>
#include <linux/of.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
@@ -181,13 +181,6 @@ unlock:
mutex_unlock(&dev->mfc_mutex);
}
-static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
-{
- mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
- mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
- mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
-}
-
static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_buf *dst_buf;
@@ -199,22 +192,23 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
dst_buf = list_entry(ctx->dst_queue.next,
struct s5p_mfc_buf, list);
mfc_debug(2, "Cleaning up buffer: %d\n",
- dst_buf->b->v4l2_buf.index);
- vb2_set_plane_payload(dst_buf->b, 0, 0);
- vb2_set_plane_payload(dst_buf->b, 1, 0);
+ dst_buf->b->vb2_buf.index);
+ vb2_set_plane_payload(&dst_buf->b->vb2_buf, 0, 0);
+ vb2_set_plane_payload(&dst_buf->b->vb2_buf, 1, 0);
list_del(&dst_buf->list);
+ dst_buf->flags |= MFC_BUF_FLAG_EOS;
ctx->dst_queue_cnt--;
- dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);
+ dst_buf->b->sequence = (ctx->sequence++);
if (s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_top, ctx) ==
s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_bot, ctx))
- dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
+ dst_buf->b->field = V4L2_FIELD_NONE;
else
- dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;
- dst_buf->b->v4l2_buf.flags |= V4L2_BUF_FLAG_LAST;
+ dst_buf->b->field = V4L2_FIELD_INTERLACED;
+ dst_buf->b->flags |= V4L2_BUF_FLAG_LAST;
- ctx->dec_dst_flag &= ~(1 << dst_buf->b->v4l2_buf.index);
- vb2_buffer_done(dst_buf->b, VB2_BUF_STATE_DONE);
+ ctx->dec_dst_flag &= ~(1 << dst_buf->b->vb2_buf.index);
+ vb2_buffer_done(&dst_buf->b->vb2_buf, VB2_BUF_STATE_DONE);
}
}
@@ -235,27 +229,28 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
appropriate flags. */
src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
- if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
- dst_buf->b->v4l2_buf.timecode =
- src_buf->b->v4l2_buf.timecode;
- dst_buf->b->v4l2_buf.timestamp =
- src_buf->b->v4l2_buf.timestamp;
- dst_buf->b->v4l2_buf.flags &=
+ if (vb2_dma_contig_plane_dma_addr(&dst_buf->b->vb2_buf, 0)
+ == dec_y_addr) {
+ dst_buf->b->timecode =
+ src_buf->b->timecode;
+ dst_buf->b->timestamp =
+ src_buf->b->timestamp;
+ dst_buf->b->flags &=
~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_buf->b->v4l2_buf.flags |=
- src_buf->b->v4l2_buf.flags
+ dst_buf->b->flags |=
+ src_buf->b->flags
& V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
switch (frame_type) {
case S5P_FIMV_DECODE_FRAME_I_FRAME:
- dst_buf->b->v4l2_buf.flags |=
+ dst_buf->b->flags |=
V4L2_BUF_FLAG_KEYFRAME;
break;
case S5P_FIMV_DECODE_FRAME_P_FRAME:
- dst_buf->b->v4l2_buf.flags |=
+ dst_buf->b->flags |=
V4L2_BUF_FLAG_PFRAME;
break;
case S5P_FIMV_DECODE_FRAME_B_FRAME:
- dst_buf->b->v4l2_buf.flags |=
+ dst_buf->b->flags |=
V4L2_BUF_FLAG_BFRAME;
break;
default:
@@ -296,25 +291,28 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
* check which videobuf does it correspond to */
list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
/* Check if this is the buffer we're looking for */
- if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dspl_y_addr) {
+ if (vb2_dma_contig_plane_dma_addr(&dst_buf->b->vb2_buf, 0)
+ == dspl_y_addr) {
list_del(&dst_buf->list);
ctx->dst_queue_cnt--;
- dst_buf->b->v4l2_buf.sequence = ctx->sequence;
+ dst_buf->b->sequence = ctx->sequence;
if (s5p_mfc_hw_call(dev->mfc_ops,
get_pic_type_top, ctx) ==
s5p_mfc_hw_call(dev->mfc_ops,
get_pic_type_bot, ctx))
- dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
+ dst_buf->b->field = V4L2_FIELD_NONE;
else
- dst_buf->b->v4l2_buf.field =
+ dst_buf->b->field =
V4L2_FIELD_INTERLACED;
- vb2_set_plane_payload(dst_buf->b, 0, ctx->luma_size);
- vb2_set_plane_payload(dst_buf->b, 1, ctx->chroma_size);
- clear_bit(dst_buf->b->v4l2_buf.index,
+ vb2_set_plane_payload(&dst_buf->b->vb2_buf, 0,
+ ctx->luma_size);
+ vb2_set_plane_payload(&dst_buf->b->vb2_buf, 1,
+ ctx->chroma_size);
+ clear_bit(dst_buf->b->vb2_buf.index,
&ctx->dec_dst_flag);
- vb2_buffer_done(dst_buf->b,
- err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&dst_buf->b->vb2_buf, err ?
+ VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
break;
}
@@ -395,7 +393,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC &&
ctx->codec_mode != S5P_MFC_CODEC_VP8_DEC &&
ctx->consumed_stream + STUFF_BYTE <
- src_buf->b->v4l2_planes[0].bytesused) {
+ src_buf->b->vb2_buf.planes[0].bytesused) {
/* Run MFC again on the same buffer */
mfc_debug(2, "Running again the same buffer\n");
ctx->after_packed_pb = 1;
@@ -407,9 +405,11 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
list_del(&src_buf->list);
ctx->src_queue_cnt--;
if (s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) > 0)
- vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&src_buf->b->vb2_buf,
+ VB2_BUF_STATE_ERROR);
else
- vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&src_buf->b->vb2_buf,
+ VB2_BUF_STATE_DONE);
}
}
leave_handle_frame:
@@ -510,7 +510,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
struct s5p_mfc_buf, list);
if (s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream,
dev) <
- src_buf->b->v4l2_planes[0].bytesused)
+ src_buf->b->vb2_buf.planes[0].bytesused)
ctx->head_processed = 0;
else
ctx->head_processed = 1;
@@ -551,7 +551,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
struct s5p_mfc_buf, list);
list_del(&src_buf->list);
ctx->src_queue_cnt--;
- vb2_buffer_done(src_buf->b,
+ vb2_buffer_done(&src_buf->b->vb2_buf,
VB2_BUF_STATE_DONE);
}
spin_unlock_irqrestore(&dev->irqlock, flags);
@@ -573,17 +573,13 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
}
}
-static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx,
- unsigned int reason, unsigned int err)
+static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *mb_entry;
mfc_debug(2, "Stream completed\n");
- s5p_mfc_clear_int_flags(dev);
- ctx->int_type = reason;
- ctx->int_err = err;
ctx->state = MFCINST_FINISHED;
spin_lock(&dev->irqlock);
@@ -592,8 +588,8 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx,
list);
list_del(&mb_entry->list);
ctx->dst_queue_cnt--;
- vb2_set_plane_payload(mb_entry->b, 0, 0);
- vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, 0);
+ vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
}
spin_unlock(&dev->irqlock);
@@ -640,6 +636,13 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
if (ctx->c_ops->post_frame_start) {
if (ctx->c_ops->post_frame_start(ctx))
mfc_err("post_frame_start() failed\n");
+
+ if (ctx->state == MFCINST_FINISHING &&
+ list_empty(&ctx->ref_queue)) {
+ s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
+ s5p_mfc_handle_stream_complete(ctx);
+ break;
+ }
s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
@@ -685,7 +688,10 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
break;
case S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET:
- s5p_mfc_handle_stream_complete(ctx, reason, err);
+ s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
+ ctx->int_type = reason;
+ ctx->int_err = err;
+ s5p_mfc_handle_stream_complete(ctx);
break;
case S5P_MFC_R2H_CMD_DPB_FLUSH_RET:
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 24262bbb1a35..d1a3f9b1bc44 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -21,7 +21,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "regs-mfc.h"
#include "regs-mfc-v8.h"
@@ -179,8 +179,8 @@ struct s5p_mfc_ctx;
* struct s5p_mfc_buf - MFC buffer
*/
struct s5p_mfc_buf {
+ struct vb2_v4l2_buffer *b;
struct list_head list;
- struct vb2_buffer *b;
union {
struct {
size_t luma;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index aebe4fd7f03a..8c5060a7534f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -22,7 +22,7 @@
#include <linux/workqueue.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
@@ -645,17 +645,22 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
mfc_err("Call on DQBUF after unrecoverable error\n");
return -EIO;
}
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+
+ switch (buf->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
- if (ret == 0 && ctx->state == MFCINST_FINISHED &&
- list_empty(&ctx->vq_dst.done_list))
+ if (ret)
+ return ret;
+
+ if (ctx->state == MFCINST_FINISHED &&
+ (ctx->dst_bufs[buf->index].flags & MFC_BUF_FLAG_EOS))
v4l2_event_queue_fh(&ctx->fh, &ev);
- } else {
- ret = -EINVAL;
+ return 0;
+ default:
+ return -EINVAL;
}
- return ret;
}
/* Export DMA buffer */
@@ -883,7 +888,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
};
static int s5p_mfc_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *buf_count,
+ const void *parg, unsigned int *buf_count,
unsigned int *plane_count, unsigned int psize[],
void *allocators[])
{
@@ -945,6 +950,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
static int s5p_mfc_buf_init(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
unsigned int i;
@@ -964,8 +970,8 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
mfc_err("Plane buffer (CAPTURE) is too small\n");
return -EINVAL;
}
- i = vb->v4l2_buf.index;
- ctx->dst_bufs[i].b = vb;
+ i = vb->index;
+ ctx->dst_bufs[i].b = vbuf;
ctx->dst_bufs[i].cookie.raw.luma =
vb2_dma_contig_plane_dma_addr(vb, 0);
ctx->dst_bufs[i].cookie.raw.chroma =
@@ -982,8 +988,8 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
return -EINVAL;
}
- i = vb->v4l2_buf.index;
- ctx->src_bufs[i].b = vb;
+ i = vb->index;
+ ctx->src_bufs[i].b = vbuf;
ctx->src_bufs[i].cookie.stream =
vb2_dma_contig_plane_dma_addr(vb, 0);
ctx->src_bufs_cnt++;
@@ -1065,18 +1071,18 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
struct s5p_mfc_buf *mfc_buf;
if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
+ mfc_buf = &ctx->src_bufs[vb->index];
mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
spin_lock_irqsave(&dev->irqlock, flags);
list_add_tail(&mfc_buf->list, &ctx->src_queue);
ctx->src_queue_cnt++;
spin_unlock_irqrestore(&dev->irqlock, flags);
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
+ mfc_buf = &ctx->dst_bufs[vb->index];
mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
/* Mark destination as available for use by MFC */
spin_lock_irqsave(&dev->irqlock, flags);
- set_bit(vb->v4l2_buf.index, &ctx->dec_dst_flag);
+ set_bit(vb->index, &ctx->dec_dst_flag);
list_add_tail(&mfc_buf->list, &ctx->dst_queue);
ctx->dst_queue_cnt++;
spin_unlock_irqrestore(&dev->irqlock, flags);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 2e57e9f45b85..5c678ec9c9f2 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -23,7 +23,7 @@
#include <media/v4l2-event.h>
#include <linux/workqueue.h>
#include <media/v4l2-ctrls.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
@@ -773,8 +773,8 @@ static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx)
spin_lock_irqsave(&dev->irqlock, flags);
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
+ dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
s5p_mfc_hw_call_void(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
@@ -796,10 +796,11 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
struct s5p_mfc_buf, list);
list_del(&dst_mb->list);
ctx->dst_queue_cnt--;
- vb2_set_plane_payload(dst_mb->b, 0,
+ vb2_set_plane_payload(&dst_mb->b->vb2_buf, 0,
s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size,
dev));
- vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&dst_mb->b->vb2_buf,
+ VB2_BUF_STATE_DONE);
}
spin_unlock_irqrestore(&dev->irqlock, flags);
}
@@ -831,16 +832,16 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
spin_lock_irqsave(&dev->irqlock, flags);
src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
- src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
+ src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
+ src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
s5p_mfc_hw_call_void(dev->mfc_ops, set_enc_frame_buffer, ctx,
src_y_addr, src_c_addr);
spin_unlock_irqrestore(&dev->irqlock, flags);
spin_lock_irqsave(&dev->irqlock, flags);
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
+ dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
s5p_mfc_hw_call_void(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
@@ -869,25 +870,29 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
s5p_mfc_hw_call_void(dev->mfc_ops, get_enc_frame_buffer, ctx,
&enc_y_addr, &enc_c_addr);
list_for_each_entry(mb_entry, &ctx->src_queue, list) {
- mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
- mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
+ mb_y_addr = vb2_dma_contig_plane_dma_addr(
+ &mb_entry->b->vb2_buf, 0);
+ mb_c_addr = vb2_dma_contig_plane_dma_addr(
+ &mb_entry->b->vb2_buf, 1);
if ((enc_y_addr == mb_y_addr) &&
(enc_c_addr == mb_c_addr)) {
list_del(&mb_entry->list);
ctx->src_queue_cnt--;
- vb2_buffer_done(mb_entry->b,
+ vb2_buffer_done(&mb_entry->b->vb2_buf,
VB2_BUF_STATE_DONE);
break;
}
}
list_for_each_entry(mb_entry, &ctx->ref_queue, list) {
- mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
- mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
+ mb_y_addr = vb2_dma_contig_plane_dma_addr(
+ &mb_entry->b->vb2_buf, 0);
+ mb_c_addr = vb2_dma_contig_plane_dma_addr(
+ &mb_entry->b->vb2_buf, 1);
if ((enc_y_addr == mb_y_addr) &&
(enc_c_addr == mb_c_addr)) {
list_del(&mb_entry->list);
ctx->ref_queue_cnt--;
- vb2_buffer_done(mb_entry->b,
+ vb2_buffer_done(&mb_entry->b->vb2_buf,
VB2_BUF_STATE_DONE);
break;
}
@@ -902,9 +907,9 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
list_add_tail(&mb_entry->list, &ctx->ref_queue);
ctx->ref_queue_cnt++;
}
- mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
- ctx->src_queue_cnt, ctx->ref_queue_cnt);
}
+ mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
+ ctx->src_queue_cnt, ctx->ref_queue_cnt);
if ((ctx->dst_queue_cnt > 0) && (strm_size > 0)) {
mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf,
list);
@@ -912,21 +917,22 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
ctx->dst_queue_cnt--;
switch (slice_type) {
case S5P_FIMV_ENC_SI_SLICE_TYPE_I:
- mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+ mb_entry->b->flags |= V4L2_BUF_FLAG_KEYFRAME;
break;
case S5P_FIMV_ENC_SI_SLICE_TYPE_P:
- mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
+ mb_entry->b->flags |= V4L2_BUF_FLAG_PFRAME;
break;
case S5P_FIMV_ENC_SI_SLICE_TYPE_B:
- mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
+ mb_entry->b->flags |= V4L2_BUF_FLAG_BFRAME;
break;
}
- vb2_set_plane_payload(mb_entry->b, 0, strm_size);
- vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);
+ vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
}
spin_unlock_irqrestore(&dev->irqlock, flags);
if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
clear_work_bit(ctx);
+
return 0;
}
@@ -1806,13 +1812,13 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
return -EINVAL;
}
mfc_debug(2, "index: %d, plane[%d] cookie: %pad\n",
- vb->v4l2_buf.index, i, &dma);
+ vb->index, i, &dma);
}
return 0;
}
static int s5p_mfc_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *buf_count, unsigned int *plane_count,
unsigned int psize[], void *allocators[])
{
@@ -1821,7 +1827,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (ctx->state != MFCINST_GOT_INST) {
- mfc_err("inavlid state: %d\n", ctx->state);
+ mfc_err("invalid state: %d\n", ctx->state);
return -EINVAL;
}
@@ -1861,7 +1867,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
}
} else {
- mfc_err("inavlid queue type: %d\n", vq->type);
+ mfc_err("invalid queue type: %d\n", vq->type);
return -EINVAL;
}
return 0;
@@ -1869,6 +1875,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
static int s5p_mfc_buf_init(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
unsigned int i;
@@ -1878,8 +1885,8 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
ret = check_vb_with_fmt(ctx->dst_fmt, vb);
if (ret < 0)
return ret;
- i = vb->v4l2_buf.index;
- ctx->dst_bufs[i].b = vb;
+ i = vb->index;
+ ctx->dst_bufs[i].b = vbuf;
ctx->dst_bufs[i].cookie.stream =
vb2_dma_contig_plane_dma_addr(vb, 0);
ctx->dst_bufs_cnt++;
@@ -1887,15 +1894,15 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
ret = check_vb_with_fmt(ctx->src_fmt, vb);
if (ret < 0)
return ret;
- i = vb->v4l2_buf.index;
- ctx->src_bufs[i].b = vb;
+ i = vb->index;
+ ctx->src_bufs[i].b = vbuf;
ctx->src_bufs[i].cookie.raw.luma =
vb2_dma_contig_plane_dma_addr(vb, 0);
ctx->src_bufs[i].cookie.raw.chroma =
vb2_dma_contig_plane_dma_addr(vb, 1);
ctx->src_bufs_cnt++;
} else {
- mfc_err("inavlid queue type: %d\n", vq->type);
+ mfc_err("invalid queue type: %d\n", vq->type);
return -EINVAL;
}
return 0;
@@ -1931,7 +1938,7 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
return -EINVAL;
}
} else {
- mfc_err("inavlid queue type: %d\n", vq->type);
+ mfc_err("invalid queue type: %d\n", vq->type);
return -EINVAL;
}
return 0;
@@ -2012,7 +2019,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
return;
}
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
+ mfc_buf = &ctx->dst_bufs[vb->index];
mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
/* Mark destination as available for use by MFC */
spin_lock_irqsave(&dev->irqlock, flags);
@@ -2020,7 +2027,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
ctx->dst_queue_cnt++;
spin_unlock_irqrestore(&dev->irqlock, flags);
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
+ mfc_buf = &ctx->src_bufs[vb->index];
mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
spin_lock_irqsave(&dev->irqlock, flags);
list_add_tail(&mfc_buf->list, &ctx->src_queue);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
index 6402f76cc620..873c933bc7d4 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
@@ -1208,11 +1208,11 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
temp_vb->flags |= MFC_BUF_FLAG_USED;
s5p_mfc_set_dec_stream_buffer_v5(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
- ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused);
+ vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),
+ ctx->consumed_stream, temp_vb->b->vb2_buf.planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
- if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
+ if (temp_vb->b->vb2_buf.planes[0].bytesused == 0) {
last_frame = MFC_DEC_LAST_FRAME;
mfc_debug(2, "Setting ctx->state to FINISHING\n");
ctx->state = MFCINST_FINISHING;
@@ -1249,16 +1249,16 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
list);
src_mb->flags |= MFC_BUF_FLAG_USED;
- if (src_mb->b->v4l2_planes[0].bytesused == 0) {
+ if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
/* send null frame */
s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2,
dev->bank2);
ctx->state = MFCINST_FINISHING;
} else {
- src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
- 0);
- src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
- 1);
+ src_y_addr = vb2_dma_contig_plane_dma_addr(
+ &src_mb->b->vb2_buf, 0);
+ src_c_addr = vb2_dma_contig_plane_dma_addr(
+ &src_mb->b->vb2_buf, 1);
s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
src_c_addr);
if (src_mb->flags & MFC_BUF_FLAG_EOS)
@@ -1267,13 +1267,13 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
}
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
dst_mb->flags |= MFC_BUF_FLAG_USED;
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
+ dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
mfc_debug(2, "encoding buffer with index=%d state=%d\n",
- src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state);
+ src_mb ? src_mb->b->vb2_buf.index : -1, ctx->state);
s5p_mfc_encode_one_frame_v5(ctx);
return 0;
}
@@ -1289,10 +1289,11 @@ static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
mfc_debug(2, "Preparing to init decoding\n");
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
s5p_mfc_set_dec_desc_buffer(ctx);
- mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
+ mfc_debug(2, "Header size: %d\n",
+ temp_vb->b->vb2_buf.planes[0].bytesused);
s5p_mfc_set_dec_stream_buffer_v5(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
- 0, temp_vb->b->v4l2_planes[0].bytesused);
+ vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),
+ 0, temp_vb->b->vb2_buf.planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_init_decode_v5(ctx);
@@ -1309,8 +1310,8 @@ static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
s5p_mfc_set_enc_ref_buffer_v5(ctx);
spin_lock_irqsave(&dev->irqlock, flags);
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
+ dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
@@ -1342,10 +1343,11 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
return -EIO;
}
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
+ mfc_debug(2, "Header size: %d\n",
+ temp_vb->b->vb2_buf.planes[0].bytesused);
s5p_mfc_set_dec_stream_buffer_v5(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
- 0, temp_vb->b->v4l2_planes[0].bytesused);
+ vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),
+ 0, temp_vb->b->vb2_buf.planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
ret = s5p_mfc_set_dec_frame_buffer_v5(ctx);
@@ -1478,9 +1480,9 @@ static void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq)
while (!list_empty(lh)) {
b = list_entry(lh->next, struct s5p_mfc_buf, list);
- for (i = 0; i < b->b->num_planes; i++)
- vb2_set_plane_payload(b->b, i, 0);
- vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
+ for (i = 0; i < b->b->vb2_buf.num_planes; i++)
+ vb2_set_plane_payload(&b->b->vb2_buf, i, 0);
+ vb2_buffer_done(&b->b->vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&b->list);
}
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index e5cb30e1f718..b95845347348 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -522,7 +522,7 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
writel(addr, mfc_regs->e_stream_buffer_addr); /* 16B align */
writel(size, mfc_regs->e_stream_buffer_size);
- mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n",
+ mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%x\n",
addr, size);
return 0;
@@ -554,7 +554,7 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr);
enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr);
- mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr);
+ mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr);
mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
}
@@ -1483,6 +1483,7 @@ static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
+ int cmd;
mfc_debug(2, "++\n");
@@ -1493,9 +1494,13 @@ static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx)
s5p_mfc_set_slice_mode(ctx);
+ if (ctx->state != MFCINST_FINISHING)
+ cmd = S5P_FIMV_CH_FRAME_START_V6;
+ else
+ cmd = S5P_FIMV_CH_LAST_FRAME_V6;
+
writel(ctx->inst_no, mfc_regs->instance_id);
- s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev,
- S5P_FIMV_CH_FRAME_START_V6, NULL);
+ s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, cmd, NULL);
mfc_debug(2, "--\n");
@@ -1562,13 +1567,13 @@ static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx)
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
temp_vb->flags |= MFC_BUF_FLAG_USED;
s5p_mfc_set_dec_stream_buffer_v6(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
+ vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),
ctx->consumed_stream,
- temp_vb->b->v4l2_planes[0].bytesused);
+ temp_vb->b->vb2_buf.planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
- if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
+ if (temp_vb->b->vb2_buf.planes[0].bytesused == 0) {
last_frame = 1;
mfc_debug(2, "Setting ctx->state to FINISHING\n");
ctx->state = MFCINST_FINISHING;
@@ -1592,7 +1597,7 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
spin_lock_irqsave(&dev->irqlock, flags);
- if (list_empty(&ctx->src_queue)) {
+ if (list_empty(&ctx->src_queue) && ctx->state != MFCINST_FINISHING) {
mfc_debug(2, "no src buffers.\n");
spin_unlock_irqrestore(&dev->irqlock, flags);
return -EAGAIN;
@@ -1604,20 +1609,33 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
return -EAGAIN;
}
- src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- src_mb->flags |= MFC_BUF_FLAG_USED;
- src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
- src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
+ if (list_empty(&ctx->src_queue)) {
+ /* send null frame */
+ s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
+ src_mb = NULL;
+ } else {
+ src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
+ src_mb->flags |= MFC_BUF_FLAG_USED;
+ if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
+ s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0);
+ ctx->state = MFCINST_FINISHING;
+ } else {
+ src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0);
+ src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1);
- mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
- mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
+ mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
+ mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
- s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
+ s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
+ if (src_mb->flags & MFC_BUF_FLAG_EOS)
+ ctx->state = MFCINST_FINISHING;
+ }
+ }
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
dst_mb->flags |= MFC_BUF_FLAG_USED;
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
+ dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size);
@@ -1639,10 +1657,10 @@ static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
spin_lock_irqsave(&dev->irqlock, flags);
mfc_debug(2, "Preparing to init decoding.\n");
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
+ mfc_debug(2, "Header size: %d\n", temp_vb->b->vb2_buf.planes[0].bytesused);
s5p_mfc_set_dec_stream_buffer_v6(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0,
- temp_vb->b->v4l2_planes[0].bytesused);
+ vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0), 0,
+ temp_vb->b->vb2_buf.planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_init_decode_v6(ctx);
@@ -1659,8 +1677,8 @@ static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
spin_lock_irqsave(&dev->irqlock, flags);
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
- dst_size = vb2_plane_size(dst_mb->b, 0);
+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);
+ dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);
s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
@@ -1836,9 +1854,9 @@ static void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq)
while (!list_empty(lh)) {
b = list_entry(lh->next, struct s5p_mfc_buf, list);
- for (i = 0; i < b->b->num_planes; i++)
- vb2_set_plane_payload(b->b, i, 0);
- vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
+ for (i = 0; i < b->b->vb2_buf.num_planes; i++)
+ vb2_set_plane_payload(&b->b->vb2_buf, i, 0);
+ vb2_buffer_done(&b->b->vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&b->list);
}
}
diff --git a/drivers/media/platform/s5p-tv/mixer.h b/drivers/media/platform/s5p-tv/mixer.h
index fb2acc53112a..42cd2709c41c 100644
--- a/drivers/media/platform/s5p-tv/mixer.h
+++ b/drivers/media/platform/s5p-tv/mixer.h
@@ -24,7 +24,7 @@
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <media/v4l2-device.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "regs-mixer.h"
@@ -113,7 +113,7 @@ struct mxr_geometry {
/** instance of a buffer */
struct mxr_buffer {
/** common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
/** node for layer's lists */
struct list_head list;
};
diff --git a/drivers/media/platform/s5p-tv/mixer_grp_layer.c b/drivers/media/platform/s5p-tv/mixer_grp_layer.c
index 74344c764daa..db3163b23ea0 100644
--- a/drivers/media/platform/s5p-tv/mixer_grp_layer.c
+++ b/drivers/media/platform/s5p-tv/mixer_grp_layer.c
@@ -86,7 +86,7 @@ static void mxr_graph_buffer_set(struct mxr_layer *layer,
dma_addr_t addr = 0;
if (buf)
- addr = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
+ addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
}
diff --git a/drivers/media/platform/s5p-tv/mixer_reg.c b/drivers/media/platform/s5p-tv/mixer_reg.c
index 5127acb1e571..a0ec14a1da13 100644
--- a/drivers/media/platform/s5p-tv/mixer_reg.c
+++ b/drivers/media/platform/s5p-tv/mixer_reg.c
@@ -279,7 +279,7 @@ static void mxr_irq_layer_handle(struct mxr_layer *layer)
layer->ops.buffer_set(layer, layer->update_buf);
if (done && done != layer->shadow_buf)
- vb2_buffer_done(&done->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&done->vb.vb2_buf, VB2_BUF_STATE_DONE);
done:
spin_unlock(&layer->enq_slock);
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index 751f3b618337..dc1c679e136c 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -881,7 +881,7 @@ static const struct v4l2_file_operations mxr_fops = {
.unlocked_ioctl = video_ioctl2,
};
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[],
void *alloc_ctxs[])
{
@@ -914,7 +914,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
static void buf_queue(struct vb2_buffer *vb)
{
- struct mxr_buffer *buffer = container_of(vb, struct mxr_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct mxr_buffer *buffer = container_of(vbuf, struct mxr_buffer, vb);
struct mxr_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
struct mxr_device *mdev = layer->mdev;
unsigned long flags;
@@ -963,11 +964,13 @@ static void mxr_watchdog(unsigned long arg)
if (layer->update_buf == layer->shadow_buf)
layer->update_buf = NULL;
if (layer->update_buf) {
- vb2_buffer_done(&layer->update_buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&layer->update_buf->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
layer->update_buf = NULL;
}
if (layer->shadow_buf) {
- vb2_buffer_done(&layer->shadow_buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&layer->shadow_buf->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
layer->shadow_buf = NULL;
}
spin_unlock_irqrestore(&layer->enq_slock, flags);
@@ -991,7 +994,7 @@ static void stop_streaming(struct vb2_queue *vq)
/* set all buffer to be done */
list_for_each_entry_safe(buf, buf_tmp, &layer->enq_list, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&layer->enq_slock, flags);
diff --git a/drivers/media/platform/s5p-tv/mixer_vp_layer.c b/drivers/media/platform/s5p-tv/mixer_vp_layer.c
index c9388c45ad75..dd002a497dbb 100644
--- a/drivers/media/platform/s5p-tv/mixer_vp_layer.c
+++ b/drivers/media/platform/s5p-tv/mixer_vp_layer.c
@@ -97,9 +97,10 @@ static void mxr_vp_buffer_set(struct mxr_layer *layer,
mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
return;
}
- luma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
+ luma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
if (layer->fmt->num_subframes == 2) {
- chroma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb, 1);
+ chroma_addr[0] =
+ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 1);
} else {
/* FIXME: mxr_get_plane_size compute integer division,
* which is slow and should not be performed in interrupt */
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index f5e3eb3a20ff..d6ab33e7060a 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -865,10 +865,11 @@ static const struct v4l2_ioctl_ops sh_veu_ioctl_ops = {
/* ========== Queue operations ========== */
static int sh_veu_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *f,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *f = parg;
struct sh_veu_dev *veu = vb2_get_drv_priv(vq);
struct sh_veu_vfmt *vfmt;
unsigned int size, count = *nbuffers;
@@ -931,9 +932,10 @@ static int sh_veu_buf_prepare(struct vb2_buffer *vb)
static void sh_veu_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct sh_veu_dev *veu = vb2_get_drv_priv(vb->vb2_queue);
- dev_dbg(veu->dev, "%s(%d)\n", __func__, vb->v4l2_buf.type);
- v4l2_m2m_buf_queue(veu->m2m_ctx, vb);
+ dev_dbg(veu->dev, "%s(%d)\n", __func__, vb->type);
+ v4l2_m2m_buf_queue(veu->m2m_ctx, vbuf);
}
static const struct vb2_ops sh_veu_qops = {
@@ -1084,8 +1086,8 @@ static irqreturn_t sh_veu_bh(int irq, void *dev_id)
static irqreturn_t sh_veu_isr(int irq, void *dev_id)
{
struct sh_veu_dev *veu = dev_id;
- struct vb2_buffer *dst;
- struct vb2_buffer *src;
+ struct vb2_v4l2_buffer *dst;
+ struct vb2_v4l2_buffer *src;
u32 status = sh_veu_reg_read(veu, VEU_EVTR);
/* bundle read mode not used */
@@ -1105,11 +1107,11 @@ static irqreturn_t sh_veu_isr(int irq, void *dev_id)
if (!src || !dst)
return IRQ_NONE;
- dst->v4l2_buf.timestamp = src->v4l2_buf.timestamp;
- dst->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst->v4l2_buf.flags |=
- src->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst->v4l2_buf.timecode = src->v4l2_buf.timecode;
+ dst->timestamp = src->timestamp;
+ dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst->flags |=
+ src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst->timecode = src->timecode;
spin_lock(&veu->lock);
v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index fe5c8ab06bd5..2231f8922df3 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -27,6 +27,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mediabus.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
/* Mirror addresses are not available for all registers */
@@ -62,11 +63,12 @@ enum sh_vou_status {
#define VOU_MIN_IMAGE_HEIGHT 16
struct sh_vou_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
-static inline struct sh_vou_buffer *to_sh_vou_buffer(struct vb2_buffer *vb2)
+static inline struct
+sh_vou_buffer *to_sh_vou_buffer(struct vb2_v4l2_buffer *vb2)
{
return container_of(vb2, struct sh_vou_buffer, vb);
}
@@ -193,11 +195,11 @@ static struct sh_vou_fmt vou_fmt[] = {
};
static void sh_vou_schedule_next(struct sh_vou_device *vou_dev,
- struct vb2_buffer *vb)
+ struct vb2_v4l2_buffer *vbuf)
{
dma_addr_t addr1, addr2;
- addr1 = vb2_dma_contig_plane_dma_addr(vb, 0);
+ addr1 = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
switch (vou_dev->pix.pixelformat) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV16:
@@ -241,10 +243,11 @@ static void sh_vou_stream_config(struct sh_vou_device *vou_dev)
}
/* Locking: caller holds fop_lock mutex */
-static int sh_vou_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int sh_vou_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct sh_vou_device *vou_dev = vb2_get_drv_priv(vq);
struct v4l2_pix_format *pix = &vou_dev->pix;
int bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
@@ -282,8 +285,9 @@ static int sh_vou_buf_prepare(struct vb2_buffer *vb)
/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
static void sh_vou_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct sh_vou_device *vou_dev = vb2_get_drv_priv(vb->vb2_queue);
- struct sh_vou_buffer *shbuf = to_sh_vou_buffer(vb);
+ struct sh_vou_buffer *shbuf = to_sh_vou_buffer(vbuf);
unsigned long flags;
spin_lock_irqsave(&vou_dev->lock, flags);
@@ -302,7 +306,8 @@ static int sh_vou_start_streaming(struct vb2_queue *vq, unsigned int count)
video, s_stream, 1);
if (ret < 0 && ret != -ENOIOCTLCMD) {
list_for_each_entry_safe(buf, node, &vou_dev->buf_list, list) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
list_del(&buf->list);
}
vou_dev->active = NULL;
@@ -353,7 +358,7 @@ static void sh_vou_stop_streaming(struct vb2_queue *vq)
msleep(50);
spin_lock_irqsave(&vou_dev->lock, flags);
list_for_each_entry_safe(buf, node, &vou_dev->buf_list, list) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&buf->list);
}
vou_dev->active = NULL;
@@ -1066,10 +1071,10 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
list_del(&vb->list);
- v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
- vb->vb.v4l2_buf.sequence = vou_dev->sequence++;
- vb->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
- vb2_buffer_done(&vb->vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vb->vb.timestamp);
+ vb->vb.sequence = vou_dev->sequence++;
+ vb->vb.field = V4L2_FIELD_INTERLACED;
+ vb2_buffer_done(&vb->vb.vb2_buf, VB2_BUF_STATE_DONE);
vou_dev->active = list_entry(vou_dev->buf_list.next,
struct sh_vou_buffer, list);
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 90701726a06a..454f68f0cdad 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -23,12 +23,13 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>
-#include <media/atmel-isi.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <media/v4l2-of.h>
#include <media/videobuf2-dma-contig.h>
+#include "atmel-isi.h"
+
#define MAX_BUFFER_NUM 32
#define MAX_SUPPORT_WIDTH 2048
#define MAX_SUPPORT_HEIGHT 2048
@@ -59,7 +60,7 @@ struct isi_dma_desc {
/* Frame buffer data */
struct frame_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct isi_dma_desc *p_dma_desc;
struct list_head list;
};
@@ -102,62 +103,71 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg)
return readl(isi->regs + reg);
}
-static int configure_geometry(struct atmel_isi *isi, u32 width,
+static void configure_geometry(struct atmel_isi *isi, u32 width,
u32 height, u32 code)
{
- u32 cfg2, cr;
+ u32 cfg2;
+ /* According to sensor's output format to set cfg2 */
switch (code) {
- /* YUV, including grey */
+ default:
+ /* Grey */
case MEDIA_BUS_FMT_Y8_1X8:
- cr = ISI_CFG2_GRAYSCALE;
+ cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr;
break;
+ /* YUV */
case MEDIA_BUS_FMT_VYUY8_2X8:
- cr = ISI_CFG2_YCC_SWAP_MODE_3;
+ cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr;
break;
case MEDIA_BUS_FMT_UYVY8_2X8:
- cr = ISI_CFG2_YCC_SWAP_MODE_2;
+ cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr;
break;
case MEDIA_BUS_FMT_YVYU8_2X8:
- cr = ISI_CFG2_YCC_SWAP_MODE_1;
+ cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr;
break;
case MEDIA_BUS_FMT_YUYV8_2X8:
- cr = ISI_CFG2_YCC_SWAP_DEFAULT;
+ cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr;
break;
/* RGB, TODO */
- default:
- return -EINVAL;
}
isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
-
- cfg2 = isi_readl(isi, ISI_CFG2);
- /* Set YCC swap mode */
- cfg2 &= ~ISI_CFG2_YCC_SWAP_MODE_MASK;
- cfg2 |= cr;
/* Set width */
- cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK);
cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
ISI_CFG2_IM_HSIZE_MASK;
/* Set height */
- cfg2 &= ~(ISI_CFG2_IM_VSIZE_MASK);
cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
& ISI_CFG2_IM_VSIZE_MASK;
isi_writel(isi, ISI_CFG2, cfg2);
+}
- return 0;
+static bool is_supported(struct soc_camera_device *icd,
+ const u32 pixformat)
+{
+ switch (pixformat) {
+ /* YUV, including grey */
+ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_VYUY:
+ return true;
+ /* RGB, TODO */
+ default:
+ return false;
+ }
}
static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
{
if (isi->active) {
- struct vb2_buffer *vb = &isi->active->vb;
+ struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
struct frame_buffer *buf = isi->active;
list_del_init(&buf->list);
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.sequence = isi->sequence++;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vbuf->timestamp);
+ vbuf->sequence = isi->sequence++;
+ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
}
if (list_empty(&isi->video_buffer_list)) {
@@ -225,7 +235,7 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
}
timeout = wait_for_completion_timeout(&isi->complete,
- msecs_to_jiffies(100));
+ msecs_to_jiffies(500));
if (timeout == 0)
return -ETIMEDOUT;
@@ -235,7 +245,7 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
/* ------------------------------------------------------------------
Videobuf operations
------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -267,7 +277,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int buffer_init(struct vb2_buffer *vb)
{
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
buf->p_dma_desc = NULL;
INIT_LIST_HEAD(&buf->list);
@@ -277,8 +288,9 @@ static int buffer_init(struct vb2_buffer *vb)
static int buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
+ struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct atmel_isi *isi = ici->priv;
unsigned long size;
@@ -292,7 +304,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
return -EINVAL;
}
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(vb, 0, size);
if (!buf->p_dma_desc) {
if (list_empty(&isi->dma_desc_head)) {
@@ -319,10 +331,11 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_cleanup(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct atmel_isi *isi = ici->priv;
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
+ struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
/* This descriptor is available now and we add to head list */
if (buf->p_dma_desc)
@@ -360,10 +373,11 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
static void buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct atmel_isi *isi = ici->priv;
- struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
+ struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
unsigned long flags = 0;
spin_lock_irqsave(&isi->lock, flags);
@@ -396,6 +410,9 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
/* Disable all interrupts */
isi_writel(isi, ISI_INTDIS, (u32)~0UL);
+ configure_geometry(isi, icd->user_width, icd->user_height,
+ icd->current_fmt->code);
+
spin_lock_irq(&isi->lock);
/* Clear any pending interrupt */
isi_readl(isi, ISI_STATUS);
@@ -422,7 +439,7 @@ static void stop_streaming(struct vb2_queue *vq)
/* Release all active buffers */
list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
list_del_init(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irq(&isi->lock);
@@ -483,8 +500,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q,
static int isi_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
@@ -494,6 +509,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_mbus_framefmt *mf = &format.format;
int ret;
+ /* check with atmel-isi support format, if not support use YUYV */
+ if (!is_supported(icd, pix->pixelformat))
+ pix->pixelformat = V4L2_PIX_FMT_YUYV;
+
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate) {
dev_warn(icd->parent, "Format %x not found\n",
@@ -517,16 +536,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd,
if (mf->code != xlate->code)
return -EINVAL;
- /* Enable PM and peripheral clock before operate isi registers */
- pm_runtime_get_sync(ici->v4l2_dev.dev);
-
- ret = configure_geometry(isi, pix->width, pix->height, xlate->code);
-
- pm_runtime_put(ici->v4l2_dev.dev);
-
- if (ret < 0)
- return ret;
-
pix->width = mf->width;
pix->height = mf->height;
pix->field = mf->field;
@@ -553,6 +562,10 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd,
u32 pixfmt = pix->pixelformat;
int ret;
+ /* check with atmel-isi support format, if not support use YUYV */
+ if (!is_supported(icd, pix->pixelformat))
+ pix->pixelformat = V4L2_PIX_FMT_YUYV;
+
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (pixfmt && !xlate) {
dev_warn(icd->parent, "Format %x not found\n", pixfmt);
@@ -824,6 +837,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
+ dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n",
+ common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
+ common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
+ common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
+
if (isi->pdata.has_emb_sync)
cfg1 |= ISI_CFG1_EMB_SYNC;
if (isi->pdata.full_mode)
@@ -873,7 +891,7 @@ static int atmel_isi_remove(struct platform_device *pdev)
return 0;
}
-static int atmel_isi_probe_dt(struct atmel_isi *isi,
+static int atmel_isi_parse_dt(struct atmel_isi *isi,
struct platform_device *pdev)
{
struct device_node *np= pdev->dev.of_node;
@@ -891,9 +909,10 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi,
}
err = v4l2_of_parse_endpoint(np, &ep);
+ of_node_put(np);
if (err) {
dev_err(&pdev->dev, "Could not parse the endpoint\n");
- goto err_probe_dt;
+ return err;
}
switch (ep.bus.parallel.bus_width) {
@@ -907,14 +926,20 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi,
default:
dev_err(&pdev->dev, "Unsupported bus width: %d\n",
ep.bus.parallel.bus_width);
- err = -EINVAL;
- goto err_probe_dt;
+ return -EINVAL;
}
-err_probe_dt:
- of_node_put(np);
+ if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+ isi->pdata.hsync_act_low = true;
+ if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+ isi->pdata.vsync_act_low = true;
+ if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+ isi->pdata.pclk_act_falling = true;
- return err;
+ if (ep.bus_type == V4L2_MBUS_BT656)
+ isi->pdata.has_emb_sync = true;
+
+ return 0;
}
static int atmel_isi_probe(struct platform_device *pdev)
@@ -923,16 +948,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
struct atmel_isi *isi;
struct resource *regs;
int ret, i;
- struct device *dev = &pdev->dev;
struct soc_camera_host *soc_host;
- struct isi_platform_data *pdata;
-
- pdata = dev->platform_data;
- if ((!pdata || !pdata->data_width_flags) && !pdev->dev.of_node) {
- dev_err(&pdev->dev,
- "No config available for Atmel ISI\n");
- return -EINVAL;
- }
isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
if (!isi) {
@@ -944,13 +960,9 @@ static int atmel_isi_probe(struct platform_device *pdev)
if (IS_ERR(isi->pclk))
return PTR_ERR(isi->pclk);
- if (pdata) {
- memcpy(&isi->pdata, pdata, sizeof(isi->pdata));
- } else {
- ret = atmel_isi_probe_dt(isi, pdev);
- if (ret)
- return ret;
- }
+ ret = atmel_isi_parse_dt(isi, pdev);
+ if (ret)
+ return ret;
isi->active = NULL;
spin_lock_init(&isi->lock);
@@ -1014,11 +1026,6 @@ static int atmel_isi_probe(struct platform_device *pdev)
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
- if (isi->pdata.asd_sizes) {
- soc_host->asd = isi->pdata.asd;
- soc_host->asd_sizes = isi->pdata.asd_sizes;
- }
-
ret = soc_camera_host_register(soc_host);
if (ret) {
dev_err(&pdev->dev, "Unable to register soc camera host\n");
@@ -1040,6 +1047,7 @@ err_alloc_ctx:
return ret;
}
+#ifdef CONFIG_PM
static int atmel_isi_runtime_suspend(struct device *dev)
{
struct soc_camera_host *soc_host = to_soc_camera_host(dev);
@@ -1058,6 +1066,7 @@ static int atmel_isi_runtime_resume(struct device *dev)
return clk_prepare_enable(isi->pclk);
}
+#endif /* CONFIG_PM */
static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
diff --git a/drivers/media/platform/soc_camera/atmel-isi.h b/drivers/media/platform/soc_camera/atmel-isi.h
new file mode 100644
index 000000000000..5acc771d2edc
--- /dev/null
+++ b/drivers/media/platform/soc_camera/atmel-isi.h
@@ -0,0 +1,128 @@
+/*
+ * Register definitions for the Atmel Image Sensor Interface.
+ *
+ * Copyright (C) 2011 Atmel Corporation
+ * Josh Wu, <josh.wu@atmel.com>
+ *
+ * Based on previous work by Lars Haring, <lars.haring@atmel.com>
+ * and Sedji Gaouaou
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ATMEL_ISI_H__
+#define __ATMEL_ISI_H__
+
+#include <linux/types.h>
+
+/* ISI_V2 register offsets */
+#define ISI_CFG1 0x0000
+#define ISI_CFG2 0x0004
+#define ISI_PSIZE 0x0008
+#define ISI_PDECF 0x000c
+#define ISI_Y2R_SET0 0x0010
+#define ISI_Y2R_SET1 0x0014
+#define ISI_R2Y_SET0 0x0018
+#define ISI_R2Y_SET1 0x001C
+#define ISI_R2Y_SET2 0x0020
+#define ISI_CTRL 0x0024
+#define ISI_STATUS 0x0028
+#define ISI_INTEN 0x002C
+#define ISI_INTDIS 0x0030
+#define ISI_INTMASK 0x0034
+#define ISI_DMA_CHER 0x0038
+#define ISI_DMA_CHDR 0x003C
+#define ISI_DMA_CHSR 0x0040
+#define ISI_DMA_P_ADDR 0x0044
+#define ISI_DMA_P_CTRL 0x0048
+#define ISI_DMA_P_DSCR 0x004C
+#define ISI_DMA_C_ADDR 0x0050
+#define ISI_DMA_C_CTRL 0x0054
+#define ISI_DMA_C_DSCR 0x0058
+
+/* Bitfields in CFG1 */
+#define ISI_CFG1_HSYNC_POL_ACTIVE_LOW (1 << 2)
+#define ISI_CFG1_VSYNC_POL_ACTIVE_LOW (1 << 3)
+#define ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING (1 << 4)
+#define ISI_CFG1_EMB_SYNC (1 << 6)
+#define ISI_CFG1_CRC_SYNC (1 << 7)
+/* Constants for FRATE(ISI_V2) */
+#define ISI_CFG1_FRATE_CAPTURE_ALL (0 << 8)
+#define ISI_CFG1_FRATE_DIV_2 (1 << 8)
+#define ISI_CFG1_FRATE_DIV_3 (2 << 8)
+#define ISI_CFG1_FRATE_DIV_4 (3 << 8)
+#define ISI_CFG1_FRATE_DIV_5 (4 << 8)
+#define ISI_CFG1_FRATE_DIV_6 (5 << 8)
+#define ISI_CFG1_FRATE_DIV_7 (6 << 8)
+#define ISI_CFG1_FRATE_DIV_8 (7 << 8)
+#define ISI_CFG1_FRATE_DIV_MASK (7 << 8)
+#define ISI_CFG1_DISCR (1 << 11)
+#define ISI_CFG1_FULL_MODE (1 << 12)
+/* Definition for THMASK(ISI_V2) */
+#define ISI_CFG1_THMASK_BEATS_4 (0 << 13)
+#define ISI_CFG1_THMASK_BEATS_8 (1 << 13)
+#define ISI_CFG1_THMASK_BEATS_16 (2 << 13)
+
+/* Bitfields in CFG2 */
+#define ISI_CFG2_GRAYSCALE (1 << 13)
+#define ISI_CFG2_COL_SPACE_YCbCr (0 << 15)
+#define ISI_CFG2_COL_SPACE_RGB (1 << 15)
+/* Constants for YCC_SWAP(ISI_V2) */
+#define ISI_CFG2_YCC_SWAP_DEFAULT (0 << 28)
+#define ISI_CFG2_YCC_SWAP_MODE_1 (1 << 28)
+#define ISI_CFG2_YCC_SWAP_MODE_2 (2 << 28)
+#define ISI_CFG2_YCC_SWAP_MODE_3 (3 << 28)
+#define ISI_CFG2_YCC_SWAP_MODE_MASK (3 << 28)
+#define ISI_CFG2_IM_VSIZE_OFFSET 0
+#define ISI_CFG2_IM_HSIZE_OFFSET 16
+#define ISI_CFG2_IM_VSIZE_MASK (0x7FF << ISI_CFG2_IM_VSIZE_OFFSET)
+#define ISI_CFG2_IM_HSIZE_MASK (0x7FF << ISI_CFG2_IM_HSIZE_OFFSET)
+
+/* Bitfields in CTRL */
+/* Also using in SR(ISI_V2) */
+#define ISI_CTRL_EN (1 << 0)
+#define ISI_CTRL_CDC (1 << 8)
+/* Also using in SR/IER/IDR/IMR(ISI_V2) */
+#define ISI_CTRL_DIS (1 << 1)
+#define ISI_CTRL_SRST (1 << 2)
+
+/* Bitfields in SR */
+#define ISI_SR_SIP (1 << 19)
+/* Also using in SR/IER/IDR/IMR */
+#define ISI_SR_VSYNC (1 << 10)
+#define ISI_SR_PXFR_DONE (1 << 16)
+#define ISI_SR_CXFR_DONE (1 << 17)
+#define ISI_SR_P_OVR (1 << 24)
+#define ISI_SR_C_OVR (1 << 25)
+#define ISI_SR_CRC_ERR (1 << 26)
+#define ISI_SR_FR_OVR (1 << 27)
+
+/* Bitfields in DMA_C_CTRL & in DMA_P_CTRL */
+#define ISI_DMA_CTRL_FETCH (1 << 0)
+#define ISI_DMA_CTRL_WB (1 << 1)
+#define ISI_DMA_CTRL_IEN (1 << 2)
+#define ISI_DMA_CTRL_DONE (1 << 3)
+
+/* Bitfields in DMA_CHSR/CHER/CHDR */
+#define ISI_DMA_CHSR_P_CH (1 << 0)
+#define ISI_DMA_CHSR_C_CH (1 << 1)
+
+/* Definition for isi_platform_data */
+#define ISI_DATAWIDTH_8 0x01
+#define ISI_DATAWIDTH_10 0x02
+
+struct v4l2_async_subdev;
+
+struct isi_platform_data {
+ u8 has_emb_sync;
+ u8 hsync_act_low;
+ u8 vsync_act_low;
+ u8 pclk_act_falling;
+ u8 full_mode;
+ u32 data_width_flags;
+ /* Using for ISI_CFG1 */
+ u32 frate;
+};
+
+#endif /* __ATMEL_ISI_H__ */
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index ea4c423f0cf8..1f28d21a3c9a 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -32,7 +32,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
@@ -225,7 +225,7 @@ struct mx2_buf_internal {
/* buffer for one video frame */
struct mx2_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct mx2_buf_internal internal;
};
@@ -469,10 +469,11 @@ static void mx2_camera_clock_stop(struct soc_camera_host *ici)
* Videobuf operations
*/
static int mx2_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *count, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
@@ -530,11 +531,12 @@ out:
static void mx2_videobuf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici =
to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
- struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
+ struct mx2_buffer *buf = container_of(vbuf, struct mx2_buffer, vb);
unsigned long flags;
dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
@@ -664,7 +666,7 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
internal.queue);
buf->internal.bufnum = 0;
- vb = &buf->vb;
+ vb = &buf->vb.vb2_buf;
phys = vb2_dma_contig_plane_dma_addr(vb, 0);
mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
@@ -673,7 +675,7 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
internal.queue);
buf->internal.bufnum = 1;
- vb = &buf->vb;
+ vb = &buf->vb.vb2_buf;
phys = vb2_dma_contig_plane_dma_addr(vb, 0);
mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
@@ -1307,6 +1309,7 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
struct mx2_buf_internal *ibuf;
struct mx2_buffer *buf;
struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vbuf;
unsigned long phys;
ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal,
@@ -1323,7 +1326,8 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
} else {
buf = mx2_ibuf_to_buf(ibuf);
- vb = &buf->vb;
+ vb = &buf->vb.vb2_buf;
+ vbuf = to_vb2_v4l2_buffer(vb);
#ifdef DEBUG
phys = vb2_dma_contig_plane_dma_addr(vb, 0);
if (prp->cfg.channel == 1) {
@@ -1347,8 +1351,8 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
vb2_get_plane_payload(vb, 0));
list_del_init(&buf->internal.queue);
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.sequence = pcdev->frame_count;
+ v4l2_get_timestamp(&vbuf->timestamp);
+ vbuf->sequence = pcdev->frame_count;
if (err)
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
else
@@ -1380,7 +1384,7 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
- vb = &buf->vb;
+ vb = &buf->vb.vb2_buf;
phys = vb2_dma_contig_plane_dma_addr(vb, 0);
mx27_update_emma_buf(pcdev, phys, bufnum);
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index ace41f53caca..49c3a257a916 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -63,7 +63,7 @@
struct mx3_camera_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head queue;
/* One descriptot per scatterlist (per frame) */
@@ -133,7 +133,7 @@ static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
__raw_writel(value, mx3->base + reg);
}
-static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
+static struct mx3_camera_buffer *to_mx3_vb(struct vb2_v4l2_buffer *vb)
{
return container_of(vb, struct mx3_camera_buffer, vb);
}
@@ -151,14 +151,14 @@ static void mx3_cam_dma_done(void *arg)
spin_lock(&mx3_cam->lock);
if (mx3_cam->active) {
- struct vb2_buffer *vb = &mx3_cam->active->vb;
+ struct vb2_v4l2_buffer *vb = &mx3_cam->active->vb;
struct mx3_camera_buffer *buf = to_mx3_vb(vb);
list_del_init(&buf->queue);
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
- vb->v4l2_buf.field = mx3_cam->field;
- vb->v4l2_buf.sequence = mx3_cam->sequence++;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ v4l2_get_timestamp(&vb->timestamp);
+ vb->field = mx3_cam->field;
+ vb->sequence = mx3_cam->sequence++;
+ vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
}
if (list_empty(&mx3_cam->capture)) {
@@ -185,10 +185,11 @@ static void mx3_cam_dma_done(void *arg)
* Calculate the __buffer__ (not data) size and number of buffers.
*/
static int mx3_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *count, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
@@ -257,10 +258,11 @@ static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
static void mx3_videobuf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
+ struct mx3_camera_buffer *buf = to_mx3_vb(vbuf);
struct scatterlist *sg = &buf->sg;
struct dma_async_tx_descriptor *txd;
struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
@@ -273,7 +275,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
if (vb2_plane_size(vb, 0) < new_size) {
dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
- vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
+ vbuf->vb2_buf.index, vb2_plane_size(vb, 0), new_size);
goto error;
}
@@ -357,10 +359,11 @@ error:
static void mx3_videobuf_release(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
+ struct mx3_camera_buffer *buf = to_mx3_vb(vbuf);
struct dma_async_tx_descriptor *txd = buf->txd;
unsigned long flags;
@@ -390,10 +393,11 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
static int mx3_videobuf_init(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
- struct mx3_camera_buffer *buf = to_mx3_vb(vb);
+ struct mx3_camera_buffer *buf = to_mx3_vb(vbuf);
if (!buf->txd) {
/* This is for locking debugging only */
@@ -424,7 +428,7 @@ static void mx3_stop_streaming(struct vb2_queue *q)
list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
list_del_init(&buf->queue);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&mx3_cam->lock, flags);
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
index 71dd71c0bd1f..efe57b23fac1 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -478,7 +478,7 @@ struct rcar_vin_priv {
struct soc_camera_host ici;
struct list_head capture;
#define MAX_BUFFER_NUM 3
- struct vb2_buffer *queue_buf[MAX_BUFFER_NUM];
+ struct vb2_v4l2_buffer *queue_buf[MAX_BUFFER_NUM];
struct vb2_alloc_ctx *alloc_ctx;
enum v4l2_field field;
unsigned int pdata_flags;
@@ -492,7 +492,7 @@ struct rcar_vin_priv {
#define is_continuous_transfer(priv) (priv->vb_count > MAX_BUFFER_NUM)
struct rcar_vin_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -527,11 +527,12 @@ struct rcar_vin_cam {
* required
*/
static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *count,
unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct rcar_vin_priv *priv = ici->priv;
@@ -748,7 +749,7 @@ static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
/* Moves a buffer from the queue to the HW slots */
static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
{
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vbuf;
dma_addr_t phys_addr_top;
int slot;
@@ -760,10 +761,11 @@ static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
if (slot < 0)
return 0;
- vb = &list_entry(priv->capture.next, struct rcar_vin_buffer, list)->vb;
- list_del_init(to_buf_list(vb));
- priv->queue_buf[slot] = vb;
- phys_addr_top = vb2_dma_contig_plane_dma_addr(vb, 0);
+ vbuf = &list_entry(priv->capture.next,
+ struct rcar_vin_buffer, list)->vb;
+ list_del_init(to_buf_list(vbuf));
+ priv->queue_buf[slot] = vbuf;
+ phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
return 1;
@@ -771,6 +773,7 @@ static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct rcar_vin_priv *priv = ici->priv;
@@ -780,7 +783,7 @@ static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
if (vb2_plane_size(vb, 0) < size) {
dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
- vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
+ vb->index, vb2_plane_size(vb, 0), size);
goto error;
}
@@ -791,14 +794,14 @@ static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
spin_lock_irq(&priv->lock);
- list_add_tail(to_buf_list(vb), &priv->capture);
+ list_add_tail(to_buf_list(vbuf), &priv->capture);
rcar_vin_fill_hw_slot(priv);
/* If we weren't running, and have enough buffers, start capturing! */
if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
if (rcar_vin_setup(priv)) {
/* Submit error */
- list_del_init(to_buf_list(vb));
+ list_del_init(to_buf_list(vbuf));
spin_unlock_irq(&priv->lock);
goto error;
}
@@ -854,7 +857,7 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
for (i = 0; i < MAX_BUFFER_NUM; i++) {
if (priv->queue_buf[i]) {
- vb2_buffer_done(priv->queue_buf[i],
+ vb2_buffer_done(&priv->queue_buf[i]->vb2_buf,
VB2_BUF_STATE_ERROR);
priv->queue_buf[i] = NULL;
}
@@ -862,7 +865,7 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
list_for_each_safe(buf_head, tmp, &priv->capture) {
vb2_buffer_done(&list_entry(buf_head,
- struct rcar_vin_buffer, list)->vb,
+ struct rcar_vin_buffer, list)->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
list_del_init(buf_head);
}
@@ -907,10 +910,11 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
else
slot = 0;
- priv->queue_buf[slot]->v4l2_buf.field = priv->field;
- priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
- v4l2_get_timestamp(&priv->queue_buf[slot]->v4l2_buf.timestamp);
- vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
+ priv->queue_buf[slot]->field = priv->field;
+ priv->queue_buf[slot]->sequence = priv->sequence++;
+ v4l2_get_timestamp(&priv->queue_buf[slot]->timestamp);
+ vb2_buffer_done(&priv->queue_buf[slot]->vb2_buf,
+ VB2_BUF_STATE_DONE);
priv->queue_buf[slot] = NULL;
if (priv->state != STOPPING)
@@ -964,7 +968,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct rcar_vin_priv *priv = ici->priv;
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vbuf;
int i;
/* disable capture, disable interrupts */
@@ -978,10 +982,10 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
/* make sure active buffer is cancelled */
spin_lock_irq(&priv->lock);
for (i = 0; i < MAX_BUFFER_NUM; i++) {
- vb = priv->queue_buf[i];
- if (vb) {
- list_del_init(to_buf_list(vb));
- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ vbuf = priv->queue_buf[i];
+ if (vbuf) {
+ list_del_init(to_buf_list(vbuf));
+ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR);
}
}
spin_unlock_irq(&priv->lock);
@@ -1602,11 +1606,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd,
case V4L2_FIELD_INTERLACED:
/* Query for standard if not explicitly mentioned _TB/_BT */
ret = v4l2_subdev_call(sd, video, querystd, &std);
- if (ret < 0)
- std = V4L2_STD_625_50;
-
- field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
- V4L2_FIELD_INTERLACED_BT;
+ if (ret == -ENOIOCTLCMD) {
+ field = V4L2_FIELD_NONE;
+ } else if (ret < 0) {
+ return ret;
+ } else {
+ field = std & V4L2_STD_625_50 ?
+ V4L2_FIELD_INTERLACED_TB :
+ V4L2_FIELD_INTERLACED_BT;
+ }
break;
}
@@ -1846,8 +1854,6 @@ MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
#endif
static struct platform_device_id rcar_vin_id_table[] = {
- { "r8a7791-vin", RCAR_GEN2 },
- { "r8a7790-vin", RCAR_GEN2 },
{ "r8a7779-vin", RCAR_H1 },
{ "r8a7778-vin", RCAR_M1 },
{ "uPD35004-vin", RCAR_E1 },
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index efdeea4490e8..67a669d826b8 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -93,7 +93,7 @@
/* per video frame buffer */
struct sh_mobile_ceu_buffer {
- struct vb2_buffer vb; /* v4l buffer must be first */
+ struct vb2_v4l2_buffer vb; /* v4l buffer must be first */
struct list_head queue;
};
@@ -112,7 +112,7 @@ struct sh_mobile_ceu_dev {
spinlock_t lock; /* Protects video buffer lists */
struct list_head capture;
- struct vb2_buffer *active;
+ struct vb2_v4l2_buffer *active;
struct vb2_alloc_ctx *alloc_ctx;
struct sh_mobile_ceu_info *pdata;
@@ -152,9 +152,9 @@ struct sh_mobile_ceu_cam {
u32 code;
};
-static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
+static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_v4l2_buffer *vbuf)
{
- return container_of(vb, struct sh_mobile_ceu_buffer, vb);
+ return container_of(vbuf, struct sh_mobile_ceu_buffer, vb);
}
static void ceu_write(struct sh_mobile_ceu_dev *priv,
@@ -210,11 +210,13 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
* for the current frame format if required
*/
static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *count, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
- struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
+ const struct v4l2_format *fmt = parg;
+ struct soc_camera_device *icd = container_of(vq,
+ struct soc_camera_device, vb2_vidq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -334,7 +336,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
bottom2 = CDBCR;
}
- phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
+ phys_addr_top =
+ vb2_dma_contig_plane_dma_addr(&pcdev->active->vb2_buf, 0);
switch (icd->current_fmt->host_fmt->fourcc) {
case V4L2_PIX_FMT_NV12:
@@ -369,7 +372,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
{
- struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vbuf);
/* Added list head initialization on alloc */
WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
@@ -379,17 +383,19 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
{
- struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct soc_camera_device *icd = container_of(vb->vb2_queue,
+ struct soc_camera_device, vb2_vidq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+ struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vbuf);
unsigned long size;
size = icd->sizeimage;
if (vb2_plane_size(vb, 0) < size) {
dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
- vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
+ vb->index, vb2_plane_size(vb, 0), size);
goto error;
}
@@ -416,7 +422,7 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
* we are not interested in the return value of
* sh_mobile_ceu_capture here.
*/
- pcdev->active = vb;
+ pcdev->active = vbuf;
sh_mobile_ceu_capture(pcdev);
}
spin_unlock_irq(&pcdev->lock);
@@ -429,14 +435,16 @@ error:
static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
{
- struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct soc_camera_device *icd = container_of(vb->vb2_queue,
+ struct soc_camera_device, vb2_vidq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+ struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vbuf);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
spin_lock_irq(&pcdev->lock);
- if (pcdev->active == vb) {
+ if (pcdev->active == vbuf) {
/* disable capture (release DMA buffer), reset */
ceu_write(pcdev, CAPSR, 1 << 16);
pcdev->active = NULL;
@@ -458,7 +466,9 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
{
- struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct soc_camera_device *icd = container_of(vb->vb2_queue,
+ struct soc_camera_device, vb2_vidq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -467,7 +477,7 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
pcdev->buf_total);
/* This is for locking debugging only */
- INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
+ INIT_LIST_HEAD(&to_ceu_vb(vbuf)->queue);
return 0;
}
@@ -504,17 +514,17 @@ static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
{
struct sh_mobile_ceu_dev *pcdev = data;
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vbuf;
int ret;
spin_lock(&pcdev->lock);
- vb = pcdev->active;
- if (!vb)
+ vbuf = pcdev->active;
+ if (!vbuf)
/* Stale interrupt from a released buffer */
goto out;
- list_del_init(&to_ceu_vb(vb)->queue);
+ list_del_init(&to_ceu_vb(vbuf)->queue);
if (!list_empty(&pcdev->capture))
pcdev->active = &list_entry(pcdev->capture.next,
@@ -523,12 +533,13 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
pcdev->active = NULL;
ret = sh_mobile_ceu_capture(pcdev);
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
+ v4l2_get_timestamp(&vbuf->timestamp);
if (!ret) {
- vb->v4l2_buf.field = pcdev->field;
- vb->v4l2_buf.sequence = pcdev->sequence++;
+ vbuf->field = pcdev->field;
+ vbuf->sequence = pcdev->sequence++;
}
- vb2_buffer_done(vb, ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&vbuf->vb2_buf,
+ ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
out:
spin_unlock(&pcdev->lock);
@@ -633,7 +644,7 @@ static void sh_mobile_ceu_clock_stop(struct soc_camera_host *ici)
spin_lock_irq(&pcdev->lock);
if (pcdev->active) {
list_del_init(&to_ceu_vb(pcdev->active)->queue);
- vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&pcdev->active->vb2_buf, VB2_BUF_STATE_ERROR);
pcdev->active = NULL;
}
spin_unlock_irq(&pcdev->lock);
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 9087fed586fb..dc98122e78dc 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -38,7 +38,7 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-of.h>
#include <media/videobuf-core.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
/* Default to VGA resolution */
#define DEFAULT_WIDTH 640
@@ -1631,7 +1631,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
struct soc_camera_async_client *sasc;
struct soc_of_info *info;
struct i2c_client *client;
- char clk_name[V4L2_SUBDEV_NAME_SIZE];
+ char clk_name[V4L2_SUBDEV_NAME_SIZE + 32];
int ret;
/* allocate a new subdev and add match info to it */
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index df61355b46f1..a0d267e017f6 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -180,7 +180,7 @@ static struct bdisp_frame *ctx_get_frame(struct bdisp_ctx *ctx,
static void bdisp_job_finish(struct bdisp_ctx *ctx, int vb_state)
{
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
if (WARN(!ctx || !ctx->fh.m2m_ctx, "Null hardware context\n"))
return;
@@ -191,10 +191,10 @@ static void bdisp_job_finish(struct bdisp_ctx *ctx, int vb_state)
dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
if (src_vb && dst_vb) {
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
- dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
- dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->v4l2_buf.flags |= src_vb->v4l2_buf.flags &
+ dst_vb->timestamp = src_vb->timestamp;
+ dst_vb->timecode = src_vb->timecode;
+ dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst_vb->flags |= src_vb->flags &
V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
v4l2_m2m_buf_done(src_vb, vb_state);
@@ -281,23 +281,23 @@ static int bdisp_get_addr(struct bdisp_ctx *ctx, struct vb2_buffer *vb,
static int bdisp_get_bufs(struct bdisp_ctx *ctx)
{
struct bdisp_frame *src, *dst;
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
int ret;
src = &ctx->src;
dst = &ctx->dst;
src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- ret = bdisp_get_addr(ctx, src_vb, src, src->paddr);
+ ret = bdisp_get_addr(ctx, &src_vb->vb2_buf, src, src->paddr);
if (ret)
return ret;
dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
- ret = bdisp_get_addr(ctx, dst_vb, dst, dst->paddr);
+ ret = bdisp_get_addr(ctx, &dst_vb->vb2_buf, dst, dst->paddr);
if (ret)
return ret;
- dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
+ dst_vb->timestamp = src_vb->timestamp;
return 0;
}
@@ -438,10 +438,11 @@ static void bdisp_ctrls_delete(struct bdisp_ctx *ctx)
}
static int bdisp_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nb_buf, unsigned int *nb_planes,
unsigned int sizes[], void *allocators[])
{
+ const struct v4l2_format *fmt = parg;
struct bdisp_ctx *ctx = vb2_get_drv_priv(vq);
struct bdisp_frame *frame = ctx_get_frame(ctx, vq->type);
@@ -483,6 +484,7 @@ static int bdisp_buf_prepare(struct vb2_buffer *vb)
static void bdisp_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
/* return to V4L2 any 0-size buffer so it can be dequeued by user */
@@ -493,13 +495,13 @@ static void bdisp_buf_queue(struct vb2_buffer *vb)
}
if (ctx->fh.m2m_ctx)
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct bdisp_ctx *ctx = q->drv_priv;
- struct vb2_buffer *buf;
+ struct vb2_v4l2_buffer *buf;
int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev);
if (ret < 0) {
diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index 641ad8f34956..7420a50572d3 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -3,7 +3,6 @@ config DVB_C8SECTPFE
depends on PINCTRL && DVB_CORE && I2C
depends on ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST
select FW_LOADER
- select FW_LOADER_USER_HELPER_FALLBACK
select DEBUG_FS
select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 486aef50d99b..8490a65ae1c6 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -1084,10 +1084,10 @@ static void load_dmem_segment(struct c8sectpfei *fei, Elf32_Phdr *phdr,
seg_num, phdr->p_paddr, phdr->p_filesz,
dst, phdr->p_memsz);
- memcpy((void __iomem *)dst, (void *)fw->data + phdr->p_offset,
+ memcpy((void __force *)dst, (void *)fw->data + phdr->p_offset,
phdr->p_filesz);
- memset((void __iomem *)dst + phdr->p_filesz, 0,
+ memset((void __force *)dst + phdr->p_filesz, 0,
phdr->p_memsz - phdr->p_filesz);
}
@@ -1097,7 +1097,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
Elf32_Ehdr *ehdr;
Elf32_Phdr *phdr;
u8 __iomem *dst;
- int err, i;
+ int err = 0, i;
if (!fw || !context)
return -EINVAL;
@@ -1106,7 +1106,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
phdr = (Elf32_Phdr *)(fw->data + ehdr->e_phoff);
/* go through the available ELF segments */
- for (i = 0; i < ehdr->e_phnum && !err; i++, phdr++) {
+ for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
/* Only consider LOAD segments */
if (phdr->p_type != PT_LOAD)
@@ -1192,7 +1192,6 @@ err:
static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
{
- int ret;
int err;
dev_info(fei->dev, "Loading firmware: %s\n", FIRMWARE_MEMDMA);
@@ -1207,7 +1206,7 @@ static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
if (err) {
dev_err(fei->dev, "request_firmware_nowait err: %d.\n", err);
complete_all(&fei->fw_ack);
- return ret;
+ return err;
}
return 0;
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index c44760b705da..de24effd984f 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -40,7 +40,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "vpdma.h"
@@ -384,8 +384,8 @@ struct vpe_ctx {
unsigned int bufs_completed; /* bufs done in this batch */
struct vpe_q_data q_data[2]; /* src & dst queue data */
- struct vb2_buffer *src_vbs[VPE_MAX_SRC_BUFS];
- struct vb2_buffer *dst_vb;
+ struct vb2_v4l2_buffer *src_vbs[VPE_MAX_SRC_BUFS];
+ struct vb2_v4l2_buffer *dst_vb;
dma_addr_t mv_buf_dma[2]; /* dma addrs of motion vector in/out bufs */
void *mv_buf[2]; /* virtual addrs of motion vector bufs */
@@ -988,7 +988,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
{
struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST];
const struct vpe_port_data *p_data = &port_data[port];
- struct vb2_buffer *vb = ctx->dst_vb;
+ struct vb2_buffer *vb = &ctx->dst_vb->vb2_buf;
struct vpe_fmt *fmt = q_data->fmt;
const struct vpdma_data_format *vpdma_fmt;
int mv_buf_selector = !ctx->src_mv_buf_selector;
@@ -1025,11 +1025,12 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
{
struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC];
const struct vpe_port_data *p_data = &port_data[port];
- struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index];
+ struct vb2_buffer *vb = &ctx->src_vbs[p_data->vb_index]->vb2_buf;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vpe_fmt *fmt = q_data->fmt;
const struct vpdma_data_format *vpdma_fmt;
int mv_buf_selector = ctx->src_mv_buf_selector;
- int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM;
+ int field = vbuf->field == V4L2_FIELD_BOTTOM;
int frame_width, frame_height;
dma_addr_t dma_addr;
u32 flags = 0;
@@ -1222,8 +1223,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
struct vpe_dev *dev = (struct vpe_dev *)data;
struct vpe_ctx *ctx;
struct vpe_q_data *d_q_data;
- struct vb2_buffer *s_vb, *d_vb;
- struct v4l2_buffer *s_buf, *d_buf;
+ struct vb2_v4l2_buffer *s_vb, *d_vb;
unsigned long flags;
u32 irqst0, irqst1;
@@ -1286,20 +1286,18 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
s_vb = ctx->src_vbs[0];
d_vb = ctx->dst_vb;
- s_buf = &s_vb->v4l2_buf;
- d_buf = &d_vb->v4l2_buf;
- d_buf->flags = s_buf->flags;
+ d_vb->flags = s_vb->flags;
+ d_vb->timestamp = s_vb->timestamp;
- d_buf->timestamp = s_buf->timestamp;
- if (s_buf->flags & V4L2_BUF_FLAG_TIMECODE)
- d_buf->timecode = s_buf->timecode;
+ if (s_vb->flags & V4L2_BUF_FLAG_TIMECODE)
+ d_vb->timecode = s_vb->timecode;
- d_buf->sequence = ctx->sequence;
+ d_vb->sequence = ctx->sequence;
d_q_data = &ctx->q_data[Q_DATA_DST];
if (d_q_data->flags & Q_DATA_INTERLACED) {
- d_buf->field = ctx->field;
+ d_vb->field = ctx->field;
if (ctx->field == V4L2_FIELD_BOTTOM) {
ctx->sequence++;
ctx->field = V4L2_FIELD_TOP;
@@ -1308,7 +1306,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
ctx->field = V4L2_FIELD_BOTTOM;
}
} else {
- d_buf->field = V4L2_FIELD_NONE;
+ d_vb->field = V4L2_FIELD_NONE;
ctx->sequence++;
}
@@ -1798,7 +1796,7 @@ static const struct v4l2_ioctl_ops vpe_ioctl_ops = {
* Queue operations
*/
static int vpe_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -1825,6 +1823,7 @@ static int vpe_queue_setup(struct vb2_queue *vq,
static int vpe_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vpe_q_data *q_data;
int i, num_planes;
@@ -1836,10 +1835,10 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
if (!(q_data->flags & Q_DATA_INTERLACED)) {
- vb->v4l2_buf.field = V4L2_FIELD_NONE;
+ vbuf->field = V4L2_FIELD_NONE;
} else {
- if (vb->v4l2_buf.field != V4L2_FIELD_TOP &&
- vb->v4l2_buf.field != V4L2_FIELD_BOTTOM)
+ if (vbuf->field != V4L2_FIELD_TOP &&
+ vbuf->field != V4L2_FIELD_BOTTOM)
return -EINVAL;
}
}
@@ -1862,9 +1861,10 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
static void vpe_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index 295fde5fdb75..e18fb9f9ed2f 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -197,8 +197,8 @@ static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx,
static int device_process(struct vim2m_ctx *ctx,
- struct vb2_buffer *in_vb,
- struct vb2_buffer *out_vb)
+ struct vb2_v4l2_buffer *in_vb,
+ struct vb2_v4l2_buffer *out_vb)
{
struct vim2m_dev *dev = ctx->dev;
struct vim2m_q_data *q_data;
@@ -213,15 +213,16 @@ static int device_process(struct vim2m_ctx *ctx,
height = q_data->height;
bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
- p_in = vb2_plane_vaddr(in_vb, 0);
- p_out = vb2_plane_vaddr(out_vb, 0);
+ p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0);
+ p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0);
if (!p_in || !p_out) {
v4l2_err(&dev->v4l2_dev,
"Acquiring kernel pointers to buffers failed\n");
return -EFAULT;
}
- if (vb2_plane_size(in_vb, 0) > vb2_plane_size(out_vb, 0)) {
+ if (vb2_plane_size(&in_vb->vb2_buf, 0) >
+ vb2_plane_size(&out_vb->vb2_buf, 0)) {
v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
return -EINVAL;
}
@@ -231,16 +232,15 @@ static int device_process(struct vim2m_ctx *ctx,
bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
w = 0;
- out_vb->v4l2_buf.sequence = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
- in_vb->v4l2_buf.sequence = q_data->sequence++;
- memcpy(&out_vb->v4l2_buf.timestamp,
- &in_vb->v4l2_buf.timestamp,
- sizeof(struct timeval));
- if (in_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TIMECODE)
- memcpy(&out_vb->v4l2_buf.timecode, &in_vb->v4l2_buf.timecode,
- sizeof(struct v4l2_timecode));
- out_vb->v4l2_buf.field = in_vb->v4l2_buf.field;
- out_vb->v4l2_buf.flags = in_vb->v4l2_buf.flags &
+ out_vb->sequence =
+ get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
+ in_vb->sequence = q_data->sequence++;
+ out_vb->timestamp = in_vb->timestamp;
+
+ if (in_vb->flags & V4L2_BUF_FLAG_TIMECODE)
+ out_vb->timecode = in_vb->timecode;
+ out_vb->field = in_vb->field;
+ out_vb->flags = in_vb->flags &
(V4L2_BUF_FLAG_TIMECODE |
V4L2_BUF_FLAG_KEYFRAME |
V4L2_BUF_FLAG_PFRAME |
@@ -374,7 +374,7 @@ static void device_run(void *priv)
{
struct vim2m_ctx *ctx = priv;
struct vim2m_dev *dev = ctx->dev;
- struct vb2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
@@ -389,7 +389,7 @@ static void device_isr(unsigned long priv)
{
struct vim2m_dev *vim2m_dev = (struct vim2m_dev *)priv;
struct vim2m_ctx *curr_ctx;
- struct vb2_buffer *src_vb, *dst_vb;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
unsigned long flags;
curr_ctx = v4l2_m2m_get_curr_priv(vim2m_dev->m2m_dev);
@@ -710,10 +710,11 @@ static const struct v4l2_ioctl_ops vim2m_ioctl_ops = {
*/
static int vim2m_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct vim2m_ctx *ctx = vb2_get_drv_priv(vq);
struct vim2m_q_data *q_data;
unsigned int size, count = *nbuffers;
@@ -747,6 +748,7 @@ static int vim2m_queue_setup(struct vb2_queue *vq,
static int vim2m_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vim2m_q_data *q_data;
@@ -754,9 +756,9 @@ static int vim2m_buf_prepare(struct vb2_buffer *vb)
q_data = get_q_data(ctx, vb->vb2_queue->type);
if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
- if (vb->v4l2_buf.field == V4L2_FIELD_ANY)
- vb->v4l2_buf.field = V4L2_FIELD_NONE;
- if (vb->v4l2_buf.field != V4L2_FIELD_NONE) {
+ if (vbuf->field == V4L2_FIELD_ANY)
+ vbuf->field = V4L2_FIELD_NONE;
+ if (vbuf->field != V4L2_FIELD_NONE) {
dprintk(ctx->dev, "%s field isn't supported\n",
__func__);
return -EINVAL;
@@ -776,9 +778,10 @@ static int vim2m_buf_prepare(struct vb2_buffer *vb)
static void vim2m_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
static int vim2m_start_streaming(struct vb2_queue *q, unsigned count)
@@ -793,18 +796,18 @@ static int vim2m_start_streaming(struct vb2_queue *q, unsigned count)
static void vim2m_stop_streaming(struct vb2_queue *q)
{
struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
- struct vb2_buffer *vb;
+ struct vb2_v4l2_buffer *vbuf;
unsigned long flags;
for (;;) {
if (V4L2_TYPE_IS_OUTPUT(q->type))
- vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
else
- vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
- if (vb == NULL)
+ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ if (vbuf == NULL)
return;
spin_lock_irqsave(&ctx->dev->irqlock, flags);
- v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
}
}
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index c3090932f06d..0885e93ad436 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -20,3 +20,11 @@ config VIDEO_VIVID
Say Y here if you want to test video apps or debug V4L devices.
When in doubt, say N.
+
+config VIDEO_VIVID_MAX_DEVS
+ int "Maximum number of devices"
+ depends on VIDEO_VIVID
+ default "64"
+ ---help---
+ This allows you to specify the maximum number of devices supported
+ by the vivid driver.
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index a047b4716741..ec125becb7af 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -51,7 +51,7 @@
#define VIVID_MODULE_NAME "vivid"
/* The maximum number of vivid devices */
-#define VIVID_MAX_DEVS 64
+#define VIVID_MAX_DEVS CONFIG_VIDEO_VIVID_MAX_DEVS
MODULE_DESCRIPTION("Virtual Video Test Driver");
MODULE_AUTHOR("Hans Verkuil");
@@ -1341,8 +1341,11 @@ static int vivid_remove(struct platform_device *pdev)
struct vivid_dev *dev;
unsigned i;
- for (i = 0; vivid_devs[i]; i++) {
+
+ for (i = 0; i < n_devs; i++) {
dev = vivid_devs[i];
+ if (!dev)
+ continue;
if (dev->has_vid_cap) {
v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index c72349c83fab..55b304a705d5 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -21,7 +21,7 @@
#define _VIVID_CORE_H_
#include <linux/fb.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ctrls.h>
@@ -93,7 +93,7 @@ extern struct vivid_fmt vivid_formats[];
/* buffer for one video frame */
struct vivid_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -123,6 +123,7 @@ enum vivid_colorspace {
VIVID_CS_SRGB,
VIVID_CS_ADOBERGB,
VIVID_CS_2020,
+ VIVID_CS_DCI_P3,
VIVID_CS_240M,
VIVID_CS_SYS_M,
VIVID_CS_SYS_BG,
@@ -451,6 +452,7 @@ struct vivid_dev {
unsigned sdr_buffersize;
unsigned sdr_adc_freq;
unsigned sdr_fm_freq;
+ unsigned sdr_fm_deviation;
int sdr_fixp_src_phase;
int sdr_fixp_mod_phase;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index 339c8b7e53c8..f41ac0b01fec 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -99,6 +99,7 @@
#define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
+#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
/* General User Controls */
@@ -342,6 +343,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
V4L2_COLORSPACE_SRGB,
V4L2_COLORSPACE_ADOBERGB,
V4L2_COLORSPACE_BT2020,
+ V4L2_COLORSPACE_DCI_P3,
V4L2_COLORSPACE_SMPTE240M,
V4L2_COLORSPACE_470_SYSTEM_M,
V4L2_COLORSPACE_470_SYSTEM_BG,
@@ -548,7 +550,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
.id = VIVID_CID_OSD_TEXT_MODE,
.name = "OSD Text Mode",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 2,
+ .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
.qmenu = vivid_ctrl_osd_mode_strings,
};
@@ -640,7 +642,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
.id = VIVID_CID_TSTAMP_SRC,
.name = "Timestamp Source",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 1,
+ .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
.qmenu = vivid_ctrl_tstamp_src_strings,
};
@@ -701,6 +703,7 @@ static const char * const vivid_ctrl_colorspace_strings[] = {
"sRGB",
"AdobeRGB",
"BT.2020",
+ "DCI-P3",
"SMPTE 240M",
"470 System M",
"470 System BG",
@@ -712,7 +715,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
.id = VIVID_CID_COLORSPACE,
.name = "Colorspace",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 7,
+ .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
.def = 2,
.qmenu = vivid_ctrl_colorspace_strings,
};
@@ -724,6 +727,8 @@ static const char * const vivid_ctrl_xfer_func_strings[] = {
"AdobeRGB",
"SMPTE 240M",
"None",
+ "DCI-P3",
+ "SMPTE 2084",
NULL,
};
@@ -732,7 +737,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
.id = VIVID_CID_XFER_FUNC,
.name = "Transfer Function",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 5,
+ .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
.qmenu = vivid_ctrl_xfer_func_strings,
};
@@ -754,7 +759,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
.id = VIVID_CID_YCBCR_ENC,
.name = "Y'CbCr Encoding",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 8,
+ .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
.qmenu = vivid_ctrl_ycbcr_enc_strings,
};
@@ -770,7 +775,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
.id = VIVID_CID_QUANTIZATION,
.name = "Quantization",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 2,
+ .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
.qmenu = vivid_ctrl_quantization_strings,
};
@@ -1088,7 +1093,7 @@ static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
.id = VIVID_CID_STD_SIGNAL_MODE,
.name = "Standard Signal Mode",
.type = V4L2_CTRL_TYPE_MENU,
- .max = 5,
+ .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
.menu_skip_mask = 1 << 3,
.qmenu = vivid_ctrl_std_signal_mode_strings,
};
@@ -1257,6 +1262,36 @@ static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
};
+/* SDR Capture Controls */
+
+static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
+
+ switch (ctrl->id) {
+ case VIVID_CID_SDR_CAP_FM_DEVIATION:
+ dev->sdr_fm_deviation = ctrl->val;
+ break;
+ }
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
+ .s_ctrl = vivid_sdr_cap_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
+ .ops = &vivid_sdr_cap_ctrl_ops,
+ .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
+ .name = "FM Deviation",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 100,
+ .max = 200000,
+ .def = 75000,
+ .step = 1,
+};
+
+
static const struct v4l2_ctrl_config vivid_ctrl_class = {
.ops = &vivid_user_gen_ctrl_ops,
.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
@@ -1314,7 +1349,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
v4l2_ctrl_handler_init(hdl_radio_tx, 17);
v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
- v4l2_ctrl_handler_init(hdl_sdr_cap, 18);
+ v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
/* User Controls */
@@ -1545,6 +1580,10 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
&vivid_radio_tx_ctrl_ops,
V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
}
+ if (dev->has_sdr_cap) {
+ v4l2_ctrl_new_custom(hdl_sdr_cap,
+ &vivid_ctrl_sdr_cap_fm_deviation, NULL);
+ }
if (hdl_user_gen->error)
return hdl_user_gen->error;
if (hdl_user_vid->error)
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 1727f5453f0b..83cc6d3b4784 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -236,8 +236,8 @@ static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf,
void *vbuf;
if (p == 0 || tpg_g_buffers(tpg) > 1)
- return vb2_plane_vaddr(&buf->vb, p);
- vbuf = vb2_plane_vaddr(&buf->vb, 0);
+ return vb2_plane_vaddr(&buf->vb.vb2_buf, p);
+ vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
for (i = 0; i < p; i++)
vbuf += bpl[i] * h / tpg->vdownsampling[i];
return vbuf;
@@ -246,7 +246,7 @@ static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf,
static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
struct vivid_buffer *vid_cap_buf)
{
- bool blank = dev->must_blank[vid_cap_buf->vb.v4l2_buf.index];
+ bool blank = dev->must_blank[vid_cap_buf->vb.vb2_buf.index];
struct tpg_data *tpg = &dev->tpg;
struct vivid_buffer *vid_out_buf = NULL;
unsigned vdiv = dev->fmt_out->vdownsampling[p];
@@ -283,12 +283,12 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
if (vid_out_buf == NULL)
return -ENODATA;
- vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field;
+ vid_cap_buf->vb.field = vid_out_buf->vb.field;
voutbuf = plane_vaddr(tpg, vid_out_buf, p,
dev->bytesperline_out, dev->fmt_out_rect.height);
if (p < dev->fmt_out->buffers)
- voutbuf += vid_out_buf->vb.v4l2_planes[p].data_offset;
+ voutbuf += vid_out_buf->vb.vb2_buf.planes[p].data_offset;
voutbuf += tpg_hdiv(tpg, p, dev->loop_vid_out.left) +
(dev->loop_vid_out.top / vdiv) * stride_out;
vcapbuf += tpg_hdiv(tpg, p, dev->compose_cap.left) +
@@ -429,17 +429,19 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
bool is_loop = false;
if (dev->loop_video && dev->can_loop_video &&
- ((vivid_is_svid_cap(dev) && !VIVID_INVALID_SIGNAL(dev->std_signal_mode)) ||
- (vivid_is_hdmi_cap(dev) && !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode))))
+ ((vivid_is_svid_cap(dev) &&
+ !VIVID_INVALID_SIGNAL(dev->std_signal_mode)) ||
+ (vivid_is_hdmi_cap(dev) &&
+ !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode))))
is_loop = true;
- buf->vb.v4l2_buf.sequence = dev->vid_cap_seq_count;
+ buf->vb.sequence = dev->vid_cap_seq_count;
/*
* Take the timestamp now if the timestamp source is set to
* "Start of Exposure".
*/
if (dev->tstamp_src_is_soe)
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ v4l2_get_timestamp(&buf->vb.timestamp);
if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
/*
* 60 Hz standards start with the bottom field, 50 Hz standards
@@ -447,19 +449,19 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
* then the field is TOP for 50 Hz and BOTTOM for 60 Hz
* standards.
*/
- buf->vb.v4l2_buf.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ?
+ buf->vb.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ?
V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
/*
* The sequence counter counts frames, not fields. So divide
* by two.
*/
- buf->vb.v4l2_buf.sequence /= 2;
+ buf->vb.sequence /= 2;
} else {
- buf->vb.v4l2_buf.field = dev->field_cap;
+ buf->vb.field = dev->field_cap;
}
- tpg_s_field(tpg, buf->vb.v4l2_buf.field,
+ tpg_s_field(tpg, buf->vb.field,
dev->field_cap == V4L2_FIELD_ALTERNATE);
- tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.v4l2_buf.index]);
+ tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.vb2_buf.index]);
vivid_precalc_copy_rects(dev);
@@ -479,13 +481,16 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
}
tpg_calc_text_basep(tpg, basep, p, vbuf);
if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf))
- tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev), p, vbuf);
+ tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev),
+ p, vbuf);
}
- dev->must_blank[buf->vb.v4l2_buf.index] = false;
+ dev->must_blank[buf->vb.vb2_buf.index] = false;
/* Updates stream time, only update at the start of a new frame. */
- if (dev->field_cap != V4L2_FIELD_ALTERNATE || (buf->vb.v4l2_buf.sequence & 1) == 0)
- dev->ms_vid_cap = jiffies_to_msecs(jiffies - dev->jiffies_vid_cap);
+ if (dev->field_cap != V4L2_FIELD_ALTERNATE ||
+ (buf->vb.sequence & 1) == 0)
+ dev->ms_vid_cap =
+ jiffies_to_msecs(jiffies - dev->jiffies_vid_cap);
ms = dev->ms_vid_cap;
if (dev->osd_mode <= 1) {
@@ -494,9 +499,9 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
(ms / (60 * 1000)) % 60,
(ms / 1000) % 60,
ms % 1000,
- buf->vb.v4l2_buf.sequence,
+ buf->vb.sequence,
(dev->field_cap == V4L2_FIELD_ALTERNATE) ?
- (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ?
+ (buf->vb.field == V4L2_FIELD_TOP ?
" top" : " bottom") : "");
tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
}
@@ -553,8 +558,8 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
* the timestamp now.
*/
if (!dev->tstamp_src_is_soe)
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
}
/*
@@ -600,7 +605,7 @@ static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf)
struct tpg_data *tpg = &dev->tpg;
unsigned pixsize = tpg_g_twopixelsize(tpg, 0) / 2;
void *vbase = dev->fb_vbase_cap;
- void *vbuf = vb2_plane_vaddr(&buf->vb, 0);
+ void *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
unsigned img_width = dev->compose_cap.width;
unsigned img_height = dev->compose_cap.height;
unsigned stride = tpg->bytesperline[0];
@@ -616,7 +621,7 @@ static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf)
return;
if ((dev->overlay_cap_field == V4L2_FIELD_TOP ||
dev->overlay_cap_field == V4L2_FIELD_BOTTOM) &&
- dev->overlay_cap_field != buf->vb.v4l2_buf.field)
+ dev->overlay_cap_field != buf->vb.field)
return;
vbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride;
@@ -699,17 +704,17 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
/* Fill buffer */
vivid_fillbuff(dev, vid_cap_buf);
dprintk(dev, 1, "filled buffer %d\n",
- vid_cap_buf->vb.v4l2_buf.index);
+ vid_cap_buf->vb.vb2_buf.index);
/* Handle overlay */
if (dev->overlay_cap_owner && dev->fb_cap.base &&
- dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc)
+ dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc)
vivid_overlay(dev, vid_cap_buf);
- vb2_buffer_done(&vid_cap_buf->vb, dev->dqbuf_error ?
+ vb2_buffer_done(&vid_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dprintk(dev, 2, "vid_cap buffer %d done\n",
- vid_cap_buf->vb.v4l2_buf.index);
+ vid_cap_buf->vb.vb2_buf.index);
}
if (vbi_cap_buf) {
@@ -717,10 +722,10 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
vivid_sliced_vbi_cap_process(dev, vbi_cap_buf);
else
vivid_raw_vbi_cap_process(dev, vbi_cap_buf);
- vb2_buffer_done(&vbi_cap_buf->vb, dev->dqbuf_error ?
+ vb2_buffer_done(&vbi_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dprintk(dev, 2, "vbi_cap %d done\n",
- vbi_cap_buf->vb.v4l2_buf.index);
+ vbi_cap_buf->vb.vb2_buf.index);
}
dev->dqbuf_error = false;
@@ -884,9 +889,9 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
buf = list_entry(dev->vid_cap_active.next,
struct vivid_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(dev, 2, "vid_cap buffer %d done\n",
- buf->vb.v4l2_buf.index);
+ buf->vb.vb2_buf.index);
}
}
@@ -897,9 +902,9 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
buf = list_entry(dev->vbi_cap_active.next,
struct vivid_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(dev, 2, "vbi_cap buffer %d done\n",
- buf->vb.v4l2_buf.index);
+ buf->vb.vb2_buf.index);
}
}
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
index d9f36ccd7efb..c2c46dcdbe95 100644
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
+++ b/drivers/media/platform/vivid/vivid-kthread-out.c
@@ -87,33 +87,33 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
return;
if (vid_out_buf) {
- vid_out_buf->vb.v4l2_buf.sequence = dev->vid_out_seq_count;
+ vid_out_buf->vb.sequence = dev->vid_out_seq_count;
if (dev->field_out == V4L2_FIELD_ALTERNATE) {
/*
- * The sequence counter counts frames, not fields. So divide
- * by two.
+ * The sequence counter counts frames, not fields.
+ * So divide by two.
*/
- vid_out_buf->vb.v4l2_buf.sequence /= 2;
+ vid_out_buf->vb.sequence /= 2;
}
- v4l2_get_timestamp(&vid_out_buf->vb.v4l2_buf.timestamp);
- vid_out_buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
- vb2_buffer_done(&vid_out_buf->vb, dev->dqbuf_error ?
+ v4l2_get_timestamp(&vid_out_buf->vb.timestamp);
+ vid_out_buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+ vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dprintk(dev, 2, "vid_out buffer %d done\n",
- vid_out_buf->vb.v4l2_buf.index);
+ vid_out_buf->vb.vb2_buf.index);
}
if (vbi_out_buf) {
if (dev->stream_sliced_vbi_out)
vivid_sliced_vbi_out_process(dev, vbi_out_buf);
- vbi_out_buf->vb.v4l2_buf.sequence = dev->vbi_out_seq_count;
- v4l2_get_timestamp(&vbi_out_buf->vb.v4l2_buf.timestamp);
- vbi_out_buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
- vb2_buffer_done(&vbi_out_buf->vb, dev->dqbuf_error ?
+ vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
+ v4l2_get_timestamp(&vbi_out_buf->vb.timestamp);
+ vbi_out_buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+ vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dprintk(dev, 2, "vbi_out buffer %d done\n",
- vbi_out_buf->vb.v4l2_buf.index);
+ vbi_out_buf->vb.vb2_buf.index);
}
dev->dqbuf_error = false;
}
@@ -274,9 +274,9 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
buf = list_entry(dev->vid_out_active.next,
struct vivid_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(dev, 2, "vid_out buffer %d done\n",
- buf->vb.v4l2_buf.index);
+ buf->vb.vb2_buf.index);
}
}
@@ -287,9 +287,9 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
buf = list_entry(dev->vbi_out_active.next,
struct vivid_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(dev, 2, "vbi_out buffer %d done\n",
- buf->vb.v4l2_buf.index);
+ buf->vb.vb2_buf.index);
}
}
diff --git a/drivers/media/platform/vivid/vivid-osd.c b/drivers/media/platform/vivid/vivid-osd.c
index 084d346fb4c4..e15eef6a94e5 100644
--- a/drivers/media/platform/vivid/vivid-osd.c
+++ b/drivers/media/platform/vivid/vivid-osd.c
@@ -85,6 +85,7 @@ static int vivid_fb_ioctl(struct fb_info *info, unsigned cmd, unsigned long arg)
case FBIOGET_VBLANK: {
struct fb_vblank vblank;
+ memset(&vblank, 0, sizeof(vblank));
vblank.flags = FB_VBLANK_HAVE_COUNT | FB_VBLANK_HAVE_VCOUNT |
FB_VBLANK_HAVE_VSYNC;
vblank.count = 0;
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
index d2f2188a0efe..082c401764ce 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/math64.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-common.h>
@@ -40,7 +41,7 @@ struct vivid_format {
};
/* format descriptions for capture and preview */
-static struct vivid_format formats[] = {
+static const struct vivid_format formats[] = {
{
.pixelformat = V4L2_SDR_FMT_CU8,
.buffersize = SDR_CAP_SAMPLES_PER_BUF * 2,
@@ -114,11 +115,11 @@ static void vivid_thread_sdr_cap_tick(struct vivid_dev *dev)
spin_unlock(&dev->slock);
if (sdr_cap_buf) {
- sdr_cap_buf->vb.v4l2_buf.sequence = dev->sdr_cap_seq_count;
+ sdr_cap_buf->vb.sequence = dev->sdr_cap_seq_count;
vivid_sdr_cap_process(dev, sdr_cap_buf);
- v4l2_get_timestamp(&sdr_cap_buf->vb.v4l2_buf.timestamp);
- sdr_cap_buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
- vb2_buffer_done(&sdr_cap_buf->vb, dev->dqbuf_error ?
+ v4l2_get_timestamp(&sdr_cap_buf->vb.timestamp);
+ sdr_cap_buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+ vb2_buffer_done(&sdr_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dev->dqbuf_error = false;
}
@@ -161,7 +162,8 @@ static int vivid_thread_sdr_cap(void *data)
/* Calculate the number of jiffies since we started streaming */
jiffies_since_start = cur_jiffies - dev->jiffies_sdr_cap;
/* Get the number of buffers streamed since the start */
- buffers_since_start = (u64)jiffies_since_start * dev->sdr_adc_freq +
+ buffers_since_start =
+ (u64)jiffies_since_start * dev->sdr_adc_freq +
(HZ * SDR_CAP_SAMPLES_PER_BUF) / 2;
do_div(buffers_since_start, HZ * SDR_CAP_SAMPLES_PER_BUF);
@@ -176,7 +178,8 @@ static int vivid_thread_sdr_cap(void *data)
dev->sdr_cap_seq_offset = buffers_since_start;
buffers_since_start = 0;
}
- dev->sdr_cap_seq_count = buffers_since_start + dev->sdr_cap_seq_offset;
+ dev->sdr_cap_seq_count =
+ buffers_since_start + dev->sdr_cap_seq_offset;
vivid_thread_sdr_cap_tick(dev);
mutex_unlock(&dev->mutex);
@@ -210,7 +213,7 @@ static int vivid_thread_sdr_cap(void *data)
return 0;
}
-static int sdr_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int sdr_cap_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned *nbuffers, unsigned *nplanes,
unsigned sizes[], void *alloc_ctxs[])
{
@@ -247,8 +250,9 @@ static int sdr_cap_buf_prepare(struct vb2_buffer *vb)
static void sdr_cap_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb);
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
dprintk(dev, 1, "%s\n", __func__);
@@ -282,7 +286,8 @@ static int sdr_cap_start_streaming(struct vb2_queue *vq, unsigned count)
list_for_each_entry_safe(buf, tmp, &dev->sdr_cap_active, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
}
return err;
@@ -299,9 +304,10 @@ static void sdr_cap_stop_streaming(struct vb2_queue *vq)
while (!list_empty(&dev->sdr_cap_active)) {
struct vivid_buffer *buf;
- buf = list_entry(dev->sdr_cap_active.next, struct vivid_buffer, list);
+ buf = list_entry(dev->sdr_cap_active.next,
+ struct vivid_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
/* shutdown control thread */
@@ -321,7 +327,8 @@ const struct vb2_ops vivid_sdr_cap_qops = {
.wait_finish = vb2_ops_wait_finish,
};
-int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
+int vivid_sdr_enum_freq_bands(struct file *file, void *fh,
+ struct v4l2_frequency_band *band)
{
switch (band->tuner) {
case 0:
@@ -339,7 +346,8 @@ int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency
}
}
-int vivid_sdr_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+int vivid_sdr_g_frequency(struct file *file, void *fh,
+ struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -357,7 +365,8 @@ int vivid_sdr_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf
}
}
-int vivid_sdr_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
+int vivid_sdr_s_frequency(struct file *file, void *fh,
+ const struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
unsigned freq = vf->frequency;
@@ -403,14 +412,16 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
case 0:
strlcpy(vt->name, "ADC", sizeof(vt->name));
vt->type = V4L2_TUNER_ADC;
- vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ vt->capability =
+ V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
vt->rangelow = bands_adc[0].rangelow;
vt->rangehigh = bands_adc[2].rangehigh;
return 0;
case 1:
strlcpy(vt->name, "RF", sizeof(vt->name));
vt->type = V4L2_TUNER_RF;
- vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ vt->capability =
+ V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
vt->rangelow = bands_fm[0].rangelow;
vt->rangehigh = bands_fm[0].rangehigh;
return 0;
@@ -488,47 +499,42 @@ int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
#define FIXP_N (15)
#define FIXP_FRAC (1 << FIXP_N)
#define FIXP_2PI ((int)(2 * 3.141592653589 * FIXP_FRAC))
+#define M_100000PI (3.14159 * 100000)
void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
{
- u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0);
+ u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
unsigned long i;
- unsigned long plane_size = vb2_plane_size(&buf->vb, 0);
+ unsigned long plane_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
+ s64 s64tmp;
s32 src_phase_step;
s32 mod_phase_step;
s32 fixp_i;
s32 fixp_q;
- /*
- * TODO: Generated beep tone goes very crackly when sample rate is
- * increased to ~1Msps or more. That is because of huge rounding error
- * of phase angle caused by used cosine implementation.
- */
-
/* calculate phase step */
#define BEEP_FREQ 1000 /* 1kHz beep */
src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ,
- dev->sdr_adc_freq);
+ dev->sdr_adc_freq);
for (i = 0; i < plane_size; i += 2) {
mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase,
FIXP_2PI) >> (31 - FIXP_N);
dev->sdr_fixp_src_phase += src_phase_step;
- dev->sdr_fixp_mod_phase += mod_phase_step / 4;
+ s64tmp = (s64) mod_phase_step * dev->sdr_fm_deviation;
+ dev->sdr_fixp_mod_phase += div_s64(s64tmp, M_100000PI);
/*
- * Transfer phases to [0 / 2xPI] in order to avoid variable
+ * Transfer phase angle to [0, 2xPI] in order to avoid variable
* overflow and make it suitable for cosine implementation
* used, which does not support negative angles.
*/
- while (dev->sdr_fixp_mod_phase < FIXP_2PI)
- dev->sdr_fixp_mod_phase += FIXP_2PI;
- while (dev->sdr_fixp_mod_phase > FIXP_2PI)
- dev->sdr_fixp_mod_phase -= FIXP_2PI;
+ dev->sdr_fixp_src_phase %= FIXP_2PI;
+ dev->sdr_fixp_mod_phase %= FIXP_2PI;
- while (dev->sdr_fixp_src_phase > FIXP_2PI)
- dev->sdr_fixp_src_phase -= FIXP_2PI;
+ if (dev->sdr_fixp_mod_phase < 0)
+ dev->sdr_fixp_mod_phase += FIXP_2PI;
fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
@@ -540,7 +546,7 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
switch (dev->sdr_pixelformat) {
case V4L2_SDR_FMT_CU8:
- /* convert 'fixp float' to u8 */
+ /* convert 'fixp float' to u8 [0, +255] */
/* u8 = X * 127.5 + 127.5; X is float [-1.0, +1.0] */
fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275;
fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275;
@@ -548,9 +554,10 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
break;
case V4L2_SDR_FMT_CS8:
- /* convert 'fixp float' to s8 */
- fixp_i = fixp_i * 1275;
- fixp_q = fixp_q * 1275;
+ /* convert 'fixp float' to s8 [-128, +127] */
+ /* s8 = X * 127.5 - 0.5; X is float [-1.0, +1.0] */
+ fixp_i = fixp_i * 1275 - FIXP_FRAC * 5;
+ fixp_q = fixp_q * 1275 - FIXP_FRAC * 5;
*vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
break;
diff --git a/drivers/media/platform/vivid/vivid-tpg-colors.c b/drivers/media/platform/vivid/vivid-tpg-colors.c
index 8f231a6e68c9..2299f0ce47c8 100644
--- a/drivers/media/platform/vivid/vivid-tpg-colors.c
+++ b/drivers/media/platform/vivid/vivid-tpg-colors.c
@@ -598,7 +598,7 @@ const unsigned short tpg_linear_to_rec709[255 * 16 + 1] = {
};
/* Generated table */
-const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_NONE + 1][TPG_COLOR_CSC_BLACK + 1] = {
+const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 },
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 },
@@ -639,6 +639,22 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][5] = { 2256, 90, 133 },
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][6] = { 110, 96, 2113 },
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][1] = { 3186, 3194, 1121 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][2] = { 0, 3197, 3173 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][3] = { 523, 3216, 1112 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][4] = { 3237, 792, 3169 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][5] = { 3248, 944, 1094 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][6] = { 1017, 967, 3168 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][1] = { 3802, 3805, 2602 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][2] = { 0, 3806, 3797 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][3] = { 1780, 3812, 2592 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][4] = { 3820, 2215, 3796 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][5] = { 3824, 2409, 2574 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][6] = { 2491, 2435, 3795 },
+ [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 },
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 },
@@ -679,6 +695,22 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][5] = { 2256, 90, 133 },
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][6] = { 110, 96, 2113 },
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][1] = { 3186, 3194, 1121 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][2] = { 0, 3197, 3173 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][3] = { 523, 3216, 1112 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][4] = { 3237, 792, 3169 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][5] = { 3248, 944, 1094 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][6] = { 1017, 967, 3168 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][1] = { 3802, 3805, 2602 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][2] = { 0, 3806, 3797 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][3] = { 1780, 3812, 2592 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][4] = { 3820, 2215, 3796 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][5] = { 3824, 2409, 2574 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][6] = { 2491, 2435, 3795 },
+ [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 547 },
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][2] = { 547, 2939, 2939 },
@@ -719,46 +751,78 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][5] = { 2125, 130, 130 },
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2125 },
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][0] = { 2892, 2988, 2807 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][1] = { 2846, 3070, 843 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][2] = { 1656, 2962, 2783 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][3] = { 1572, 3045, 763 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][4] = { 2476, 229, 2742 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][5] = { 2420, 672, 614 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][6] = { 725, 63, 2718 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][7] = { 534, 561, 509 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][0] = { 3013, 3099, 2935 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][1] = { 2970, 3174, 1091 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][2] = { 1871, 3076, 2913 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][3] = { 1791, 3152, 1013 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][4] = { 2632, 468, 2876 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2581, 924, 866 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 976, 180, 2854 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 786, 813, 762 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 2990, 3077, 2912 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2947, 3153, 1119 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1859, 3053, 2889 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1782, 3130, 1047 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2608, 556, 2852 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2557, 964, 912 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1013, 309, 2830 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 839, 864, 817 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2879, 2975, 2793 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2832, 3059, 806 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1629, 2949, 2768 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][3] = { 1543, 3033, 725 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][4] = { 2457, 203, 2727 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][5] = { 2401, 633, 574 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][6] = { 687, 56, 2702 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][7] = { 493, 521, 469 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][0] = { 2060, 2194, 1943 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][1] = { 1995, 2314, 237 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][2] = { 725, 2157, 1911 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][3] = { 660, 2278, 205 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][4] = { 1525, 50, 1857 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][5] = { 1461, 171, 151 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][6] = { 190, 14, 1825 },
- [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][7] = { 126, 134, 118 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1084 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][2] = { 1084, 3175, 3175 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][3] = { 1084, 3175, 1084 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][4] = { 3175, 1084, 3175 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][5] = { 3175, 1084, 1084 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3175 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2563 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][2] = { 2563, 3798, 3798 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][3] = { 2563, 3798, 2563 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][4] = { 3798, 2563, 3798 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][5] = { 3798, 2563, 2563 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3798 },
+ [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][1] = { 2892, 3034, 910 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][2] = { 1715, 2916, 2914 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][3] = { 1631, 3012, 828 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][4] = { 2497, 119, 2867 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][5] = { 2440, 649, 657 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][6] = { 740, 0, 2841 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3055, 3056 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][1] = { 3013, 3142, 1157 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][2] = { 1926, 3034, 3032 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][3] = { 1847, 3121, 1076 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][4] = { 2651, 304, 2990 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2599, 901, 909 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 991, 0, 2966 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2989, 3120, 1180 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1913, 3011, 3009 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1836, 3099, 1105 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2627, 413, 2966 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2576, 943, 951 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1026, 0, 2942 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2879, 3022, 874 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1688, 2903, 2901 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][3] = { 1603, 2999, 791 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][4] = { 2479, 106, 2853 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][5] = { 2422, 610, 618 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][6] = { 702, 0, 2827 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][1] = { 2059, 2262, 266 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][2] = { 771, 2092, 2089 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][3] = { 705, 2229, 231 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][4] = { 1550, 26, 2024 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][5] = { 1484, 163, 165 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][6] = { 196, 0, 1988 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][1] = { 3136, 3251, 1429 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][2] = { 2150, 3156, 3154 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][3] = { 2077, 3233, 1352 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][4] = { 2812, 589, 3116 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][5] = { 2765, 1182, 1190 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][6] = { 1270, 0, 3094 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][1] = { 3784, 3825, 2879 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][2] = { 3351, 3791, 3790 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][3] = { 3311, 3819, 2815 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][4] = { 3659, 1900, 3777 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][5] = { 3640, 2662, 2669 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][6] = { 2743, 0, 3769 },
+ [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 464 },
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][2] = { 786, 2939, 2939 },
@@ -799,6 +863,22 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][5] = { 2041, 130, 130 },
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2149 },
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1003 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][2] = { 1313, 3175, 3175 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][3] = { 1313, 3175, 1003 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][4] = { 3126, 1084, 3188 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][5] = { 3126, 1084, 1084 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3188 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2476 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][2] = { 2782, 3798, 3798 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][3] = { 2782, 3798, 2476 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][4] = { 3780, 2563, 3803 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][5] = { 3780, 2563, 2563 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3803 },
+ [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 547 },
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][2] = { 547, 2939, 2939 },
@@ -839,6 +919,22 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][5] = { 2125, 130, 130 },
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2125 },
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1084 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][2] = { 1084, 3175, 3175 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][3] = { 1084, 3175, 1084 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][4] = { 3175, 1084, 3175 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][5] = { 3175, 1084, 1084 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3175 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2563 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 2563, 3798, 3798 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 2563, 3798, 2563 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 3798, 2563, 3798 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 3798, 2563, 2563 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3798 },
+ [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
@@ -879,6 +975,22 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2778 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 3306, 3798, 3798 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 3306, 3798, 2778 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 3661, 2563, 3781 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 3661, 2563, 2563 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3781 },
+ [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 },
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 },
@@ -919,6 +1031,78 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][5] = { 1382, 268, 162 },
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][6] = { 216, 152, 1917 },
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][1] = { 3124, 3161, 1566 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][2] = { 2255, 3094, 3156 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][3] = { 2166, 3080, 1506 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][4] = { 2754, 1477, 3071 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][5] = { 2690, 1431, 1182 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][6] = { 1318, 1153, 3051 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][1] = { 3780, 3793, 2984 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][2] = { 3406, 3768, 3791 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][3] = { 3359, 3763, 2939 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][4] = { 3636, 2916, 3760 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][5] = { 3609, 2880, 2661 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][6] = { 2786, 2633, 3753 },
+ [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][1] = { 2936, 2934, 992 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][2] = { 1159, 2890, 2916 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][3] = { 1150, 2885, 921 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][4] = { 2751, 766, 2837 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][5] = { 2747, 747, 650 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][6] = { 563, 570, 2812 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3055 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][1] = { 3052, 3051, 1237 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][2] = { 1397, 3011, 3034 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][3] = { 1389, 3006, 1168 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][4] = { 2884, 1016, 2962 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][5] = { 2880, 998, 902 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][6] = { 816, 823, 2940 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][1] = { 3029, 3028, 1255 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][2] = { 1406, 2988, 3011 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][3] = { 1398, 2983, 1190 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][4] = { 2860, 1050, 2939 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][5] = { 2857, 1033, 945 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][6] = { 866, 873, 2916 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][1] = { 2923, 2921, 957 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][2] = { 1125, 2877, 2902 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][3] = { 1116, 2871, 885 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][4] = { 2736, 729, 2823 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][5] = { 2732, 710, 611 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][6] = { 523, 531, 2798 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][1] = { 2120, 2118, 305 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][2] = { 392, 2056, 2092 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][3] = { 387, 2049, 271 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][4] = { 1868, 206, 1983 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][5] = { 1863, 199, 163 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][6] = { 135, 137, 1950 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][1] = { 3172, 3170, 1505 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][2] = { 1657, 3135, 3155 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][3] = { 1649, 3130, 1439 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][4] = { 3021, 1294, 3091 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][5] = { 3018, 1276, 1184 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][6] = { 1100, 1107, 3071 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][1] = { 3797, 3796, 2938 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][2] = { 3049, 3783, 3791 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][3] = { 3044, 3782, 2887 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][4] = { 3741, 2765, 3768 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][5] = { 3740, 2749, 2663 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][6] = { 2580, 2587, 3760 },
+ [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 },
};
#else
@@ -930,9 +1114,13 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_N
#include <stdlib.h>
static const double rec709_to_ntsc1953[3][3] = {
- { 0.6689794, 0.2678309, 0.0323187 },
- { 0.0184901, 1.0742442, -0.0602820 },
- { 0.0162259, 0.0431716, 0.8549253 }
+ /*
+ * This transform uses the Bradford method to compensate for
+ * the different whitepoints.
+ */
+ { 0.6785011, 0.2883441, 0.0331548 },
+ { 0.0165284, 1.0518725, -0.0684009 },
+ { 0.0179230, 0.0506096, 0.9314674 }
};
static const double rec709_to_ebu[3][3] = {
@@ -965,6 +1153,16 @@ static const double rec709_to_bt2020[3][3] = {
{ 0.0163976, 0.0880301, 0.8955723 },
};
+static const double rec709_to_dcip3[3][3] = {
+ /*
+ * This transform uses the Bradford method to compensate for
+ * the different whitepoints.
+ */
+ { 0.8686648, 0.1288456, 0.0024896 },
+ { 0.0345479, 0.9618084, 0.0036437 },
+ { 0.0167785, 0.0710559, 0.9121655 }
+};
+
static void mult_matrix(double *r, double *g, double *b, const double m[3][3])
{
double ir, ig, ib;
@@ -1015,6 +1213,23 @@ static double transfer_rgb_to_adobergb(double v)
return pow(v, 1.0 / 2.19921875);
}
+static double transfer_rgb_to_dcip3(double v)
+{
+ return pow(v, 1.0 / 2.6);
+}
+
+static double transfer_rgb_to_smpte2084(double v)
+{
+ const double m1 = (2610.0 / 4096.0) / 4.0;
+ const double m2 = 128.0 * 2523.0 / 4096.0;
+ const double c1 = 3424.0 / 4096.0;
+ const double c2 = 32.0 * 2413.0 / 4096.0;
+ const double c3 = 32.0 * 2392.0 / 4096.0;
+
+ v = pow(v, m1);
+ return pow((c1 + c2 * v) / (1 + c3 * v), m2);
+}
+
static double transfer_srgb_to_rec709(double v)
{
return transfer_rgb_to_rec709(transfer_srgb_to_rgb(v));
@@ -1049,6 +1264,9 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
case V4L2_COLORSPACE_BT2020:
mult_matrix(r, g, b, rec709_to_bt2020);
break;
+ case V4L2_COLORSPACE_DCI_P3:
+ mult_matrix(r, g, b, rec709_to_dcip3);
+ break;
case V4L2_COLORSPACE_SRGB:
case V4L2_COLORSPACE_REC709:
break;
@@ -1078,6 +1296,16 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
*g = transfer_rgb_to_adobergb(*g);
*b = transfer_rgb_to_adobergb(*b);
break;
+ case V4L2_XFER_FUNC_DCI_P3:
+ *r = transfer_rgb_to_dcip3(*r);
+ *g = transfer_rgb_to_dcip3(*g);
+ *b = transfer_rgb_to_dcip3(*b);
+ break;
+ case V4L2_XFER_FUNC_SMPTE2084:
+ *r = transfer_rgb_to_smpte2084(*r);
+ *g = transfer_rgb_to_smpte2084(*g);
+ *b = transfer_rgb_to_smpte2084(*b);
+ break;
case V4L2_XFER_FUNC_SMPTE240M:
*r = transfer_rgb_to_smpte240m(*r);
*g = transfer_rgb_to_smpte240m(*g);
@@ -1102,6 +1330,8 @@ int main(int argc, char **argv)
V4L2_COLORSPACE_SRGB,
V4L2_COLORSPACE_ADOBERGB,
V4L2_COLORSPACE_BT2020,
+ 0,
+ V4L2_COLORSPACE_DCI_P3,
};
static const char * const colorspace_names[] = {
"",
@@ -1115,6 +1345,8 @@ int main(int argc, char **argv)
"V4L2_COLORSPACE_SRGB",
"V4L2_COLORSPACE_ADOBERGB",
"V4L2_COLORSPACE_BT2020",
+ "",
+ "V4L2_COLORSPACE_DCI_P3",
};
static const char * const xfer_func_names[] = {
"",
@@ -1123,6 +1355,8 @@ int main(int argc, char **argv)
"V4L2_XFER_FUNC_ADOBERGB",
"V4L2_XFER_FUNC_SMPTE240M",
"V4L2_XFER_FUNC_NONE",
+ "V4L2_XFER_FUNC_DCI_P3",
+ "V4L2_XFER_FUNC_SMPTE2084",
};
int i;
int x;
@@ -1153,9 +1387,9 @@ int main(int argc, char **argv)
printf("\n};\n\n");
printf("/* Generated table */\n");
- printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_NONE + 1][TPG_COLOR_CSC_BLACK + 1] = {\n");
- for (c = 0; c <= V4L2_COLORSPACE_BT2020; c++) {
- for (x = 1; x <= V4L2_XFER_FUNC_NONE; x++) {
+ printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {\n");
+ for (c = 0; c <= V4L2_COLORSPACE_DCI_P3; c++) {
+ for (x = 1; x <= V4L2_XFER_FUNC_SMPTE2084; x++) {
for (i = 0; i <= TPG_COLOR_CSC_BLACK; i++) {
double r, g, b;
diff --git a/drivers/media/platform/vivid/vivid-tpg-colors.h b/drivers/media/platform/vivid/vivid-tpg-colors.h
index 86b8bf3fe745..4e5a76a1e25b 100644
--- a/drivers/media/platform/vivid/vivid-tpg-colors.h
+++ b/drivers/media/platform/vivid/vivid-tpg-colors.h
@@ -61,8 +61,8 @@ enum tpg_color {
extern const struct color tpg_colors[TPG_COLOR_MAX];
extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
-extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1]
- [V4L2_XFER_FUNC_NONE + 1]
+extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
+ [V4L2_XFER_FUNC_SMPTE2084 + 1]
[TPG_COLOR_CSC_BLACK + 1];
#endif
diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c
index 1458c7955547..14256141f905 100644
--- a/drivers/media/platform/vivid/vivid-tpg.c
+++ b/drivers/media/platform/vivid/vivid-tpg.c
@@ -193,6 +193,14 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
+ case V4L2_PIX_FMT_SBGGR10:
+ case V4L2_PIX_FMT_SGBRG10:
+ case V4L2_PIX_FMT_SGRBG10:
+ case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SBGGR12:
+ case V4L2_PIX_FMT_SGBRG12:
+ case V4L2_PIX_FMT_SGRBG12:
+ case V4L2_PIX_FMT_SRGGB12:
tpg->interleaved = true;
tpg->vdownsampling[1] = 1;
tpg->hdownsampling[1] = 1;
@@ -349,6 +357,17 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
tpg->twopixelsize[0] = 2;
tpg->twopixelsize[1] = 2;
break;
+ case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SGRBG10:
+ case V4L2_PIX_FMT_SGBRG10:
+ case V4L2_PIX_FMT_SBGGR10:
+ case V4L2_PIX_FMT_SRGGB12:
+ case V4L2_PIX_FMT_SGRBG12:
+ case V4L2_PIX_FMT_SGBRG12:
+ case V4L2_PIX_FMT_SBGGR12:
+ tpg->twopixelsize[0] = 4;
+ tpg->twopixelsize[1] = 4;
+ break;
case V4L2_PIX_FMT_YUV422P:
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
@@ -1112,6 +1131,70 @@ static void gen_twopix(struct tpg_data *tpg,
buf[0][offset] = odd ? g_u : r_y;
buf[1][offset] = odd ? b_v : g_u;
break;
+ case V4L2_PIX_FMT_SBGGR10:
+ buf[0][offset] = odd ? g_u << 2 : b_v << 2;
+ buf[0][offset + 1] = odd ? g_u >> 6 : b_v >> 6;
+ buf[1][offset] = odd ? r_y << 2 : g_u << 2;
+ buf[1][offset + 1] = odd ? r_y >> 6 : g_u >> 6;
+ buf[0][offset] |= (buf[0][offset] >> 2) & 3;
+ buf[1][offset] |= (buf[1][offset] >> 2) & 3;
+ break;
+ case V4L2_PIX_FMT_SGBRG10:
+ buf[0][offset] = odd ? b_v << 2 : g_u << 2;
+ buf[0][offset + 1] = odd ? b_v >> 6 : g_u >> 6;
+ buf[1][offset] = odd ? g_u << 2 : r_y << 2;
+ buf[1][offset + 1] = odd ? g_u >> 6 : r_y >> 6;
+ buf[0][offset] |= (buf[0][offset] >> 2) & 3;
+ buf[1][offset] |= (buf[1][offset] >> 2) & 3;
+ break;
+ case V4L2_PIX_FMT_SGRBG10:
+ buf[0][offset] = odd ? r_y << 2 : g_u << 2;
+ buf[0][offset + 1] = odd ? r_y >> 6 : g_u >> 6;
+ buf[1][offset] = odd ? g_u << 2 : b_v << 2;
+ buf[1][offset + 1] = odd ? g_u >> 6 : b_v >> 6;
+ buf[0][offset] |= (buf[0][offset] >> 2) & 3;
+ buf[1][offset] |= (buf[1][offset] >> 2) & 3;
+ break;
+ case V4L2_PIX_FMT_SRGGB10:
+ buf[0][offset] = odd ? g_u << 2 : r_y << 2;
+ buf[0][offset + 1] = odd ? g_u >> 6 : r_y >> 6;
+ buf[1][offset] = odd ? b_v << 2 : g_u << 2;
+ buf[1][offset + 1] = odd ? b_v >> 6 : g_u >> 6;
+ buf[0][offset] |= (buf[0][offset] >> 2) & 3;
+ buf[1][offset] |= (buf[1][offset] >> 2) & 3;
+ break;
+ case V4L2_PIX_FMT_SBGGR12:
+ buf[0][offset] = odd ? g_u << 4 : b_v << 4;
+ buf[0][offset + 1] = odd ? g_u >> 4 : b_v >> 4;
+ buf[1][offset] = odd ? r_y << 4 : g_u << 4;
+ buf[1][offset + 1] = odd ? r_y >> 4 : g_u >> 4;
+ buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
+ buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
+ break;
+ case V4L2_PIX_FMT_SGBRG12:
+ buf[0][offset] = odd ? b_v << 4 : g_u << 4;
+ buf[0][offset + 1] = odd ? b_v >> 4 : g_u >> 4;
+ buf[1][offset] = odd ? g_u << 4 : r_y << 4;
+ buf[1][offset + 1] = odd ? g_u >> 4 : r_y >> 4;
+ buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
+ buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
+ break;
+ case V4L2_PIX_FMT_SGRBG12:
+ buf[0][offset] = odd ? r_y << 4 : g_u << 4;
+ buf[0][offset + 1] = odd ? r_y >> 4 : g_u >> 4;
+ buf[1][offset] = odd ? g_u << 4 : b_v << 4;
+ buf[1][offset + 1] = odd ? g_u >> 4 : b_v >> 4;
+ buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
+ buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
+ break;
+ case V4L2_PIX_FMT_SRGGB12:
+ buf[0][offset] = odd ? g_u << 4 : r_y << 4;
+ buf[0][offset + 1] = odd ? g_u >> 4 : r_y >> 4;
+ buf[1][offset] = odd ? b_v << 4 : g_u << 4;
+ buf[1][offset + 1] = odd ? b_v >> 4 : g_u >> 4;
+ buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
+ buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
+ break;
}
}
@@ -1122,6 +1205,14 @@ unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
+ case V4L2_PIX_FMT_SBGGR10:
+ case V4L2_PIX_FMT_SGBRG10:
+ case V4L2_PIX_FMT_SGRBG10:
+ case V4L2_PIX_FMT_SRGGB10:
+ case V4L2_PIX_FMT_SBGGR12:
+ case V4L2_PIX_FMT_SGBRG12:
+ case V4L2_PIX_FMT_SGRBG12:
+ case V4L2_PIX_FMT_SRGGB12:
return buf_line & 1;
default:
return 0;
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c b/drivers/media/platform/vivid/vivid-vbi-cap.c
index ef81b01b53d2..e903d023e9df 100644
--- a/drivers/media/platform/vivid/vivid-vbi-cap.c
+++ b/drivers/media/platform/vivid/vivid-vbi-cap.c
@@ -94,36 +94,38 @@ static void vivid_g_fmt_vbi_cap(struct vivid_dev *dev, struct v4l2_vbi_format *v
void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
{
struct v4l2_vbi_format vbi;
- u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0);
+ u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
vivid_g_fmt_vbi_cap(dev, &vbi);
- buf->vb.v4l2_buf.sequence = dev->vbi_cap_seq_count;
+ buf->vb.sequence = dev->vbi_cap_seq_count;
if (dev->field_cap == V4L2_FIELD_ALTERNATE)
- buf->vb.v4l2_buf.sequence /= 2;
+ buf->vb.sequence /= 2;
- vivid_sliced_vbi_cap_fill(dev, buf->vb.v4l2_buf.sequence);
+ vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
- memset(vbuf, 0x10, vb2_plane_size(&buf->vb, 0));
+ memset(vbuf, 0x10, vb2_plane_size(&buf->vb.vb2_buf, 0));
if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode))
vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
}
-void vivid_sliced_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
+void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
+ struct vivid_buffer *buf)
{
- struct v4l2_sliced_vbi_data *vbuf = vb2_plane_vaddr(&buf->vb, 0);
+ struct v4l2_sliced_vbi_data *vbuf =
+ vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
- buf->vb.v4l2_buf.sequence = dev->vbi_cap_seq_count;
+ buf->vb.sequence = dev->vbi_cap_seq_count;
if (dev->field_cap == V4L2_FIELD_ALTERNATE)
- buf->vb.v4l2_buf.sequence /= 2;
+ buf->vb.sequence /= 2;
- vivid_sliced_vbi_cap_fill(dev, buf->vb.v4l2_buf.sequence);
+ vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
- memset(vbuf, 0, vb2_plane_size(&buf->vb, 0));
+ memset(vbuf, 0, vb2_plane_size(&buf->vb.vb2_buf, 0));
if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode)) {
unsigned i;
@@ -131,11 +133,11 @@ void vivid_sliced_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *bu
vbuf[i] = dev->vbi_gen.data[i];
}
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
}
-static int vbi_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int vbi_cap_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned *nbuffers, unsigned *nplanes,
unsigned sizes[], void *alloc_ctxs[])
{
@@ -187,8 +189,9 @@ static int vbi_cap_buf_prepare(struct vb2_buffer *vb)
static void vbi_cap_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb);
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
dprintk(dev, 1, "%s\n", __func__);
@@ -215,7 +218,8 @@ static int vbi_cap_start_streaming(struct vb2_queue *vq, unsigned count)
list_for_each_entry_safe(buf, tmp, &dev->vbi_cap_active, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
}
return err;
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c b/drivers/media/platform/vivid/vivid-vbi-out.c
index 4e4c70e1e04a..75c5709f938e 100644
--- a/drivers/media/platform/vivid/vivid-vbi-out.c
+++ b/drivers/media/platform/vivid/vivid-vbi-out.c
@@ -27,7 +27,7 @@
#include "vivid-vbi-out.h"
#include "vivid-vbi-cap.h"
-static int vbi_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int vbi_out_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned *nbuffers, unsigned *nplanes,
unsigned sizes[], void *alloc_ctxs[])
{
@@ -79,8 +79,9 @@ static int vbi_out_buf_prepare(struct vb2_buffer *vb)
static void vbi_out_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb);
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
dprintk(dev, 1, "%s\n", __func__);
@@ -107,7 +108,8 @@ static int vbi_out_start_streaming(struct vb2_queue *vq, unsigned count)
list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
}
return err;
@@ -201,7 +203,8 @@ int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_forma
return 0;
}
-int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
@@ -217,10 +220,13 @@ int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format
return 0;
}
-void vivid_sliced_vbi_out_process(struct vivid_dev *dev, struct vivid_buffer *buf)
+void vivid_sliced_vbi_out_process(struct vivid_dev *dev,
+ struct vivid_buffer *buf)
{
- struct v4l2_sliced_vbi_data *vbi = vb2_plane_vaddr(&buf->vb, 0);
- unsigned elems = vb2_get_plane_payload(&buf->vb, 0) / sizeof(*vbi);
+ struct v4l2_sliced_vbi_data *vbi =
+ vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+ unsigned elems =
+ vb2_get_plane_payload(&buf->vb.vb2_buf, 0) / sizeof(*vbi);
dev->vbi_out_have_cc[0] = false;
dev->vbi_out_have_cc[1] = false;
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index ed0b8788a66f..ef5412311b2f 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -95,10 +95,11 @@ static const struct v4l2_discrete_probe webcam_probe = {
VIVID_WEBCAM_SIZES
};
-static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int vid_cap_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned *nbuffers, unsigned *nplanes,
unsigned sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct vivid_dev *dev = vb2_get_drv_priv(vq);
unsigned buffers = tpg_g_buffers(&dev->tpg);
unsigned h = dev->fmt_cap_rect.height;
@@ -198,7 +199,7 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb)
}
vb2_set_plane_payload(vb, p, size);
- vb->v4l2_planes[p].data_offset = dev->fmt_cap->data_offset[p];
+ vb->planes[p].data_offset = dev->fmt_cap->data_offset[p];
}
return 0;
@@ -206,10 +207,11 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb)
static void vid_cap_buf_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct v4l2_timecode *tc = &vb->v4l2_buf.timecode;
+ struct v4l2_timecode *tc = &vbuf->timecode;
unsigned fps = 25;
- unsigned seq = vb->v4l2_buf.sequence;
+ unsigned seq = vbuf->sequence;
if (!vivid_is_sdtv_cap(dev))
return;
@@ -218,7 +220,7 @@ static void vid_cap_buf_finish(struct vb2_buffer *vb)
* Set the timecode. Rarely used, so it is interesting to
* test this.
*/
- vb->v4l2_buf.flags |= V4L2_BUF_FLAG_TIMECODE;
+ vbuf->flags |= V4L2_BUF_FLAG_TIMECODE;
if (dev->std_cap & V4L2_STD_525_60)
fps = 30;
tc->type = (fps == 30) ? V4L2_TC_TYPE_30FPS : V4L2_TC_TYPE_25FPS;
@@ -231,8 +233,9 @@ static void vid_cap_buf_finish(struct vb2_buffer *vb)
static void vid_cap_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb);
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
dprintk(dev, 1, "%s\n", __func__);
@@ -268,7 +271,8 @@ static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)
list_for_each_entry_safe(buf, tmp, &dev->vid_cap_active, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
}
return err;
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index fc73927a4abc..1678b730dba2 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -390,6 +390,62 @@ struct vivid_fmt vivid_formats[] = {
.buffers = 1,
},
{
+ .fourcc = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
.fourcc = V4L2_PIX_FMT_NV16M,
.vdownsampling = { 1, 1 },
.bit_depth = { 8, 8 },
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
index c404e275eae0..b77acb6a7013 100644
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
@@ -31,10 +31,11 @@
#include "vivid-kthread-out.h"
#include "vivid-vid-out.h"
-static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int vid_out_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned *nbuffers, unsigned *nplanes,
unsigned sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct vivid_dev *dev = vb2_get_drv_priv(vq);
const struct vivid_fmt *vfmt = dev->fmt_out;
unsigned planes = vfmt->buffers;
@@ -109,6 +110,7 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
static int vid_out_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
unsigned long size;
unsigned planes;
@@ -131,14 +133,14 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb)
}
if (dev->field_out != V4L2_FIELD_ALTERNATE)
- vb->v4l2_buf.field = dev->field_out;
- else if (vb->v4l2_buf.field != V4L2_FIELD_TOP &&
- vb->v4l2_buf.field != V4L2_FIELD_BOTTOM)
+ vbuf->field = dev->field_out;
+ else if (vbuf->field != V4L2_FIELD_TOP &&
+ vbuf->field != V4L2_FIELD_BOTTOM)
return -EINVAL;
for (p = 0; p < planes; p++) {
size = dev->bytesperline_out[p] * dev->fmt_out_rect.height +
- vb->v4l2_planes[p].data_offset;
+ vb->planes[p].data_offset;
if (vb2_get_plane_payload(vb, p) < size) {
dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %lu)\n",
@@ -152,8 +154,9 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb)
static void vid_out_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb);
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
dprintk(dev, 1, "%s\n", __func__);
@@ -186,7 +189,8 @@ static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count)
list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
}
return err;
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..cd5248a9a271 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -200,10 +200,10 @@ static void rpf_vdev_queue(struct vsp1_video *video,
vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y,
buf->addr[0] + rpf->offsets[0]);
- if (buf->buf.num_planes > 1)
+ if (buf->buf.vb2_buf.num_planes > 1)
vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0,
buf->addr[1] + rpf->offsets[1]);
- if (buf->buf.num_planes > 2)
+ if (buf->buf.vb2_buf.num_planes > 2)
vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1,
buf->addr[2] + rpf->offsets[1]);
}
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3c124c14ce14..5ce88e1f5d71 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -24,7 +24,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-subdev.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "vsp1.h"
@@ -610,11 +610,11 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
spin_unlock_irqrestore(&video->irqlock, flags);
- done->buf.v4l2_buf.sequence = video->sequence++;
- v4l2_get_timestamp(&done->buf.v4l2_buf.timestamp);
- for (i = 0; i < done->buf.num_planes; ++i)
- vb2_set_plane_payload(&done->buf, i, done->length[i]);
- vb2_buffer_done(&done->buf, VB2_BUF_STATE_DONE);
+ done->buf.sequence = video->sequence++;
+ v4l2_get_timestamp(&done->buf.timestamp);
+ for (i = 0; i < done->buf.vb2_buf.num_planes; ++i)
+ vb2_set_plane_payload(&done->buf.vb2_buf, i, done->length[i]);
+ vb2_buffer_done(&done->buf.vb2_buf, VB2_BUF_STATE_DONE);
return next;
}
@@ -787,10 +787,11 @@ void vsp1_pipelines_resume(struct vsp1_device *vsp1)
*/
static int
-vsp1_video_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+vsp1_video_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct vsp1_video *video = vb2_get_drv_priv(vq);
const struct v4l2_pix_format_mplane *format;
struct v4l2_pix_format_mplane pix_mp;
@@ -820,8 +821,9 @@ vsp1_video_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int vsp1_video_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue);
- struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vb);
+ struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vbuf);
const struct v4l2_pix_format_mplane *format = &video->format;
unsigned int i;
@@ -841,9 +843,10 @@ static int vsp1_video_buffer_prepare(struct vb2_buffer *vb)
static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue);
struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity);
- struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vb);
+ struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vbuf);
unsigned long flags;
bool empty;
@@ -954,7 +957,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
/* Remove all buffers from the IRQ queue. */
spin_lock_irqsave(&video->irqlock, flags);
list_for_each_entry(buffer, &video->irqqueue, queue)
- vb2_buffer_done(&buffer->buf, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buffer->buf.vb2_buf, VB2_BUF_STATE_ERROR);
INIT_LIST_HEAD(&video->irqqueue);
spin_unlock_irqrestore(&video->irqlock, flags);
}
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 0887a4d2742c..a929aa81cdbf 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -18,7 +18,7 @@
#include <linux/wait.h>
#include <media/media-entity.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
struct vsp1_video;
@@ -94,7 +94,7 @@ static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
}
struct vsp1_video_buffer {
- struct vb2_buffer buf;
+ struct vb2_v4l2_buffer buf;
struct list_head queue;
dma_addr_t addr[3];
@@ -102,9 +102,9 @@ struct vsp1_video_buffer {
};
static inline struct vsp1_video_buffer *
-to_vsp1_video_buffer(struct vb2_buffer *vb)
+to_vsp1_video_buffer(struct vb2_v4l2_buffer *vbuf)
{
- return container_of(vb, struct vsp1_video_buffer, buf);
+ return container_of(vbuf, struct vsp1_video_buffer, buf);
}
struct vsp1_video_operations {
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..95b62f4f77e7 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -201,9 +201,9 @@ static void wpf_vdev_queue(struct vsp1_video *video,
struct vsp1_rwpf *wpf = container_of(video, struct vsp1_rwpf, video);
vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, buf->addr[0]);
- if (buf->buf.num_planes > 1)
+ if (buf->buf.vb2_buf.num_planes > 1)
vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, buf->addr[1]);
- if (buf->buf.num_planes > 2)
+ if (buf->buf.vb2_buf.num_planes > 2)
vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, buf->addr[2]);
}
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index e779c93cb015..d11cc7072cd5 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -22,7 +22,7 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include "xilinx-dma.h"
@@ -285,7 +285,7 @@ done:
* @dma: DMA channel that uses the buffer
*/
struct xvip_dma_buffer {
- struct vb2_buffer buf;
+ struct vb2_v4l2_buffer buf;
struct list_head queue;
struct xvip_dma *dma;
};
@@ -301,18 +301,19 @@ static void xvip_dma_complete(void *param)
list_del(&buf->queue);
spin_unlock(&dma->queued_lock);
- buf->buf.v4l2_buf.field = V4L2_FIELD_NONE;
- buf->buf.v4l2_buf.sequence = dma->sequence++;
- v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp);
- vb2_set_plane_payload(&buf->buf, 0, dma->format.sizeimage);
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
+ buf->buf.field = V4L2_FIELD_NONE;
+ buf->buf.sequence = dma->sequence++;
+ v4l2_get_timestamp(&buf->buf.timestamp);
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, dma->format.sizeimage);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
}
static int
-xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+xvip_dma_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct xvip_dma *dma = vb2_get_drv_priv(vq);
/* Make sure the image size is large enough. */
@@ -329,8 +330,9 @@ xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int xvip_dma_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
- struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
+ struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vbuf);
buf->dma = dma;
@@ -339,8 +341,9 @@ static int xvip_dma_buffer_prepare(struct vb2_buffer *vb)
static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
- struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
+ struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vbuf);
struct dma_async_tx_descriptor *desc;
dma_addr_t addr = vb2_dma_contig_plane_dma_addr(vb, 0);
u32 flags;
@@ -367,7 +370,7 @@ static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags);
if (!desc) {
dev_err(dma->xdev->dev, "Failed to prepare DMA transfer\n");
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR);
return;
}
desc->callback = xvip_dma_complete;
@@ -434,7 +437,7 @@ error:
/* Give back all queued buffers to videobuf2. */
spin_lock_irq(&dma->queued_lock);
list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_QUEUED);
list_del(&buf->queue);
}
spin_unlock_irq(&dma->queued_lock);
@@ -461,7 +464,7 @@ static void xvip_dma_stop_streaming(struct vb2_queue *vq)
/* Give back all queued buffers to videobuf2. */
spin_lock_irq(&dma->queued_lock);
list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&buf->queue);
}
spin_unlock_irq(&dma->queued_lock);
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h
index a540111f8d3d..7a1621a2ef40 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.h
+++ b/drivers/media/platform/xilinx/xilinx-dma.h
@@ -22,7 +22,7 @@
#include <media/media-entity.h>
#include <media/v4l2-dev.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
struct dma_chan;
struct xvip_composite_device;
diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c
index 1c087cb76815..d0549fba711c 100644
--- a/drivers/media/rc/ir-hix5hd2.c
+++ b/drivers/media/rc/ir-hix5hd2.c
@@ -257,7 +257,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
goto clkerr;
if (devm_request_irq(dev, priv->irq, hix5hd2_ir_rx_interrupt,
- IRQF_NO_SUSPEND, pdev->name, priv) < 0) {
+ 0, pdev->name, priv) < 0) {
dev_err(dev, "IRQ %d register failed\n", priv->irq);
ret = -EINVAL;
goto regerr;
diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c
index b533240f8ec0..3a12ef35682b 100644
--- a/drivers/media/tuners/msi001.c
+++ b/drivers/media/tuners/msi001.c
@@ -513,7 +513,6 @@ MODULE_DEVICE_TABLE(spi, msi001_id_table);
static struct spi_driver msi001_driver = {
.driver = {
.name = "msi001",
- .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = msi001_probe,
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 507382160e5e..ce157edd45fa 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -166,6 +166,10 @@ static int si2157_init(struct dvb_frontend *fe)
for (remaining = fw->size; remaining > 0; remaining -= 17) {
len = fw->data[fw->size - remaining];
+ if (len > SI2157_ARGLEN) {
+ dev_err(&client->dev, "Bad firmware length\n");
+ goto err_release_firmware;
+ }
memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
cmd.wlen = len;
cmd.rlen = 1;
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index 8f2e1c277c5f..fcbb49757614 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -21,6 +21,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
/* AirSpy USB API commands (from AirSpy Library) */
@@ -97,7 +98,8 @@ static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
/* intermediate buffers with raw data from the USB device */
struct airspy_frame_buf {
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -310,13 +312,13 @@ static void airspy_urb_complete(struct urb *urb)
}
/* fill framebuffer */
- ptr = vb2_plane_vaddr(&fbuf->vb, 0);
+ ptr = vb2_plane_vaddr(&fbuf->vb.vb2_buf, 0);
len = airspy_convert_stream(s, ptr, urb->transfer_buffer,
urb->actual_length);
- vb2_set_plane_payload(&fbuf->vb, 0, len);
- v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);
- fbuf->vb.v4l2_buf.sequence = s->sequence++;
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len);
+ v4l2_get_timestamp(&fbuf->vb.timestamp);
+ fbuf->vb.sequence = s->sequence++;
+ vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
skip:
usb_submit_urb(urb, GFP_ATOMIC);
@@ -459,7 +461,7 @@ static void airspy_cleanup_queued_bufs(struct airspy *s)
buf = list_entry(s->queued_bufs.next,
struct airspy_frame_buf, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
}
@@ -486,7 +488,7 @@ static void airspy_disconnect(struct usb_interface *intf)
/* Videobuf2 operations */
static int airspy_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbuffers,
+ const void *parg, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
struct airspy *s = vb2_get_drv_priv(vq);
@@ -505,14 +507,15 @@ static int airspy_queue_setup(struct vb2_queue *vq,
static void airspy_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct airspy *s = vb2_get_drv_priv(vb->vb2_queue);
struct airspy_frame_buf *buf =
- container_of(vb, struct airspy_frame_buf, vb);
+ container_of(vbuf, struct airspy_frame_buf, vb);
unsigned long flags;
/* Check the device has not disconnected between prep and queuing */
if (unlikely(!s->udev)) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
return;
}
@@ -571,7 +574,8 @@ err_clear_bit:
list_for_each_entry_safe(buf, tmp, &s->queued_bufs, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ vb2_buffer_done(&buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
}
}
diff --git a/drivers/media/usb/au0828/au0828-vbi.c b/drivers/media/usb/au0828/au0828-vbi.c
index f67247cf1a5a..130c8b49bf7f 100644
--- a/drivers/media/usb/au0828/au0828-vbi.c
+++ b/drivers/media/usb/au0828/au0828-vbi.c
@@ -30,10 +30,11 @@
/* ------------------------------------------------------------------ */
-static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int vbi_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct au0828_dev *dev = vb2_get_drv_priv(vq);
unsigned long img_size = dev->vbi_width * dev->vbi_height * 2;
unsigned long size;
@@ -52,7 +53,6 @@ static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int vbi_buffer_prepare(struct vb2_buffer *vb)
{
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
unsigned long size;
size = dev->vbi_width * dev->vbi_height * 2;
@@ -62,7 +62,7 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb)
__func__, vb2_plane_size(vb, 0), size);
return -EINVAL;
}
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(vb, 0, size);
return 0;
}
@@ -71,7 +71,9 @@ static void
vbi_buffer_queue(struct vb2_buffer *vb)
{
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct au0828_buffer *buf =
+ container_of(vbuf, struct au0828_buffer, vb);
struct au0828_dmaqueue *vbiq = &dev->vbiq;
unsigned long flags = 0;
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 1a362a041ab3..45c622e234f7 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -302,20 +302,20 @@ static inline void buffer_filled(struct au0828_dev *dev,
struct au0828_dmaqueue *dma_q,
struct au0828_buffer *buf)
{
- struct vb2_buffer *vb = &buf->vb;
- struct vb2_queue *q = vb->vb2_queue;
+ struct vb2_v4l2_buffer *vb = &buf->vb;
+ struct vb2_queue *q = vb->vb2_buf.vb2_queue;
/* Advice that buffer was filled */
au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field);
if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- vb->v4l2_buf.sequence = dev->frame_count++;
+ vb->sequence = dev->frame_count++;
else
- vb->v4l2_buf.sequence = dev->vbi_frame_count++;
+ vb->sequence = dev->vbi_frame_count++;
- vb->v4l2_buf.field = V4L2_FIELD_INTERLACED;
- v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ vb->field = V4L2_FIELD_INTERLACED;
+ v4l2_get_timestamp(&vb->timestamp);
+ vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
}
/*
@@ -531,11 +531,11 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
buf = dev->isoc_ctl.buf;
if (buf != NULL)
- outp = vb2_plane_vaddr(&buf->vb, 0);
+ outp = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
vbi_buf = dev->isoc_ctl.vbi_buf;
if (vbi_buf != NULL)
- vbioutp = vb2_plane_vaddr(&vbi_buf->vb, 0);
+ vbioutp = vb2_plane_vaddr(&vbi_buf->vb.vb2_buf, 0);
for (i = 0; i < urb->number_of_packets; i++) {
int status = urb->iso_frame_desc[i].status;
@@ -574,7 +574,7 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
vbioutp = NULL;
else
vbioutp = vb2_plane_vaddr(
- &vbi_buf->vb, 0);
+ &vbi_buf->vb.vb2_buf, 0);
/* Video */
if (buf != NULL)
@@ -583,7 +583,8 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
if (buf == NULL)
outp = NULL;
else
- outp = vb2_plane_vaddr(&buf->vb, 0);
+ outp = vb2_plane_vaddr(
+ &buf->vb.vb2_buf, 0);
/* As long as isoc traffic is arriving, keep
resetting the timer */
@@ -637,10 +638,11 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
return rc;
}
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct au0828_dev *dev = vb2_get_drv_priv(vq);
unsigned long img_size = dev->height * dev->bytesperline;
unsigned long size;
@@ -658,7 +660,9 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int
buffer_prepare(struct vb2_buffer *vb)
{
- struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct au0828_buffer *buf = container_of(vbuf,
+ struct au0828_buffer, vb);
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
buf->length = dev->height * dev->bytesperline;
@@ -668,14 +672,15 @@ buffer_prepare(struct vb2_buffer *vb)
__func__, vb2_plane_size(vb, 0), buf->length);
return -EINVAL;
}
- vb2_set_plane_payload(&buf->vb, 0, buf->length);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->length);
return 0;
}
static void
buffer_queue(struct vb2_buffer *vb)
{
- struct au0828_buffer *buf = container_of(vb,
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct au0828_buffer *buf = container_of(vbuf,
struct au0828_buffer,
vb);
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
@@ -826,14 +831,15 @@ static void au0828_stop_streaming(struct vb2_queue *vq)
spin_lock_irqsave(&dev->slock, flags);
if (dev->isoc_ctl.buf != NULL) {
- vb2_buffer_done(&dev->isoc_ctl.buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&dev->isoc_ctl.buf->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
dev->isoc_ctl.buf = NULL;
}
while (!list_empty(&vidq->active)) {
struct au0828_buffer *buf;
buf = list_entry(vidq->active.next, struct au0828_buffer, list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&buf->list);
}
spin_unlock_irqrestore(&dev->slock, flags);
@@ -853,7 +859,7 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq)
spin_lock_irqsave(&dev->slock, flags);
if (dev->isoc_ctl.vbi_buf != NULL) {
- vb2_buffer_done(&dev->isoc_ctl.vbi_buf->vb,
+ vb2_buffer_done(&dev->isoc_ctl.vbi_buf->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
dev->isoc_ctl.vbi_buf = NULL;
}
@@ -862,7 +868,7 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq)
buf = list_entry(vbiq->active.next, struct au0828_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
@@ -911,7 +917,7 @@ static void au0828_vid_buffer_timeout(unsigned long data)
buf = dev->isoc_ctl.buf;
if (buf != NULL) {
- vid_data = vb2_plane_vaddr(&buf->vb, 0);
+ vid_data = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
memset(vid_data, 0x00, buf->length); /* Blank green frame */
buffer_filled(dev, dma_q, buf);
}
@@ -935,7 +941,7 @@ static void au0828_vbi_buffer_timeout(unsigned long data)
buf = dev->isoc_ctl.vbi_buf;
if (buf != NULL) {
- vbi_data = vb2_plane_vaddr(&buf->vb, 0);
+ vbi_data = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
memset(vbi_data, 0x00, buf->length);
buffer_filled(dev, dma_q, buf);
}
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 3b480005ce3b..60b59391ea2a 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -28,6 +28,7 @@
/* Analog */
#include <linux/videodev2.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
@@ -167,7 +168,7 @@ struct au0828_usb_isoc_ctl {
/* buffer for one video frame */
struct au0828_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
void *mem;
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 9798160698a3..d0d8f08e37c8 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -1114,7 +1114,8 @@ int cx231xx_enum_input(struct file *file, void *priv,
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
u32 gen_stat;
- unsigned int ret, n;
+ unsigned int n;
+ int ret;
n = i->index;
if (n >= MAX_CX231XX_INPUT)
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 0376c092bab8..1dd962535f97 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -847,6 +847,10 @@ static const struct usb_device_id dvbsky_id_table[] = {
USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI,
&dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI",
RC_MAP_TT_1500) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC,
+ USB_PID_TERRATEC_H7_3,
+ &dvbsky_t680c_props, "Terratec H7 Rev.4",
+ RC_MAP_TT_1500) },
{ }
};
MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index c3cac4c12fb3..5a503a6bb8c5 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -34,6 +34,14 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
unsigned int pipe;
u8 requesttype;
+ mutex_lock(&d->usb_mutex);
+
+ if (req->size > sizeof(dev->buf)) {
+ dev_err(&d->intf->dev, "too large message %u\n", req->size);
+ ret = -EINVAL;
+ goto err_mutex_unlock;
+ }
+
if (req->index & CMD_WR_FLAG) {
/* write */
memcpy(dev->buf, req->data, req->size);
@@ -50,14 +58,17 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value,
req->index, dev->buf, req->size);
if (ret < 0)
- goto err;
+ goto err_mutex_unlock;
/* read request, copy returned data to return buf */
if (requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
memcpy(req->data, dev->buf, req->size);
+ mutex_unlock(&d->usb_mutex);
+
return 0;
-err:
+err_mutex_unlock:
+ mutex_unlock(&d->usb_mutex);
dev_dbg(&d->intf->dev, "failed=%d\n", ret);
return ret;
}
@@ -1885,6 +1896,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
&rtl28xxu_props, "MSI DIGIVOX Micro HD", NULL) },
{ DVB_USB_DEVICE(USB_VID_COMPRO, 0x0620,
&rtl28xxu_props, "Compro VideoMate U620F", NULL) },
+ { DVB_USB_DEVICE(USB_VID_COMPRO, 0x0650,
+ &rtl28xxu_props, "Compro VideoMate U650F", NULL) },
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
&rtl28xxu_props, "MaxMedia HU394-T", NULL) },
{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03,
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 9f6115a2ee01..138062960a73 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -71,7 +71,7 @@
struct rtl28xxu_dev {
- u8 buf[28];
+ u8 buf[128];
u8 chip_id;
u8 tuner;
char *tuner_name;
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c
index 744e7ed743e1..e23c285b3108 100644
--- a/drivers/media/usb/em28xx/em28xx-vbi.c
+++ b/drivers/media/usb/em28xx/em28xx-vbi.c
@@ -31,10 +31,11 @@
/* ------------------------------------------------------------------ */
-static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int vbi_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct em28xx *dev = vb2_get_drv_priv(vq);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
unsigned long size;
@@ -61,7 +62,6 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb)
{
struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
unsigned long size;
size = v4l2->vbi_width * v4l2->vbi_height * 2;
@@ -71,7 +71,7 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb)
__func__, vb2_plane_size(vb, 0), size);
return -EINVAL;
}
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(vb, 0, size);
return 0;
}
@@ -79,8 +79,10 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb)
static void
vbi_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf =
+ container_of(vbuf, struct em28xx_buffer, vb);
struct em28xx_dmaqueue *vbiq = &dev->vbiq;
unsigned long flags = 0;
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 4397ce5e78df..6a3cf342e087 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -433,14 +433,14 @@ static inline void finish_buffer(struct em28xx *dev,
{
em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field);
- buf->vb.v4l2_buf.sequence = dev->v4l2->field_count++;
+ buf->vb.sequence = dev->v4l2->field_count++;
if (dev->v4l2->progressive)
- buf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
+ buf->vb.field = V4L2_FIELD_NONE;
else
- buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ buf->vb.field = V4L2_FIELD_INTERLACED;
+ v4l2_get_timestamp(&buf->vb.timestamp);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
/*
@@ -871,10 +871,11 @@ static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type)
Videobuf2 operations
------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct em28xx *dev = vb2_get_drv_priv(vq);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
unsigned long size;
@@ -900,12 +901,12 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int
buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
unsigned long size;
- em28xx_videodbg("%s, field=%d\n", __func__, vb->v4l2_buf.field);
+ em28xx_videodbg("%s, field=%d\n", __func__, vbuf->field);
size = (v4l2->width * v4l2->height * v4l2->format->depth + 7) >> 3;
@@ -914,7 +915,7 @@ buffer_prepare(struct vb2_buffer *vb)
__func__, vb2_plane_size(vb, 0), size);
return -EINVAL;
}
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(vb, 0, size);
return 0;
}
@@ -924,6 +925,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
struct em28xx *dev = vb2_get_drv_priv(vq);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
struct v4l2_frequency f;
+ struct v4l2_fh *owner;
int rc = 0;
em28xx_videodbg("%s\n", __func__);
@@ -964,7 +966,8 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
/* Ask tuner to go to analog or radio mode */
memset(&f, 0, sizeof(f));
f.frequency = v4l2->frequency;
- if (vq->owner && vq->owner->vdev->vfl_type == VFL_TYPE_RADIO)
+ owner = (struct v4l2_fh *)vq->owner;
+ if (owner && owner->vdev->vfl_type == VFL_TYPE_RADIO)
f.type = V4L2_TUNER_RADIO;
else
f.type = V4L2_TUNER_ANALOG_TV;
@@ -995,7 +998,8 @@ static void em28xx_stop_streaming(struct vb2_queue *vq)
spin_lock_irqsave(&dev->slock, flags);
if (dev->usb_ctl.vid_buf != NULL) {
- vb2_buffer_done(&dev->usb_ctl.vid_buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&dev->usb_ctl.vid_buf->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
dev->usb_ctl.vid_buf = NULL;
}
while (!list_empty(&vidq->active)) {
@@ -1003,7 +1007,7 @@ static void em28xx_stop_streaming(struct vb2_queue *vq)
buf = list_entry(vidq->active.next, struct em28xx_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
@@ -1026,7 +1030,8 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq)
spin_lock_irqsave(&dev->slock, flags);
if (dev->usb_ctl.vbi_buf != NULL) {
- vb2_buffer_done(&dev->usb_ctl.vbi_buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&dev->usb_ctl.vbi_buf->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
dev->usb_ctl.vbi_buf = NULL;
}
while (!list_empty(&vbiq->active)) {
@@ -1034,7 +1039,7 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq)
buf = list_entry(vbiq->active.next, struct em28xx_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->slock, flags);
}
@@ -1042,8 +1047,10 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq)
static void
buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf =
+ container_of(vbuf, struct em28xx_buffer, vb);
struct em28xx_dmaqueue *vidq = &dev->vidq;
unsigned long flags = 0;
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index e6559c6f143c..76bf8ba372b3 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -35,6 +35,7 @@
#include <linux/kref.h>
#include <linux/videodev2.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
@@ -264,7 +265,7 @@ struct em28xx_fmt {
/* buffer for one video frame */
struct em28xx_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
void *mem;
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index 0ab81ec8897a..ae1cfa792c58 100644
--- a/drivers/media/usb/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -386,10 +386,10 @@ start_error:
*/
static inline void store_byte(struct go7007_buffer *vb, u8 byte)
{
- if (vb && vb->vb.v4l2_planes[0].bytesused < GO7007_BUF_SIZE) {
- u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
+ if (vb && vb->vb.vb2_buf.planes[0].bytesused < GO7007_BUF_SIZE) {
+ u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
- ptr[vb->vb.v4l2_planes[0].bytesused++] = byte;
+ ptr[vb->vb.vb2_buf.planes[0].bytesused++] = byte;
}
}
@@ -401,7 +401,7 @@ static void go7007_set_motion_regions(struct go7007 *go, struct go7007_buffer *v
.type = V4L2_EVENT_MOTION_DET,
.u.motion_det = {
.flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
- .frame_sequence = vb->vb.v4l2_buf.sequence,
+ .frame_sequence = vb->vb.sequence,
.region_mask = motion_regions,
},
};
@@ -417,7 +417,7 @@ static void go7007_set_motion_regions(struct go7007 *go, struct go7007_buffer *v
*/
static void go7007_motion_regions(struct go7007 *go, struct go7007_buffer *vb)
{
- u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
+ u32 *bytesused = &vb->vb.vb2_buf.planes[0].bytesused;
unsigned motion[4] = { 0, 0, 0, 0 };
u32 motion_regions = 0;
unsigned stride = (go->width + 7) >> 3;
@@ -458,25 +458,26 @@ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buf
go->next_seq++;
return vb;
}
- bytesused = &vb->vb.v4l2_planes[0].bytesused;
+ bytesused = &vb->vb.vb2_buf.planes[0].bytesused;
- vb->vb.v4l2_buf.sequence = go->next_seq++;
+ vb->vb.sequence = go->next_seq++;
if (vb->modet_active && *bytesused + 216 < GO7007_BUF_SIZE)
go7007_motion_regions(go, vb);
else
go7007_set_motion_regions(go, vb, 0);
- v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
+ v4l2_get_timestamp(&vb->vb.timestamp);
vb_tmp = vb;
spin_lock(&go->spinlock);
list_del(&vb->list);
if (list_empty(&go->vidq_active))
vb = NULL;
else
- vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list);
+ vb = list_first_entry(&go->vidq_active,
+ struct go7007_buffer, list);
go->active_buf = vb;
spin_unlock(&go->spinlock);
- vb2_buffer_done(&vb_tmp->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&vb_tmp->vb.vb2_buf, VB2_BUF_STATE_DONE);
return vb;
}
@@ -519,9 +520,10 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
}
for (i = 0; i < length; ++i) {
- if (vb && vb->vb.v4l2_planes[0].bytesused >= GO7007_BUF_SIZE - 3) {
+ if (vb && vb->vb.vb2_buf.planes[0].bytesused >=
+ GO7007_BUF_SIZE - 3) {
v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
- vb->vb.v4l2_planes[0].bytesused = 0;
+ vb->vb.vb2_buf.planes[0].bytesused = 0;
vb->frame_offset = 0;
vb->modet_active = 0;
vb = go->active_buf = NULL;
@@ -601,7 +603,8 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
vb = frame_boundary(go, vb);
go->seen_frame = buf[i] == frame_start_code;
if (vb && go->seen_frame)
- vb->frame_offset = vb->vb.v4l2_planes[0].bytesused;
+ vb->frame_offset =
+ vb->vb.vb2_buf.planes[0].bytesused;
}
/* Handle any special chunk types, or just write the
* start code to the (potentially new) buffer */
diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c
index 5f4c9b9e899a..60bf5f0644d1 100644
--- a/drivers/media/usb/go7007/go7007-fw.c
+++ b/drivers/media/usb/go7007/go7007-fw.c
@@ -379,7 +379,7 @@ static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space)
buf = kzalloc(4096, GFP_KERNEL);
if (buf == NULL)
- return -1;
+ return -ENOMEM;
for (i = 1; i < 32; ++i) {
mjpeg_frame_header(go, buf + size, i);
@@ -646,7 +646,7 @@ static int gen_mpeg1hdr_to_package(struct go7007 *go,
buf = kzalloc(5120, GFP_KERNEL);
if (buf == NULL)
- return -1;
+ return -ENOMEM;
framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
if (go->interlace_coding)
@@ -832,7 +832,7 @@ static int gen_mpeg4hdr_to_package(struct go7007 *go,
buf = kzalloc(5120, GFP_KERNEL);
if (buf == NULL)
- return -1;
+ return -ENOMEM;
framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
i = 368;
diff --git a/drivers/media/usb/go7007/go7007-priv.h b/drivers/media/usb/go7007/go7007-priv.h
index 2251c3f99d1d..745185eb060b 100644
--- a/drivers/media/usb/go7007/go7007-priv.h
+++ b/drivers/media/usb/go7007/go7007-priv.h
@@ -20,7 +20,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
struct go7007;
@@ -136,7 +136,7 @@ struct go7007_hpi_ops {
#define GO7007_BUF_SIZE (GO7007_BUF_PAGES << PAGE_SHIFT)
struct go7007_buffer {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
unsigned int frame_offset;
u32 modet_active;
diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c
index c57207e268c3..f3d187db9368 100644
--- a/drivers/media/usb/go7007/go7007-v4l2.c
+++ b/drivers/media/usb/go7007/go7007-v4l2.c
@@ -52,7 +52,7 @@ static bool valid_pixelformat(u32 pixelformat)
static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
{
- u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
+ u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
switch (format) {
case V4L2_PIX_FMT_MJPEG:
@@ -369,7 +369,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
}
static int go7007_queue_setup(struct vb2_queue *q,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -386,8 +386,9 @@ static void go7007_buf_queue(struct vb2_buffer *vb)
{
struct vb2_queue *vq = vb->vb2_queue;
struct go7007 *go = vb2_get_drv_priv(vq);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct go7007_buffer *go7007_vb =
- container_of(vb, struct go7007_buffer, vb);
+ container_of(vbuf, struct go7007_buffer, vb);
unsigned long flags;
spin_lock_irqsave(&go->spinlock, flags);
@@ -397,12 +398,13 @@ static void go7007_buf_queue(struct vb2_buffer *vb)
static int go7007_buf_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct go7007_buffer *go7007_vb =
- container_of(vb, struct go7007_buffer, vb);
+ container_of(vbuf, struct go7007_buffer, vb);
go7007_vb->modet_active = 0;
go7007_vb->frame_offset = 0;
- vb->v4l2_planes[0].bytesused = 0;
+ vb->planes[0].bytesused = 0;
return 0;
}
@@ -410,15 +412,15 @@ static void go7007_buf_finish(struct vb2_buffer *vb)
{
struct vb2_queue *vq = vb->vb2_queue;
struct go7007 *go = vb2_get_drv_priv(vq);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct go7007_buffer *go7007_vb =
- container_of(vb, struct go7007_buffer, vb);
+ container_of(vbuf, struct go7007_buffer, vb);
u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
- struct v4l2_buffer *buf = &vb->v4l2_buf;
- buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
+ vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
V4L2_BUF_FLAG_PFRAME);
- buf->flags |= frame_type_flag;
- buf->field = V4L2_FIELD_NONE;
+ vbuf->flags |= frame_type_flag;
+ vbuf->field = V4L2_FIELD_NONE;
}
static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index e54cee856a80..af5cd8213e8b 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -436,7 +436,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
}
j = gspca_dev->fr_queue[i];
frame = &gspca_dev->frame[j];
- frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
+ v4l2_get_timestamp(&frame->v4l2_buf.timestamp);
frame->v4l2_buf.sequence = gspca_dev->sequence++;
gspca_dev->image = frame->data;
gspca_dev->image_len = 0;
@@ -1909,7 +1909,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
}
/* get a frame */
- timestamp = ktime_to_timeval(ktime_get());
+ v4l2_get_timestamp(&timestamp);
timestamp.tv_sec--;
n = 2;
for (;;) {
diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c
index fd1fa412e094..e05bfec90f46 100644
--- a/drivers/media/usb/hackrf/hackrf.c
+++ b/drivers/media/usb/hackrf/hackrf.c
@@ -21,6 +21,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
/* HackRF USB API commands (from HackRF Library) */
@@ -31,8 +32,10 @@ enum {
CMD_BOARD_ID_READ = 0x0e,
CMD_VERSION_STRING_READ = 0x0f,
CMD_SET_FREQ = 0x10,
+ CMD_AMP_ENABLE = 0x11,
CMD_SET_LNA_GAIN = 0x13,
CMD_SET_VGA_GAIN = 0x14,
+ CMD_SET_TXVGA_GAIN = 0x15,
};
/*
@@ -43,10 +46,10 @@ enum {
#define MAX_BULK_BUFS (6)
#define BULK_BUFFER_SIZE (128 * 512)
-static const struct v4l2_frequency_band bands_adc[] = {
+static const struct v4l2_frequency_band bands_adc_dac[] = {
{
.tuner = 0,
- .type = V4L2_TUNER_ADC,
+ .type = V4L2_TUNER_SDR,
.index = 0,
.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
.rangelow = 200000,
@@ -54,7 +57,7 @@ static const struct v4l2_frequency_band bands_adc[] = {
},
};
-static const struct v4l2_frequency_band bands_rf[] = {
+static const struct v4l2_frequency_band bands_rx_tx[] = {
{
.tuner = 1,
.type = V4L2_TUNER_RF,
@@ -67,7 +70,6 @@ static const struct v4l2_frequency_band bands_rf[] = {
/* stream formats */
struct hackrf_format {
- char *name;
u32 pixelformat;
u32 buffersize;
};
@@ -75,7 +77,6 @@ struct hackrf_format {
/* format descriptions for capture and preview */
static struct hackrf_format formats[] = {
{
- .name = "Complex S8",
.pixelformat = V4L2_SDR_FMT_CS8,
.buffersize = BULK_BUFFER_SIZE,
},
@@ -84,28 +85,44 @@ static struct hackrf_format formats[] = {
static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
/* intermediate buffers with raw data from the USB device */
-struct hackrf_frame_buf {
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
+struct hackrf_buffer {
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
struct hackrf_dev {
-#define POWER_ON (1 << 1)
-#define URB_BUF (1 << 2)
-#define USB_STATE_URB_BUF (1 << 3)
+#define USB_STATE_URB_BUF 1 /* XXX: set manually */
+#define RX_ON 4
+#define TX_ON 5
+#define RX_ADC_FREQUENCY 11
+#define TX_DAC_FREQUENCY 12
+#define RX_BANDWIDTH 13
+#define TX_BANDWIDTH 14
+#define RX_RF_FREQUENCY 15
+#define TX_RF_FREQUENCY 16
+#define RX_RF_GAIN 17
+#define TX_RF_GAIN 18
+#define RX_IF_GAIN 19
+#define RX_LNA_GAIN 20
+#define TX_LNA_GAIN 21
unsigned long flags;
+ struct usb_interface *intf;
struct device *dev;
struct usb_device *udev;
- struct video_device vdev;
+ struct video_device rx_vdev;
+ struct video_device tx_vdev;
struct v4l2_device v4l2_dev;
/* videobuf2 queue and queued buffers list */
- struct vb2_queue vb_queue;
- struct list_head queued_bufs;
- spinlock_t queued_bufs_lock; /* Protects queued_bufs */
+ struct vb2_queue rx_vb2_queue;
+ struct vb2_queue tx_vb2_queue;
+ struct list_head rx_buffer_list;
+ struct list_head tx_buffer_list;
+ spinlock_t buffer_list_lock; /* Protects buffer_list */
unsigned sequence; /* Buffer sequence counter */
unsigned int vb_full; /* vb is full and packets dropped */
+ unsigned int vb_empty; /* vb is empty and packets dropped */
/* Note if taking both locks v4l2_lock must always be locked first! */
struct mutex v4l2_lock; /* Protects everything else */
@@ -125,16 +142,24 @@ struct hackrf_dev {
/* Current configuration */
unsigned int f_adc;
- unsigned int f_rf;
+ unsigned int f_dac;
+ unsigned int f_rx;
+ unsigned int f_tx;
u32 pixelformat;
u32 buffersize;
/* Controls */
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *bandwidth_auto;
- struct v4l2_ctrl *bandwidth;
- struct v4l2_ctrl *lna_gain;
- struct v4l2_ctrl *if_gain;
+ struct v4l2_ctrl_handler rx_ctrl_handler;
+ struct v4l2_ctrl *rx_bandwidth_auto;
+ struct v4l2_ctrl *rx_bandwidth;
+ struct v4l2_ctrl *rx_rf_gain;
+ struct v4l2_ctrl *rx_lna_gain;
+ struct v4l2_ctrl *rx_if_gain;
+ struct v4l2_ctrl_handler tx_ctrl_handler;
+ struct v4l2_ctrl *tx_bandwidth_auto;
+ struct v4l2_ctrl *tx_bandwidth;
+ struct v4l2_ctrl *tx_rf_gain;
+ struct v4l2_ctrl *tx_lna_gain;
/* Sample rate calc */
unsigned long jiffies_next;
@@ -164,6 +189,7 @@ static int hackrf_ctrl_msg(struct hackrf_dev *dev, u8 request, u16 value,
switch (request) {
case CMD_SET_TRANSCEIVER_MODE:
case CMD_SET_FREQ:
+ case CMD_AMP_ENABLE:
case CMD_SAMPLE_RATE_SET:
case CMD_BASEBAND_FILTER_BANDWIDTH_SET:
pipe = usb_sndctrlpipe(dev->udev, 0);
@@ -173,6 +199,7 @@ static int hackrf_ctrl_msg(struct hackrf_dev *dev, u8 request, u16 value,
case CMD_VERSION_STRING_READ:
case CMD_SET_LNA_GAIN:
case CMD_SET_VGA_GAIN:
+ case CMD_SET_TXVGA_GAIN:
pipe = usb_rcvctrlpipe(dev->udev, 0);
requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
break;
@@ -205,25 +232,227 @@ err:
return ret;
}
+static int hackrf_set_params(struct hackrf_dev *dev)
+{
+ struct usb_interface *intf = dev->intf;
+ int ret, i;
+ u8 buf[8], u8tmp;
+ unsigned int uitmp, uitmp1, uitmp2;
+ const bool rx = test_bit(RX_ON, &dev->flags);
+ const bool tx = test_bit(TX_ON, &dev->flags);
+ static const struct {
+ u32 freq;
+ } bandwidth_lut[] = {
+ { 1750000}, /* 1.75 MHz */
+ { 2500000}, /* 2.5 MHz */
+ { 3500000}, /* 3.5 MHz */
+ { 5000000}, /* 5 MHz */
+ { 5500000}, /* 5.5 MHz */
+ { 6000000}, /* 6 MHz */
+ { 7000000}, /* 7 MHz */
+ { 8000000}, /* 8 MHz */
+ { 9000000}, /* 9 MHz */
+ {10000000}, /* 10 MHz */
+ {12000000}, /* 12 MHz */
+ {14000000}, /* 14 MHz */
+ {15000000}, /* 15 MHz */
+ {20000000}, /* 20 MHz */
+ {24000000}, /* 24 MHz */
+ {28000000}, /* 28 MHz */
+ };
+
+ if (!rx && !tx) {
+ dev_dbg(&intf->dev, "device is sleeping\n");
+ return 0;
+ }
+
+ /* ADC / DAC frequency */
+ if (rx && test_and_clear_bit(RX_ADC_FREQUENCY, &dev->flags)) {
+ dev_dbg(&intf->dev, "RX ADC frequency=%u Hz\n", dev->f_adc);
+ uitmp1 = dev->f_adc;
+ uitmp2 = 1;
+ set_bit(TX_DAC_FREQUENCY, &dev->flags);
+ } else if (tx && test_and_clear_bit(TX_DAC_FREQUENCY, &dev->flags)) {
+ dev_dbg(&intf->dev, "TX DAC frequency=%u Hz\n", dev->f_dac);
+ uitmp1 = dev->f_dac;
+ uitmp2 = 1;
+ set_bit(RX_ADC_FREQUENCY, &dev->flags);
+ } else {
+ uitmp1 = uitmp2 = 0;
+ }
+ if (uitmp1 || uitmp2) {
+ buf[0] = (uitmp1 >> 0) & 0xff;
+ buf[1] = (uitmp1 >> 8) & 0xff;
+ buf[2] = (uitmp1 >> 16) & 0xff;
+ buf[3] = (uitmp1 >> 24) & 0xff;
+ buf[4] = (uitmp2 >> 0) & 0xff;
+ buf[5] = (uitmp2 >> 8) & 0xff;
+ buf[6] = (uitmp2 >> 16) & 0xff;
+ buf[7] = (uitmp2 >> 24) & 0xff;
+ ret = hackrf_ctrl_msg(dev, CMD_SAMPLE_RATE_SET, 0, 0, buf, 8);
+ if (ret)
+ goto err;
+ }
+
+ /* bandwidth */
+ if (rx && test_and_clear_bit(RX_BANDWIDTH, &dev->flags)) {
+ if (dev->rx_bandwidth_auto->val == true)
+ uitmp = dev->f_adc;
+ else
+ uitmp = dev->rx_bandwidth->val;
+
+ for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
+ if (uitmp <= bandwidth_lut[i].freq) {
+ uitmp = bandwidth_lut[i].freq;
+ break;
+ }
+ }
+ dev->rx_bandwidth->val = uitmp;
+ dev->rx_bandwidth->cur.val = uitmp;
+ dev_dbg(&intf->dev, "RX bandwidth selected=%u\n", uitmp);
+ set_bit(TX_BANDWIDTH, &dev->flags);
+ } else if (tx && test_and_clear_bit(TX_BANDWIDTH, &dev->flags)) {
+ if (dev->tx_bandwidth_auto->val == true)
+ uitmp = dev->f_dac;
+ else
+ uitmp = dev->tx_bandwidth->val;
+
+ for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
+ if (uitmp <= bandwidth_lut[i].freq) {
+ uitmp = bandwidth_lut[i].freq;
+ break;
+ }
+ }
+ dev->tx_bandwidth->val = uitmp;
+ dev->tx_bandwidth->cur.val = uitmp;
+ dev_dbg(&intf->dev, "TX bandwidth selected=%u\n", uitmp);
+ set_bit(RX_BANDWIDTH, &dev->flags);
+ } else {
+ uitmp = 0;
+ }
+ if (uitmp) {
+ uitmp1 = uitmp2 = 0;
+ uitmp1 |= ((uitmp >> 0) & 0xff) << 0;
+ uitmp1 |= ((uitmp >> 8) & 0xff) << 8;
+ uitmp2 |= ((uitmp >> 16) & 0xff) << 0;
+ uitmp2 |= ((uitmp >> 24) & 0xff) << 8;
+ ret = hackrf_ctrl_msg(dev, CMD_BASEBAND_FILTER_BANDWIDTH_SET,
+ uitmp1, uitmp2, NULL, 0);
+ if (ret)
+ goto err;
+ }
+
+ /* RX / TX RF frequency */
+ if (rx && test_and_clear_bit(RX_RF_FREQUENCY, &dev->flags)) {
+ dev_dbg(&intf->dev, "RX RF frequency=%u Hz\n", dev->f_rx);
+ uitmp1 = dev->f_rx / 1000000;
+ uitmp2 = dev->f_rx % 1000000;
+ set_bit(TX_RF_FREQUENCY, &dev->flags);
+ } else if (tx && test_and_clear_bit(TX_RF_FREQUENCY, &dev->flags)) {
+ dev_dbg(&intf->dev, "TX RF frequency=%u Hz\n", dev->f_tx);
+ uitmp1 = dev->f_tx / 1000000;
+ uitmp2 = dev->f_tx % 1000000;
+ set_bit(RX_RF_FREQUENCY, &dev->flags);
+ } else {
+ uitmp1 = uitmp2 = 0;
+ }
+ if (uitmp1 || uitmp2) {
+ buf[0] = (uitmp1 >> 0) & 0xff;
+ buf[1] = (uitmp1 >> 8) & 0xff;
+ buf[2] = (uitmp1 >> 16) & 0xff;
+ buf[3] = (uitmp1 >> 24) & 0xff;
+ buf[4] = (uitmp2 >> 0) & 0xff;
+ buf[5] = (uitmp2 >> 8) & 0xff;
+ buf[6] = (uitmp2 >> 16) & 0xff;
+ buf[7] = (uitmp2 >> 24) & 0xff;
+ ret = hackrf_ctrl_msg(dev, CMD_SET_FREQ, 0, 0, buf, 8);
+ if (ret)
+ goto err;
+ }
+
+ /* RX RF gain */
+ if (rx && test_and_clear_bit(RX_RF_GAIN, &dev->flags)) {
+ dev_dbg(&intf->dev, "RX RF gain val=%d->%d\n",
+ dev->rx_rf_gain->cur.val, dev->rx_rf_gain->val);
+
+ u8tmp = (dev->rx_rf_gain->val) ? 1 : 0;
+ ret = hackrf_ctrl_msg(dev, CMD_AMP_ENABLE, u8tmp, 0, NULL, 0);
+ if (ret)
+ goto err;
+ set_bit(TX_RF_GAIN, &dev->flags);
+ }
+
+ /* TX RF gain */
+ if (tx && test_and_clear_bit(TX_RF_GAIN, &dev->flags)) {
+ dev_dbg(&intf->dev, "TX RF gain val=%d->%d\n",
+ dev->tx_rf_gain->cur.val, dev->tx_rf_gain->val);
+
+ u8tmp = (dev->tx_rf_gain->val) ? 1 : 0;
+ ret = hackrf_ctrl_msg(dev, CMD_AMP_ENABLE, u8tmp, 0, NULL, 0);
+ if (ret)
+ goto err;
+ set_bit(RX_RF_GAIN, &dev->flags);
+ }
+
+ /* RX LNA gain */
+ if (rx && test_and_clear_bit(RX_LNA_GAIN, &dev->flags)) {
+ dev_dbg(dev->dev, "RX LNA gain val=%d->%d\n",
+ dev->rx_lna_gain->cur.val, dev->rx_lna_gain->val);
+
+ ret = hackrf_ctrl_msg(dev, CMD_SET_LNA_GAIN, 0,
+ dev->rx_lna_gain->val, &u8tmp, 1);
+ if (ret)
+ goto err;
+ }
+
+ /* RX IF gain */
+ if (rx && test_and_clear_bit(RX_IF_GAIN, &dev->flags)) {
+ dev_dbg(&intf->dev, "IF gain val=%d->%d\n",
+ dev->rx_if_gain->cur.val, dev->rx_if_gain->val);
+
+ ret = hackrf_ctrl_msg(dev, CMD_SET_VGA_GAIN, 0,
+ dev->rx_if_gain->val, &u8tmp, 1);
+ if (ret)
+ goto err;
+ }
+
+ /* TX LNA gain */
+ if (tx && test_and_clear_bit(TX_LNA_GAIN, &dev->flags)) {
+ dev_dbg(&intf->dev, "TX LNA gain val=%d->%d\n",
+ dev->tx_lna_gain->cur.val, dev->tx_lna_gain->val);
+
+ ret = hackrf_ctrl_msg(dev, CMD_SET_TXVGA_GAIN, 0,
+ dev->tx_lna_gain->val, &u8tmp, 1);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
+ return ret;
+}
+
/* Private functions */
-static struct hackrf_frame_buf *hackrf_get_next_fill_buf(struct hackrf_dev *dev)
+static struct hackrf_buffer *hackrf_get_next_buffer(struct hackrf_dev *dev,
+ struct list_head *buffer_list)
{
unsigned long flags;
- struct hackrf_frame_buf *buf = NULL;
+ struct hackrf_buffer *buffer = NULL;
- spin_lock_irqsave(&dev->queued_bufs_lock, flags);
- if (list_empty(&dev->queued_bufs))
+ spin_lock_irqsave(&dev->buffer_list_lock, flags);
+ if (list_empty(buffer_list))
goto leave;
- buf = list_entry(dev->queued_bufs.next, struct hackrf_frame_buf, list);
- list_del(&buf->list);
+ buffer = list_entry(buffer_list->next, struct hackrf_buffer, list);
+ list_del(&buffer->list);
leave:
- spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);
- return buf;
+ spin_unlock_irqrestore(&dev->buffer_list_lock, flags);
+ return buffer;
}
-static unsigned int hackrf_convert_stream(struct hackrf_dev *dev,
- void *dst, void *src, unsigned int src_len)
+static void hackrf_copy_stream(struct hackrf_dev *dev, void *dst, void *src,
+ unsigned int src_len)
{
memcpy(dst, src, src_len);
@@ -243,22 +472,21 @@ static unsigned int hackrf_convert_stream(struct hackrf_dev *dev,
/* total number of samples */
dev->sample += src_len / 2;
-
- return src_len;
}
/*
* This gets called for the bulk stream pipe. This is done in interrupt
* time, so it has to be fast, not crash, and not stall. Neat.
*/
-static void hackrf_urb_complete(struct urb *urb)
+static void hackrf_urb_complete_in(struct urb *urb)
{
struct hackrf_dev *dev = urb->context;
- struct hackrf_frame_buf *fbuf;
+ struct usb_interface *intf = dev->intf;
+ struct hackrf_buffer *buffer;
+ unsigned int len;
- dev_dbg_ratelimited(dev->dev, "status=%d length=%d/%d errors=%d\n",
- urb->status, urb->actual_length,
- urb->transfer_buffer_length, urb->error_count);
+ dev_dbg_ratelimited(&intf->dev, "status=%d length=%u/%u\n", urb->status,
+ urb->actual_length, urb->transfer_buffer_length);
switch (urb->status) {
case 0: /* success */
@@ -269,33 +497,74 @@ static void hackrf_urb_complete(struct urb *urb)
case -ESHUTDOWN:
return;
default: /* error */
- dev_err_ratelimited(dev->dev, "URB failed %d\n", urb->status);
- break;
+ dev_err_ratelimited(&intf->dev, "URB failed %d\n", urb->status);
+ goto exit_usb_submit_urb;
}
- if (likely(urb->actual_length > 0)) {
- void *ptr;
- unsigned int len;
- /* get free framebuffer */
- fbuf = hackrf_get_next_fill_buf(dev);
- if (unlikely(fbuf == NULL)) {
- dev->vb_full++;
- dev_notice_ratelimited(dev->dev,
- "videobuf is full, %d packets dropped\n",
- dev->vb_full);
- goto skip;
- }
+ /* get buffer to write */
+ buffer = hackrf_get_next_buffer(dev, &dev->rx_buffer_list);
+ if (unlikely(buffer == NULL)) {
+ dev->vb_full++;
+ dev_notice_ratelimited(&intf->dev,
+ "buffer is full - %u packets dropped\n",
+ dev->vb_full);
+ goto exit_usb_submit_urb;
+ }
+
+ len = min_t(unsigned long, vb2_plane_size(&buffer->vb.vb2_buf, 0),
+ urb->actual_length);
+ hackrf_copy_stream(dev, vb2_plane_vaddr(&buffer->vb.vb2_buf, 0),
+ urb->transfer_buffer, len);
+ vb2_set_plane_payload(&buffer->vb.vb2_buf, 0, len);
+ buffer->vb.sequence = dev->sequence++;
+ v4l2_get_timestamp(&buffer->vb.timestamp);
+ vb2_buffer_done(&buffer->vb.vb2_buf, VB2_BUF_STATE_DONE);
+exit_usb_submit_urb:
+ usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static void hackrf_urb_complete_out(struct urb *urb)
+{
+ struct hackrf_dev *dev = urb->context;
+ struct usb_interface *intf = dev->intf;
+ struct hackrf_buffer *buffer;
+ unsigned int len;
+
+ dev_dbg_ratelimited(&intf->dev, "status=%d length=%u/%u\n", urb->status,
+ urb->actual_length, urb->transfer_buffer_length);
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dev_err_ratelimited(&intf->dev, "URB failed %d\n", urb->status);
+ }
- /* fill framebuffer */
- ptr = vb2_plane_vaddr(&fbuf->vb, 0);
- len = hackrf_convert_stream(dev, ptr, urb->transfer_buffer,
- urb->actual_length);
- vb2_set_plane_payload(&fbuf->vb, 0, len);
- v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);
- fbuf->vb.v4l2_buf.sequence = dev->sequence++;
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ /* get buffer to read */
+ buffer = hackrf_get_next_buffer(dev, &dev->tx_buffer_list);
+ if (unlikely(buffer == NULL)) {
+ dev->vb_empty++;
+ dev_notice_ratelimited(&intf->dev,
+ "buffer is empty - %u packets dropped\n",
+ dev->vb_empty);
+ urb->actual_length = 0;
+ goto exit_usb_submit_urb;
}
-skip:
+
+ len = min_t(unsigned long, urb->transfer_buffer_length,
+ vb2_get_plane_payload(&buffer->vb.vb2_buf, 0));
+ hackrf_copy_stream(dev, urb->transfer_buffer,
+ vb2_plane_vaddr(&buffer->vb.vb2_buf, 0), len);
+ urb->actual_length = len;
+ buffer->vb.sequence = dev->sequence++;
+ v4l2_get_timestamp(&buffer->vb.timestamp);
+ vb2_buffer_done(&buffer->vb.vb2_buf, VB2_BUF_STATE_DONE);
+exit_usb_submit_urb:
usb_submit_urb(urb, GFP_ATOMIC);
}
@@ -394,9 +663,19 @@ static int hackrf_free_urbs(struct hackrf_dev *dev)
return 0;
}
-static int hackrf_alloc_urbs(struct hackrf_dev *dev)
+static int hackrf_alloc_urbs(struct hackrf_dev *dev, bool rcv)
{
int i, j;
+ unsigned int pipe;
+ usb_complete_t complete;
+
+ if (rcv) {
+ pipe = usb_rcvbulkpipe(dev->udev, 0x81);
+ complete = &hackrf_urb_complete_in;
+ } else {
+ pipe = usb_sndbulkpipe(dev->udev, 0x02);
+ complete = &hackrf_urb_complete_out;
+ }
/* allocate the URBs */
for (i = 0; i < MAX_BULK_BUFS; i++) {
@@ -410,10 +689,10 @@ static int hackrf_alloc_urbs(struct hackrf_dev *dev)
}
usb_fill_bulk_urb(dev->urb_list[i],
dev->udev,
- usb_rcvbulkpipe(dev->udev, 0x81),
+ pipe,
dev->buf_list[i],
BULK_BUFFER_SIZE,
- hackrf_urb_complete, dev);
+ complete, dev);
dev->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
dev->urb_list[i]->transfer_dma = dev->dma_addr[i];
@@ -423,25 +702,6 @@ static int hackrf_alloc_urbs(struct hackrf_dev *dev)
return 0;
}
-/* Must be called with vb_queue_lock hold */
-static void hackrf_cleanup_queued_bufs(struct hackrf_dev *dev)
-{
- unsigned long flags;
-
- dev_dbg(dev->dev, "\n");
-
- spin_lock_irqsave(&dev->queued_bufs_lock, flags);
- while (!list_empty(&dev->queued_bufs)) {
- struct hackrf_frame_buf *buf;
-
- buf = list_entry(dev->queued_bufs.next,
- struct hackrf_frame_buf, list);
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);
-}
-
/* The user yanked out the cable... */
static void hackrf_disconnect(struct usb_interface *intf)
{
@@ -455,7 +715,8 @@ static void hackrf_disconnect(struct usb_interface *intf)
/* No need to keep the urbs around after disconnection */
dev->udev = NULL;
v4l2_device_disconnect(&dev->v4l2_dev);
- video_unregister_device(&dev->vdev);
+ video_unregister_device(&dev->tx_vdev);
+ video_unregister_device(&dev->rx_vdev);
mutex_unlock(&dev->v4l2_lock);
mutex_unlock(&dev->vb_queue_lock);
@@ -463,8 +724,33 @@ static void hackrf_disconnect(struct usb_interface *intf)
}
/* Videobuf2 operations */
+static void hackrf_return_all_buffers(struct vb2_queue *vq,
+ enum vb2_buffer_state state)
+{
+ struct hackrf_dev *dev = vb2_get_drv_priv(vq);
+ struct usb_interface *intf = dev->intf;
+ struct hackrf_buffer *buffer, *node;
+ struct list_head *buffer_list;
+ unsigned long flags;
+
+ dev_dbg(&intf->dev, "\n");
+
+ if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE)
+ buffer_list = &dev->rx_buffer_list;
+ else
+ buffer_list = &dev->tx_buffer_list;
+
+ spin_lock_irqsave(&dev->buffer_list_lock, flags);
+ list_for_each_entry_safe(buffer, node, buffer_list, list) {
+ dev_dbg(&intf->dev, "list_for_each_entry_safe\n");
+ vb2_buffer_done(&buffer->vb.vb2_buf, state);
+ list_del(&buffer->list);
+ }
+ spin_unlock_irqrestore(&dev->buffer_list_lock, flags);
+}
+
static int hackrf_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbuffers,
+ const void *parg, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
struct hackrf_dev *dev = vb2_get_drv_priv(vq);
@@ -483,37 +769,62 @@ static int hackrf_queue_setup(struct vb2_queue *vq,
static void hackrf_buf_queue(struct vb2_buffer *vb)
{
- struct hackrf_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct hackrf_frame_buf *buf =
- container_of(vb, struct hackrf_frame_buf, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct hackrf_dev *dev = vb2_get_drv_priv(vq);
+ struct hackrf_buffer *buffer = container_of(vbuf, struct hackrf_buffer, vb);
+ struct list_head *buffer_list;
unsigned long flags;
- spin_lock_irqsave(&dev->queued_bufs_lock, flags);
- list_add_tail(&buf->list, &dev->queued_bufs);
- spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);
+ dev_dbg_ratelimited(&dev->intf->dev, "\n");
+
+ if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE)
+ buffer_list = &dev->rx_buffer_list;
+ else
+ buffer_list = &dev->tx_buffer_list;
+
+ spin_lock_irqsave(&dev->buffer_list_lock, flags);
+ list_add_tail(&buffer->list, buffer_list);
+ spin_unlock_irqrestore(&dev->buffer_list_lock, flags);
}
static int hackrf_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct hackrf_dev *dev = vb2_get_drv_priv(vq);
+ struct usb_interface *intf = dev->intf;
int ret;
+ unsigned int mode;
- dev_dbg(dev->dev, "\n");
-
- if (!dev->udev)
- return -ENODEV;
+ dev_dbg(&intf->dev, "count=%i\n", count);
mutex_lock(&dev->v4l2_lock);
- dev->sequence = 0;
+ /* Allow only RX or TX, not both same time */
+ if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE) {
+ if (test_bit(TX_ON, &dev->flags)) {
+ ret = -EBUSY;
+ goto err_hackrf_return_all_buffers;
+ }
+
+ mode = 1;
+ set_bit(RX_ON, &dev->flags);
+ } else {
+ if (test_bit(RX_ON, &dev->flags)) {
+ ret = -EBUSY;
+ goto err_hackrf_return_all_buffers;
+ }
+
+ mode = 2;
+ set_bit(TX_ON, &dev->flags);
+ }
- set_bit(POWER_ON, &dev->flags);
+ dev->sequence = 0;
ret = hackrf_alloc_stream_bufs(dev);
if (ret)
goto err;
- ret = hackrf_alloc_urbs(dev);
+ ret = hackrf_alloc_urbs(dev, (mode == 1));
if (ret)
goto err;
@@ -521,39 +832,37 @@ static int hackrf_start_streaming(struct vb2_queue *vq, unsigned int count)
if (ret)
goto err;
+ ret = hackrf_set_params(dev);
+ if (ret)
+ goto err;
+
/* start hardware streaming */
- ret = hackrf_ctrl_msg(dev, CMD_SET_TRANSCEIVER_MODE, 1, 0, NULL, 0);
+ ret = hackrf_ctrl_msg(dev, CMD_SET_TRANSCEIVER_MODE, mode, 0, NULL, 0);
if (ret)
goto err;
- goto exit_mutex_unlock;
+ mutex_unlock(&dev->v4l2_lock);
+
+ return 0;
err:
hackrf_kill_urbs(dev);
hackrf_free_urbs(dev);
hackrf_free_stream_bufs(dev);
- clear_bit(POWER_ON, &dev->flags);
-
- /* return all queued buffers to vb2 */
- {
- struct hackrf_frame_buf *buf, *tmp;
-
- list_for_each_entry_safe(buf, tmp, &dev->queued_bufs, list) {
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
- }
- }
-
-exit_mutex_unlock:
+ clear_bit(RX_ON, &dev->flags);
+ clear_bit(TX_ON, &dev->flags);
+err_hackrf_return_all_buffers:
+ hackrf_return_all_buffers(vq, VB2_BUF_STATE_QUEUED);
mutex_unlock(&dev->v4l2_lock);
-
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
static void hackrf_stop_streaming(struct vb2_queue *vq)
{
struct hackrf_dev *dev = vb2_get_drv_priv(vq);
+ struct usb_interface *intf = dev->intf;
- dev_dbg(dev->dev, "\n");
+ dev_dbg(&intf->dev, "\n");
mutex_lock(&dev->v4l2_lock);
@@ -564,9 +873,12 @@ static void hackrf_stop_streaming(struct vb2_queue *vq)
hackrf_free_urbs(dev);
hackrf_free_stream_bufs(dev);
- hackrf_cleanup_queued_bufs(dev);
+ hackrf_return_all_buffers(vq, VB2_BUF_STATE_ERROR);
- clear_bit(POWER_ON, &dev->flags);
+ if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE)
+ clear_bit(RX_ON, &dev->flags);
+ else
+ clear_bit(TX_ON, &dev->flags);
mutex_unlock(&dev->v4l2_lock);
}
@@ -584,29 +896,46 @@ static int hackrf_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
struct hackrf_dev *dev = video_drvdata(file);
+ struct usb_interface *intf = dev->intf;
+ struct video_device *vdev = video_devdata(file);
- dev_dbg(dev->dev, "\n");
+ dev_dbg(&intf->dev, "\n");
+
+ if (vdev->vfl_dir == VFL_DIR_RX)
+ cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER |
+ V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+ else
+ cap->device_caps = V4L2_CAP_SDR_OUTPUT | V4L2_CAP_MODULATOR |
+ V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+
+ cap->capabilities = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER |
+ V4L2_CAP_SDR_OUTPUT | V4L2_CAP_MODULATOR |
+ V4L2_CAP_STREAMING | V4L2_CAP_READWRITE |
+ V4L2_CAP_DEVICE_CAPS;
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
- strlcpy(cap->card, dev->vdev.name, sizeof(cap->card));
+ strlcpy(cap->card, dev->rx_vdev.name, sizeof(cap->card));
usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
-static int hackrf_s_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+static int hackrf_s_fmt_sdr(struct file *file, void *priv,
+ struct v4l2_format *f)
{
struct hackrf_dev *dev = video_drvdata(file);
- struct vb2_queue *q = &dev->vb_queue;
+ struct video_device *vdev = video_devdata(file);
+ struct vb2_queue *q;
int i;
dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n",
(char *)&f->fmt.sdr.pixelformat);
+ if (vdev->vfl_dir == VFL_DIR_RX)
+ q = &dev->rx_vb2_queue;
+ else
+ q = &dev->tx_vb2_queue;
+
if (vb2_is_busy(q))
return -EBUSY;
@@ -628,8 +957,8 @@ static int hackrf_s_fmt_sdr_cap(struct file *file, void *priv,
return 0;
}
-static int hackrf_g_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+static int hackrf_g_fmt_sdr(struct file *file, void *priv,
+ struct v4l2_format *f)
{
struct hackrf_dev *dev = video_drvdata(file);
@@ -643,8 +972,8 @@ static int hackrf_g_fmt_sdr_cap(struct file *file, void *priv,
return 0;
}
-static int hackrf_try_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+static int hackrf_try_fmt_sdr(struct file *file, void *priv,
+ struct v4l2_format *f)
{
struct hackrf_dev *dev = video_drvdata(file);
int i;
@@ -666,8 +995,8 @@ static int hackrf_try_fmt_sdr_cap(struct file *file, void *priv,
return 0;
}
-static int hackrf_enum_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
+static int hackrf_enum_fmt_sdr(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
{
struct hackrf_dev *dev = video_drvdata(file);
@@ -676,7 +1005,6 @@ static int hackrf_enum_fmt_sdr_cap(struct file *file, void *priv,
if (f->index >= NUM_FORMATS)
return -EINVAL;
- strlcpy(f->description, formats[f->index].name, sizeof(f->description));
f->pixelformat = formats[f->index].pixelformat;
return 0;
@@ -709,17 +1037,56 @@ static int hackrf_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
if (v->index == 0) {
strlcpy(v->name, "HackRF ADC", sizeof(v->name));
- v->type = V4L2_TUNER_ADC;
+ v->type = V4L2_TUNER_SDR;
v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = bands_adc[0].rangelow;
- v->rangehigh = bands_adc[0].rangehigh;
+ v->rangelow = bands_adc_dac[0].rangelow;
+ v->rangehigh = bands_adc_dac[0].rangehigh;
ret = 0;
} else if (v->index == 1) {
strlcpy(v->name, "HackRF RF", sizeof(v->name));
v->type = V4L2_TUNER_RF;
v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = bands_rf[0].rangelow;
- v->rangehigh = bands_rf[0].rangehigh;
+ v->rangelow = bands_rx_tx[0].rangelow;
+ v->rangehigh = bands_rx_tx[0].rangehigh;
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int hackrf_s_modulator(struct file *file, void *fh,
+ const struct v4l2_modulator *a)
+{
+ struct hackrf_dev *dev = video_drvdata(file);
+
+ dev_dbg(dev->dev, "index=%d\n", a->index);
+
+ return a->index > 1 ? -EINVAL : 0;
+}
+
+static int hackrf_g_modulator(struct file *file, void *fh,
+ struct v4l2_modulator *a)
+{
+ struct hackrf_dev *dev = video_drvdata(file);
+ int ret;
+
+ dev_dbg(dev->dev, "index=%d\n", a->index);
+
+ if (a->index == 0) {
+ strlcpy(a->name, "HackRF DAC", sizeof(a->name));
+ a->type = V4L2_TUNER_SDR;
+ a->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ a->rangelow = bands_adc_dac[0].rangelow;
+ a->rangehigh = bands_adc_dac[0].rangehigh;
+ ret = 0;
+ } else if (a->index == 1) {
+ strlcpy(a->name, "HackRF RF", sizeof(a->name));
+ a->type = V4L2_TUNER_RF;
+ a->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ a->rangelow = bands_rx_tx[0].rangelow;
+ a->rangehigh = bands_rx_tx[0].rangehigh;
ret = 0;
} else {
ret = -EINVAL;
@@ -732,47 +1099,46 @@ static int hackrf_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct hackrf_dev *dev = video_drvdata(file);
+ struct usb_interface *intf = dev->intf;
+ struct video_device *vdev = video_devdata(file);
int ret;
- unsigned int upper, lower;
- u8 buf[8];
+ unsigned int uitmp;
- dev_dbg(dev->dev, "tuner=%d type=%d frequency=%u\n",
+ dev_dbg(&intf->dev, "tuner=%d type=%d frequency=%u\n",
f->tuner, f->type, f->frequency);
if (f->tuner == 0) {
- dev->f_adc = clamp_t(unsigned int, f->frequency,
- bands_adc[0].rangelow, bands_adc[0].rangehigh);
- dev_dbg(dev->dev, "ADC frequency=%u Hz\n", dev->f_adc);
- upper = dev->f_adc;
- lower = 1;
- buf[0] = (upper >> 0) & 0xff;
- buf[1] = (upper >> 8) & 0xff;
- buf[2] = (upper >> 16) & 0xff;
- buf[3] = (upper >> 24) & 0xff;
- buf[4] = (lower >> 0) & 0xff;
- buf[5] = (lower >> 8) & 0xff;
- buf[6] = (lower >> 16) & 0xff;
- buf[7] = (lower >> 24) & 0xff;
- ret = hackrf_ctrl_msg(dev, CMD_SAMPLE_RATE_SET, 0, 0, buf, 8);
+ uitmp = clamp(f->frequency, bands_adc_dac[0].rangelow,
+ bands_adc_dac[0].rangehigh);
+ if (vdev->vfl_dir == VFL_DIR_RX) {
+ dev->f_adc = uitmp;
+ set_bit(RX_ADC_FREQUENCY, &dev->flags);
+ } else {
+ dev->f_dac = uitmp;
+ set_bit(TX_DAC_FREQUENCY, &dev->flags);
+ }
} else if (f->tuner == 1) {
- dev->f_rf = clamp_t(unsigned int, f->frequency,
- bands_rf[0].rangelow, bands_rf[0].rangehigh);
- dev_dbg(dev->dev, "RF frequency=%u Hz\n", dev->f_rf);
- upper = dev->f_rf / 1000000;
- lower = dev->f_rf % 1000000;
- buf[0] = (upper >> 0) & 0xff;
- buf[1] = (upper >> 8) & 0xff;
- buf[2] = (upper >> 16) & 0xff;
- buf[3] = (upper >> 24) & 0xff;
- buf[4] = (lower >> 0) & 0xff;
- buf[5] = (lower >> 8) & 0xff;
- buf[6] = (lower >> 16) & 0xff;
- buf[7] = (lower >> 24) & 0xff;
- ret = hackrf_ctrl_msg(dev, CMD_SET_FREQ, 0, 0, buf, 8);
+ uitmp = clamp(f->frequency, bands_rx_tx[0].rangelow,
+ bands_rx_tx[0].rangehigh);
+ if (vdev->vfl_dir == VFL_DIR_RX) {
+ dev->f_rx = uitmp;
+ set_bit(RX_RF_FREQUENCY, &dev->flags);
+ } else {
+ dev->f_tx = uitmp;
+ set_bit(TX_RF_FREQUENCY, &dev->flags);
+ }
} else {
ret = -EINVAL;
+ goto err;
}
+ ret = hackrf_set_params(dev);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
@@ -780,22 +1146,32 @@ static int hackrf_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct hackrf_dev *dev = video_drvdata(file);
+ struct usb_interface *intf = dev->intf;
+ struct video_device *vdev = video_devdata(file);
int ret;
dev_dbg(dev->dev, "tuner=%d type=%d\n", f->tuner, f->type);
if (f->tuner == 0) {
- f->type = V4L2_TUNER_ADC;
- f->frequency = dev->f_adc;
- ret = 0;
+ f->type = V4L2_TUNER_SDR;
+ if (vdev->vfl_dir == VFL_DIR_RX)
+ f->frequency = dev->f_adc;
+ else
+ f->frequency = dev->f_dac;
} else if (f->tuner == 1) {
f->type = V4L2_TUNER_RF;
- f->frequency = dev->f_rf;
- ret = 0;
+ if (vdev->vfl_dir == VFL_DIR_RX)
+ f->frequency = dev->f_rx;
+ else
+ f->frequency = dev->f_tx;
} else {
ret = -EINVAL;
+ goto err;
}
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
@@ -809,17 +1185,17 @@ static int hackrf_enum_freq_bands(struct file *file, void *priv,
band->tuner, band->type, band->index);
if (band->tuner == 0) {
- if (band->index >= ARRAY_SIZE(bands_adc)) {
+ if (band->index >= ARRAY_SIZE(bands_adc_dac)) {
ret = -EINVAL;
} else {
- *band = bands_adc[band->index];
+ *band = bands_adc_dac[band->index];
ret = 0;
}
} else if (band->tuner == 1) {
- if (band->index >= ARRAY_SIZE(bands_rf)) {
+ if (band->index >= ARRAY_SIZE(bands_rx_tx)) {
ret = -EINVAL;
} else {
- *band = bands_rf[band->index];
+ *band = bands_rx_tx[band->index];
ret = 0;
}
} else {
@@ -832,10 +1208,15 @@ static int hackrf_enum_freq_bands(struct file *file, void *priv,
static const struct v4l2_ioctl_ops hackrf_ioctl_ops = {
.vidioc_querycap = hackrf_querycap,
- .vidioc_s_fmt_sdr_cap = hackrf_s_fmt_sdr_cap,
- .vidioc_g_fmt_sdr_cap = hackrf_g_fmt_sdr_cap,
- .vidioc_enum_fmt_sdr_cap = hackrf_enum_fmt_sdr_cap,
- .vidioc_try_fmt_sdr_cap = hackrf_try_fmt_sdr_cap,
+ .vidioc_s_fmt_sdr_cap = hackrf_s_fmt_sdr,
+ .vidioc_g_fmt_sdr_cap = hackrf_g_fmt_sdr,
+ .vidioc_enum_fmt_sdr_cap = hackrf_enum_fmt_sdr,
+ .vidioc_try_fmt_sdr_cap = hackrf_try_fmt_sdr,
+
+ .vidioc_s_fmt_sdr_out = hackrf_s_fmt_sdr,
+ .vidioc_g_fmt_sdr_out = hackrf_g_fmt_sdr,
+ .vidioc_enum_fmt_sdr_out = hackrf_enum_fmt_sdr,
+ .vidioc_try_fmt_sdr_out = hackrf_try_fmt_sdr,
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
@@ -843,6 +1224,7 @@ static const struct v4l2_ioctl_ops hackrf_ioctl_ops = {
.vidioc_querybuf = vb2_ioctl_querybuf,
.vidioc_qbuf = vb2_ioctl_qbuf,
.vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
@@ -850,6 +1232,9 @@ static const struct v4l2_ioctl_ops hackrf_ioctl_ops = {
.vidioc_s_tuner = hackrf_s_tuner,
.vidioc_g_tuner = hackrf_g_tuner,
+ .vidioc_s_modulator = hackrf_s_modulator,
+ .vidioc_g_modulator = hackrf_g_modulator,
+
.vidioc_s_frequency = hackrf_s_frequency,
.vidioc_g_frequency = hackrf_g_frequency,
.vidioc_enum_freq_bands = hackrf_enum_freq_bands,
@@ -864,6 +1249,7 @@ static const struct v4l2_file_operations hackrf_fops = {
.open = v4l2_fh_open,
.release = vb2_fop_release,
.read = vb2_fop_read,
+ .write = vb2_fop_write,
.poll = vb2_fop_poll,
.mmap = vb2_fop_mmap,
.unlocked_ioctl = video_ioctl2,
@@ -880,135 +1266,93 @@ static void hackrf_video_release(struct v4l2_device *v)
{
struct hackrf_dev *dev = container_of(v, struct hackrf_dev, v4l2_dev);
- v4l2_ctrl_handler_free(&dev->hdl);
+ dev_dbg(dev->dev, "\n");
+
+ v4l2_ctrl_handler_free(&dev->rx_ctrl_handler);
+ v4l2_ctrl_handler_free(&dev->tx_ctrl_handler);
v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev);
}
-static int hackrf_set_bandwidth(struct hackrf_dev *dev)
-{
- int ret, i;
- u16 u16tmp, u16tmp2;
- unsigned int bandwidth;
-
- static const struct {
- u32 freq;
- } bandwidth_lut[] = {
- { 1750000}, /* 1.75 MHz */
- { 2500000}, /* 2.5 MHz */
- { 3500000}, /* 3.5 MHz */
- { 5000000}, /* 5 MHz */
- { 5500000}, /* 5.5 MHz */
- { 6000000}, /* 6 MHz */
- { 7000000}, /* 7 MHz */
- { 8000000}, /* 8 MHz */
- { 9000000}, /* 9 MHz */
- {10000000}, /* 10 MHz */
- {12000000}, /* 12 MHz */
- {14000000}, /* 14 MHz */
- {15000000}, /* 15 MHz */
- {20000000}, /* 20 MHz */
- {24000000}, /* 24 MHz */
- {28000000}, /* 28 MHz */
- };
-
- dev_dbg(dev->dev, "bandwidth auto=%d->%d val=%d->%d f_adc=%u\n",
- dev->bandwidth_auto->cur.val,
- dev->bandwidth_auto->val, dev->bandwidth->cur.val,
- dev->bandwidth->val, dev->f_adc);
-
- if (dev->bandwidth_auto->val == true)
- bandwidth = dev->f_adc;
- else
- bandwidth = dev->bandwidth->val;
-
- for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
- if (bandwidth <= bandwidth_lut[i].freq) {
- bandwidth = bandwidth_lut[i].freq;
- break;
- }
- }
-
- dev->bandwidth->val = bandwidth;
- dev->bandwidth->cur.val = bandwidth;
-
- dev_dbg(dev->dev, "bandwidth selected=%d\n", bandwidth);
-
- u16tmp = 0;
- u16tmp |= ((bandwidth >> 0) & 0xff) << 0;
- u16tmp |= ((bandwidth >> 8) & 0xff) << 8;
- u16tmp2 = 0;
- u16tmp2 |= ((bandwidth >> 16) & 0xff) << 0;
- u16tmp2 |= ((bandwidth >> 24) & 0xff) << 8;
-
- ret = hackrf_ctrl_msg(dev, CMD_BASEBAND_FILTER_BANDWIDTH_SET,
- u16tmp, u16tmp2, NULL, 0);
- if (ret)
- dev_dbg(dev->dev, "failed=%d\n", ret);
-
- return ret;
-}
-
-static int hackrf_set_lna_gain(struct hackrf_dev *dev)
-{
- int ret;
- u8 u8tmp;
-
- dev_dbg(dev->dev, "lna val=%d->%d\n",
- dev->lna_gain->cur.val, dev->lna_gain->val);
-
- ret = hackrf_ctrl_msg(dev, CMD_SET_LNA_GAIN, 0, dev->lna_gain->val,
- &u8tmp, 1);
- if (ret)
- dev_dbg(dev->dev, "failed=%d\n", ret);
-
- return ret;
-}
-
-static int hackrf_set_if_gain(struct hackrf_dev *dev)
+static int hackrf_s_ctrl_rx(struct v4l2_ctrl *ctrl)
{
+ struct hackrf_dev *dev = container_of(ctrl->handler,
+ struct hackrf_dev, rx_ctrl_handler);
+ struct usb_interface *intf = dev->intf;
int ret;
- u8 u8tmp;
- dev_dbg(dev->dev, "val=%d->%d\n",
- dev->if_gain->cur.val, dev->if_gain->val);
+ switch (ctrl->id) {
+ case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
+ case V4L2_CID_RF_TUNER_BANDWIDTH:
+ set_bit(RX_BANDWIDTH, &dev->flags);
+ break;
+ case V4L2_CID_RF_TUNER_RF_GAIN:
+ set_bit(RX_RF_GAIN, &dev->flags);
+ break;
+ case V4L2_CID_RF_TUNER_LNA_GAIN:
+ set_bit(RX_LNA_GAIN, &dev->flags);
+ break;
+ case V4L2_CID_RF_TUNER_IF_GAIN:
+ set_bit(RX_IF_GAIN, &dev->flags);
+ break;
+ default:
+ dev_dbg(&intf->dev, "unknown ctrl: id=%d name=%s\n",
+ ctrl->id, ctrl->name);
+ ret = -EINVAL;
+ goto err;
+ }
- ret = hackrf_ctrl_msg(dev, CMD_SET_VGA_GAIN, 0, dev->if_gain->val,
- &u8tmp, 1);
+ ret = hackrf_set_params(dev);
if (ret)
- dev_dbg(dev->dev, "failed=%d\n", ret);
+ goto err;
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
-static int hackrf_s_ctrl(struct v4l2_ctrl *ctrl)
+static int hackrf_s_ctrl_tx(struct v4l2_ctrl *ctrl)
{
struct hackrf_dev *dev = container_of(ctrl->handler,
- struct hackrf_dev, hdl);
+ struct hackrf_dev, tx_ctrl_handler);
+ struct usb_interface *intf = dev->intf;
int ret;
switch (ctrl->id) {
case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
case V4L2_CID_RF_TUNER_BANDWIDTH:
- ret = hackrf_set_bandwidth(dev);
+ set_bit(TX_BANDWIDTH, &dev->flags);
break;
case V4L2_CID_RF_TUNER_LNA_GAIN:
- ret = hackrf_set_lna_gain(dev);
+ set_bit(TX_LNA_GAIN, &dev->flags);
break;
- case V4L2_CID_RF_TUNER_IF_GAIN:
- ret = hackrf_set_if_gain(dev);
+ case V4L2_CID_RF_TUNER_RF_GAIN:
+ set_bit(TX_RF_GAIN, &dev->flags);
break;
default:
- dev_dbg(dev->dev, "unknown ctrl: id=%d name=%s\n",
- ctrl->id, ctrl->name);
+ dev_dbg(&intf->dev, "unknown ctrl: id=%d name=%s\n",
+ ctrl->id, ctrl->name);
ret = -EINVAL;
+ goto err;
}
+ ret = hackrf_set_params(dev);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
-static const struct v4l2_ctrl_ops hackrf_ctrl_ops = {
- .s_ctrl = hackrf_s_ctrl,
+static const struct v4l2_ctrl_ops hackrf_ctrl_ops_rx = {
+ .s_ctrl = hackrf_s_ctrl_rx,
+};
+
+static const struct v4l2_ctrl_ops hackrf_ctrl_ops_tx = {
+ .s_ctrl = hackrf_s_ctrl_tx,
};
static int hackrf_probe(struct usb_interface *intf,
@@ -1019,19 +1363,29 @@ static int hackrf_probe(struct usb_interface *intf,
u8 u8tmp, buf[BUF_SIZE];
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- return -ENOMEM;
+ if (!dev) {
+ ret = -ENOMEM;
+ goto err;
+ }
mutex_init(&dev->v4l2_lock);
mutex_init(&dev->vb_queue_lock);
- spin_lock_init(&dev->queued_bufs_lock);
- INIT_LIST_HEAD(&dev->queued_bufs);
+ spin_lock_init(&dev->buffer_list_lock);
+ INIT_LIST_HEAD(&dev->rx_buffer_list);
+ INIT_LIST_HEAD(&dev->tx_buffer_list);
+ dev->intf = intf;
dev->dev = &intf->dev;
dev->udev = interface_to_usbdev(intf);
- dev->f_adc = bands_adc[0].rangelow;
- dev->f_rf = bands_rf[0].rangelow;
dev->pixelformat = formats[0].pixelformat;
dev->buffersize = formats[0].buffersize;
+ dev->f_adc = bands_adc_dac[0].rangelow;
+ dev->f_dac = bands_adc_dac[0].rangelow;
+ dev->f_rx = bands_rx_tx[0].rangelow;
+ dev->f_tx = bands_rx_tx[0].rangelow;
+ set_bit(RX_ADC_FREQUENCY, &dev->flags);
+ set_bit(TX_DAC_FREQUENCY, &dev->flags);
+ set_bit(RX_RF_FREQUENCY, &dev->flags);
+ set_bit(TX_RF_FREQUENCY, &dev->flags);
/* Detect device */
ret = hackrf_ctrl_msg(dev, CMD_BOARD_ID_READ, 0, 0, &u8tmp, 1);
@@ -1040,83 +1394,143 @@ static int hackrf_probe(struct usb_interface *intf,
buf, BUF_SIZE);
if (ret) {
dev_err(dev->dev, "Could not detect board\n");
- goto err_free_mem;
+ goto err_kfree;
}
buf[BUF_SIZE - 1] = '\0';
-
dev_info(dev->dev, "Board ID: %02x\n", u8tmp);
dev_info(dev->dev, "Firmware version: %s\n", buf);
- /* Init videobuf2 queue structure */
- dev->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
- dev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- dev->vb_queue.drv_priv = dev;
- dev->vb_queue.buf_struct_size = sizeof(struct hackrf_frame_buf);
- dev->vb_queue.ops = &hackrf_vb2_ops;
- dev->vb_queue.mem_ops = &vb2_vmalloc_memops;
- dev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- ret = vb2_queue_init(&dev->vb_queue);
+ /* Init vb2 queue structure for receiver */
+ dev->rx_vb2_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
+ dev->rx_vb2_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF |
+ VB2_READ;
+ dev->rx_vb2_queue.ops = &hackrf_vb2_ops;
+ dev->rx_vb2_queue.mem_ops = &vb2_vmalloc_memops;
+ dev->rx_vb2_queue.drv_priv = dev;
+ dev->rx_vb2_queue.buf_struct_size = sizeof(struct hackrf_buffer);
+ dev->rx_vb2_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ ret = vb2_queue_init(&dev->rx_vb2_queue);
if (ret) {
- dev_err(dev->dev, "Could not initialize vb2 queue\n");
- goto err_free_mem;
+ dev_err(dev->dev, "Could not initialize rx vb2 queue\n");
+ goto err_kfree;
}
- /* Init video_device structure */
- dev->vdev = hackrf_template;
- dev->vdev.queue = &dev->vb_queue;
- dev->vdev.queue->lock = &dev->vb_queue_lock;
- video_set_drvdata(&dev->vdev, dev);
+ /* Init vb2 queue structure for transmitter */
+ dev->tx_vb2_queue.type = V4L2_BUF_TYPE_SDR_OUTPUT;
+ dev->tx_vb2_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF |
+ VB2_WRITE;
+ dev->tx_vb2_queue.ops = &hackrf_vb2_ops;
+ dev->tx_vb2_queue.mem_ops = &vb2_vmalloc_memops;
+ dev->tx_vb2_queue.drv_priv = dev;
+ dev->tx_vb2_queue.buf_struct_size = sizeof(struct hackrf_buffer);
+ dev->tx_vb2_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ ret = vb2_queue_init(&dev->tx_vb2_queue);
+ if (ret) {
+ dev_err(dev->dev, "Could not initialize tx vb2 queue\n");
+ goto err_kfree;
+ }
+
+ /* Register controls for receiver */
+ v4l2_ctrl_handler_init(&dev->rx_ctrl_handler, 5);
+ dev->rx_bandwidth_auto = v4l2_ctrl_new_std(&dev->rx_ctrl_handler,
+ &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
+ 0, 1, 0, 1);
+ dev->rx_bandwidth = v4l2_ctrl_new_std(&dev->rx_ctrl_handler,
+ &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_BANDWIDTH,
+ 1750000, 28000000, 50000, 1750000);
+ v4l2_ctrl_auto_cluster(2, &dev->rx_bandwidth_auto, 0, false);
+ dev->rx_rf_gain = v4l2_ctrl_new_std(&dev->rx_ctrl_handler,
+ &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_RF_GAIN, 0, 12, 12, 0);
+ dev->rx_lna_gain = v4l2_ctrl_new_std(&dev->rx_ctrl_handler,
+ &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 40, 8, 0);
+ dev->rx_if_gain = v4l2_ctrl_new_std(&dev->rx_ctrl_handler,
+ &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_IF_GAIN, 0, 62, 2, 0);
+ if (dev->rx_ctrl_handler.error) {
+ ret = dev->rx_ctrl_handler.error;
+ dev_err(dev->dev, "Could not initialize controls\n");
+ goto err_v4l2_ctrl_handler_free_rx;
+ }
+ v4l2_ctrl_handler_setup(&dev->rx_ctrl_handler);
+
+ /* Register controls for transmitter */
+ v4l2_ctrl_handler_init(&dev->tx_ctrl_handler, 4);
+ dev->tx_bandwidth_auto = v4l2_ctrl_new_std(&dev->tx_ctrl_handler,
+ &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
+ 0, 1, 0, 1);
+ dev->tx_bandwidth = v4l2_ctrl_new_std(&dev->tx_ctrl_handler,
+ &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_BANDWIDTH,
+ 1750000, 28000000, 50000, 1750000);
+ v4l2_ctrl_auto_cluster(2, &dev->tx_bandwidth_auto, 0, false);
+ dev->tx_lna_gain = v4l2_ctrl_new_std(&dev->tx_ctrl_handler,
+ &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 47, 1, 0);
+ dev->tx_rf_gain = v4l2_ctrl_new_std(&dev->tx_ctrl_handler,
+ &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_RF_GAIN, 0, 15, 15, 0);
+ if (dev->tx_ctrl_handler.error) {
+ ret = dev->tx_ctrl_handler.error;
+ dev_err(dev->dev, "Could not initialize controls\n");
+ goto err_v4l2_ctrl_handler_free_tx;
+ }
+ v4l2_ctrl_handler_setup(&dev->tx_ctrl_handler);
/* Register the v4l2_device structure */
dev->v4l2_dev.release = hackrf_video_release;
ret = v4l2_device_register(&intf->dev, &dev->v4l2_dev);
if (ret) {
dev_err(dev->dev, "Failed to register v4l2-device (%d)\n", ret);
- goto err_free_mem;
+ goto err_v4l2_ctrl_handler_free_tx;
}
- /* Register controls */
- v4l2_ctrl_handler_init(&dev->hdl, 4);
- dev->bandwidth_auto = v4l2_ctrl_new_std(&dev->hdl, &hackrf_ctrl_ops,
- V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
- dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &hackrf_ctrl_ops,
- V4L2_CID_RF_TUNER_BANDWIDTH,
- 1750000, 28000000, 50000, 1750000);
- v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false);
- dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &hackrf_ctrl_ops,
- V4L2_CID_RF_TUNER_LNA_GAIN, 0, 40, 8, 0);
- dev->if_gain = v4l2_ctrl_new_std(&dev->hdl, &hackrf_ctrl_ops,
- V4L2_CID_RF_TUNER_IF_GAIN, 0, 62, 2, 0);
- if (dev->hdl.error) {
- ret = dev->hdl.error;
- dev_err(dev->dev, "Could not initialize controls\n");
- goto err_free_controls;
+ /* Init video_device structure for receiver */
+ dev->rx_vdev = hackrf_template;
+ dev->rx_vdev.queue = &dev->rx_vb2_queue;
+ dev->rx_vdev.queue->lock = &dev->vb_queue_lock;
+ dev->rx_vdev.v4l2_dev = &dev->v4l2_dev;
+ dev->rx_vdev.ctrl_handler = &dev->rx_ctrl_handler;
+ dev->rx_vdev.lock = &dev->v4l2_lock;
+ dev->rx_vdev.vfl_dir = VFL_DIR_RX;
+ video_set_drvdata(&dev->rx_vdev, dev);
+ ret = video_register_device(&dev->rx_vdev, VFL_TYPE_SDR, -1);
+ if (ret) {
+ dev_err(dev->dev,
+ "Failed to register as video device (%d)\n", ret);
+ goto err_v4l2_device_unregister;
}
-
- v4l2_ctrl_handler_setup(&dev->hdl);
-
- dev->v4l2_dev.ctrl_handler = &dev->hdl;
- dev->vdev.v4l2_dev = &dev->v4l2_dev;
- dev->vdev.lock = &dev->v4l2_lock;
-
- ret = video_register_device(&dev->vdev, VFL_TYPE_SDR, -1);
+ dev_info(dev->dev, "Registered as %s\n",
+ video_device_node_name(&dev->rx_vdev));
+
+ /* Init video_device structure for transmitter */
+ dev->tx_vdev = hackrf_template;
+ dev->tx_vdev.queue = &dev->tx_vb2_queue;
+ dev->tx_vdev.queue->lock = &dev->vb_queue_lock;
+ dev->tx_vdev.v4l2_dev = &dev->v4l2_dev;
+ dev->tx_vdev.ctrl_handler = &dev->tx_ctrl_handler;
+ dev->tx_vdev.lock = &dev->v4l2_lock;
+ dev->tx_vdev.vfl_dir = VFL_DIR_TX;
+ video_set_drvdata(&dev->tx_vdev, dev);
+ ret = video_register_device(&dev->tx_vdev, VFL_TYPE_SDR, -1);
if (ret) {
- dev_err(dev->dev, "Failed to register as video device (%d)\n",
- ret);
- goto err_unregister_v4l2_dev;
+ dev_err(dev->dev,
+ "Failed to register as video device (%d)\n", ret);
+ goto err_video_unregister_device_rx;
}
dev_info(dev->dev, "Registered as %s\n",
- video_device_node_name(&dev->vdev));
+ video_device_node_name(&dev->tx_vdev));
+
dev_notice(dev->dev, "SDR API is still slightly experimental and functionality changes may follow\n");
return 0;
-
-err_free_controls:
- v4l2_ctrl_handler_free(&dev->hdl);
-err_unregister_v4l2_dev:
+err_video_unregister_device_rx:
+ video_unregister_device(&dev->rx_vdev);
+err_v4l2_device_unregister:
v4l2_device_unregister(&dev->v4l2_dev);
-err_free_mem:
+err_v4l2_ctrl_handler_free_tx:
+ v4l2_ctrl_handler_free(&dev->tx_ctrl_handler);
+err_v4l2_ctrl_handler_free_rx:
+ v4l2_ctrl_handler_free(&dev->rx_ctrl_handler);
+err_kfree:
kfree(dev);
+err:
+ dev_dbg(dev->dev, "failed=%d\n", ret);
return ret;
}
diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c
index 3f276d921cca..e06a21a4fbd9 100644
--- a/drivers/media/usb/msi2500/msi2500.c
+++ b/drivers/media/usb/msi2500/msi2500.c
@@ -28,6 +28,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <linux/usb.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <linux/spi/spi.h>
@@ -112,7 +113,8 @@ static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
/* intermediate buffers with raw data from the USB device */
struct msi2500_frame_buf {
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -431,10 +433,10 @@ static void msi2500_isoc_handler(struct urb *urb)
}
/* fill framebuffer */
- ptr = vb2_plane_vaddr(&fbuf->vb, 0);
+ ptr = vb2_plane_vaddr(&fbuf->vb.vb2_buf, 0);
flen = msi2500_convert_stream(dev, ptr, iso_buf, flen);
- vb2_set_plane_payload(&fbuf->vb, 0, flen);
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, flen);
+ vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
handler_end:
@@ -569,7 +571,7 @@ static void msi2500_cleanup_queued_bufs(struct msi2500_dev *dev)
buf = list_entry(dev->queued_bufs.next,
struct msi2500_frame_buf, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);
}
@@ -614,7 +616,7 @@ static int msi2500_querycap(struct file *file, void *fh,
/* Videobuf2 operations */
static int msi2500_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt,
+ const void *parg,
unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[],
void *alloc_ctxs[])
@@ -633,15 +635,16 @@ static int msi2500_queue_setup(struct vb2_queue *vq,
static void msi2500_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct msi2500_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct msi2500_frame_buf *buf = container_of(vb,
+ struct msi2500_frame_buf *buf = container_of(vbuf,
struct msi2500_frame_buf,
vb);
unsigned long flags;
/* Check the device has not disconnected between prep and queuing */
if (unlikely(!dev->udev)) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
return;
}
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index 702267e208ba..b79c36fd8cd2 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -240,9 +240,9 @@ static void pwc_frame_complete(struct pwc_device *pdev)
PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
" discarded.\n", fbuf->filled);
} else {
- fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
- fbuf->vb.v4l2_buf.sequence = pdev->vframe_count;
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ fbuf->vb.field = V4L2_FIELD_NONE;
+ fbuf->vb.sequence = pdev->vframe_count;
+ vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
pdev->fill_buf = NULL;
pdev->vsync = 0;
}
@@ -287,7 +287,7 @@ static void pwc_isoc_handler(struct urb *urb)
{
PWC_ERROR("Too many ISOC errors, bailing out.\n");
if (pdev->fill_buf) {
- vb2_buffer_done(&pdev->fill_buf->vb,
+ vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
pdev->fill_buf = NULL;
}
@@ -317,7 +317,7 @@ static void pwc_isoc_handler(struct urb *urb)
if (pdev->vsync == 1) {
v4l2_get_timestamp(
- &fbuf->vb.v4l2_buf.timestamp);
+ &fbuf->vb.timestamp);
pdev->vsync = 2;
}
@@ -520,7 +520,7 @@ static void pwc_cleanup_queued_bufs(struct pwc_device *pdev,
buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, state);
+ vb2_buffer_done(&buf->vb.vb2_buf, state);
}
spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
}
@@ -571,7 +571,7 @@ static void pwc_video_release(struct v4l2_device *v)
/***************************************************************************/
/* Videobuf2 operations */
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -594,7 +594,9 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int buffer_init(struct vb2_buffer *vb)
{
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct pwc_frame_buf *buf =
+ container_of(vbuf, struct pwc_frame_buf, vb);
/* need vmalloc since frame buffer > 128K */
buf->data = vzalloc(PWC_FRAME_SIZE);
@@ -618,7 +620,9 @@ static int buffer_prepare(struct vb2_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb)
{
struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct pwc_frame_buf *buf =
+ container_of(vbuf, struct pwc_frame_buf, vb);
if (vb->state == VB2_BUF_STATE_DONE) {
/*
@@ -633,7 +637,9 @@ static void buffer_finish(struct vb2_buffer *vb)
static void buffer_cleanup(struct vb2_buffer *vb)
{
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct pwc_frame_buf *buf =
+ container_of(vbuf, struct pwc_frame_buf, vb);
vfree(buf->data);
}
@@ -641,12 +647,14 @@ static void buffer_cleanup(struct vb2_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
- struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct pwc_frame_buf *buf =
+ container_of(vbuf, struct pwc_frame_buf, vb);
unsigned long flags = 0;
/* Check the device has not disconnected between prep and queuing */
if (!pdev->udev) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
return;
}
@@ -695,7 +703,8 @@ static void stop_streaming(struct vb2_queue *vq)
pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_ERROR);
if (pdev->fill_buf)
- vb2_buffer_done(&pdev->fill_buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf,
+ VB2_BUF_STATE_ERROR);
mutex_unlock(&pdev->v4l2_lock);
}
diff --git a/drivers/media/usb/pwc/pwc-uncompress.c b/drivers/media/usb/pwc/pwc-uncompress.c
index b65903fbcf0d..98c46f93f119 100644
--- a/drivers/media/usb/pwc/pwc-uncompress.c
+++ b/drivers/media/usb/pwc/pwc-uncompress.c
@@ -40,7 +40,7 @@ int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
u16 *src;
u16 *dsty, *dstu, *dstv;
- image = vb2_plane_vaddr(&fbuf->vb, 0);
+ image = vb2_plane_vaddr(&fbuf->vb.vb2_buf, 0);
yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
@@ -55,12 +55,12 @@ int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
* determine this using the type of the webcam */
memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
memcpy(raw_frame+1, yuv, pdev->frame_size);
- vb2_set_plane_payload(&fbuf->vb, 0,
+ vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0,
pdev->frame_size + sizeof(struct pwc_raw_frame));
return 0;
}
- vb2_set_plane_payload(&fbuf->vb, 0,
+ vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0,
pdev->width * pdev->height * 3 / 2);
if (pdev->vbandlength == 0) {
diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h
index 81b017a554bc..3c73bdaae450 100644
--- a/drivers/media/usb/pwc/pwc.h
+++ b/drivers/media/usb/pwc/pwc.h
@@ -40,6 +40,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
#include <linux/input.h>
@@ -210,7 +211,8 @@ struct pwc_raw_frame {
/* intermediate buffers with raw data from the USB cam */
struct pwc_frame_buf
{
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_v4l2_buffer vb;
struct list_head list;
void *data;
int filled; /* number of bytes filled */
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 0f3c34d47ec3..e7acb12ad21d 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -45,6 +45,7 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/usb.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
@@ -293,7 +294,7 @@ struct s2255_fmt {
/* buffer for one video frame */
struct s2255_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
@@ -573,14 +574,14 @@ static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
buf = list_entry(vc->buf_list.next,
struct s2255_buffer, list);
list_del(&buf->list);
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- buf->vb.v4l2_buf.field = vc->field;
- buf->vb.v4l2_buf.sequence = vc->frame_count;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ buf->vb.field = vc->field;
+ buf->vb.sequence = vc->frame_count;
spin_unlock_irqrestore(&vc->qlock, flags);
s2255_fillbuff(vc, buf, jpgsize);
/* tell v4l buffer was filled */
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
}
@@ -612,7 +613,7 @@ static void s2255_fillbuff(struct s2255_vc *vc,
{
int pos = 0;
const char *tmpbuf;
- char *vbuf = vb2_plane_vaddr(&buf->vb, 0);
+ char *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
unsigned long last_frame;
struct s2255_dev *dev = vc->dev;
@@ -635,7 +636,7 @@ static void s2255_fillbuff(struct s2255_vc *vc,
break;
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_MJPEG:
- vb2_set_plane_payload(&buf->vb, 0, jpgsize);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, jpgsize);
memcpy(vbuf, tmpbuf, jpgsize);
break;
case V4L2_PIX_FMT_YUV422P:
@@ -659,7 +660,7 @@ static void s2255_fillbuff(struct s2255_vc *vc,
Videobuf operations
------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -674,7 +675,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int buffer_prepare(struct vb2_buffer *vb)
{
struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
- struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
int w = vc->width;
int h = vc->height;
unsigned long size;
@@ -696,13 +698,14 @@ static int buffer_prepare(struct vb2_buffer *vb)
return -EINVAL;
}
- vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
return 0;
}
static void buffer_queue(struct vb2_buffer *vb)
{
- struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
unsigned long flags = 0;
dprintk(vc->dev, 1, "%s\n", __func__);
@@ -1116,9 +1119,9 @@ static void stop_streaming(struct vb2_queue *vq)
spin_lock_irqsave(&vc->qlock, flags);
list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(vc->dev, 2, "[%p/%d] done\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
spin_unlock_irqrestore(&vc->qlock, flags);
}
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
index e12b10352871..0bd34f1e7fa9 100644
--- a/drivers/media/usb/stk1160/stk1160-v4l.c
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -664,7 +664,7 @@ static const struct v4l2_ioctl_ops stk1160_ioctl_ops = {
/*
* Videobuf2 operations
*/
-static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *v4l_fmt,
+static int queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
@@ -695,8 +695,9 @@ static void buffer_queue(struct vb2_buffer *vb)
{
unsigned long flags;
struct stk1160 *dev = vb2_get_drv_priv(vb->vb2_queue);
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct stk1160_buffer *buf =
- container_of(vb, struct stk1160_buffer, vb);
+ container_of(vbuf, struct stk1160_buffer, vb);
spin_lock_irqsave(&dev->buf_lock, flags);
if (!dev->udev) {
@@ -704,7 +705,7 @@ static void buffer_queue(struct vb2_buffer *vb)
* If the device is disconnected return the buffer to userspace
* directly. The next QBUF call will fail with -ENODEV.
*/
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
} else {
buf->mem = vb2_plane_vaddr(vb, 0);
@@ -717,7 +718,7 @@ static void buffer_queue(struct vb2_buffer *vb)
* the buffer to userspace directly.
*/
if (buf->length < dev->width * dev->height * 2)
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
else
list_add_tail(&buf->list, &dev->avail_bufs);
@@ -769,9 +770,9 @@ void stk1160_clear_queue(struct stk1160 *dev)
buf = list_first_entry(&dev->avail_bufs,
struct stk1160_buffer, list);
list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
stk1160_dbg("buffer [%p/%d] aborted\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
/* It's important to release the current buffer */
@@ -779,9 +780,9 @@ void stk1160_clear_queue(struct stk1160 *dev)
buf = dev->isoc_ctl.buf;
dev->isoc_ctl.buf = NULL;
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
stk1160_dbg("buffer [%p/%d] aborted\n",
- buf, buf->vb.v4l2_buf.index);
+ buf, buf->vb.vb2_buf.index);
}
spin_unlock_irqrestore(&dev->buf_lock, flags);
}
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index 940c3eaea507..75654e676e80 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -96,13 +96,13 @@ void stk1160_buffer_done(struct stk1160 *dev)
{
struct stk1160_buffer *buf = dev->isoc_ctl.buf;
- buf->vb.v4l2_buf.sequence = dev->sequence++;
- buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
- buf->vb.v4l2_buf.bytesused = buf->bytesused;
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ buf->vb.sequence = dev->sequence++;
+ buf->vb.field = V4L2_FIELD_INTERLACED;
+ buf->vb.vb2_buf.planes[0].bytesused = buf->bytesused;
+ v4l2_get_timestamp(&buf->vb.timestamp);
- vb2_set_plane_payload(&buf->vb, 0, buf->bytesused);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->bytesused);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
dev->isoc_ctl.buf = NULL;
}
diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h
index 72cc8e8cbef7..1ed1cc43cdb2 100644
--- a/drivers/media/usb/stk1160/stk1160.h
+++ b/drivers/media/usb/stk1160/stk1160.h
@@ -23,7 +23,7 @@
#include <linux/i2c.h>
#include <sound/core.h>
#include <sound/ac97_codec.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
@@ -77,7 +77,7 @@
/* Buffer for one video frame */
struct stk1160_buffer {
/* common v4l buffer stuff -- must be first */
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
void *mem;
diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c
index 74e5697d8678..e21c7aacecb6 100644
--- a/drivers/media/usb/tm6000/tm6000-alsa.c
+++ b/drivers/media/usb/tm6000/tm6000-alsa.c
@@ -42,7 +42,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable tm6000x soundcard. default enabled.");
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index 7c3a7c55d969..a5de46f04247 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -375,8 +375,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
struct ttusb_dec *dec = priv;
dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
- &dec->audio_filter->feed->feed.ts,
- DMX_OK);
+ &dec->audio_filter->feed->feed.ts);
return 0;
}
@@ -386,8 +385,7 @@ static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
struct ttusb_dec *dec = priv;
dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
- &dec->video_filter->feed->feed.ts,
- DMX_OK);
+ &dec->video_filter->feed->feed.ts);
return 0;
}
@@ -439,7 +437,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
if (output_pva) {
dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
- &dec->video_filter->feed->feed.ts, DMX_OK);
+ &dec->video_filter->feed->feed.ts);
return;
}
@@ -500,7 +498,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
case 0x02: /* MainAudioStream */
if (output_pva) {
dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
- &dec->audio_filter->feed->feed.ts, DMX_OK);
+ &dec->audio_filter->feed->feed.ts);
return;
}
@@ -538,7 +536,7 @@ static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
if (filter)
filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
- &filter->filter, DMX_OK);
+ &filter->filter);
}
static void ttusb_dec_process_packet(struct ttusb_dec *dec)
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index 08fb0f2da64d..e645c9df2d94 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -29,7 +29,7 @@
*/
#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include "usbtv.h"
@@ -306,7 +306,7 @@ static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk)
/* First available buffer. */
buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
- frame = vb2_plane_vaddr(&buf->vb, 0);
+ frame = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
/* Copy the chunk data. */
usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
@@ -314,17 +314,17 @@ static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk)
/* Last chunk in a frame, signalling an end */
if (odd && chunk_no == usbtv->n_chunks-1) {
- int size = vb2_plane_size(&buf->vb, 0);
+ int size = vb2_plane_size(&buf->vb.vb2_buf, 0);
enum vb2_buffer_state state = usbtv->chunks_done ==
usbtv->n_chunks ?
VB2_BUF_STATE_DONE :
VB2_BUF_STATE_ERROR;
- buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
- buf->vb.v4l2_buf.sequence = usbtv->sequence++;
- v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
- vb2_set_plane_payload(&buf->vb, 0, size);
- vb2_buffer_done(&buf->vb, state);
+ buf->vb.field = V4L2_FIELD_INTERLACED;
+ buf->vb.sequence = usbtv->sequence++;
+ v4l2_get_timestamp(&buf->vb.timestamp);
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+ vb2_buffer_done(&buf->vb.vb2_buf, state);
list_del(&buf->list);
}
@@ -422,7 +422,7 @@ static void usbtv_stop(struct usbtv *usbtv)
while (!list_empty(&usbtv->bufs)) {
struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,
struct usbtv_buf, list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
list_del(&buf->list);
}
spin_unlock_irqrestore(&usbtv->buflock, flags);
@@ -599,9 +599,10 @@ static struct v4l2_file_operations usbtv_fops = {
};
static int usbtv_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbuffers,
+ const void *parg, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct usbtv *usbtv = vb2_get_drv_priv(vq);
unsigned size = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);
@@ -617,8 +618,9 @@ static int usbtv_queue_setup(struct vb2_queue *vq,
static void usbtv_buf_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);
- struct usbtv_buf *buf = container_of(vb, struct usbtv_buf, vb);
+ struct usbtv_buf *buf = container_of(vbuf, struct usbtv_buf, vb);
unsigned long flags;
if (usbtv->udev == NULL) {
diff --git a/drivers/media/usb/usbtv/usbtv.h b/drivers/media/usb/usbtv/usbtv.h
index 968119581fab..19cb8bf7c4e9 100644
--- a/drivers/media/usb/usbtv/usbtv.h
+++ b/drivers/media/usb/usbtv/usbtv.h
@@ -24,6 +24,7 @@
#include <linux/usb.h>
#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
/* Hardware. */
@@ -61,7 +62,7 @@ struct usbtv_norm_params {
/* A single videobuf2 frame buffer. */
struct usbtv_buf {
- struct vb2_buffer vb;
+ struct vb2_v4l2_buffer vb;
struct list_head list;
};
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 4b5b3e8fb7d3..d11fd6ac2df0 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -32,6 +32,7 @@
#define DRIVER_DESC "USB Video Class driver"
unsigned int uvc_clock_param = CLOCK_MONOTONIC;
+unsigned int uvc_hw_timestamps_param;
unsigned int uvc_no_drop_param;
static unsigned int uvc_quirks_param = -1;
unsigned int uvc_trace_param;
@@ -2078,6 +2079,8 @@ static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
&uvc_clock_param, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
+module_param_named(hwtimestamps, uvc_hw_timestamps_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(hwtimestamps, "Use hardware timestamps");
module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index f16b9b42689d..cfb868a48b5f 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -20,6 +20,7 @@
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include "uvcvideo.h"
@@ -60,7 +61,7 @@ static void uvc_queue_return_buffers(struct uvc_video_queue *queue,
queue);
list_del(&buf->queue);
buf->state = state;
- vb2_buffer_done(&buf->buf, vb2_state);
+ vb2_buffer_done(&buf->buf.vb2_buf, vb2_state);
}
}
@@ -68,10 +69,11 @@ static void uvc_queue_return_buffers(struct uvc_video_queue *queue,
* videobuf2 queue operations
*/
-static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+static int uvc_queue_setup(struct vb2_queue *vq, const void *parg,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
+ const struct v4l2_format *fmt = parg;
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
struct uvc_streaming *stream = uvc_queue_to_stream(queue);
@@ -89,10 +91,11 @@ static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
static int uvc_buffer_prepare(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
+ struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
- if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
return -EINVAL;
@@ -105,7 +108,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
buf->error = 0;
buf->mem = vb2_plane_vaddr(vb, 0);
buf->length = vb2_plane_size(vb, 0);
- if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
buf->bytesused = 0;
else
buf->bytesused = vb2_get_plane_payload(vb, 0);
@@ -115,8 +118,9 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
static void uvc_buffer_queue(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
+ struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
unsigned long flags;
spin_lock_irqsave(&queue->irqlock, flags);
@@ -127,7 +131,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb)
* directly. The next QBUF call will fail with -ENODEV.
*/
buf->state = UVC_BUF_STATE_ERROR;
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -135,12 +139,13 @@ static void uvc_buffer_queue(struct vb2_buffer *vb)
static void uvc_buffer_finish(struct vb2_buffer *vb)
{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
struct uvc_streaming *stream = uvc_queue_to_stream(queue);
- struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
+ struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
if (vb->state == VB2_BUF_STATE_DONE)
- uvc_video_clock_update(stream, &vb->v4l2_buf, buf);
+ uvc_video_clock_update(stream, vbuf, buf);
}
static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count)
@@ -398,7 +403,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
buf->error = 0;
buf->state = UVC_BUF_STATE_QUEUED;
buf->bytesused = 0;
- vb2_set_plane_payload(&buf->buf, 0, 0);
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
return buf;
}
@@ -412,8 +417,8 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
spin_unlock_irqrestore(&queue->irqlock, flags);
buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
- vb2_set_plane_payload(&buf->buf, 0, buf->bytesused);
- vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
return nextbuf;
}
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index f839654ea436..2b276ab7764f 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -606,7 +606,7 @@ static u16 uvc_video_clock_host_sof(const struct uvc_clock_sample *sample)
* timestamp of the sliding window to 1s.
*/
void uvc_video_clock_update(struct uvc_streaming *stream,
- struct v4l2_buffer *v4l2_buf,
+ struct vb2_v4l2_buffer *vbuf,
struct uvc_buffer *buf)
{
struct uvc_clock *clock = &stream->clock;
@@ -623,6 +623,9 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
u32 rem;
u64 y;
+ if (!uvc_hw_timestamps_param)
+ return;
+
spin_lock_irqsave(&clock->lock, flags);
if (clock->count < clock->size)
@@ -696,14 +699,14 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
stream->dev->name,
sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
y, ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC,
- v4l2_buf->timestamp.tv_sec,
- (unsigned long)v4l2_buf->timestamp.tv_usec,
+ vbuf->timestamp.tv_sec,
+ (unsigned long)vbuf->timestamp.tv_usec,
x1, first->host_sof, first->dev_sof,
x2, last->host_sof, last->dev_sof, y1, y2);
/* Update the V4L2 buffer. */
- v4l2_buf->timestamp.tv_sec = ts.tv_sec;
- v4l2_buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+ vbuf->timestamp.tv_sec = ts.tv_sec;
+ vbuf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
done:
spin_unlock_irqrestore(&stream->clock.lock, flags);
@@ -1029,10 +1032,10 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
uvc_video_get_ts(&ts);
- buf->buf.v4l2_buf.field = V4L2_FIELD_NONE;
- buf->buf.v4l2_buf.sequence = stream->sequence;
- buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
- buf->buf.v4l2_buf.timestamp.tv_usec =
+ buf->buf.field = V4L2_FIELD_NONE;
+ buf->buf.sequence = stream->sequence;
+ buf->buf.timestamp.tv_sec = ts.tv_sec;
+ buf->buf.timestamp.tv_usec =
ts.tv_nsec / NSEC_PER_USEC;
/* TODO: Handle PTS and SCR. */
@@ -1305,7 +1308,7 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
if (buf->bytesused == stream->queue.buf_used) {
stream->queue.buf_used = 0;
buf->state = UVC_BUF_STATE_READY;
- buf->buf.v4l2_buf.sequence = ++stream->sequence;
+ buf->buf.sequence = ++stream->sequence;
uvc_queue_next_buffer(&stream->queue, buf);
stream->last_fid ^= UVC_STREAM_FID;
}
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 816dd1a0fd81..f0f2391e1b43 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -15,7 +15,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
/* --------------------------------------------------------------------------
* UVC constants
@@ -354,7 +354,7 @@ enum uvc_buffer_state {
};
struct uvc_buffer {
- struct vb2_buffer buf;
+ struct vb2_v4l2_buffer buf;
struct list_head queue;
enum uvc_buffer_state state;
@@ -593,6 +593,7 @@ extern unsigned int uvc_clock_param;
extern unsigned int uvc_no_drop_param;
extern unsigned int uvc_trace_param;
extern unsigned int uvc_timeout_param;
+extern unsigned int uvc_hw_timestamps_param;
#define uvc_trace(flag, msg...) \
do { \
@@ -673,7 +674,7 @@ extern int uvc_probe_video(struct uvc_streaming *stream,
extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
__u8 intfnum, __u8 cs, void *data, __u16 size);
void uvc_video_clock_update(struct uvc_streaming *stream,
- struct v4l2_buffer *v4l2_buf,
+ struct vb2_v4l2_buffer *vbuf,
struct uvc_buffer *buf);
/* Status */
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 82876a67f144..9beece00869b 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -47,7 +47,7 @@ config V4L2_MEM2MEM_DEV
# Used by LED subsystem flash drivers
config V4L2_FLASH_LED_CLASS
tristate "V4L2 flash API for LED flash class devices"
- depends on VIDEO_V4L2_SUBDEV_API
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on LEDS_CLASS_FLASH
---help---
Say Y here to enable V4L2 flash API support for LED flash
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index d1dd440d9d9b..1dc8bba2b198 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -14,7 +14,7 @@ ifeq ($(CONFIG_OF),y)
videodev-objs += v4l2-of.o
endif
ifeq ($(CONFIG_TRACEPOINTS),y)
- videodev-objs += v4l2-trace.o
+ videodev-objs += vb2-trace.o v4l2-trace.o
endif
obj-$(CONFIG_VIDEO_V4L2) += videodev.o
@@ -33,7 +33,7 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
-obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
+obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index af635430524e..327e83ac2469 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -147,6 +147,20 @@ static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp,
return 0;
}
+static inline int get_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
+{
+ if (copy_from_user(kp, up, sizeof(struct v4l2_sdr_format)))
+ return -EFAULT;
+ return 0;
+}
+
+static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
+{
+ if (copy_to_user(up, kp, sizeof(struct v4l2_sdr_format)))
+ return -EFAULT;
+ return 0;
+}
+
struct v4l2_format32 {
__u32 type; /* enum v4l2_buf_type */
union {
@@ -155,6 +169,7 @@ struct v4l2_format32 {
struct v4l2_window32 win;
struct v4l2_vbi_format vbi;
struct v4l2_sliced_vbi_format sliced;
+ struct v4l2_sdr_format sdr;
__u8 raw_data[200]; /* user-defined */
} fmt;
};
@@ -198,8 +213,11 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
default:
- printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
+ pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
kp->type);
return -EINVAL;
}
@@ -242,8 +260,11 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
default:
- printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
+ pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
kp->type);
return -EINVAL;
}
@@ -266,7 +287,7 @@ static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_
struct v4l2_standard32 {
__u32 index;
- __u32 id[2]; /* __u64 would get the alignment wrong */
+ compat_u64 id;
__u8 name[24];
struct v4l2_fract frameperiod; /* Frames, not fields */
__u32 framelines;
@@ -286,7 +307,7 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
{
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
put_user(kp->index, &up->index) ||
- copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
+ put_user(kp->id, &up->id) ||
copy_to_user(up->name, kp->name, 24) ||
copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
put_user(kp->framelines, &up->framelines) ||
@@ -587,10 +608,10 @@ struct v4l2_input32 {
__u32 type; /* Type of input */
__u32 audioset; /* Associated audios (bitfield) */
__u32 tuner; /* Associated tuner */
- v4l2_std_id std;
+ compat_u64 std;
__u32 status;
__u32 reserved[4];
-} __attribute__ ((packed));
+};
/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
Otherwise it is identical to the 32-bit version. */
@@ -609,11 +630,11 @@ static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __
}
struct v4l2_ext_controls32 {
- __u32 ctrl_class;
- __u32 count;
- __u32 error_idx;
- __u32 reserved[2];
- compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
+ __u32 ctrl_class;
+ __u32 count;
+ __u32 error_idx;
+ __u32 reserved[2];
+ compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
};
struct v4l2_ext_control32 {
@@ -655,7 +676,8 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
get_user(kp->ctrl_class, &up->ctrl_class) ||
get_user(kp->count, &up->count) ||
get_user(kp->error_idx, &up->error_idx) ||
- copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ copy_from_user(kp->reserved, up->reserved,
+ sizeof(kp->reserved)))
return -EFAULT;
n = kp->count;
if (n == 0) {
@@ -738,6 +760,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
struct v4l2_event32 {
__u32 type;
union {
+ compat_s64 value64;
__u8 data[64];
} u;
__u32 pending;
@@ -1033,8 +1056,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
ret = vdev->fops->compat_ioctl32(file, cmd, arg);
if (ret == -ENOIOCTLCMD)
- pr_warn("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
- _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
+ pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
+ _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
return ret;
}
EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index b6b7dcc1b77d..4a1d9fdd14bb 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -888,6 +888,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis";
case V4L2_CID_RDS_RECEPTION: return "RDS Reception";
case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls";
+ case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain";
case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto";
case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain";
case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto";
@@ -1161,6 +1162,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_PILOT_TONE_FREQUENCY:
case V4L2_CID_TUNE_POWER_LEVEL:
case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+ case V4L2_CID_RF_TUNER_RF_GAIN:
case V4L2_CID_RF_TUNER_LNA_GAIN:
case V4L2_CID_RF_TUNER_MIXER_GAIN:
case V4L2_CID_RF_TUNER_IF_GAIN:
@@ -2498,7 +2500,7 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr
/* We found a control with the given ID, so just get
the next valid one in the list. */
list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) {
- is_compound =
+ is_compound = ref->ctrl->is_array ||
ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
if (id < ref->ctrl->id &&
(is_compound & mask) == match)
@@ -2512,7 +2514,7 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr
is one, otherwise the first 'if' above would have
been true. */
list_for_each_entry(ref, &hdl->ctrl_refs, node) {
- is_compound =
+ is_compound = ref->ctrl->is_array ||
ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
if (id < ref->ctrl->id &&
(is_compound & mask) == match)
@@ -2884,7 +2886,7 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
* cur_to_user() calls below would need to be modified not to access
* userspace memory when called from get_ctrl().
*/
- if (!ctrl->is_int)
+ if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64)
return -EINVAL;
if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
@@ -2942,9 +2944,9 @@ s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)
/* It's a driver bug if this happens. */
WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
- c.value = 0;
+ c.value64 = 0;
get_ctrl(ctrl, &c);
- return c.value;
+ return c.value64;
}
EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64);
@@ -3043,7 +3045,7 @@ static void update_from_auto_cluster(struct v4l2_ctrl *master)
{
int i;
- for (i = 0; i < master->ncontrols; i++)
+ for (i = 1; i < master->ncontrols; i++)
cur_to_new(master->cluster[i]);
if (!call_op(master, g_volatile_ctrl))
for (i = 1; i < master->ncontrols; i++)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 71a1b93b0790..6b1eaeddbdb3 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -637,8 +637,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_try_fmt_sliced_vbi_out)))
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
- } else if (is_sdr) {
- /* SDR specific ioctls */
+ } else if (is_sdr && is_rx) {
+ /* SDR receiver specific ioctls */
if (ops->vidioc_enum_fmt_sdr_cap)
set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
if (ops->vidioc_g_fmt_sdr_cap)
@@ -647,6 +647,16 @@ static void determine_valid_ioctls(struct video_device *vdev)
set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
if (ops->vidioc_try_fmt_sdr_cap)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
+ } else if (is_sdr && is_tx) {
+ /* SDR transmitter specific ioctls */
+ if (ops->vidioc_enum_fmt_sdr_out)
+ set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
+ if (ops->vidioc_g_fmt_sdr_out)
+ set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
+ if (ops->vidioc_s_fmt_sdr_out)
+ set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
+ if (ops->vidioc_try_fmt_sdr_out)
+ set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
if (is_vid || is_vbi || is_sdr) {
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 4a384fc765b8..7486af2c8ae4 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -26,7 +26,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/v4l2-device.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <trace/events/v4l2.h>
@@ -153,6 +153,7 @@ const char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
[V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
+ [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
};
EXPORT_SYMBOL(v4l2_type_names);
@@ -326,6 +327,7 @@ static void v4l_print_format(const void *arg, bool write_only)
sliced->service_lines[1][i]);
break;
case V4L2_BUF_TYPE_SDR_CAPTURE:
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
sdr = &p->fmt.sdr;
pr_cont(", pixelformat=%c%c%c%c\n",
(sdr->pixelformat >> 0) & 0xff,
@@ -974,6 +976,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
return 0;
break;
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
+ return 0;
+ break;
default:
break;
}
@@ -1324,6 +1330,11 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
break;
ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
break;
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_enum_fmt_sdr_out))
+ break;
+ ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
+ break;
}
if (ret == 0)
v4l_fill_fmtdesc(p);
@@ -1418,6 +1429,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
break;
return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
+ break;
+ return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1497,6 +1512,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_s_fmt_sdr_out))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sdr);
+ return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1576,6 +1596,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ if (unlikely(!is_tx || !is_sdr || !ops->vidioc_try_fmt_sdr_out))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sdr);
+ return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1621,15 +1646,31 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
+ struct video_device *vfd = video_devdata(file);
struct v4l2_modulator *p = arg;
int err;
+ if (vfd->vfl_type == VFL_TYPE_RADIO)
+ p->type = V4L2_TUNER_RADIO;
+
err = ops->vidioc_g_modulator(file, fh, p);
if (!err)
p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
return err;
}
+static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+ struct video_device *vfd = video_devdata(file);
+ struct v4l2_modulator *p = arg;
+
+ if (vfd->vfl_type == VFL_TYPE_RADIO)
+ p->type = V4L2_TUNER_RADIO;
+
+ return ops->vidioc_s_modulator(file, fh, p);
+}
+
static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -1637,7 +1678,7 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
struct v4l2_frequency *p = arg;
if (vfd->vfl_type == VFL_TYPE_SDR)
- p->type = V4L2_TUNER_ADC;
+ p->type = V4L2_TUNER_SDR;
else
p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
@@ -1652,7 +1693,7 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
enum v4l2_tuner_type type;
if (vfd->vfl_type == VFL_TYPE_SDR) {
- if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+ if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
return -EINVAL;
} else {
type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
@@ -2277,7 +2318,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
int err;
if (vfd->vfl_type == VFL_TYPE_SDR) {
- if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+ if (p->type != V4L2_TUNER_SDR && p->type != V4L2_TUNER_RF)
return -EINVAL;
type = p->type;
} else {
@@ -2416,7 +2457,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
- IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
+ IOCTL_INFO_FNC(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index ec3ad4eb0c57..61d56c940f80 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -17,7 +17,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
@@ -583,32 +583,25 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
goto end;
}
- if (m2m_ctx->m2m_dev->m2m_ops->unlock)
- m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
- else if (m2m_ctx->q_lock)
- mutex_unlock(m2m_ctx->q_lock);
-
+ spin_lock_irqsave(&src_q->done_lock, flags);
if (list_empty(&src_q->done_list))
poll_wait(file, &src_q->done_wq, wait);
+ spin_unlock_irqrestore(&src_q->done_lock, flags);
+
+ spin_lock_irqsave(&dst_q->done_lock, flags);
if (list_empty(&dst_q->done_list)) {
/*
* If the last buffer was dequeued from the capture queue,
* return immediately. DQBUF will return -EPIPE.
*/
- if (dst_q->last_buffer_dequeued)
+ if (dst_q->last_buffer_dequeued) {
+ spin_unlock_irqrestore(&dst_q->done_lock, flags);
return rc | POLLIN | POLLRDNORM;
+ }
poll_wait(file, &dst_q->done_wq, wait);
}
-
- if (m2m_ctx->m2m_dev->m2m_ops->lock)
- m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
- else if (m2m_ctx->q_lock) {
- if (mutex_lock_interruptible(m2m_ctx->q_lock)) {
- rc |= POLLERR;
- goto end;
- }
- }
+ spin_unlock_irqrestore(&dst_q->done_lock, flags);
spin_lock_irqsave(&src_q->done_lock, flags);
if (!list_empty(&src_q->done_list))
@@ -773,13 +766,15 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_release);
*
* Call from buf_queue(), videobuf_queue_ops callback.
*/
-void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
+void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
+ struct vb2_v4l2_buffer *vbuf)
{
- struct v4l2_m2m_buffer *b = container_of(vb, struct v4l2_m2m_buffer, vb);
+ struct v4l2_m2m_buffer *b = container_of(vbuf,
+ struct v4l2_m2m_buffer, vb);
struct v4l2_m2m_queue_ctx *q_ctx;
unsigned long flags;
- q_ctx = get_queue_ctx(m2m_ctx, vb->vb2_queue->type);
+ q_ctx = get_queue_ctx(m2m_ctx, vbuf->vb2_buf.vb2_queue->type);
if (!q_ctx)
return;
diff --git a/drivers/media/v4l2-core/v4l2-trace.c b/drivers/media/v4l2-core/v4l2-trace.c
index ae10b0248c8e..7416010542c1 100644
--- a/drivers/media/v4l2-core/v4l2-trace.c
+++ b/drivers/media/v4l2-core/v4l2-trace.c
@@ -1,11 +1,11 @@
#include <media/v4l2-common.h>
#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#define CREATE_TRACE_POINTS
#include <trace/events/v4l2.h>
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done);
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue);
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf);
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_done);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_queue);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_dqbuf);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_qbuf);
diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/v4l2-core/vb2-trace.c
new file mode 100644
index 000000000000..61e74f5936b3
--- /dev/null
+++ b/drivers/media/v4l2-core/vb2-trace.c
@@ -0,0 +1,9 @@
+#include <media/videobuf2-core.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/vb2.h>
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf);
diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c
index 926836d1813a..6c02989ee33f 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -576,7 +576,8 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
}
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
|| q->type == V4L2_BUF_TYPE_VBI_OUTPUT
- || q->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
+ || q->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
+ || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {
buf->size = b->bytesused;
buf->field = b->field;
buf->ts = b->timestamp;
@@ -1154,6 +1155,7 @@ unsigned int videobuf_poll_stream(struct file *file,
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VBI_OUTPUT:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
rc = POLLOUT | POLLWRNORM;
break;
default:
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 4f59b7ec05d0..33bdd81065e8 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1,5 +1,5 @@
/*
- * videobuf2-core.c - V4L2 driver helper framework
+ * videobuf2-core.c - video buffer 2 core framework
*
* Copyright (C) 2010 Samsung Electronics
*
@@ -24,164 +24,15 @@
#include <linux/freezer.h>
#include <linux/kthread.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
#include <media/videobuf2-core.h>
-#include <trace/events/v4l2.h>
+#include <trace/events/vb2.h>
-static int debug;
-module_param(debug, int, 0644);
+#include "videobuf2-internal.h"
-#define dprintk(level, fmt, arg...) \
- do { \
- if (debug >= level) \
- pr_info("vb2: %s: " fmt, __func__, ## arg); \
- } while (0)
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-
-/*
- * If advanced debugging is on, then count how often each op is called
- * successfully, which can either be per-buffer or per-queue.
- *
- * This makes it easy to check that the 'init' and 'cleanup'
- * (and variations thereof) stay balanced.
- */
-
-#define log_memop(vb, op) \
- dprintk(2, "call_memop(%p, %d, %s)%s\n", \
- (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \
- (vb)->vb2_queue->mem_ops->op ? "" : " (nop)")
-
-#define call_memop(vb, op, args...) \
-({ \
- struct vb2_queue *_q = (vb)->vb2_queue; \
- int err; \
- \
- log_memop(vb, op); \
- err = _q->mem_ops->op ? _q->mem_ops->op(args) : 0; \
- if (!err) \
- (vb)->cnt_mem_ ## op++; \
- err; \
-})
-
-#define call_ptr_memop(vb, op, args...) \
-({ \
- struct vb2_queue *_q = (vb)->vb2_queue; \
- void *ptr; \
- \
- log_memop(vb, op); \
- ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL; \
- if (!IS_ERR_OR_NULL(ptr)) \
- (vb)->cnt_mem_ ## op++; \
- ptr; \
-})
-
-#define call_void_memop(vb, op, args...) \
-({ \
- struct vb2_queue *_q = (vb)->vb2_queue; \
- \
- log_memop(vb, op); \
- if (_q->mem_ops->op) \
- _q->mem_ops->op(args); \
- (vb)->cnt_mem_ ## op++; \
-})
-
-#define log_qop(q, op) \
- dprintk(2, "call_qop(%p, %s)%s\n", q, #op, \
- (q)->ops->op ? "" : " (nop)")
-
-#define call_qop(q, op, args...) \
-({ \
- int err; \
- \
- log_qop(q, op); \
- err = (q)->ops->op ? (q)->ops->op(args) : 0; \
- if (!err) \
- (q)->cnt_ ## op++; \
- err; \
-})
-
-#define call_void_qop(q, op, args...) \
-({ \
- log_qop(q, op); \
- if ((q)->ops->op) \
- (q)->ops->op(args); \
- (q)->cnt_ ## op++; \
-})
-
-#define log_vb_qop(vb, op, args...) \
- dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \
- (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \
- (vb)->vb2_queue->ops->op ? "" : " (nop)")
-
-#define call_vb_qop(vb, op, args...) \
-({ \
- int err; \
- \
- log_vb_qop(vb, op); \
- err = (vb)->vb2_queue->ops->op ? \
- (vb)->vb2_queue->ops->op(args) : 0; \
- if (!err) \
- (vb)->cnt_ ## op++; \
- err; \
-})
-
-#define call_void_vb_qop(vb, op, args...) \
-({ \
- log_vb_qop(vb, op); \
- if ((vb)->vb2_queue->ops->op) \
- (vb)->vb2_queue->ops->op(args); \
- (vb)->cnt_ ## op++; \
-})
-
-#else
-
-#define call_memop(vb, op, args...) \
- ((vb)->vb2_queue->mem_ops->op ? \
- (vb)->vb2_queue->mem_ops->op(args) : 0)
-
-#define call_ptr_memop(vb, op, args...) \
- ((vb)->vb2_queue->mem_ops->op ? \
- (vb)->vb2_queue->mem_ops->op(args) : NULL)
-
-#define call_void_memop(vb, op, args...) \
- do { \
- if ((vb)->vb2_queue->mem_ops->op) \
- (vb)->vb2_queue->mem_ops->op(args); \
- } while (0)
-
-#define call_qop(q, op, args...) \
- ((q)->ops->op ? (q)->ops->op(args) : 0)
-
-#define call_void_qop(q, op, args...) \
- do { \
- if ((q)->ops->op) \
- (q)->ops->op(args); \
- } while (0)
-
-#define call_vb_qop(vb, op, args...) \
- ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
-
-#define call_void_vb_qop(vb, op, args...) \
- do { \
- if ((vb)->vb2_queue->ops->op) \
- (vb)->vb2_queue->ops->op(args); \
- } while (0)
-
-#endif
-
-/* Flags that are set by the vb2 core */
-#define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
- V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
- V4L2_BUF_FLAG_PREPARED | \
- V4L2_BUF_FLAG_TIMESTAMP_MASK)
-/* Output buffer flags that should be passed on to the driver */
-#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
- V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
+int vb2_debug;
+EXPORT_SYMBOL_GPL(vb2_debug);
+module_param_named(debug, vb2_debug, int, 0644);
static void __vb2_queue_cancel(struct vb2_queue *q);
static void __enqueue_in_driver(struct vb2_buffer *vb);
@@ -193,7 +44,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
{
struct vb2_queue *q = vb->vb2_queue;
enum dma_data_direction dma_dir =
- V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
void *mem_priv;
int plane;
@@ -211,7 +62,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
/* Associate allocator private data with this plane */
vb->planes[plane].mem_priv = mem_priv;
- vb->v4l2_planes[plane].length = q->plane_sizes[plane];
+ vb->planes[plane].length = q->plane_sizes[plane];
}
return 0;
@@ -235,8 +86,7 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb)
for (plane = 0; plane < vb->num_planes; ++plane) {
call_void_memop(vb, put, vb->planes[plane].mem_priv);
vb->planes[plane].mem_priv = NULL;
- dprintk(3, "freed plane %d of buffer %d\n", plane,
- vb->v4l2_buf.index);
+ dprintk(3, "freed plane %d of buffer %d\n", plane, vb->index);
}
}
@@ -269,7 +119,9 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p)
call_void_memop(vb, detach_dmabuf, p->mem_priv);
dma_buf_put(p->dbuf);
- memset(p, 0, sizeof(*p));
+ p->mem_priv = NULL;
+ p->dbuf = NULL;
+ p->dbuf_mapped = 0;
}
/**
@@ -299,7 +151,7 @@ static void __setup_lengths(struct vb2_queue *q, unsigned int n)
continue;
for (plane = 0; plane < vb->num_planes; ++plane)
- vb->v4l2_planes[plane].length = q->plane_sizes[plane];
+ vb->planes[plane].length = q->plane_sizes[plane];
}
}
@@ -314,10 +166,10 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)
unsigned long off;
if (q->num_buffers) {
- struct v4l2_plane *p;
+ struct vb2_plane *p;
vb = q->bufs[q->num_buffers - 1];
- p = &vb->v4l2_planes[vb->num_planes - 1];
- off = PAGE_ALIGN(p->m.mem_offset + p->length);
+ p = &vb->planes[vb->num_planes - 1];
+ off = PAGE_ALIGN(p->m.offset + p->length);
} else {
off = 0;
}
@@ -328,12 +180,12 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)
continue;
for (plane = 0; plane < vb->num_planes; ++plane) {
- vb->v4l2_planes[plane].m.mem_offset = off;
+ vb->planes[plane].m.offset = off;
dprintk(3, "buffer %d, plane %d offset 0x%08lx\n",
buffer, plane, off);
- off += vb->v4l2_planes[plane].length;
+ off += vb->planes[plane].length;
off = PAGE_ALIGN(off);
}
}
@@ -346,7 +198,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)
*
* Returns the number of buffers successfully allocated.
*/
-static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
+static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
unsigned int num_buffers, unsigned int num_planes)
{
unsigned int buffer;
@@ -361,19 +213,15 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
break;
}
- /* Length stores number of planes for multiplanar buffers */
- if (V4L2_TYPE_IS_MULTIPLANAR(q->type))
- vb->v4l2_buf.length = num_planes;
-
vb->state = VB2_BUF_STATE_DEQUEUED;
vb->vb2_queue = q;
vb->num_planes = num_planes;
- vb->v4l2_buf.index = q->num_buffers + buffer;
- vb->v4l2_buf.type = q->type;
- vb->v4l2_buf.memory = memory;
+ vb->index = q->num_buffers + buffer;
+ vb->type = q->type;
+ vb->memory = memory;
/* Allocate video buffer memory for the MMAP type */
- if (memory == V4L2_MEMORY_MMAP) {
+ if (memory == VB2_MEMORY_MMAP) {
ret = __vb2_buf_mem_alloc(vb);
if (ret) {
dprintk(1, "failed allocating memory for "
@@ -400,7 +248,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
}
__setup_lengths(q, buffer);
- if (memory == V4L2_MEMORY_MMAP)
+ if (memory == VB2_MEMORY_MMAP)
__setup_offsets(q, buffer);
dprintk(1, "allocated %d buffers, %d plane(s) each\n",
@@ -424,9 +272,9 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
continue;
/* Free MMAP buffers or release USERPTR buffers */
- if (q->memory == V4L2_MEMORY_MMAP)
+ if (q->memory == VB2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
- else if (q->memory == V4L2_MEMORY_DMABUF)
+ else if (q->memory == VB2_MEMORY_DMABUF)
__vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
@@ -482,7 +330,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
bool unbalanced = q->cnt_start_streaming != q->cnt_stop_streaming ||
q->cnt_wait_prepare != q->cnt_wait_finish;
- if (unbalanced || debug) {
+ if (unbalanced || vb2_debug) {
pr_info("vb2: counters for queue %p:%s\n", q,
unbalanced ? " UNBALANCED!" : "");
pr_info("vb2: setup: %u start_streaming: %u stop_streaming: %u\n",
@@ -508,7 +356,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
vb->cnt_buf_prepare != vb->cnt_buf_finish ||
vb->cnt_buf_init != vb->cnt_buf_cleanup;
- if (unbalanced || debug) {
+ if (unbalanced || vb2_debug) {
pr_info("vb2: counters for queue %p, buffer %d:%s\n",
q, buffer, unbalanced ? " UNBALANCED!" : "");
pr_info("vb2: buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
@@ -550,76 +398,10 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
}
/**
- * __verify_planes_array() - verify that the planes array passed in struct
- * v4l2_buffer from userspace can be safely used
- */
-static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- if (!V4L2_TYPE_IS_MULTIPLANAR(b->type))
- return 0;
-
- /* Is memory for copying plane information present? */
- if (NULL == b->m.planes) {
- dprintk(1, "multi-planar buffer passed but "
- "planes array not provided\n");
- return -EINVAL;
- }
-
- if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) {
- dprintk(1, "incorrect planes array length, "
- "expected %d, got %d\n", vb->num_planes, b->length);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * __verify_length() - Verify that the bytesused value for each plane fits in
- * the plane length and that the data offset doesn't exceed the bytesused value.
- */
-static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
-{
- unsigned int length;
- unsigned int bytesused;
- unsigned int plane;
-
- if (!V4L2_TYPE_IS_OUTPUT(b->type))
- return 0;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
- for (plane = 0; plane < vb->num_planes; ++plane) {
- length = (b->memory == V4L2_MEMORY_USERPTR ||
- b->memory == V4L2_MEMORY_DMABUF)
- ? b->m.planes[plane].length
- : vb->v4l2_planes[plane].length;
- bytesused = b->m.planes[plane].bytesused
- ? b->m.planes[plane].bytesused : length;
-
- if (b->m.planes[plane].bytesused > length)
- return -EINVAL;
-
- if (b->m.planes[plane].data_offset > 0 &&
- b->m.planes[plane].data_offset >= bytesused)
- return -EINVAL;
- }
- } else {
- length = (b->memory == V4L2_MEMORY_USERPTR)
- ? b->length : vb->v4l2_planes[0].length;
- bytesused = b->bytesused ? b->bytesused : length;
-
- if (b->bytesused > length)
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * __buffer_in_use() - return true if the buffer is in use and
+ * vb2_buffer_in_use() - return true if the buffer is in use and
* the queue cannot be freed (by the means of REQBUFS(0)) call
*/
-static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
+bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
{
unsigned int plane;
for (plane = 0; plane < vb->num_planes; ++plane) {
@@ -635,6 +417,7 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
}
return false;
}
+EXPORT_SYMBOL(vb2_buffer_in_use);
/**
* __buffers_in_use() - return true if any buffers on the queue are in use and
@@ -644,122 +427,30 @@ static bool __buffers_in_use(struct vb2_queue *q)
{
unsigned int buffer;
for (buffer = 0; buffer < q->num_buffers; ++buffer) {
- if (__buffer_in_use(q, q->bufs[buffer]))
+ if (vb2_buffer_in_use(q, q->bufs[buffer]))
return true;
}
return false;
}
/**
- * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
- * returned to userspace
- */
-static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
-{
- struct vb2_queue *q = vb->vb2_queue;
-
- /* Copy back data such as timestamp, flags, etc. */
- memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
- b->reserved2 = vb->v4l2_buf.reserved2;
- b->reserved = vb->v4l2_buf.reserved;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) {
- /*
- * Fill in plane-related data if userspace provided an array
- * for it. The caller has already verified memory and size.
- */
- b->length = vb->num_planes;
- memcpy(b->m.planes, vb->v4l2_planes,
- b->length * sizeof(struct v4l2_plane));
- } else {
- /*
- * We use length and offset in v4l2_planes array even for
- * single-planar buffers, but userspace does not.
- */
- b->length = vb->v4l2_planes[0].length;
- b->bytesused = vb->v4l2_planes[0].bytesused;
- if (q->memory == V4L2_MEMORY_MMAP)
- b->m.offset = vb->v4l2_planes[0].m.mem_offset;
- else if (q->memory == V4L2_MEMORY_USERPTR)
- b->m.userptr = vb->v4l2_planes[0].m.userptr;
- else if (q->memory == V4L2_MEMORY_DMABUF)
- b->m.fd = vb->v4l2_planes[0].m.fd;
- }
-
- /*
- * Clear any buffer state related flags.
- */
- b->flags &= ~V4L2_BUFFER_MASK_FLAGS;
- b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK;
- if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
- V4L2_BUF_FLAG_TIMESTAMP_COPY) {
- /*
- * For non-COPY timestamps, drop timestamp source bits
- * and obtain the timestamp source from the queue.
- */
- b->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- }
-
- switch (vb->state) {
- case VB2_BUF_STATE_QUEUED:
- case VB2_BUF_STATE_ACTIVE:
- b->flags |= V4L2_BUF_FLAG_QUEUED;
- break;
- case VB2_BUF_STATE_ERROR:
- b->flags |= V4L2_BUF_FLAG_ERROR;
- /* fall through */
- case VB2_BUF_STATE_DONE:
- b->flags |= V4L2_BUF_FLAG_DONE;
- break;
- case VB2_BUF_STATE_PREPARED:
- b->flags |= V4L2_BUF_FLAG_PREPARED;
- break;
- case VB2_BUF_STATE_PREPARING:
- case VB2_BUF_STATE_DEQUEUED:
- case VB2_BUF_STATE_REQUEUEING:
- /* nothing */
- break;
- }
-
- if (__buffer_in_use(q, vb))
- b->flags |= V4L2_BUF_FLAG_MAPPED;
-}
-
-/**
- * vb2_querybuf() - query video buffer information
+ * vb2_core_querybuf() - query video buffer information
* @q: videobuf queue
- * @b: buffer struct passed from userspace to vidioc_querybuf handler
- * in driver
+ * @index: id number of the buffer
+ * @pb: buffer struct passed from userspace
*
* Should be called from vidioc_querybuf ioctl handler in driver.
- * This function will verify the passed v4l2_buffer structure and fill the
- * relevant information for the userspace.
+ * The passed buffer should have been verified.
+ * This function fills the relevant information for the userspace.
*
* The return values from this function are intended to be directly returned
* from vidioc_querybuf handler in driver.
*/
-int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
+int vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb)
{
- struct vb2_buffer *vb;
- int ret;
-
- if (b->type != q->type) {
- dprintk(1, "wrong buffer type\n");
- return -EINVAL;
- }
-
- if (b->index >= q->num_buffers) {
- dprintk(1, "buffer index out of range\n");
- return -EINVAL;
- }
- vb = q->bufs[b->index];
- ret = __verify_planes_array(vb, b);
- if (!ret)
- __fill_v4l2_buffer(vb, b);
- return ret;
+ return call_bufop(q, fill_user_buffer, q->bufs[index], pb);
}
-EXPORT_SYMBOL(vb2_querybuf);
+EXPORT_SYMBOL_GPL(vb2_core_querybuf);
/**
* __verify_userptr_ops() - verify that all memory operations required for
@@ -802,14 +493,14 @@ static int __verify_dmabuf_ops(struct vb2_queue *q)
}
/**
- * __verify_memory_type() - Check whether the memory type and buffer type
+ * vb2_verify_memory_type() - Check whether the memory type and buffer type
* passed to a buffer operation are compatible with the queue.
*/
-static int __verify_memory_type(struct vb2_queue *q,
- enum v4l2_memory memory, enum v4l2_buf_type type)
+int vb2_verify_memory_type(struct vb2_queue *q,
+ enum vb2_memory memory, unsigned int type)
{
- if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR &&
- memory != V4L2_MEMORY_DMABUF) {
+ if (memory != VB2_MEMORY_MMAP && memory != VB2_MEMORY_USERPTR &&
+ memory != VB2_MEMORY_DMABUF) {
dprintk(1, "unsupported memory type\n");
return -EINVAL;
}
@@ -823,17 +514,17 @@ static int __verify_memory_type(struct vb2_queue *q,
* Make sure all the required memory ops for given memory type
* are available.
*/
- if (memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
+ if (memory == VB2_MEMORY_MMAP && __verify_mmap_ops(q)) {
dprintk(1, "MMAP for current setup unsupported\n");
return -EINVAL;
}
- if (memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
+ if (memory == VB2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
dprintk(1, "USERPTR for current setup unsupported\n");
return -EINVAL;
}
- if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
+ if (memory == VB2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
dprintk(1, "DMABUF for current setup unsupported\n");
return -EINVAL;
}
@@ -849,11 +540,13 @@ static int __verify_memory_type(struct vb2_queue *q,
}
return 0;
}
+EXPORT_SYMBOL(vb2_verify_memory_type);
/**
- * __reqbufs() - Initiate streaming
+ * vb2_core_reqbufs() - Initiate streaming
* @q: videobuf2 queue
- * @req: struct passed from userspace to vidioc_reqbufs handler in driver
+ * @memory: memory type
+ * @count: requested buffer count
*
* Should be called from vidioc_reqbufs ioctl handler of a driver.
* This function:
@@ -873,7 +566,8 @@ static int __verify_memory_type(struct vb2_queue *q,
* The return values from this function are intended to be directly returned
* from vidioc_reqbufs handler in driver.
*/
-static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
+int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ unsigned int *count)
{
unsigned int num_buffers, allocated_buffers, num_planes = 0;
int ret;
@@ -883,13 +577,13 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
return -EBUSY;
}
- if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) {
+ if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
/*
* We already have buffers allocated, so first check if they
* are not in use and can be freed.
*/
mutex_lock(&q->mmap_lock);
- if (q->memory == V4L2_MEMORY_MMAP && __buffers_in_use(q)) {
+ if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) {
mutex_unlock(&q->mmap_lock);
dprintk(1, "memory in use, cannot free\n");
return -EBUSY;
@@ -910,18 +604,18 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
* In case of REQBUFS(0) return immediately without calling
* driver's queue_setup() callback and allocating resources.
*/
- if (req->count == 0)
+ if (*count == 0)
return 0;
}
/*
* Make sure the requested values and current defaults are sane.
*/
- num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
+ num_buffers = min_t(unsigned int, *count, VB2_MAX_FRAME);
num_buffers = max_t(unsigned int, num_buffers, q->min_buffers_needed);
memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
- q->memory = req->memory;
+ q->memory = memory;
/*
* Ask the driver how many buffers and planes per buffer it requires.
@@ -933,7 +627,8 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
return ret;
/* Finally, allocate buffers and video memory */
- allocated_buffers = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes);
+ allocated_buffers =
+ __vb2_queue_alloc(q, memory, num_buffers, num_planes);
if (allocated_buffers == 0) {
dprintk(1, "memory allocation failed\n");
return -ENOMEM;
@@ -982,31 +677,19 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
* Return the number of successfully allocated buffers
* to the userspace.
*/
- req->count = allocated_buffers;
- q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
+ *count = allocated_buffers;
+ q->waiting_for_buffers = !q->is_output;
return 0;
}
+EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
/**
- * vb2_reqbufs() - Wrapper for __reqbufs() that also verifies the memory and
- * type values.
+ * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs
* @q: videobuf2 queue
- * @req: struct passed from userspace to vidioc_reqbufs handler in driver
- */
-int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
-{
- int ret = __verify_memory_type(q, req->memory, req->type);
-
- return ret ? ret : __reqbufs(q, req);
-}
-EXPORT_SYMBOL_GPL(vb2_reqbufs);
-
-/**
- * __create_bufs() - Allocate buffers and any required auxiliary structs
- * @q: videobuf2 queue
- * @create: creation parameters, passed from userspace to vidioc_create_bufs
- * handler in driver
+ * @memory: memory type
+ * @count: requested buffer count
+ * @parg: parameter passed to device driver
*
* Should be called from vidioc_create_bufs ioctl handler of a driver.
* This function:
@@ -1017,12 +700,13 @@ EXPORT_SYMBOL_GPL(vb2_reqbufs);
* The return values from this function are intended to be directly returned
* from vidioc_create_bufs handler in driver.
*/
-static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
+int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ unsigned int *count, const void *parg)
{
unsigned int num_planes = 0, num_buffers, allocated_buffers;
int ret;
- if (q->num_buffers == VIDEO_MAX_FRAME) {
+ if (q->num_buffers == VB2_MAX_FRAME) {
dprintk(1, "maximum number of buffers already allocated\n");
return -ENOBUFS;
}
@@ -1030,23 +714,23 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
if (!q->num_buffers) {
memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
- q->memory = create->memory;
- q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
+ q->memory = memory;
+ q->waiting_for_buffers = !q->is_output;
}
- num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
+ num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers);
/*
* Ask the driver, whether the requested number of buffers, planes per
* buffer and their sizes are acceptable
*/
- ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
+ ret = call_qop(q, queue_setup, q, parg, &num_buffers,
&num_planes, q->plane_sizes, q->alloc_ctx);
if (ret)
return ret;
/* Finally, allocate buffers and video memory */
- allocated_buffers = __vb2_queue_alloc(q, create->memory, num_buffers,
+ allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,
num_planes);
if (allocated_buffers == 0) {
dprintk(1, "memory allocation failed\n");
@@ -1063,7 +747,7 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
* q->num_buffers contains the total number of buffers, that the
* queue driver has set up
*/
- ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
+ ret = call_qop(q, queue_setup, q, parg, &num_buffers,
&num_planes, q->plane_sizes, q->alloc_ctx);
if (!ret && allocated_buffers < num_buffers)
@@ -1093,28 +777,11 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
* Return the number of successfully allocated buffers
* to the userspace.
*/
- create->count = allocated_buffers;
+ *count = allocated_buffers;
return 0;
}
-
-/**
- * vb2_create_bufs() - Wrapper for __create_bufs() that also verifies the
- * memory and type values.
- * @q: videobuf2 queue
- * @create: creation parameters, passed from userspace to vidioc_create_bufs
- * handler in driver
- */
-int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
-{
- int ret = __verify_memory_type(q, create->memory, create->format.type);
-
- create->index = q->num_buffers;
- if (create->count == 0)
- return ret != -EBUSY ? ret : 0;
- return ret ? ret : __create_bufs(q, create);
-}
-EXPORT_SYMBOL_GPL(vb2_create_bufs);
+EXPORT_SYMBOL_GPL(vb2_core_create_bufs);
/**
* vb2_plane_vaddr() - Return a kernel virtual address of a given plane
@@ -1197,7 +864,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
vb->cnt_buf_done++;
#endif
dprintk(4, "done processing on buffer %d, state: %d\n",
- vb->v4l2_buf.index, state);
+ vb->index, state);
/* sync buffers */
for (plane = 0; plane < vb->num_planes; ++plane)
@@ -1256,182 +923,41 @@ void vb2_discard_done(struct vb2_queue *q)
}
EXPORT_SYMBOL_GPL(vb2_discard_done);
-static void vb2_warn_zero_bytesused(struct vb2_buffer *vb)
-{
- static bool check_once;
-
- if (check_once)
- return;
-
- check_once = true;
- WARN_ON(1);
-
- pr_warn("use of bytesused == 0 is deprecated and will be removed in the future,\n");
- if (vb->vb2_queue->allow_zero_bytesused)
- pr_warn("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n");
- else
- pr_warn("use the actual size instead.\n");
-}
-
-/**
- * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
- * v4l2_buffer by the userspace. The caller has already verified that struct
- * v4l2_buffer has a valid number of planes.
- */
-static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
- struct v4l2_plane *v4l2_planes)
-{
- unsigned int plane;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
- if (b->memory == V4L2_MEMORY_USERPTR) {
- for (plane = 0; plane < vb->num_planes; ++plane) {
- v4l2_planes[plane].m.userptr =
- b->m.planes[plane].m.userptr;
- v4l2_planes[plane].length =
- b->m.planes[plane].length;
- }
- }
- if (b->memory == V4L2_MEMORY_DMABUF) {
- for (plane = 0; plane < vb->num_planes; ++plane) {
- v4l2_planes[plane].m.fd =
- b->m.planes[plane].m.fd;
- v4l2_planes[plane].length =
- b->m.planes[plane].length;
- }
- }
-
- /* Fill in driver-provided information for OUTPUT types */
- if (V4L2_TYPE_IS_OUTPUT(b->type)) {
- /*
- * Will have to go up to b->length when API starts
- * accepting variable number of planes.
- *
- * If bytesused == 0 for the output buffer, then fall
- * back to the full buffer size. In that case
- * userspace clearly never bothered to set it and
- * it's a safe assumption that they really meant to
- * use the full plane sizes.
- *
- * Some drivers, e.g. old codec drivers, use bytesused == 0
- * as a way to indicate that streaming is finished.
- * In that case, the driver should use the
- * allow_zero_bytesused flag to keep old userspace
- * applications working.
- */
- for (plane = 0; plane < vb->num_planes; ++plane) {
- struct v4l2_plane *pdst = &v4l2_planes[plane];
- struct v4l2_plane *psrc = &b->m.planes[plane];
-
- if (psrc->bytesused == 0)
- vb2_warn_zero_bytesused(vb);
-
- if (vb->vb2_queue->allow_zero_bytesused)
- pdst->bytesused = psrc->bytesused;
- else
- pdst->bytesused = psrc->bytesused ?
- psrc->bytesused : pdst->length;
- pdst->data_offset = psrc->data_offset;
- }
- }
- } else {
- /*
- * Single-planar buffers do not use planes array,
- * so fill in relevant v4l2_buffer struct fields instead.
- * In videobuf we use our internal V4l2_planes struct for
- * single-planar buffers as well, for simplicity.
- *
- * If bytesused == 0 for the output buffer, then fall back
- * to the full buffer size as that's a sensible default.
- *
- * Some drivers, e.g. old codec drivers, use bytesused == 0 as
- * a way to indicate that streaming is finished. In that case,
- * the driver should use the allow_zero_bytesused flag to keep
- * old userspace applications working.
- */
- if (b->memory == V4L2_MEMORY_USERPTR) {
- v4l2_planes[0].m.userptr = b->m.userptr;
- v4l2_planes[0].length = b->length;
- }
-
- if (b->memory == V4L2_MEMORY_DMABUF) {
- v4l2_planes[0].m.fd = b->m.fd;
- v4l2_planes[0].length = b->length;
- }
-
- if (V4L2_TYPE_IS_OUTPUT(b->type)) {
- if (b->bytesused == 0)
- vb2_warn_zero_bytesused(vb);
-
- if (vb->vb2_queue->allow_zero_bytesused)
- v4l2_planes[0].bytesused = b->bytesused;
- else
- v4l2_planes[0].bytesused = b->bytesused ?
- b->bytesused : v4l2_planes[0].length;
- } else
- v4l2_planes[0].bytesused = 0;
-
- }
-
- /* Zero flags that the vb2 core handles */
- vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
- if ((vb->vb2_queue->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
- V4L2_BUF_FLAG_TIMESTAMP_COPY || !V4L2_TYPE_IS_OUTPUT(b->type)) {
- /*
- * Non-COPY timestamps and non-OUTPUT queues will get
- * their timestamp and timestamp source flags from the
- * queue.
- */
- vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- }
-
- if (V4L2_TYPE_IS_OUTPUT(b->type)) {
- /*
- * For output buffers mask out the timecode flag:
- * this will be handled later in vb2_internal_qbuf().
- * The 'field' is valid metadata for this output buffer
- * and so that needs to be copied here.
- */
- vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE;
- vb->v4l2_buf.field = b->field;
- } else {
- /* Zero any output buffer flags as this is a capture buffer */
- vb->v4l2_buf.flags &= ~V4L2_BUFFER_OUT_FLAGS;
- }
-}
-
/**
* __qbuf_mmap() - handle qbuf of an MMAP buffer
*/
-static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+static int __qbuf_mmap(struct vb2_buffer *vb, const void *pb)
{
- __fill_vb2_buffer(vb, b, vb->v4l2_planes);
- return call_vb_qop(vb, buf_prepare, vb);
+ int ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+ vb, pb, vb->planes);
+ return ret ? ret : call_vb_qop(vb, buf_prepare, vb);
}
/**
* __qbuf_userptr() - handle qbuf of a USERPTR buffer
*/
-static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb)
{
- struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ struct vb2_plane planes[VB2_MAX_PLANES];
struct vb2_queue *q = vb->vb2_queue;
void *mem_priv;
unsigned int plane;
int ret;
enum dma_data_direction dma_dir =
- V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
bool reacquired = vb->planes[0].mem_priv == NULL;
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
/* Copy relevant information provided by the userspace */
- __fill_vb2_buffer(vb, b, planes);
+ ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, vb, pb, planes);
+ if (ret)
+ return ret;
for (plane = 0; plane < vb->num_planes; ++plane) {
/* Skip the plane if already verified */
- if (vb->v4l2_planes[plane].m.userptr &&
- vb->v4l2_planes[plane].m.userptr == planes[plane].m.userptr
- && vb->v4l2_planes[plane].length == planes[plane].length)
+ if (vb->planes[plane].m.userptr &&
+ vb->planes[plane].m.userptr == planes[plane].m.userptr
+ && vb->planes[plane].length == planes[plane].length)
continue;
dprintk(3, "userspace address for plane %d changed, "
@@ -1457,7 +983,10 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
}
vb->planes[plane].mem_priv = NULL;
- memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
+ vb->planes[plane].bytesused = 0;
+ vb->planes[plane].length = 0;
+ vb->planes[plane].m.userptr = 0;
+ vb->planes[plane].data_offset = 0;
/* Acquire each plane's memory */
mem_priv = call_ptr_memop(vb, get_userptr, q->alloc_ctx[plane],
@@ -1476,8 +1005,12 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
* Now that everything is in order, copy relevant information
* provided by userspace.
*/
- for (plane = 0; plane < vb->num_planes; ++plane)
- vb->v4l2_planes[plane] = planes[plane];
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ vb->planes[plane].bytesused = planes[plane].bytesused;
+ vb->planes[plane].length = planes[plane].length;
+ vb->planes[plane].m.userptr = planes[plane].m.userptr;
+ vb->planes[plane].data_offset = planes[plane].data_offset;
+ }
if (reacquired) {
/*
@@ -1504,10 +1037,11 @@ err:
/* In case of errors, release planes that were already acquired */
for (plane = 0; plane < vb->num_planes; ++plane) {
if (vb->planes[plane].mem_priv)
- call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv);
+ call_void_memop(vb, put_userptr,
+ vb->planes[plane].mem_priv);
vb->planes[plane].mem_priv = NULL;
- vb->v4l2_planes[plane].m.userptr = 0;
- vb->v4l2_planes[plane].length = 0;
+ vb->planes[plane].m.userptr = 0;
+ vb->planes[plane].length = 0;
}
return ret;
@@ -1516,20 +1050,22 @@ err:
/**
* __qbuf_dmabuf() - handle qbuf of a DMABUF buffer
*/
-static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb)
{
- struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ struct vb2_plane planes[VB2_MAX_PLANES];
struct vb2_queue *q = vb->vb2_queue;
void *mem_priv;
unsigned int plane;
int ret;
enum dma_data_direction dma_dir =
- V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
bool reacquired = vb->planes[0].mem_priv == NULL;
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
/* Copy relevant information provided by the userspace */
- __fill_vb2_buffer(vb, b, planes);
+ ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, vb, pb, planes);
+ if (ret)
+ return ret;
for (plane = 0; plane < vb->num_planes; ++plane) {
struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
@@ -1554,7 +1090,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
/* Skip the plane if already verified */
if (dbuf == vb->planes[plane].dbuf &&
- vb->v4l2_planes[plane].length == planes[plane].length) {
+ vb->planes[plane].length == planes[plane].length) {
dma_buf_put(dbuf);
continue;
}
@@ -1568,11 +1104,15 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
/* Release previously acquired memory if present */
__vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
- memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
+ vb->planes[plane].bytesused = 0;
+ vb->planes[plane].length = 0;
+ vb->planes[plane].m.fd = 0;
+ vb->planes[plane].data_offset = 0;
/* Acquire each plane's memory */
- mem_priv = call_ptr_memop(vb, attach_dmabuf, q->alloc_ctx[plane],
- dbuf, planes[plane].length, dma_dir);
+ mem_priv = call_ptr_memop(vb, attach_dmabuf,
+ q->alloc_ctx[plane], dbuf, planes[plane].length,
+ dma_dir);
if (IS_ERR(mem_priv)) {
dprintk(1, "failed to attach dmabuf\n");
ret = PTR_ERR(mem_priv);
@@ -1602,8 +1142,12 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
* Now that everything is in order, copy relevant information
* provided by userspace.
*/
- for (plane = 0; plane < vb->num_planes; ++plane)
- vb->v4l2_planes[plane] = planes[plane];
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ vb->planes[plane].bytesused = planes[plane].bytesused;
+ vb->planes[plane].length = planes[plane].length;
+ vb->planes[plane].m.fd = planes[plane].m.fd;
+ vb->planes[plane].data_offset = planes[plane].data_offset;
+ }
if (reacquired) {
/*
@@ -1652,49 +1196,27 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
call_void_vb_qop(vb, buf_queue, vb);
}
-static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
{
struct vb2_queue *q = vb->vb2_queue;
int ret;
- ret = __verify_length(vb, b);
- if (ret < 0) {
- dprintk(1, "plane parameters verification failed: %d\n", ret);
- return ret;
- }
- if (b->field == V4L2_FIELD_ALTERNATE && V4L2_TYPE_IS_OUTPUT(q->type)) {
- /*
- * If the format's field is ALTERNATE, then the buffer's field
- * should be either TOP or BOTTOM, not ALTERNATE since that
- * makes no sense. The driver has to know whether the
- * buffer represents a top or a bottom field in order to
- * program any DMA correctly. Using ALTERNATE is wrong, since
- * that just says that it is either a top or a bottom field,
- * but not which of the two it is.
- */
- dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n");
- return -EINVAL;
- }
-
if (q->error) {
dprintk(1, "fatal error occurred on queue\n");
return -EIO;
}
vb->state = VB2_BUF_STATE_PREPARING;
- vb->v4l2_buf.timestamp.tv_sec = 0;
- vb->v4l2_buf.timestamp.tv_usec = 0;
- vb->v4l2_buf.sequence = 0;
switch (q->memory) {
- case V4L2_MEMORY_MMAP:
- ret = __qbuf_mmap(vb, b);
+ case VB2_MEMORY_MMAP:
+ ret = __qbuf_mmap(vb, pb);
break;
- case V4L2_MEMORY_USERPTR:
- ret = __qbuf_userptr(vb, b);
+ case VB2_MEMORY_USERPTR:
+ ret = __qbuf_userptr(vb, pb);
break;
- case V4L2_MEMORY_DMABUF:
- ret = __qbuf_dmabuf(vb, b);
+ case VB2_MEMORY_DMABUF:
+ ret = __qbuf_dmabuf(vb, pb);
break;
default:
WARN(1, "Invalid queue type\n");
@@ -1708,79 +1230,48 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
return ret;
}
-static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
- const char *opname)
-{
- if (b->type != q->type) {
- dprintk(1, "%s: invalid buffer type\n", opname);
- return -EINVAL;
- }
-
- if (b->index >= q->num_buffers) {
- dprintk(1, "%s: buffer index out of range\n", opname);
- return -EINVAL;
- }
-
- if (q->bufs[b->index] == NULL) {
- /* Should never happen */
- dprintk(1, "%s: buffer is NULL\n", opname);
- return -EINVAL;
- }
-
- if (b->memory != q->memory) {
- dprintk(1, "%s: invalid memory type\n", opname);
- return -EINVAL;
- }
-
- return __verify_planes_array(q->bufs[b->index], b);
-}
-
/**
- * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
+ * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace
+ * to the kernel
* @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_prepare_buf
+ * @index: id number of the buffer
+ * @pb: buffer structure passed from userspace to vidioc_prepare_buf
* handler in driver
*
* Should be called from vidioc_prepare_buf ioctl handler of a driver.
- * This function:
- * 1) verifies the passed buffer,
- * 2) calls buf_prepare callback in the driver (if provided), in which
- * driver-specific buffer initialization can be performed,
+ * The passed buffer should have been verified.
+ * This function calls buf_prepare callback in the driver (if provided),
+ * in which driver-specific buffer initialization can be performed,
*
* The return values from this function are intended to be directly returned
* from vidioc_prepare_buf handler in driver.
*/
-int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
+int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
{
struct vb2_buffer *vb;
int ret;
- if (vb2_fileio_is_active(q)) {
- dprintk(1, "file io in progress\n");
- return -EBUSY;
- }
-
- ret = vb2_queue_or_prepare_buf(q, b, "prepare_buf");
- if (ret)
- return ret;
-
- vb = q->bufs[b->index];
+ vb = q->bufs[index];
if (vb->state != VB2_BUF_STATE_DEQUEUED) {
dprintk(1, "invalid buffer state %d\n",
vb->state);
return -EINVAL;
}
- ret = __buf_prepare(vb, b);
- if (!ret) {
- /* Fill buffer information for the userspace */
- __fill_v4l2_buffer(vb, b);
+ ret = __buf_prepare(vb, pb);
+ if (ret)
+ return ret;
+
+ /* Fill buffer information for the userspace */
+ ret = call_bufop(q, fill_user_buffer, vb, pb);
+ if (ret)
+ return ret;
+
+ dprintk(1, "prepare of buffer %d succeeded\n", vb->index);
- dprintk(1, "prepare of buffer %d succeeded\n", vb->v4l2_buf.index);
- }
return ret;
}
-EXPORT_SYMBOL_GPL(vb2_prepare_buf);
+EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
/**
* vb2_start_streaming() - Attempt to start streaming.
@@ -1845,19 +1336,34 @@ static int vb2_start_streaming(struct vb2_queue *q)
return ret;
}
-static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
+/**
+ * vb2_core_qbuf() - Queue a buffer from userspace
+ * @q: videobuf2 queue
+ * @index: id number of the buffer
+ * @pb: buffer structure passed from userspace to vidioc_qbuf handler
+ * in driver
+ *
+ * Should be called from vidioc_qbuf ioctl handler of a driver.
+ * The passed buffer should have been verified.
+ * This function:
+ * 1) if necessary, calls buf_prepare callback in the driver (if provided), in
+ * which driver-specific buffer initialization can be performed,
+ * 2) if streaming is on, queues the buffer in driver by the means of buf_queue
+ * callback for processing.
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_qbuf handler in driver.
+ */
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
{
- int ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
struct vb2_buffer *vb;
+ int ret;
- if (ret)
- return ret;
-
- vb = q->bufs[b->index];
+ vb = q->bufs[index];
switch (vb->state) {
case VB2_BUF_STATE_DEQUEUED:
- ret = __buf_prepare(vb, b);
+ ret = __buf_prepare(vb, pb);
if (ret)
return ret;
break;
@@ -1879,18 +1385,8 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
q->queued_count++;
q->waiting_for_buffers = false;
vb->state = VB2_BUF_STATE_QUEUED;
- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- /*
- * For output buffers copy the timestamp if needed,
- * and the timecode field and flag if needed.
- */
- if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
- V4L2_BUF_FLAG_TIMESTAMP_COPY)
- vb->v4l2_buf.timestamp = b->timestamp;
- vb->v4l2_buf.flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
- if (b->flags & V4L2_BUF_FLAG_TIMECODE)
- vb->v4l2_buf.timecode = b->timecode;
- }
+
+ call_bufop(q, set_timestamp, vb, pb);
trace_vb2_qbuf(q, vb);
@@ -1902,7 +1398,9 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
__enqueue_in_driver(vb);
/* Fill buffer information for the userspace */
- __fill_v4l2_buffer(vb, b);
+ ret = call_bufop(q, fill_user_buffer, vb, pb);
+ if (ret)
+ return ret;
/*
* If streamon has been called, and we haven't yet called
@@ -1917,37 +1415,10 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
return ret;
}
- dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
+ dprintk(1, "qbuf of buffer %d succeeded\n", vb->index);
return 0;
}
-
-/**
- * vb2_qbuf() - Queue a buffer from userspace
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_qbuf handler
- * in driver
- *
- * Should be called from vidioc_qbuf ioctl handler of a driver.
- * This function:
- * 1) verifies the passed buffer,
- * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
- * which driver-specific buffer initialization can be performed,
- * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
- * callback for processing.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_qbuf handler in driver.
- */
-int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
-{
- if (vb2_fileio_is_active(q)) {
- dprintk(1, "file io in progress\n");
- return -EBUSY;
- }
-
- return vb2_internal_qbuf(q, b);
-}
-EXPORT_SYMBOL_GPL(vb2_qbuf);
+EXPORT_SYMBOL_GPL(vb2_core_qbuf);
/**
* __vb2_wait_for_done_vb() - wait for a buffer to become available
@@ -2031,7 +1502,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
* Will sleep if required for nonblocking == false.
*/
static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
- struct v4l2_buffer *b, int nonblocking)
+ int nonblocking)
{
unsigned long flags;
int ret;
@@ -2052,10 +1523,10 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
/*
* Only remove the buffer from done_list if v4l2_buffer can handle all
* the planes.
+ * Verifying planes is NOT necessary since it already has been checked
+ * before the buffer is queued/prepared. So it can never fail.
*/
- ret = __verify_planes_array(*vb, b);
- if (!ret)
- list_del(&(*vb)->done_entry);
+ list_del(&(*vb)->done_entry);
spin_unlock_irqrestore(&q->done_lock, flags);
return ret;
@@ -2098,7 +1569,7 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
vb->state = VB2_BUF_STATE_DEQUEUED;
/* unmap DMABUF buffer */
- if (q->memory == V4L2_MEMORY_DMABUF)
+ if (q->memory == VB2_MEMORY_DMABUF)
for (i = 0; i < vb->num_planes; ++i) {
if (!vb->planes[i].dbuf_mapped)
continue;
@@ -2107,16 +1578,33 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
}
}
-static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
+/**
+ * vb2_dqbuf() - Dequeue a buffer to the userspace
+ * @q: videobuf2 queue
+ * @pb: buffer structure passed from userspace to vidioc_dqbuf handler
+ * in driver
+ * @nonblocking: if true, this call will not sleep waiting for a buffer if no
+ * buffers ready for dequeuing are present. Normally the driver
+ * would be passing (file->f_flags & O_NONBLOCK) here
+ *
+ * Should be called from vidioc_dqbuf ioctl handler of a driver.
+ * The passed buffer should have been verified.
+ * This function:
+ * 1) calls buf_finish callback in the driver (if provided), in which
+ * driver can perform any additional operations that may be required before
+ * returning the buffer to userspace, such as cache sync,
+ * 2) the buffer struct members are filled with relevant information for
+ * the userspace.
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_dqbuf handler in driver.
+ */
+int vb2_core_dqbuf(struct vb2_queue *q, void *pb, bool nonblocking)
{
struct vb2_buffer *vb = NULL;
int ret;
- if (b->type != q->type) {
- dprintk(1, "invalid buffer type\n");
- return -EINVAL;
- }
- ret = __vb2_get_done_vb(q, &vb, b, nonblocking);
+ ret = __vb2_get_done_vb(q, &vb, nonblocking);
if (ret < 0)
return ret;
@@ -2135,55 +1623,26 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
call_void_vb_qop(vb, buf_finish, vb);
/* Fill buffer information for the userspace */
- __fill_v4l2_buffer(vb, b);
+ ret = call_bufop(q, fill_user_buffer, vb, pb);
+ if (ret)
+ return ret;
+
/* Remove from videobuf queue */
list_del(&vb->queued_entry);
q->queued_count--;
trace_vb2_dqbuf(q, vb);
- if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
- vb->v4l2_buf.flags & V4L2_BUF_FLAG_LAST)
- q->last_buffer_dequeued = true;
/* go back to dequeued state */
__vb2_dqbuf(vb);
dprintk(1, "dqbuf of buffer %d, with state %d\n",
- vb->v4l2_buf.index, vb->state);
+ vb->index, vb->state);
return 0;
-}
-/**
- * vb2_dqbuf() - Dequeue a buffer to the userspace
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_dqbuf handler
- * in driver
- * @nonblocking: if true, this call will not sleep waiting for a buffer if no
- * buffers ready for dequeuing are present. Normally the driver
- * would be passing (file->f_flags & O_NONBLOCK) here
- *
- * Should be called from vidioc_dqbuf ioctl handler of a driver.
- * This function:
- * 1) verifies the passed buffer,
- * 2) calls buf_finish callback in the driver (if provided), in which
- * driver can perform any additional operations that may be required before
- * returning the buffer to userspace, such as cache sync,
- * 3) the buffer struct members are filled with relevant information for
- * the userspace.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_dqbuf handler in driver.
- */
-int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
-{
- if (vb2_fileio_is_active(q)) {
- dprintk(1, "file io in progress\n");
- return -EBUSY;
- }
- return vb2_internal_dqbuf(q, b, nonblocking);
}
-EXPORT_SYMBOL_GPL(vb2_dqbuf);
+EXPORT_SYMBOL_GPL(vb2_core_dqbuf);
/**
* __vb2_queue_cancel() - cancel and stop (pause) streaming
@@ -2253,7 +1712,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
}
}
-static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
+int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
{
int ret;
@@ -2295,6 +1754,7 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
dprintk(3, "successful\n");
return 0;
}
+EXPORT_SYMBOL_GPL(vb2_core_streamon);
/**
* vb2_queue_error() - signal a fatal error on the queue
@@ -2317,30 +1777,7 @@ void vb2_queue_error(struct vb2_queue *q)
}
EXPORT_SYMBOL_GPL(vb2_queue_error);
-/**
- * vb2_streamon - start streaming
- * @q: videobuf2 queue
- * @type: type argument passed from userspace to vidioc_streamon handler
- *
- * Should be called from vidioc_streamon handler of a driver.
- * This function:
- * 1) verifies current state
- * 2) passes any previously queued buffers to the driver and starts streaming
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_streamon handler in the driver.
- */
-int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
-{
- if (vb2_fileio_is_active(q)) {
- dprintk(1, "file io in progress\n");
- return -EBUSY;
- }
- return vb2_internal_streamon(q, type);
-}
-EXPORT_SYMBOL_GPL(vb2_streamon);
-
-static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
+int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)
{
if (type != q->type) {
dprintk(1, "invalid stream type\n");
@@ -2357,37 +1794,13 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
* their normal dequeued state.
*/
__vb2_queue_cancel(q);
- q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
+ q->waiting_for_buffers = !q->is_output;
q->last_buffer_dequeued = false;
dprintk(3, "successful\n");
return 0;
}
-
-/**
- * vb2_streamoff - stop streaming
- * @q: videobuf2 queue
- * @type: type argument passed from userspace to vidioc_streamoff handler
- *
- * Should be called from vidioc_streamoff handler of a driver.
- * This function:
- * 1) verifies current state,
- * 2) stop streaming and dequeues any queued buffers, including those previously
- * passed to the driver (after waiting for the driver to finish).
- *
- * This call can be used for pausing playback.
- * The return values from this function are intended to be directly returned
- * from vidioc_streamoff handler in the driver
- */
-int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
-{
- if (vb2_fileio_is_active(q)) {
- dprintk(1, "file io in progress\n");
- return -EBUSY;
- }
- return vb2_internal_streamoff(q, type);
-}
-EXPORT_SYMBOL_GPL(vb2_streamoff);
+EXPORT_SYMBOL_GPL(vb2_core_streamoff);
/**
* __find_plane_by_offset() - find plane associated with the given offset off
@@ -2407,7 +1820,7 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
vb = q->bufs[buffer];
for (plane = 0; plane < vb->num_planes; ++plane) {
- if (vb->v4l2_planes[plane].m.mem_offset == off) {
+ if (vb->planes[plane].m.offset == off) {
*_buffer = buffer;
*_plane = plane;
return 0;
@@ -2419,22 +1832,27 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
}
/**
- * vb2_expbuf() - Export a buffer as a file descriptor
+ * vb2_core_expbuf() - Export a buffer as a file descriptor
* @q: videobuf2 queue
- * @eb: export buffer structure passed from userspace to vidioc_expbuf
- * handler in driver
+ * @fd: file descriptor associated with DMABUF (set by driver) *
+ * @type: buffer type
+ * @index: id number of the buffer
+ * @plane: index of the plane to be exported, 0 for single plane queues
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
*
* The return values from this function are intended to be directly returned
* from vidioc_expbuf handler in driver.
*/
-int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
+ unsigned int index, unsigned int plane, unsigned int flags)
{
struct vb2_buffer *vb = NULL;
struct vb2_plane *vb_plane;
int ret;
struct dma_buf *dbuf;
- if (q->memory != V4L2_MEMORY_MMAP) {
+ if (q->memory != VB2_MEMORY_MMAP) {
dprintk(1, "queue is not currently set up for mmap\n");
return -EINVAL;
}
@@ -2444,24 +1862,24 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
return -EINVAL;
}
- if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) {
+ if (flags & ~(O_CLOEXEC | O_ACCMODE)) {
dprintk(1, "queue does support only O_CLOEXEC and access mode flags\n");
return -EINVAL;
}
- if (eb->type != q->type) {
+ if (type != q->type) {
dprintk(1, "invalid buffer type\n");
return -EINVAL;
}
- if (eb->index >= q->num_buffers) {
+ if (index >= q->num_buffers) {
dprintk(1, "buffer index out of range\n");
return -EINVAL;
}
- vb = q->bufs[eb->index];
+ vb = q->bufs[index];
- if (eb->plane >= vb->num_planes) {
+ if (plane >= vb->num_planes) {
dprintk(1, "buffer plane out of range\n");
return -EINVAL;
}
@@ -2471,30 +1889,31 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
return -EBUSY;
}
- vb_plane = &vb->planes[eb->plane];
+ vb_plane = &vb->planes[plane];
- dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
+ dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv,
+ flags & O_ACCMODE);
if (IS_ERR_OR_NULL(dbuf)) {
dprintk(1, "failed to export buffer %d, plane %d\n",
- eb->index, eb->plane);
+ index, plane);
return -EINVAL;
}
- ret = dma_buf_fd(dbuf, eb->flags & ~O_ACCMODE);
+ ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE);
if (ret < 0) {
dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
- eb->index, eb->plane, ret);
+ index, plane, ret);
dma_buf_put(dbuf);
return ret;
}
dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
- eb->index, eb->plane, ret);
- eb->fd = ret;
+ index, plane, ret);
+ *fd = ret;
return 0;
}
-EXPORT_SYMBOL_GPL(vb2_expbuf);
+EXPORT_SYMBOL_GPL(vb2_core_expbuf);
/**
* vb2_mmap() - map video buffers into application address space
@@ -2523,7 +1942,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
int ret;
unsigned long length;
- if (q->memory != V4L2_MEMORY_MMAP) {
+ if (q->memory != VB2_MEMORY_MMAP) {
dprintk(1, "queue is not currently set up for mmap\n");
return -EINVAL;
}
@@ -2535,7 +1954,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
dprintk(1, "invalid vma flags, VM_SHARED needed\n");
return -EINVAL;
}
- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+ if (q->is_output) {
if (!(vma->vm_flags & VM_WRITE)) {
dprintk(1, "invalid vma flags, VM_WRITE needed\n");
return -EINVAL;
@@ -2565,7 +1984,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
* The buffer length was page_aligned at __vb2_buf_mem_alloc(),
* so, we need to do the same here.
*/
- length = PAGE_ALIGN(vb->v4l2_planes[plane].length);
+ length = PAGE_ALIGN(vb->planes[plane].length);
if (length < (vma->vm_end - vma->vm_start)) {
dprintk(1,
"MMAP invalid, as it would overflow buffer length\n");
@@ -2596,7 +2015,7 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
void *vaddr;
int ret;
- if (q->memory != V4L2_MEMORY_MMAP) {
+ if (q->memory != VB2_MEMORY_MMAP) {
dprintk(1, "queue is not currently set up for mmap\n");
return -EINVAL;
}
@@ -2616,123 +2035,8 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
#endif
-static int __vb2_init_fileio(struct vb2_queue *q, int read);
-static int __vb2_cleanup_fileio(struct vb2_queue *q);
-
-/**
- * vb2_poll() - implements poll userspace operation
- * @q: videobuf2 queue
- * @file: file argument passed to the poll file operation handler
- * @wait: wait argument passed to the poll file operation handler
- *
- * This function implements poll file operation handler for a driver.
- * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
- * be informed that the file descriptor of a video device is available for
- * reading.
- * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
- * will be reported as available for writing.
- *
- * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
- * pending events.
- *
- * The return values from this function are intended to be directly returned
- * from poll handler in driver.
- */
-unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
-{
- struct video_device *vfd = video_devdata(file);
- unsigned long req_events = poll_requested_events(wait);
- struct vb2_buffer *vb = NULL;
- unsigned int res = 0;
- unsigned long flags;
-
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
- struct v4l2_fh *fh = file->private_data;
-
- if (v4l2_event_pending(fh))
- res = POLLPRI;
- else if (req_events & POLLPRI)
- poll_wait(file, &fh->wait, wait);
- }
-
- if (!V4L2_TYPE_IS_OUTPUT(q->type) && !(req_events & (POLLIN | POLLRDNORM)))
- return res;
- if (V4L2_TYPE_IS_OUTPUT(q->type) && !(req_events & (POLLOUT | POLLWRNORM)))
- return res;
-
- /*
- * Start file I/O emulator only if streaming API has not been used yet.
- */
- if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) {
- if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) &&
- (req_events & (POLLIN | POLLRDNORM))) {
- if (__vb2_init_fileio(q, 1))
- return res | POLLERR;
- }
- if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE) &&
- (req_events & (POLLOUT | POLLWRNORM))) {
- if (__vb2_init_fileio(q, 0))
- return res | POLLERR;
- /*
- * Write to OUTPUT queue can be done immediately.
- */
- return res | POLLOUT | POLLWRNORM;
- }
- }
-
- /*
- * There is nothing to wait for if the queue isn't streaming, or if the
- * error flag is set.
- */
- if (!vb2_is_streaming(q) || q->error)
- return res | POLLERR;
- /*
- * For compatibility with vb1: if QBUF hasn't been called yet, then
- * return POLLERR as well. This only affects capture queues, output
- * queues will always initialize waiting_for_buffers to false.
- */
- if (q->waiting_for_buffers)
- return res | POLLERR;
-
- /*
- * For output streams you can write as long as there are fewer buffers
- * queued than there are buffers available.
- */
- if (V4L2_TYPE_IS_OUTPUT(q->type) && q->queued_count < q->num_buffers)
- return res | POLLOUT | POLLWRNORM;
-
- if (list_empty(&q->done_list)) {
- /*
- * If the last buffer was dequeued from a capture queue,
- * return immediately. DQBUF will return -EPIPE.
- */
- if (q->last_buffer_dequeued)
- return res | POLLIN | POLLRDNORM;
-
- poll_wait(file, &q->done_wq, wait);
- }
-
- /*
- * Take first buffer available for dequeuing.
- */
- spin_lock_irqsave(&q->done_lock, flags);
- if (!list_empty(&q->done_list))
- vb = list_first_entry(&q->done_list, struct vb2_buffer,
- done_entry);
- spin_unlock_irqrestore(&q->done_lock, flags);
-
- if (vb && (vb->state == VB2_BUF_STATE_DONE
- || vb->state == VB2_BUF_STATE_ERROR)) {
- return (V4L2_TYPE_IS_OUTPUT(q->type)) ?
- res | POLLOUT | POLLWRNORM :
- res | POLLIN | POLLRDNORM;
- }
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_poll);
-
/**
- * vb2_queue_init() - initialize a videobuf2 queue
+ * vb2_core_queue_init() - initialize a videobuf2 queue
* @q: videobuf2 queue; this structure should be allocated in driver
*
* The vb2_queue structure should be allocated by the driver. The driver is
@@ -2742,7 +2046,7 @@ EXPORT_SYMBOL_GPL(vb2_poll);
* to the struct vb2_queue description in include/media/videobuf2-core.h
* for more information.
*/
-int vb2_queue_init(struct vb2_queue *q)
+int vb2_core_queue_init(struct vb2_queue *q)
{
/*
* Sanity check
@@ -2753,16 +2057,9 @@ int vb2_queue_init(struct vb2_queue *q)
WARN_ON(!q->type) ||
WARN_ON(!q->io_modes) ||
WARN_ON(!q->ops->queue_setup) ||
- WARN_ON(!q->ops->buf_queue) ||
- WARN_ON(q->timestamp_flags &
- ~(V4L2_BUF_FLAG_TIMESTAMP_MASK |
- V4L2_BUF_FLAG_TSTAMP_SRC_MASK)))
+ WARN_ON(!q->ops->buf_queue))
return -EINVAL;
- /* Warn that the driver should choose an appropriate timestamp type */
- WARN_ON((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
- V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN);
-
INIT_LIST_HEAD(&q->queued_list);
INIT_LIST_HEAD(&q->done_list);
spin_lock_init(&q->done_lock);
@@ -2774,819 +2071,24 @@ int vb2_queue_init(struct vb2_queue *q)
return 0;
}
-EXPORT_SYMBOL_GPL(vb2_queue_init);
+EXPORT_SYMBOL_GPL(vb2_core_queue_init);
/**
- * vb2_queue_release() - stop streaming, release the queue and free memory
+ * vb2_core_queue_release() - stop streaming, release the queue and free memory
* @q: videobuf2 queue
*
* This function stops streaming and performs necessary clean ups, including
* freeing video buffer memory. The driver is responsible for freeing
* the vb2_queue structure itself.
*/
-void vb2_queue_release(struct vb2_queue *q)
+void vb2_core_queue_release(struct vb2_queue *q)
{
- __vb2_cleanup_fileio(q);
__vb2_queue_cancel(q);
mutex_lock(&q->mmap_lock);
__vb2_queue_free(q, q->num_buffers);
mutex_unlock(&q->mmap_lock);
}
-EXPORT_SYMBOL_GPL(vb2_queue_release);
-
-/**
- * struct vb2_fileio_buf - buffer context used by file io emulator
- *
- * vb2 provides a compatibility layer and emulator of file io (read and
- * write) calls on top of streaming API. This structure is used for
- * tracking context related to the buffers.
- */
-struct vb2_fileio_buf {
- void *vaddr;
- unsigned int size;
- unsigned int pos;
- unsigned int queued:1;
-};
-
-/**
- * struct vb2_fileio_data - queue context used by file io emulator
- *
- * @cur_index: the index of the buffer currently being read from or
- * written to. If equal to q->num_buffers then a new buffer
- * must be dequeued.
- * @initial_index: in the read() case all buffers are queued up immediately
- * in __vb2_init_fileio() and __vb2_perform_fileio() just cycles
- * buffers. However, in the write() case no buffers are initially
- * queued, instead whenever a buffer is full it is queued up by
- * __vb2_perform_fileio(). Only once all available buffers have
- * been queued up will __vb2_perform_fileio() start to dequeue
- * buffers. This means that initially __vb2_perform_fileio()
- * needs to know what buffer index to use when it is queuing up
- * the buffers for the first time. That initial index is stored
- * in this field. Once it is equal to q->num_buffers all
- * available buffers have been queued and __vb2_perform_fileio()
- * should start the normal dequeue/queue cycle.
- *
- * vb2 provides a compatibility layer and emulator of file io (read and
- * write) calls on top of streaming API. For proper operation it required
- * this structure to save the driver state between each call of the read
- * or write function.
- */
-struct vb2_fileio_data {
- struct v4l2_requestbuffers req;
- struct v4l2_plane p;
- struct v4l2_buffer b;
- struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
- unsigned int cur_index;
- unsigned int initial_index;
- unsigned int q_count;
- unsigned int dq_count;
- unsigned read_once:1;
- unsigned write_immediately:1;
-};
-
-/**
- * __vb2_init_fileio() - initialize file io emulator
- * @q: videobuf2 queue
- * @read: mode selector (1 means read, 0 means write)
- */
-static int __vb2_init_fileio(struct vb2_queue *q, int read)
-{
- struct vb2_fileio_data *fileio;
- int i, ret;
- unsigned int count = 0;
-
- /*
- * Sanity check
- */
- if (WARN_ON((read && !(q->io_modes & VB2_READ)) ||
- (!read && !(q->io_modes & VB2_WRITE))))
- return -EINVAL;
-
- /*
- * Check if device supports mapping buffers to kernel virtual space.
- */
- if (!q->mem_ops->vaddr)
- return -EBUSY;
-
- /*
- * Check if streaming api has not been already activated.
- */
- if (q->streaming || q->num_buffers > 0)
- return -EBUSY;
-
- /*
- * Start with count 1, driver can increase it in queue_setup()
- */
- count = 1;
-
- dprintk(3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n",
- (read) ? "read" : "write", count, q->fileio_read_once,
- q->fileio_write_immediately);
-
- fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
- if (fileio == NULL)
- return -ENOMEM;
-
- fileio->read_once = q->fileio_read_once;
- fileio->write_immediately = q->fileio_write_immediately;
-
- /*
- * Request buffers and use MMAP type to force driver
- * to allocate buffers by itself.
- */
- fileio->req.count = count;
- fileio->req.memory = V4L2_MEMORY_MMAP;
- fileio->req.type = q->type;
- q->fileio = fileio;
- ret = __reqbufs(q, &fileio->req);
- if (ret)
- goto err_kfree;
-
- /*
- * Check if plane_count is correct
- * (multiplane buffers are not supported).
- */
- if (q->bufs[0]->num_planes != 1) {
- ret = -EBUSY;
- goto err_reqbufs;
- }
-
- /*
- * Get kernel address of each buffer.
- */
- for (i = 0; i < q->num_buffers; i++) {
- fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
- if (fileio->bufs[i].vaddr == NULL) {
- ret = -EINVAL;
- goto err_reqbufs;
- }
- fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
- }
-
- /*
- * Read mode requires pre queuing of all buffers.
- */
- if (read) {
- bool is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type);
-
- /*
- * Queue all buffers.
- */
- for (i = 0; i < q->num_buffers; i++) {
- struct v4l2_buffer *b = &fileio->b;
-
- memset(b, 0, sizeof(*b));
- b->type = q->type;
- if (is_multiplanar) {
- memset(&fileio->p, 0, sizeof(fileio->p));
- b->m.planes = &fileio->p;
- b->length = 1;
- }
- b->memory = q->memory;
- b->index = i;
- ret = vb2_internal_qbuf(q, b);
- if (ret)
- goto err_reqbufs;
- fileio->bufs[i].queued = 1;
- }
- /*
- * All buffers have been queued, so mark that by setting
- * initial_index to q->num_buffers
- */
- fileio->initial_index = q->num_buffers;
- fileio->cur_index = q->num_buffers;
- }
-
- /*
- * Start streaming.
- */
- ret = vb2_internal_streamon(q, q->type);
- if (ret)
- goto err_reqbufs;
-
- return ret;
-
-err_reqbufs:
- fileio->req.count = 0;
- __reqbufs(q, &fileio->req);
-
-err_kfree:
- q->fileio = NULL;
- kfree(fileio);
- return ret;
-}
-
-/**
- * __vb2_cleanup_fileio() - free resourced used by file io emulator
- * @q: videobuf2 queue
- */
-static int __vb2_cleanup_fileio(struct vb2_queue *q)
-{
- struct vb2_fileio_data *fileio = q->fileio;
-
- if (fileio) {
- vb2_internal_streamoff(q, q->type);
- q->fileio = NULL;
- fileio->req.count = 0;
- vb2_reqbufs(q, &fileio->req);
- kfree(fileio);
- dprintk(3, "file io emulator closed\n");
- }
- return 0;
-}
-
-/**
- * __vb2_perform_fileio() - perform a single file io (read or write) operation
- * @q: videobuf2 queue
- * @data: pointed to target userspace buffer
- * @count: number of bytes to read or write
- * @ppos: file handle position tracking pointer
- * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
- * @read: access mode selector (1 means read, 0 means write)
- */
-static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
- loff_t *ppos, int nonblock, int read)
-{
- struct vb2_fileio_data *fileio;
- struct vb2_fileio_buf *buf;
- bool is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type);
- /*
- * When using write() to write data to an output video node the vb2 core
- * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody
- * else is able to provide this information with the write() operation.
- */
- bool set_timestamp = !read &&
- (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
- V4L2_BUF_FLAG_TIMESTAMP_COPY;
- int ret, index;
-
- dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n",
- read ? "read" : "write", (long)*ppos, count,
- nonblock ? "non" : "");
-
- if (!data)
- return -EINVAL;
-
- /*
- * Initialize emulator on first call.
- */
- if (!vb2_fileio_is_active(q)) {
- ret = __vb2_init_fileio(q, read);
- dprintk(3, "vb2_init_fileio result: %d\n", ret);
- if (ret)
- return ret;
- }
- fileio = q->fileio;
-
- /*
- * Check if we need to dequeue the buffer.
- */
- index = fileio->cur_index;
- if (index >= q->num_buffers) {
- /*
- * Call vb2_dqbuf to get buffer back.
- */
- memset(&fileio->b, 0, sizeof(fileio->b));
- fileio->b.type = q->type;
- fileio->b.memory = q->memory;
- if (is_multiplanar) {
- memset(&fileio->p, 0, sizeof(fileio->p));
- fileio->b.m.planes = &fileio->p;
- fileio->b.length = 1;
- }
- ret = vb2_internal_dqbuf(q, &fileio->b, nonblock);
- dprintk(5, "vb2_dqbuf result: %d\n", ret);
- if (ret)
- return ret;
- fileio->dq_count += 1;
-
- fileio->cur_index = index = fileio->b.index;
- buf = &fileio->bufs[index];
-
- /*
- * Get number of bytes filled by the driver
- */
- buf->pos = 0;
- buf->queued = 0;
- buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0)
- : vb2_plane_size(q->bufs[index], 0);
- /* Compensate for data_offset on read in the multiplanar case. */
- if (is_multiplanar && read &&
- fileio->b.m.planes[0].data_offset < buf->size) {
- buf->pos = fileio->b.m.planes[0].data_offset;
- buf->size -= buf->pos;
- }
- } else {
- buf = &fileio->bufs[index];
- }
-
- /*
- * Limit count on last few bytes of the buffer.
- */
- if (buf->pos + count > buf->size) {
- count = buf->size - buf->pos;
- dprintk(5, "reducing read count: %zd\n", count);
- }
-
- /*
- * Transfer data to userspace.
- */
- dprintk(3, "copying %zd bytes - buffer %d, offset %u\n",
- count, index, buf->pos);
- if (read)
- ret = copy_to_user(data, buf->vaddr + buf->pos, count);
- else
- ret = copy_from_user(buf->vaddr + buf->pos, data, count);
- if (ret) {
- dprintk(3, "error copying data\n");
- return -EFAULT;
- }
-
- /*
- * Update counters.
- */
- buf->pos += count;
- *ppos += count;
-
- /*
- * Queue next buffer if required.
- */
- if (buf->pos == buf->size || (!read && fileio->write_immediately)) {
- /*
- * Check if this is the last buffer to read.
- */
- if (read && fileio->read_once && fileio->dq_count == 1) {
- dprintk(3, "read limit reached\n");
- return __vb2_cleanup_fileio(q);
- }
-
- /*
- * Call vb2_qbuf and give buffer to the driver.
- */
- memset(&fileio->b, 0, sizeof(fileio->b));
- fileio->b.type = q->type;
- fileio->b.memory = q->memory;
- fileio->b.index = index;
- fileio->b.bytesused = buf->pos;
- if (is_multiplanar) {
- memset(&fileio->p, 0, sizeof(fileio->p));
- fileio->p.bytesused = buf->pos;
- fileio->b.m.planes = &fileio->p;
- fileio->b.length = 1;
- }
- if (set_timestamp)
- v4l2_get_timestamp(&fileio->b.timestamp);
- ret = vb2_internal_qbuf(q, &fileio->b);
- dprintk(5, "vb2_dbuf result: %d\n", ret);
- if (ret)
- return ret;
-
- /*
- * Buffer has been queued, update the status
- */
- buf->pos = 0;
- buf->queued = 1;
- buf->size = vb2_plane_size(q->bufs[index], 0);
- fileio->q_count += 1;
- /*
- * If we are queuing up buffers for the first time, then
- * increase initial_index by one.
- */
- if (fileio->initial_index < q->num_buffers)
- fileio->initial_index++;
- /*
- * The next buffer to use is either a buffer that's going to be
- * queued for the first time (initial_index < q->num_buffers)
- * or it is equal to q->num_buffers, meaning that the next
- * time we need to dequeue a buffer since we've now queued up
- * all the 'first time' buffers.
- */
- fileio->cur_index = fileio->initial_index;
- }
-
- /*
- * Return proper number of bytes processed.
- */
- if (ret == 0)
- ret = count;
- return ret;
-}
-
-size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
- loff_t *ppos, int nonblocking)
-{
- return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
-}
-EXPORT_SYMBOL_GPL(vb2_read);
-
-size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
- loff_t *ppos, int nonblocking)
-{
- return __vb2_perform_fileio(q, (char __user *) data, count,
- ppos, nonblocking, 0);
-}
-EXPORT_SYMBOL_GPL(vb2_write);
-
-struct vb2_threadio_data {
- struct task_struct *thread;
- vb2_thread_fnc fnc;
- void *priv;
- bool stop;
-};
-
-static int vb2_thread(void *data)
-{
- struct vb2_queue *q = data;
- struct vb2_threadio_data *threadio = q->threadio;
- struct vb2_fileio_data *fileio = q->fileio;
- bool set_timestamp = false;
- int prequeue = 0;
- int index = 0;
- int ret = 0;
-
- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- prequeue = q->num_buffers;
- set_timestamp =
- (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
- V4L2_BUF_FLAG_TIMESTAMP_COPY;
- }
-
- set_freezable();
-
- for (;;) {
- struct vb2_buffer *vb;
-
- /*
- * Call vb2_dqbuf to get buffer back.
- */
- memset(&fileio->b, 0, sizeof(fileio->b));
- fileio->b.type = q->type;
- fileio->b.memory = q->memory;
- if (prequeue) {
- fileio->b.index = index++;
- prequeue--;
- } else {
- call_void_qop(q, wait_finish, q);
- if (!threadio->stop)
- ret = vb2_internal_dqbuf(q, &fileio->b, 0);
- call_void_qop(q, wait_prepare, q);
- dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
- }
- if (ret || threadio->stop)
- break;
- try_to_freeze();
-
- vb = q->bufs[fileio->b.index];
- if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR))
- if (threadio->fnc(vb, threadio->priv))
- break;
- call_void_qop(q, wait_finish, q);
- if (set_timestamp)
- v4l2_get_timestamp(&fileio->b.timestamp);
- if (!threadio->stop)
- ret = vb2_internal_qbuf(q, &fileio->b);
- call_void_qop(q, wait_prepare, q);
- if (ret || threadio->stop)
- break;
- }
-
- /* Hmm, linux becomes *very* unhappy without this ... */
- while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- }
- return 0;
-}
-
-/*
- * This function should not be used for anything else but the videobuf2-dvb
- * support. If you think you have another good use-case for this, then please
- * contact the linux-media mailinglist first.
- */
-int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
- const char *thread_name)
-{
- struct vb2_threadio_data *threadio;
- int ret = 0;
-
- if (q->threadio)
- return -EBUSY;
- if (vb2_is_busy(q))
- return -EBUSY;
- if (WARN_ON(q->fileio))
- return -EBUSY;
-
- threadio = kzalloc(sizeof(*threadio), GFP_KERNEL);
- if (threadio == NULL)
- return -ENOMEM;
- threadio->fnc = fnc;
- threadio->priv = priv;
-
- ret = __vb2_init_fileio(q, !V4L2_TYPE_IS_OUTPUT(q->type));
- dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
- if (ret)
- goto nomem;
- q->threadio = threadio;
- threadio->thread = kthread_run(vb2_thread, q, "vb2-%s", thread_name);
- if (IS_ERR(threadio->thread)) {
- ret = PTR_ERR(threadio->thread);
- threadio->thread = NULL;
- goto nothread;
- }
- return 0;
-
-nothread:
- __vb2_cleanup_fileio(q);
-nomem:
- kfree(threadio);
- return ret;
-}
-EXPORT_SYMBOL_GPL(vb2_thread_start);
-
-int vb2_thread_stop(struct vb2_queue *q)
-{
- struct vb2_threadio_data *threadio = q->threadio;
- int err;
-
- if (threadio == NULL)
- return 0;
- threadio->stop = true;
- /* Wake up all pending sleeps in the thread */
- vb2_queue_error(q);
- err = kthread_stop(threadio->thread);
- __vb2_cleanup_fileio(q);
- threadio->thread = NULL;
- kfree(threadio);
- q->threadio = NULL;
- return err;
-}
-EXPORT_SYMBOL_GPL(vb2_thread_stop);
-
-/*
- * The following functions are not part of the vb2 core API, but are helper
- * functions that plug into struct v4l2_ioctl_ops, struct v4l2_file_operations
- * and struct vb2_ops.
- * They contain boilerplate code that most if not all drivers have to do
- * and so they simplify the driver code.
- */
-
-/* The queue is busy if there is a owner and you are not that owner. */
-static inline bool vb2_queue_is_busy(struct video_device *vdev, struct file *file)
-{
- return vdev->queue->owner && vdev->queue->owner != file->private_data;
-}
-
-/* vb2 ioctl helpers */
-
-int vb2_ioctl_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct video_device *vdev = video_devdata(file);
- int res = __verify_memory_type(vdev->queue, p->memory, p->type);
-
- if (res)
- return res;
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- res = __reqbufs(vdev->queue, p);
- /* If count == 0, then the owner has released all buffers and he
- is no longer owner of the queue. Otherwise we have a new owner. */
- if (res == 0)
- vdev->queue->owner = p->count ? file->private_data : NULL;
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_reqbufs);
-
-int vb2_ioctl_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *p)
-{
- struct video_device *vdev = video_devdata(file);
- int res = __verify_memory_type(vdev->queue, p->memory, p->format.type);
-
- p->index = vdev->queue->num_buffers;
- /* If count == 0, then just check if memory and type are valid.
- Any -EBUSY result from __verify_memory_type can be mapped to 0. */
- if (p->count == 0)
- return res != -EBUSY ? res : 0;
- if (res)
- return res;
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- res = __create_bufs(vdev->queue, p);
- if (res == 0)
- vdev->queue->owner = file->private_data;
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_create_bufs);
-
-int vb2_ioctl_prepare_buf(struct file *file, void *priv,
- struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_prepare_buf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf);
-
-int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- /* No need to call vb2_queue_is_busy(), anyone can query buffers. */
- return vb2_querybuf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_querybuf);
-
-int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_qbuf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf);
-
-int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_dqbuf(vdev->queue, p, file->f_flags & O_NONBLOCK);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_dqbuf);
-
-int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_streamon(vdev->queue, i);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_streamon);
-
-int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_streamoff(vdev->queue, i);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
-
-int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (vb2_queue_is_busy(vdev, file))
- return -EBUSY;
- return vb2_expbuf(vdev->queue, p);
-}
-EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
-
-/* v4l2_file_operations helpers */
-
-int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *vdev = video_devdata(file);
-
- return vb2_mmap(vdev->queue, vma);
-}
-EXPORT_SYMBOL_GPL(vb2_fop_mmap);
-
-int _vb2_fop_release(struct file *file, struct mutex *lock)
-{
- struct video_device *vdev = video_devdata(file);
-
- if (lock)
- mutex_lock(lock);
- if (file->private_data == vdev->queue->owner) {
- vb2_queue_release(vdev->queue);
- vdev->queue->owner = NULL;
- }
- if (lock)
- mutex_unlock(lock);
- return v4l2_fh_release(file);
-}
-EXPORT_SYMBOL_GPL(_vb2_fop_release);
-
-int vb2_fop_release(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
-
- return _vb2_fop_release(file, lock);
-}
-EXPORT_SYMBOL_GPL(vb2_fop_release);
-
-ssize_t vb2_fop_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *vdev = video_devdata(file);
- struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
- int err = -EBUSY;
-
- if (!(vdev->queue->io_modes & VB2_WRITE))
- return -EINVAL;
- if (lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
- if (vb2_queue_is_busy(vdev, file))
- goto exit;
- err = vb2_write(vdev->queue, buf, count, ppos,
- file->f_flags & O_NONBLOCK);
- if (vdev->queue->fileio)
- vdev->queue->owner = file->private_data;
-exit:
- if (lock)
- mutex_unlock(lock);
- return err;
-}
-EXPORT_SYMBOL_GPL(vb2_fop_write);
-
-ssize_t vb2_fop_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *vdev = video_devdata(file);
- struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
- int err = -EBUSY;
-
- if (!(vdev->queue->io_modes & VB2_READ))
- return -EINVAL;
- if (lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
- if (vb2_queue_is_busy(vdev, file))
- goto exit;
- err = vb2_read(vdev->queue, buf, count, ppos,
- file->f_flags & O_NONBLOCK);
- if (vdev->queue->fileio)
- vdev->queue->owner = file->private_data;
-exit:
- if (lock)
- mutex_unlock(lock);
- return err;
-}
-EXPORT_SYMBOL_GPL(vb2_fop_read);
-
-unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
-{
- struct video_device *vdev = video_devdata(file);
- struct vb2_queue *q = vdev->queue;
- struct mutex *lock = q->lock ? q->lock : vdev->lock;
- unsigned res;
- void *fileio;
-
- /*
- * If this helper doesn't know how to lock, then you shouldn't be using
- * it but you should write your own.
- */
- WARN_ON(!lock);
-
- if (lock && mutex_lock_interruptible(lock))
- return POLLERR;
-
- fileio = q->fileio;
-
- res = vb2_poll(vdev->queue, file, wait);
-
- /* If fileio was started, then we have a new queue owner. */
- if (!fileio && q->fileio)
- q->owner = file->private_data;
- if (lock)
- mutex_unlock(lock);
- return res;
-}
-EXPORT_SYMBOL_GPL(vb2_fop_poll);
-
-#ifndef CONFIG_MMU
-unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct video_device *vdev = video_devdata(file);
-
- return vb2_get_unmapped_area(vdev->queue, addr, len, pgoff, flags);
-}
-EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area);
-#endif
-
-/* vb2_ops helpers. Only use if vq->lock is non-NULL. */
-
-void vb2_ops_wait_prepare(struct vb2_queue *vq)
-{
- mutex_unlock(vq->lock);
-}
-EXPORT_SYMBOL_GPL(vb2_ops_wait_prepare);
-
-void vb2_ops_wait_finish(struct vb2_queue *vq)
-{
- mutex_lock(vq->lock);
-}
-EXPORT_SYMBOL_GPL(vb2_ops_wait_finish);
+EXPORT_SYMBOL_GPL(vb2_core_queue_release);
MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 2397ceb1dc6b..c33127284cfe 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -17,7 +17,7 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-memops.h>
@@ -100,7 +100,8 @@ static void vb2_dc_prepare(void *buf_priv)
if (!sgt || buf->db_attach)
return;
- dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+ dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
+ buf->dma_dir);
}
static void vb2_dc_finish(void *buf_priv)
@@ -112,7 +113,7 @@ static void vb2_dc_finish(void *buf_priv)
if (!sgt || buf->db_attach)
return;
- dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+ dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
}
/*********************************************/
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index be7bd6535c9d..9985c89f0513 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -17,7 +17,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-memops.h>
#include <media/videobuf2-dma-sg.h>
@@ -210,7 +210,8 @@ static void vb2_dma_sg_prepare(void *buf_priv)
if (buf->db_attach)
return;
- dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+ dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
+ buf->dma_dir);
}
static void vb2_dma_sg_finish(void *buf_priv)
@@ -222,7 +223,7 @@ static void vb2_dma_sg_finish(void *buf_priv)
if (buf->db_attach)
return;
- dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+ dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
}
static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
diff --git a/drivers/media/v4l2-core/videobuf2-internal.h b/drivers/media/v4l2-core/videobuf2-internal.h
new file mode 100644
index 000000000000..79018c749282
--- /dev/null
+++ b/drivers/media/v4l2-core/videobuf2-internal.h
@@ -0,0 +1,161 @@
+#ifndef _MEDIA_VIDEOBUF2_INTERNAL_H
+#define _MEDIA_VIDEOBUF2_INTERNAL_H
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <media/videobuf2-core.h>
+
+extern int vb2_debug;
+
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (vb2_debug >= level) \
+ pr_info("vb2: %s: " fmt, __func__, ## arg); \
+ } while (0)
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+/*
+ * If advanced debugging is on, then count how often each op is called
+ * successfully, which can either be per-buffer or per-queue.
+ *
+ * This makes it easy to check that the 'init' and 'cleanup'
+ * (and variations thereof) stay balanced.
+ */
+
+#define log_memop(vb, op) \
+ dprintk(2, "call_memop(%p, %d, %s)%s\n", \
+ (vb)->vb2_queue, (vb)->index, #op, \
+ (vb)->vb2_queue->mem_ops->op ? "" : " (nop)")
+
+#define call_memop(vb, op, args...) \
+({ \
+ struct vb2_queue *_q = (vb)->vb2_queue; \
+ int err; \
+ \
+ log_memop(vb, op); \
+ err = _q->mem_ops->op ? _q->mem_ops->op(args) : 0; \
+ if (!err) \
+ (vb)->cnt_mem_ ## op++; \
+ err; \
+})
+
+#define call_ptr_memop(vb, op, args...) \
+({ \
+ struct vb2_queue *_q = (vb)->vb2_queue; \
+ void *ptr; \
+ \
+ log_memop(vb, op); \
+ ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL; \
+ if (!IS_ERR_OR_NULL(ptr)) \
+ (vb)->cnt_mem_ ## op++; \
+ ptr; \
+})
+
+#define call_void_memop(vb, op, args...) \
+({ \
+ struct vb2_queue *_q = (vb)->vb2_queue; \
+ \
+ log_memop(vb, op); \
+ if (_q->mem_ops->op) \
+ _q->mem_ops->op(args); \
+ (vb)->cnt_mem_ ## op++; \
+})
+
+#define log_qop(q, op) \
+ dprintk(2, "call_qop(%p, %s)%s\n", q, #op, \
+ (q)->ops->op ? "" : " (nop)")
+
+#define call_qop(q, op, args...) \
+({ \
+ int err; \
+ \
+ log_qop(q, op); \
+ err = (q)->ops->op ? (q)->ops->op(args) : 0; \
+ if (!err) \
+ (q)->cnt_ ## op++; \
+ err; \
+})
+
+#define call_void_qop(q, op, args...) \
+({ \
+ log_qop(q, op); \
+ if ((q)->ops->op) \
+ (q)->ops->op(args); \
+ (q)->cnt_ ## op++; \
+})
+
+#define log_vb_qop(vb, op, args...) \
+ dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \
+ (vb)->vb2_queue, (vb)->index, #op, \
+ (vb)->vb2_queue->ops->op ? "" : " (nop)")
+
+#define call_vb_qop(vb, op, args...) \
+({ \
+ int err; \
+ \
+ log_vb_qop(vb, op); \
+ err = (vb)->vb2_queue->ops->op ? \
+ (vb)->vb2_queue->ops->op(args) : 0; \
+ if (!err) \
+ (vb)->cnt_ ## op++; \
+ err; \
+})
+
+#define call_void_vb_qop(vb, op, args...) \
+({ \
+ log_vb_qop(vb, op); \
+ if ((vb)->vb2_queue->ops->op) \
+ (vb)->vb2_queue->ops->op(args); \
+ (vb)->cnt_ ## op++; \
+})
+
+#else
+
+#define call_memop(vb, op, args...) \
+ ((vb)->vb2_queue->mem_ops->op ? \
+ (vb)->vb2_queue->mem_ops->op(args) : 0)
+
+#define call_ptr_memop(vb, op, args...) \
+ ((vb)->vb2_queue->mem_ops->op ? \
+ (vb)->vb2_queue->mem_ops->op(args) : NULL)
+
+#define call_void_memop(vb, op, args...) \
+ do { \
+ if ((vb)->vb2_queue->mem_ops->op) \
+ (vb)->vb2_queue->mem_ops->op(args); \
+ } while (0)
+
+#define call_qop(q, op, args...) \
+ ((q)->ops->op ? (q)->ops->op(args) : 0)
+
+#define call_void_qop(q, op, args...) \
+ do { \
+ if ((q)->ops->op) \
+ (q)->ops->op(args); \
+ } while (0)
+
+#define call_vb_qop(vb, op, args...) \
+ ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
+
+#define call_void_vb_qop(vb, op, args...) \
+ do { \
+ if ((vb)->vb2_queue->ops->op) \
+ (vb)->vb2_queue->ops->op(args); \
+ } while (0)
+
+#endif
+
+#define call_bufop(q, op, args...) \
+({ \
+ int ret = 0; \
+ if (q && q->buf_ops && q->buf_ops->op) \
+ ret = q->buf_ops->op(args); \
+ ret; \
+})
+
+bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
+int vb2_verify_memory_type(struct vb2_queue *q,
+ enum vb2_memory memory, unsigned int type);
+#endif /* _MEDIA_VIDEOBUF2_INTERNAL_H */
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c
index 48c6a49c4928..dbec5923fcf0 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -19,7 +19,7 @@
#include <linux/sched.h>
#include <linux/file.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-memops.h>
/**
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
new file mode 100644
index 000000000000..27b4b9e7c0c2
--- /dev/null
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -0,0 +1,1661 @@
+/*
+ * videobuf2-v4l2.c - V4L2 driver helper framework
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak <pawel@osciak.com>
+ * Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * The vb2_thread implementation was based on code from videobuf-dvb.c:
+ * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
+ *
+ * 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.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-common.h>
+
+#include <media/videobuf2-v4l2.h>
+
+#include "videobuf2-internal.h"
+
+/* Flags that are set by the vb2 core */
+#define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
+ V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
+ V4L2_BUF_FLAG_PREPARED | \
+ V4L2_BUF_FLAG_TIMESTAMP_MASK)
+/* Output buffer flags that should be passed on to the driver */
+#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
+ V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
+
+/**
+ * __verify_planes_array() - verify that the planes array passed in struct
+ * v4l2_buffer from userspace can be safely used
+ */
+static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+{
+ if (!V4L2_TYPE_IS_MULTIPLANAR(b->type))
+ return 0;
+
+ /* Is memory for copying plane information present? */
+ if (NULL == b->m.planes) {
+ dprintk(1, "multi-planar buffer passed but "
+ "planes array not provided\n");
+ return -EINVAL;
+ }
+
+ if (b->length < vb->num_planes || b->length > VB2_MAX_PLANES) {
+ dprintk(1, "incorrect planes array length, "
+ "expected %d, got %d\n", vb->num_planes, b->length);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * __verify_length() - Verify that the bytesused value for each plane fits in
+ * the plane length and that the data offset doesn't exceed the bytesused value.
+ */
+static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+{
+ unsigned int length;
+ unsigned int bytesused;
+ unsigned int plane;
+
+ if (!V4L2_TYPE_IS_OUTPUT(b->type))
+ return 0;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ length = (b->memory == VB2_MEMORY_USERPTR ||
+ b->memory == VB2_MEMORY_DMABUF)
+ ? b->m.planes[plane].length
+ : vb->planes[plane].length;
+ bytesused = b->m.planes[plane].bytesused
+ ? b->m.planes[plane].bytesused : length;
+
+ if (b->m.planes[plane].bytesused > length)
+ return -EINVAL;
+
+ if (b->m.planes[plane].data_offset > 0 &&
+ b->m.planes[plane].data_offset >= bytesused)
+ return -EINVAL;
+ }
+ } else {
+ length = (b->memory == VB2_MEMORY_USERPTR)
+ ? b->length : vb->planes[0].length;
+
+ if (b->bytesused > length)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __set_timestamp(struct vb2_buffer *vb, const void *pb)
+{
+ const struct v4l2_buffer *b = pb;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vb2_queue *q = vb->vb2_queue;
+
+ if (q->is_output) {
+ /*
+ * For output buffers copy the timestamp if needed,
+ * and the timecode field and flag if needed.
+ */
+ if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
+ V4L2_BUF_FLAG_TIMESTAMP_COPY)
+ vbuf->timestamp = b->timestamp;
+ vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
+ if (b->flags & V4L2_BUF_FLAG_TIMECODE)
+ vbuf->timecode = b->timecode;
+ }
+ return 0;
+};
+
+static void vb2_warn_zero_bytesused(struct vb2_buffer *vb)
+{
+ static bool check_once;
+
+ if (check_once)
+ return;
+
+ check_once = true;
+ WARN_ON(1);
+
+ pr_warn("use of bytesused == 0 is deprecated and will be removed in the future,\n");
+ if (vb->vb2_queue->allow_zero_bytesused)
+ pr_warn("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n");
+ else
+ pr_warn("use the actual size instead.\n");
+}
+
+static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
+ const char *opname)
+{
+ if (b->type != q->type) {
+ dprintk(1, "%s: invalid buffer type\n", opname);
+ return -EINVAL;
+ }
+
+ if (b->index >= q->num_buffers) {
+ dprintk(1, "%s: buffer index out of range\n", opname);
+ return -EINVAL;
+ }
+
+ if (q->bufs[b->index] == NULL) {
+ /* Should never happen */
+ dprintk(1, "%s: buffer is NULL\n", opname);
+ return -EINVAL;
+ }
+
+ if (b->memory != q->memory) {
+ dprintk(1, "%s: invalid memory type\n", opname);
+ return -EINVAL;
+ }
+
+ return __verify_planes_array(q->bufs[b->index], b);
+}
+
+/**
+ * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
+ * returned to userspace
+ */
+static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
+{
+ struct v4l2_buffer *b = pb;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vb2_queue *q = vb->vb2_queue;
+ unsigned int plane;
+
+ /* Copy back data such as timestamp, flags, etc. */
+ b->index = vb->index;
+ b->type = vb->type;
+ b->memory = vb->memory;
+ b->bytesused = 0;
+
+ b->flags = vbuf->flags;
+ b->field = vbuf->field;
+ b->timestamp = vbuf->timestamp;
+ b->timecode = vbuf->timecode;
+ b->sequence = vbuf->sequence;
+ b->reserved2 = 0;
+ b->reserved = 0;
+
+ if (q->is_multiplanar) {
+ /*
+ * Fill in plane-related data if userspace provided an array
+ * for it. The caller has already verified memory and size.
+ */
+ b->length = vb->num_planes;
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ struct v4l2_plane *pdst = &b->m.planes[plane];
+ struct vb2_plane *psrc = &vb->planes[plane];
+
+ pdst->bytesused = psrc->bytesused;
+ pdst->length = psrc->length;
+ if (q->memory == VB2_MEMORY_MMAP)
+ pdst->m.mem_offset = psrc->m.offset;
+ else if (q->memory == VB2_MEMORY_USERPTR)
+ pdst->m.userptr = psrc->m.userptr;
+ else if (q->memory == VB2_MEMORY_DMABUF)
+ pdst->m.fd = psrc->m.fd;
+ pdst->data_offset = psrc->data_offset;
+ memset(pdst->reserved, 0, sizeof(pdst->reserved));
+ }
+ } else {
+ /*
+ * We use length and offset in v4l2_planes array even for
+ * single-planar buffers, but userspace does not.
+ */
+ b->length = vb->planes[0].length;
+ b->bytesused = vb->planes[0].bytesused;
+ if (q->memory == VB2_MEMORY_MMAP)
+ b->m.offset = vb->planes[0].m.offset;
+ else if (q->memory == VB2_MEMORY_USERPTR)
+ b->m.userptr = vb->planes[0].m.userptr;
+ else if (q->memory == VB2_MEMORY_DMABUF)
+ b->m.fd = vb->planes[0].m.fd;
+ }
+
+ /*
+ * Clear any buffer state related flags.
+ */
+ b->flags &= ~V4L2_BUFFER_MASK_FLAGS;
+ b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK;
+ if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
+ V4L2_BUF_FLAG_TIMESTAMP_COPY) {
+ /*
+ * For non-COPY timestamps, drop timestamp source bits
+ * and obtain the timestamp source from the queue.
+ */
+ b->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ }
+
+ switch (vb->state) {
+ case VB2_BUF_STATE_QUEUED:
+ case VB2_BUF_STATE_ACTIVE:
+ b->flags |= V4L2_BUF_FLAG_QUEUED;
+ break;
+ case VB2_BUF_STATE_ERROR:
+ b->flags |= V4L2_BUF_FLAG_ERROR;
+ /* fall through */
+ case VB2_BUF_STATE_DONE:
+ b->flags |= V4L2_BUF_FLAG_DONE;
+ break;
+ case VB2_BUF_STATE_PREPARED:
+ b->flags |= V4L2_BUF_FLAG_PREPARED;
+ break;
+ case VB2_BUF_STATE_PREPARING:
+ case VB2_BUF_STATE_DEQUEUED:
+ case VB2_BUF_STATE_REQUEUEING:
+ /* nothing */
+ break;
+ }
+
+ if (vb2_buffer_in_use(q, vb))
+ b->flags |= V4L2_BUF_FLAG_MAPPED;
+
+ return 0;
+}
+
+/**
+ * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
+ * v4l2_buffer by the userspace. It also verifies that struct
+ * v4l2_buffer has a valid number of planes.
+ */
+static int __fill_vb2_buffer(struct vb2_buffer *vb,
+ const void *pb, struct vb2_plane *planes)
+{
+ struct vb2_queue *q = vb->vb2_queue;
+ const struct v4l2_buffer *b = pb;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ unsigned int plane;
+ int ret;
+
+ ret = __verify_length(vb, b);
+ if (ret < 0) {
+ dprintk(1, "plane parameters verification failed: %d\n", ret);
+ return ret;
+ }
+ if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) {
+ /*
+ * If the format's field is ALTERNATE, then the buffer's field
+ * should be either TOP or BOTTOM, not ALTERNATE since that
+ * makes no sense. The driver has to know whether the
+ * buffer represents a top or a bottom field in order to
+ * program any DMA correctly. Using ALTERNATE is wrong, since
+ * that just says that it is either a top or a bottom field,
+ * but not which of the two it is.
+ */
+ dprintk(1, "the field is incorrectly set to ALTERNATE "
+ "for an output buffer\n");
+ return -EINVAL;
+ }
+ vbuf->timestamp.tv_sec = 0;
+ vbuf->timestamp.tv_usec = 0;
+ vbuf->sequence = 0;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+ if (b->memory == VB2_MEMORY_USERPTR) {
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ planes[plane].m.userptr =
+ b->m.planes[plane].m.userptr;
+ planes[plane].length =
+ b->m.planes[plane].length;
+ }
+ }
+ if (b->memory == VB2_MEMORY_DMABUF) {
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ planes[plane].m.fd =
+ b->m.planes[plane].m.fd;
+ planes[plane].length =
+ b->m.planes[plane].length;
+ }
+ }
+
+ /* Fill in driver-provided information for OUTPUT types */
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ /*
+ * Will have to go up to b->length when API starts
+ * accepting variable number of planes.
+ *
+ * If bytesused == 0 for the output buffer, then fall
+ * back to the full buffer size. In that case
+ * userspace clearly never bothered to set it and
+ * it's a safe assumption that they really meant to
+ * use the full plane sizes.
+ *
+ * Some drivers, e.g. old codec drivers, use bytesused == 0
+ * as a way to indicate that streaming is finished.
+ * In that case, the driver should use the
+ * allow_zero_bytesused flag to keep old userspace
+ * applications working.
+ */
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ struct vb2_plane *pdst = &planes[plane];
+ struct v4l2_plane *psrc = &b->m.planes[plane];
+
+ if (psrc->bytesused == 0)
+ vb2_warn_zero_bytesused(vb);
+
+ if (vb->vb2_queue->allow_zero_bytesused)
+ pdst->bytesused = psrc->bytesused;
+ else
+ pdst->bytesused = psrc->bytesused ?
+ psrc->bytesused : pdst->length;
+ pdst->data_offset = psrc->data_offset;
+ }
+ }
+ } else {
+ /*
+ * Single-planar buffers do not use planes array,
+ * so fill in relevant v4l2_buffer struct fields instead.
+ * In videobuf we use our internal V4l2_planes struct for
+ * single-planar buffers as well, for simplicity.
+ *
+ * If bytesused == 0 for the output buffer, then fall back
+ * to the full buffer size as that's a sensible default.
+ *
+ * Some drivers, e.g. old codec drivers, use bytesused == 0 as
+ * a way to indicate that streaming is finished. In that case,
+ * the driver should use the allow_zero_bytesused flag to keep
+ * old userspace applications working.
+ */
+ if (b->memory == VB2_MEMORY_USERPTR) {
+ planes[0].m.userptr = b->m.userptr;
+ planes[0].length = b->length;
+ }
+
+ if (b->memory == VB2_MEMORY_DMABUF) {
+ planes[0].m.fd = b->m.fd;
+ planes[0].length = b->length;
+ }
+
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ if (b->bytesused == 0)
+ vb2_warn_zero_bytesused(vb);
+
+ if (vb->vb2_queue->allow_zero_bytesused)
+ planes[0].bytesused = b->bytesused;
+ else
+ planes[0].bytesused = b->bytesused ?
+ b->bytesused : planes[0].length;
+ } else
+ planes[0].bytesused = 0;
+
+ }
+
+ /* Zero flags that the vb2 core handles */
+ vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
+ if ((vb->vb2_queue->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
+ V4L2_BUF_FLAG_TIMESTAMP_COPY || !V4L2_TYPE_IS_OUTPUT(b->type)) {
+ /*
+ * Non-COPY timestamps and non-OUTPUT queues will get
+ * their timestamp and timestamp source flags from the
+ * queue.
+ */
+ vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ }
+
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ /*
+ * For output buffers mask out the timecode flag:
+ * this will be handled later in vb2_internal_qbuf().
+ * The 'field' is valid metadata for this output buffer
+ * and so that needs to be copied here.
+ */
+ vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE;
+ vbuf->field = b->field;
+ } else {
+ /* Zero any output buffer flags as this is a capture buffer */
+ vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
+ }
+
+ return 0;
+}
+
+static const struct vb2_buf_ops v4l2_buf_ops = {
+ .fill_user_buffer = __fill_v4l2_buffer,
+ .fill_vb2_buffer = __fill_vb2_buffer,
+ .set_timestamp = __set_timestamp,
+};
+
+/**
+ * vb2_querybuf() - query video buffer information
+ * @q: videobuf queue
+ * @b: buffer struct passed from userspace to vidioc_querybuf handler
+ * in driver
+ *
+ * Should be called from vidioc_querybuf ioctl handler in driver.
+ * This function will verify the passed v4l2_buffer structure and fill the
+ * relevant information for the userspace.
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_querybuf handler in driver.
+ */
+int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+ struct vb2_buffer *vb;
+ int ret;
+
+ if (b->type != q->type) {
+ dprintk(1, "wrong buffer type\n");
+ return -EINVAL;
+ }
+
+ if (b->index >= q->num_buffers) {
+ dprintk(1, "buffer index out of range\n");
+ return -EINVAL;
+ }
+ vb = q->bufs[b->index];
+ ret = __verify_planes_array(vb, b);
+
+ return ret ? ret : vb2_core_querybuf(q, b->index, b);
+}
+EXPORT_SYMBOL(vb2_querybuf);
+
+/**
+ * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies
+ * the memory and type values.
+ * @q: videobuf2 queue
+ * @req: struct passed from userspace to vidioc_reqbufs handler
+ * in driver
+ */
+int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
+{
+ int ret = vb2_verify_memory_type(q, req->memory, req->type);
+
+ return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count);
+}
+EXPORT_SYMBOL_GPL(vb2_reqbufs);
+
+/**
+ * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
+ * @q: videobuf2 queue
+ * @b: buffer structure passed from userspace to vidioc_prepare_buf
+ * handler in driver
+ *
+ * Should be called from vidioc_prepare_buf ioctl handler of a driver.
+ * This function:
+ * 1) verifies the passed buffer,
+ * 2) calls buf_prepare callback in the driver (if provided), in which
+ * driver-specific buffer initialization can be performed,
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_prepare_buf handler in driver.
+ */
+int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+ int ret;
+
+ if (vb2_fileio_is_active(q)) {
+ dprintk(1, "file io in progress\n");
+ return -EBUSY;
+ }
+
+ ret = vb2_queue_or_prepare_buf(q, b, "prepare_buf");
+
+ return ret ? ret : vb2_core_prepare_buf(q, b->index, b);
+}
+EXPORT_SYMBOL_GPL(vb2_prepare_buf);
+
+/**
+ * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies
+ * the memory and type values.
+ * @q: videobuf2 queue
+ * @create: creation parameters, passed from userspace to vidioc_create_bufs
+ * handler in driver
+ */
+int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
+{
+ int ret = vb2_verify_memory_type(q, create->memory,
+ create->format.type);
+
+ create->index = q->num_buffers;
+ if (create->count == 0)
+ return ret != -EBUSY ? ret : 0;
+ return ret ? ret : vb2_core_create_bufs(q, create->memory,
+ &create->count, &create->format);
+}
+EXPORT_SYMBOL_GPL(vb2_create_bufs);
+
+static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+ int ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
+
+ return ret ? ret : vb2_core_qbuf(q, b->index, b);
+}
+
+/**
+ * vb2_qbuf() - Queue a buffer from userspace
+ * @q: videobuf2 queue
+ * @b: buffer structure passed from userspace to vidioc_qbuf handler
+ * in driver
+ *
+ * Should be called from vidioc_qbuf ioctl handler of a driver.
+ * This function:
+ * 1) verifies the passed buffer,
+ * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
+ * which driver-specific buffer initialization can be performed,
+ * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
+ * callback for processing.
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_qbuf handler in driver.
+ */
+int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+ if (vb2_fileio_is_active(q)) {
+ dprintk(1, "file io in progress\n");
+ return -EBUSY;
+ }
+
+ return vb2_internal_qbuf(q, b);
+}
+EXPORT_SYMBOL_GPL(vb2_qbuf);
+
+static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b,
+ bool nonblocking)
+{
+ int ret;
+
+ if (b->type != q->type) {
+ dprintk(1, "invalid buffer type\n");
+ return -EINVAL;
+ }
+
+ ret = vb2_core_dqbuf(q, b, nonblocking);
+
+ if (!ret && !q->is_output &&
+ b->flags & V4L2_BUF_FLAG_LAST)
+ q->last_buffer_dequeued = true;
+
+ return ret;
+}
+
+/**
+ * vb2_dqbuf() - Dequeue a buffer to the userspace
+ * @q: videobuf2 queue
+ * @b: buffer structure passed from userspace to vidioc_dqbuf handler
+ * in driver
+ * @nonblocking: if true, this call will not sleep waiting for a buffer if no
+ * buffers ready for dequeuing are present. Normally the driver
+ * would be passing (file->f_flags & O_NONBLOCK) here
+ *
+ * Should be called from vidioc_dqbuf ioctl handler of a driver.
+ * This function:
+ * 1) verifies the passed buffer,
+ * 2) calls buf_finish callback in the driver (if provided), in which
+ * driver can perform any additional operations that may be required before
+ * returning the buffer to userspace, such as cache sync,
+ * 3) the buffer struct members are filled with relevant information for
+ * the userspace.
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_dqbuf handler in driver.
+ */
+int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
+{
+ if (vb2_fileio_is_active(q)) {
+ dprintk(1, "file io in progress\n");
+ return -EBUSY;
+ }
+ return vb2_internal_dqbuf(q, b, nonblocking);
+}
+EXPORT_SYMBOL_GPL(vb2_dqbuf);
+
+/**
+ * vb2_streamon - start streaming
+ * @q: videobuf2 queue
+ * @type: type argument passed from userspace to vidioc_streamon handler
+ *
+ * Should be called from vidioc_streamon handler of a driver.
+ * This function:
+ * 1) verifies current state
+ * 2) passes any previously queued buffers to the driver and starts streaming
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_streamon handler in the driver.
+ */
+int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
+{
+ if (vb2_fileio_is_active(q)) {
+ dprintk(1, "file io in progress\n");
+ return -EBUSY;
+ }
+ return vb2_core_streamon(q, type);
+}
+EXPORT_SYMBOL_GPL(vb2_streamon);
+
+/**
+ * vb2_streamoff - stop streaming
+ * @q: videobuf2 queue
+ * @type: type argument passed from userspace to vidioc_streamoff handler
+ *
+ * Should be called from vidioc_streamoff handler of a driver.
+ * This function:
+ * 1) verifies current state,
+ * 2) stop streaming and dequeues any queued buffers, including those previously
+ * passed to the driver (after waiting for the driver to finish).
+ *
+ * This call can be used for pausing playback.
+ * The return values from this function are intended to be directly returned
+ * from vidioc_streamoff handler in the driver
+ */
+int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
+{
+ if (vb2_fileio_is_active(q)) {
+ dprintk(1, "file io in progress\n");
+ return -EBUSY;
+ }
+ return vb2_core_streamoff(q, type);
+}
+EXPORT_SYMBOL_GPL(vb2_streamoff);
+
+/**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @eb: export buffer structure passed from userspace to vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+ return vb2_core_expbuf(q, &eb->fd, eb->type, eb->index,
+ eb->plane, eb->flags);
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
+/**
+ * vb2_queue_init() - initialize a videobuf2 queue
+ * @q: videobuf2 queue; this structure should be allocated in driver
+ *
+ * The vb2_queue structure should be allocated by the driver. The driver is
+ * responsible of clearing it's content and setting initial values for some
+ * required entries before calling this function.
+ * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
+ * to the struct vb2_queue description in include/media/videobuf2-core.h
+ * for more information.
+ */
+int vb2_queue_init(struct vb2_queue *q)
+{
+ /*
+ * Sanity check
+ */
+ if (WARN_ON(!q) ||
+ WARN_ON(q->timestamp_flags &
+ ~(V4L2_BUF_FLAG_TIMESTAMP_MASK |
+ V4L2_BUF_FLAG_TSTAMP_SRC_MASK)))
+ return -EINVAL;
+
+ /* Warn that the driver should choose an appropriate timestamp type */
+ WARN_ON((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
+ V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN);
+
+ /* Warn that vb2_memory should match with v4l2_memory */
+ if (WARN_ON(VB2_MEMORY_MMAP != (int)V4L2_MEMORY_MMAP)
+ || WARN_ON(VB2_MEMORY_USERPTR != (int)V4L2_MEMORY_USERPTR)
+ || WARN_ON(VB2_MEMORY_DMABUF != (int)V4L2_MEMORY_DMABUF))
+ return -EINVAL;
+
+ if (q->buf_struct_size == 0)
+ q->buf_struct_size = sizeof(struct vb2_v4l2_buffer);
+
+ q->buf_ops = &v4l2_buf_ops;
+ q->is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type);
+ q->is_output = V4L2_TYPE_IS_OUTPUT(q->type);
+
+ return vb2_core_queue_init(q);
+}
+EXPORT_SYMBOL_GPL(vb2_queue_init);
+
+static int __vb2_init_fileio(struct vb2_queue *q, int read);
+static int __vb2_cleanup_fileio(struct vb2_queue *q);
+
+/**
+ * vb2_queue_release() - stop streaming, release the queue and free memory
+ * @q: videobuf2 queue
+ *
+ * This function stops streaming and performs necessary clean ups, including
+ * freeing video buffer memory. The driver is responsible for freeing
+ * the vb2_queue structure itself.
+ */
+void vb2_queue_release(struct vb2_queue *q)
+{
+ __vb2_cleanup_fileio(q);
+ vb2_core_queue_release(q);
+}
+EXPORT_SYMBOL_GPL(vb2_queue_release);
+
+/**
+ * vb2_poll() - implements poll userspace operation
+ * @q: videobuf2 queue
+ * @file: file argument passed to the poll file operation handler
+ * @wait: wait argument passed to the poll file operation handler
+ *
+ * This function implements poll file operation handler for a driver.
+ * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
+ * be informed that the file descriptor of a video device is available for
+ * reading.
+ * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
+ * will be reported as available for writing.
+ *
+ * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
+ * pending events.
+ *
+ * The return values from this function are intended to be directly returned
+ * from poll handler in driver.
+ */
+unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
+{
+ struct video_device *vfd = video_devdata(file);
+ unsigned long req_events = poll_requested_events(wait);
+ struct vb2_buffer *vb = NULL;
+ unsigned int res = 0;
+ unsigned long flags;
+
+ if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
+ struct v4l2_fh *fh = file->private_data;
+
+ if (v4l2_event_pending(fh))
+ res = POLLPRI;
+ else if (req_events & POLLPRI)
+ poll_wait(file, &fh->wait, wait);
+ }
+
+ if (!q->is_output && !(req_events & (POLLIN | POLLRDNORM)))
+ return res;
+ if (q->is_output && !(req_events & (POLLOUT | POLLWRNORM)))
+ return res;
+
+ /*
+ * Start file I/O emulator only if streaming API has not been used yet.
+ */
+ if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) {
+ if (!q->is_output && (q->io_modes & VB2_READ) &&
+ (req_events & (POLLIN | POLLRDNORM))) {
+ if (__vb2_init_fileio(q, 1))
+ return res | POLLERR;
+ }
+ if (q->is_output && (q->io_modes & VB2_WRITE) &&
+ (req_events & (POLLOUT | POLLWRNORM))) {
+ if (__vb2_init_fileio(q, 0))
+ return res | POLLERR;
+ /*
+ * Write to OUTPUT queue can be done immediately.
+ */
+ return res | POLLOUT | POLLWRNORM;
+ }
+ }
+
+ /*
+ * There is nothing to wait for if the queue isn't streaming, or if the
+ * error flag is set.
+ */
+ if (!vb2_is_streaming(q) || q->error)
+ return res | POLLERR;
+ /*
+ * For compatibility with vb1: if QBUF hasn't been called yet, then
+ * return POLLERR as well. This only affects capture queues, output
+ * queues will always initialize waiting_for_buffers to false.
+ */
+ if (q->waiting_for_buffers)
+ return res | POLLERR;
+
+ /*
+ * For output streams you can write as long as there are fewer buffers
+ * queued than there are buffers available.
+ */
+ if (q->is_output && q->queued_count < q->num_buffers)
+ return res | POLLOUT | POLLWRNORM;
+
+ if (list_empty(&q->done_list)) {
+ /*
+ * If the last buffer was dequeued from a capture queue,
+ * return immediately. DQBUF will return -EPIPE.
+ */
+ if (q->last_buffer_dequeued)
+ return res | POLLIN | POLLRDNORM;
+
+ poll_wait(file, &q->done_wq, wait);
+ }
+
+ /*
+ * Take first buffer available for dequeuing.
+ */
+ spin_lock_irqsave(&q->done_lock, flags);
+ if (!list_empty(&q->done_list))
+ vb = list_first_entry(&q->done_list, struct vb2_buffer,
+ done_entry);
+ spin_unlock_irqrestore(&q->done_lock, flags);
+
+ if (vb && (vb->state == VB2_BUF_STATE_DONE
+ || vb->state == VB2_BUF_STATE_ERROR)) {
+ return (q->is_output) ?
+ res | POLLOUT | POLLWRNORM :
+ res | POLLIN | POLLRDNORM;
+ }
+ return res;
+}
+EXPORT_SYMBOL_GPL(vb2_poll);
+
+/**
+ * struct vb2_fileio_buf - buffer context used by file io emulator
+ *
+ * vb2 provides a compatibility layer and emulator of file io (read and
+ * write) calls on top of streaming API. This structure is used for
+ * tracking context related to the buffers.
+ */
+struct vb2_fileio_buf {
+ void *vaddr;
+ unsigned int size;
+ unsigned int pos;
+ unsigned int queued:1;
+};
+
+/**
+ * struct vb2_fileio_data - queue context used by file io emulator
+ *
+ * @cur_index: the index of the buffer currently being read from or
+ * written to. If equal to q->num_buffers then a new buffer
+ * must be dequeued.
+ * @initial_index: in the read() case all buffers are queued up immediately
+ * in __vb2_init_fileio() and __vb2_perform_fileio() just cycles
+ * buffers. However, in the write() case no buffers are initially
+ * queued, instead whenever a buffer is full it is queued up by
+ * __vb2_perform_fileio(). Only once all available buffers have
+ * been queued up will __vb2_perform_fileio() start to dequeue
+ * buffers. This means that initially __vb2_perform_fileio()
+ * needs to know what buffer index to use when it is queuing up
+ * the buffers for the first time. That initial index is stored
+ * in this field. Once it is equal to q->num_buffers all
+ * available buffers have been queued and __vb2_perform_fileio()
+ * should start the normal dequeue/queue cycle.
+ *
+ * vb2 provides a compatibility layer and emulator of file io (read and
+ * write) calls on top of streaming API. For proper operation it required
+ * this structure to save the driver state between each call of the read
+ * or write function.
+ */
+struct vb2_fileio_data {
+ struct v4l2_requestbuffers req;
+ struct v4l2_plane p;
+ struct v4l2_buffer b;
+ struct vb2_fileio_buf bufs[VB2_MAX_FRAME];
+ unsigned int cur_index;
+ unsigned int initial_index;
+ unsigned int q_count;
+ unsigned int dq_count;
+ unsigned read_once:1;
+ unsigned write_immediately:1;
+};
+
+/**
+ * __vb2_init_fileio() - initialize file io emulator
+ * @q: videobuf2 queue
+ * @read: mode selector (1 means read, 0 means write)
+ */
+static int __vb2_init_fileio(struct vb2_queue *q, int read)
+{
+ struct vb2_fileio_data *fileio;
+ int i, ret;
+ unsigned int count = 0;
+
+ /*
+ * Sanity check
+ */
+ if (WARN_ON((read && !(q->io_modes & VB2_READ)) ||
+ (!read && !(q->io_modes & VB2_WRITE))))
+ return -EINVAL;
+
+ /*
+ * Check if device supports mapping buffers to kernel virtual space.
+ */
+ if (!q->mem_ops->vaddr)
+ return -EBUSY;
+
+ /*
+ * Check if streaming api has not been already activated.
+ */
+ if (q->streaming || q->num_buffers > 0)
+ return -EBUSY;
+
+ /*
+ * Start with count 1, driver can increase it in queue_setup()
+ */
+ count = 1;
+
+ dprintk(3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n",
+ (read) ? "read" : "write", count, q->fileio_read_once,
+ q->fileio_write_immediately);
+
+ fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
+ if (fileio == NULL)
+ return -ENOMEM;
+
+ fileio->read_once = q->fileio_read_once;
+ fileio->write_immediately = q->fileio_write_immediately;
+
+ /*
+ * Request buffers and use MMAP type to force driver
+ * to allocate buffers by itself.
+ */
+ fileio->req.count = count;
+ fileio->req.memory = VB2_MEMORY_MMAP;
+ fileio->req.type = q->type;
+ q->fileio = fileio;
+ ret = vb2_core_reqbufs(q, fileio->req.memory, &fileio->req.count);
+ if (ret)
+ goto err_kfree;
+
+ /*
+ * Check if plane_count is correct
+ * (multiplane buffers are not supported).
+ */
+ if (q->bufs[0]->num_planes != 1) {
+ ret = -EBUSY;
+ goto err_reqbufs;
+ }
+
+ /*
+ * Get kernel address of each buffer.
+ */
+ for (i = 0; i < q->num_buffers; i++) {
+ fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
+ if (fileio->bufs[i].vaddr == NULL) {
+ ret = -EINVAL;
+ goto err_reqbufs;
+ }
+ fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
+ }
+
+ /*
+ * Read mode requires pre queuing of all buffers.
+ */
+ if (read) {
+ bool is_multiplanar = q->is_multiplanar;
+
+ /*
+ * Queue all buffers.
+ */
+ for (i = 0; i < q->num_buffers; i++) {
+ struct v4l2_buffer *b = &fileio->b;
+
+ memset(b, 0, sizeof(*b));
+ b->type = q->type;
+ if (is_multiplanar) {
+ memset(&fileio->p, 0, sizeof(fileio->p));
+ b->m.planes = &fileio->p;
+ b->length = 1;
+ }
+ b->memory = q->memory;
+ b->index = i;
+ ret = vb2_internal_qbuf(q, b);
+ if (ret)
+ goto err_reqbufs;
+ fileio->bufs[i].queued = 1;
+ }
+ /*
+ * All buffers have been queued, so mark that by setting
+ * initial_index to q->num_buffers
+ */
+ fileio->initial_index = q->num_buffers;
+ fileio->cur_index = q->num_buffers;
+ }
+
+ /*
+ * Start streaming.
+ */
+ ret = vb2_core_streamon(q, q->type);
+ if (ret)
+ goto err_reqbufs;
+
+ return ret;
+
+err_reqbufs:
+ fileio->req.count = 0;
+ vb2_core_reqbufs(q, fileio->req.memory, &fileio->req.count);
+
+err_kfree:
+ q->fileio = NULL;
+ kfree(fileio);
+ return ret;
+}
+
+/**
+ * __vb2_cleanup_fileio() - free resourced used by file io emulator
+ * @q: videobuf2 queue
+ */
+static int __vb2_cleanup_fileio(struct vb2_queue *q)
+{
+ struct vb2_fileio_data *fileio = q->fileio;
+
+ if (fileio) {
+ vb2_core_streamoff(q, q->type);
+ q->fileio = NULL;
+ fileio->req.count = 0;
+ vb2_reqbufs(q, &fileio->req);
+ kfree(fileio);
+ dprintk(3, "file io emulator closed\n");
+ }
+ return 0;
+}
+
+/**
+ * __vb2_perform_fileio() - perform a single file io (read or write) operation
+ * @q: videobuf2 queue
+ * @data: pointed to target userspace buffer
+ * @count: number of bytes to read or write
+ * @ppos: file handle position tracking pointer
+ * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
+ * @read: access mode selector (1 means read, 0 means write)
+ */
+static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
+ loff_t *ppos, int nonblock, int read)
+{
+ struct vb2_fileio_data *fileio;
+ struct vb2_fileio_buf *buf;
+ bool is_multiplanar = q->is_multiplanar;
+ /*
+ * When using write() to write data to an output video node the vb2 core
+ * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody
+ * else is able to provide this information with the write() operation.
+ */
+ bool set_timestamp = !read &&
+ (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
+ V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ int ret, index;
+
+ dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n",
+ read ? "read" : "write", (long)*ppos, count,
+ nonblock ? "non" : "");
+
+ if (!data)
+ return -EINVAL;
+
+ /*
+ * Initialize emulator on first call.
+ */
+ if (!vb2_fileio_is_active(q)) {
+ ret = __vb2_init_fileio(q, read);
+ dprintk(3, "vb2_init_fileio result: %d\n", ret);
+ if (ret)
+ return ret;
+ }
+ fileio = q->fileio;
+
+ /*
+ * Check if we need to dequeue the buffer.
+ */
+ index = fileio->cur_index;
+ if (index >= q->num_buffers) {
+ /*
+ * Call vb2_dqbuf to get buffer back.
+ */
+ memset(&fileio->b, 0, sizeof(fileio->b));
+ fileio->b.type = q->type;
+ fileio->b.memory = q->memory;
+ if (is_multiplanar) {
+ memset(&fileio->p, 0, sizeof(fileio->p));
+ fileio->b.m.planes = &fileio->p;
+ fileio->b.length = 1;
+ }
+ ret = vb2_internal_dqbuf(q, &fileio->b, nonblock);
+ dprintk(5, "vb2_dqbuf result: %d\n", ret);
+ if (ret)
+ return ret;
+ fileio->dq_count += 1;
+
+ fileio->cur_index = index = fileio->b.index;
+ buf = &fileio->bufs[index];
+
+ /*
+ * Get number of bytes filled by the driver
+ */
+ buf->pos = 0;
+ buf->queued = 0;
+ buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0)
+ : vb2_plane_size(q->bufs[index], 0);
+ /* Compensate for data_offset on read in the multiplanar case. */
+ if (is_multiplanar && read &&
+ fileio->b.m.planes[0].data_offset < buf->size) {
+ buf->pos = fileio->b.m.planes[0].data_offset;
+ buf->size -= buf->pos;
+ }
+ } else {
+ buf = &fileio->bufs[index];
+ }
+
+ /*
+ * Limit count on last few bytes of the buffer.
+ */
+ if (buf->pos + count > buf->size) {
+ count = buf->size - buf->pos;
+ dprintk(5, "reducing read count: %zd\n", count);
+ }
+
+ /*
+ * Transfer data to userspace.
+ */
+ dprintk(3, "copying %zd bytes - buffer %d, offset %u\n",
+ count, index, buf->pos);
+ if (read)
+ ret = copy_to_user(data, buf->vaddr + buf->pos, count);
+ else
+ ret = copy_from_user(buf->vaddr + buf->pos, data, count);
+ if (ret) {
+ dprintk(3, "error copying data\n");
+ return -EFAULT;
+ }
+
+ /*
+ * Update counters.
+ */
+ buf->pos += count;
+ *ppos += count;
+
+ /*
+ * Queue next buffer if required.
+ */
+ if (buf->pos == buf->size || (!read && fileio->write_immediately)) {
+ /*
+ * Check if this is the last buffer to read.
+ */
+ if (read && fileio->read_once && fileio->dq_count == 1) {
+ dprintk(3, "read limit reached\n");
+ return __vb2_cleanup_fileio(q);
+ }
+
+ /*
+ * Call vb2_qbuf and give buffer to the driver.
+ */
+ memset(&fileio->b, 0, sizeof(fileio->b));
+ fileio->b.type = q->type;
+ fileio->b.memory = q->memory;
+ fileio->b.index = index;
+ fileio->b.bytesused = buf->pos;
+ if (is_multiplanar) {
+ memset(&fileio->p, 0, sizeof(fileio->p));
+ fileio->p.bytesused = buf->pos;
+ fileio->b.m.planes = &fileio->p;
+ fileio->b.length = 1;
+ }
+ if (set_timestamp)
+ v4l2_get_timestamp(&fileio->b.timestamp);
+ ret = vb2_internal_qbuf(q, &fileio->b);
+ dprintk(5, "vb2_dbuf result: %d\n", ret);
+ if (ret)
+ return ret;
+
+ /*
+ * Buffer has been queued, update the status
+ */
+ buf->pos = 0;
+ buf->queued = 1;
+ buf->size = vb2_plane_size(q->bufs[index], 0);
+ fileio->q_count += 1;
+ /*
+ * If we are queuing up buffers for the first time, then
+ * increase initial_index by one.
+ */
+ if (fileio->initial_index < q->num_buffers)
+ fileio->initial_index++;
+ /*
+ * The next buffer to use is either a buffer that's going to be
+ * queued for the first time (initial_index < q->num_buffers)
+ * or it is equal to q->num_buffers, meaning that the next
+ * time we need to dequeue a buffer since we've now queued up
+ * all the 'first time' buffers.
+ */
+ fileio->cur_index = fileio->initial_index;
+ }
+
+ /*
+ * Return proper number of bytes processed.
+ */
+ if (ret == 0)
+ ret = count;
+ return ret;
+}
+
+size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
+ loff_t *ppos, int nonblocking)
+{
+ return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
+}
+EXPORT_SYMBOL_GPL(vb2_read);
+
+size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
+ loff_t *ppos, int nonblocking)
+{
+ return __vb2_perform_fileio(q, (char __user *) data, count,
+ ppos, nonblocking, 0);
+}
+EXPORT_SYMBOL_GPL(vb2_write);
+
+struct vb2_threadio_data {
+ struct task_struct *thread;
+ vb2_thread_fnc fnc;
+ void *priv;
+ bool stop;
+};
+
+static int vb2_thread(void *data)
+{
+ struct vb2_queue *q = data;
+ struct vb2_threadio_data *threadio = q->threadio;
+ struct vb2_fileio_data *fileio = q->fileio;
+ bool set_timestamp = false;
+ int prequeue = 0;
+ int index = 0;
+ int ret = 0;
+
+ if (q->is_output) {
+ prequeue = q->num_buffers;
+ set_timestamp =
+ (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
+ V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ }
+
+ set_freezable();
+
+ for (;;) {
+ struct vb2_buffer *vb;
+
+ /*
+ * Call vb2_dqbuf to get buffer back.
+ */
+ memset(&fileio->b, 0, sizeof(fileio->b));
+ fileio->b.type = q->type;
+ fileio->b.memory = q->memory;
+ if (prequeue) {
+ fileio->b.index = index++;
+ prequeue--;
+ } else {
+ call_void_qop(q, wait_finish, q);
+ if (!threadio->stop)
+ ret = vb2_internal_dqbuf(q, &fileio->b, 0);
+ call_void_qop(q, wait_prepare, q);
+ dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
+ }
+ if (ret || threadio->stop)
+ break;
+ try_to_freeze();
+
+ vb = q->bufs[fileio->b.index];
+ if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR))
+ if (threadio->fnc(vb, threadio->priv))
+ break;
+ call_void_qop(q, wait_finish, q);
+ if (set_timestamp)
+ v4l2_get_timestamp(&fileio->b.timestamp);
+ if (!threadio->stop)
+ ret = vb2_internal_qbuf(q, &fileio->b);
+ call_void_qop(q, wait_prepare, q);
+ if (ret || threadio->stop)
+ break;
+ }
+
+ /* Hmm, linux becomes *very* unhappy without this ... */
+ while (!kthread_should_stop()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+ return 0;
+}
+
+/*
+ * This function should not be used for anything else but the videobuf2-dvb
+ * support. If you think you have another good use-case for this, then please
+ * contact the linux-media mailinglist first.
+ */
+int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
+ const char *thread_name)
+{
+ struct vb2_threadio_data *threadio;
+ int ret = 0;
+
+ if (q->threadio)
+ return -EBUSY;
+ if (vb2_is_busy(q))
+ return -EBUSY;
+ if (WARN_ON(q->fileio))
+ return -EBUSY;
+
+ threadio = kzalloc(sizeof(*threadio), GFP_KERNEL);
+ if (threadio == NULL)
+ return -ENOMEM;
+ threadio->fnc = fnc;
+ threadio->priv = priv;
+
+ ret = __vb2_init_fileio(q, !q->is_output);
+ dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
+ if (ret)
+ goto nomem;
+ q->threadio = threadio;
+ threadio->thread = kthread_run(vb2_thread, q, "vb2-%s", thread_name);
+ if (IS_ERR(threadio->thread)) {
+ ret = PTR_ERR(threadio->thread);
+ threadio->thread = NULL;
+ goto nothread;
+ }
+ return 0;
+
+nothread:
+ __vb2_cleanup_fileio(q);
+nomem:
+ kfree(threadio);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(vb2_thread_start);
+
+int vb2_thread_stop(struct vb2_queue *q)
+{
+ struct vb2_threadio_data *threadio = q->threadio;
+ int err;
+
+ if (threadio == NULL)
+ return 0;
+ threadio->stop = true;
+ /* Wake up all pending sleeps in the thread */
+ vb2_queue_error(q);
+ err = kthread_stop(threadio->thread);
+ __vb2_cleanup_fileio(q);
+ threadio->thread = NULL;
+ kfree(threadio);
+ q->threadio = NULL;
+ return err;
+}
+EXPORT_SYMBOL_GPL(vb2_thread_stop);
+
+/*
+ * The following functions are not part of the vb2 core API, but are helper
+ * functions that plug into struct v4l2_ioctl_ops, struct v4l2_file_operations
+ * and struct vb2_ops.
+ * They contain boilerplate code that most if not all drivers have to do
+ * and so they simplify the driver code.
+ */
+
+/* The queue is busy if there is a owner and you are not that owner. */
+static inline bool vb2_queue_is_busy(struct video_device *vdev, struct file *file)
+{
+ return vdev->queue->owner && vdev->queue->owner != file->private_data;
+}
+
+/* vb2 ioctl helpers */
+
+int vb2_ioctl_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+{
+ struct video_device *vdev = video_devdata(file);
+ int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type);
+
+ if (res)
+ return res;
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ res = vb2_core_reqbufs(vdev->queue, p->memory, &p->count);
+ /* If count == 0, then the owner has released all buffers and he
+ is no longer owner of the queue. Otherwise we have a new owner. */
+ if (res == 0)
+ vdev->queue->owner = p->count ? file->private_data : NULL;
+ return res;
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_reqbufs);
+
+int vb2_ioctl_create_bufs(struct file *file, void *priv,
+ struct v4l2_create_buffers *p)
+{
+ struct video_device *vdev = video_devdata(file);
+ int res = vb2_verify_memory_type(vdev->queue, p->memory,
+ p->format.type);
+
+ p->index = vdev->queue->num_buffers;
+ /*
+ * If count == 0, then just check if memory and type are valid.
+ * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0.
+ */
+ if (p->count == 0)
+ return res != -EBUSY ? res : 0;
+ if (res)
+ return res;
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ res = vb2_core_create_bufs(vdev->queue, p->memory, &p->count,
+ &p->format);
+ if (res == 0)
+ vdev->queue->owner = file->private_data;
+ return res;
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_create_bufs);
+
+int vb2_ioctl_prepare_buf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ return vb2_prepare_buf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf);
+
+int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ /* No need to call vb2_queue_is_busy(), anyone can query buffers. */
+ return vb2_querybuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_querybuf);
+
+int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ return vb2_qbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf);
+
+int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ return vb2_dqbuf(vdev->queue, p, file->f_flags & O_NONBLOCK);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_dqbuf);
+
+int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ return vb2_streamon(vdev->queue, i);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_streamon);
+
+int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ return vb2_streamoff(vdev->queue, i);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
+
+int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (vb2_queue_is_busy(vdev, file))
+ return -EBUSY;
+ return vb2_expbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
+
+/* v4l2_file_operations helpers */
+
+int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ return vb2_mmap(vdev->queue, vma);
+}
+EXPORT_SYMBOL_GPL(vb2_fop_mmap);
+
+int _vb2_fop_release(struct file *file, struct mutex *lock)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ if (lock)
+ mutex_lock(lock);
+ if (file->private_data == vdev->queue->owner) {
+ vb2_queue_release(vdev->queue);
+ vdev->queue->owner = NULL;
+ }
+ if (lock)
+ mutex_unlock(lock);
+ return v4l2_fh_release(file);
+}
+EXPORT_SYMBOL_GPL(_vb2_fop_release);
+
+int vb2_fop_release(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
+
+ return _vb2_fop_release(file, lock);
+}
+EXPORT_SYMBOL_GPL(vb2_fop_release);
+
+ssize_t vb2_fop_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
+ int err = -EBUSY;
+
+ if (!(vdev->queue->io_modes & VB2_WRITE))
+ return -EINVAL;
+ if (lock && mutex_lock_interruptible(lock))
+ return -ERESTARTSYS;
+ if (vb2_queue_is_busy(vdev, file))
+ goto exit;
+ err = vb2_write(vdev->queue, buf, count, ppos,
+ file->f_flags & O_NONBLOCK);
+ if (vdev->queue->fileio)
+ vdev->queue->owner = file->private_data;
+exit:
+ if (lock)
+ mutex_unlock(lock);
+ return err;
+}
+EXPORT_SYMBOL_GPL(vb2_fop_write);
+
+ssize_t vb2_fop_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
+ int err = -EBUSY;
+
+ if (!(vdev->queue->io_modes & VB2_READ))
+ return -EINVAL;
+ if (lock && mutex_lock_interruptible(lock))
+ return -ERESTARTSYS;
+ if (vb2_queue_is_busy(vdev, file))
+ goto exit;
+ err = vb2_read(vdev->queue, buf, count, ppos,
+ file->f_flags & O_NONBLOCK);
+ if (vdev->queue->fileio)
+ vdev->queue->owner = file->private_data;
+exit:
+ if (lock)
+ mutex_unlock(lock);
+ return err;
+}
+EXPORT_SYMBOL_GPL(vb2_fop_read);
+
+unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct vb2_queue *q = vdev->queue;
+ struct mutex *lock = q->lock ? q->lock : vdev->lock;
+ unsigned res;
+ void *fileio;
+
+ /*
+ * If this helper doesn't know how to lock, then you shouldn't be using
+ * it but you should write your own.
+ */
+ WARN_ON(!lock);
+
+ if (lock && mutex_lock_interruptible(lock))
+ return POLLERR;
+
+ fileio = q->fileio;
+
+ res = vb2_poll(vdev->queue, file, wait);
+
+ /* If fileio was started, then we have a new queue owner. */
+ if (!fileio && q->fileio)
+ q->owner = file->private_data;
+ if (lock)
+ mutex_unlock(lock);
+ return res;
+}
+EXPORT_SYMBOL_GPL(vb2_fop_poll);
+
+#ifndef CONFIG_MMU
+unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ return vb2_get_unmapped_area(vdev->queue, addr, len, pgoff, flags);
+}
+EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area);
+#endif
+
+/* vb2_ops helpers. Only use if vq->lock is non-NULL. */
+
+void vb2_ops_wait_prepare(struct vb2_queue *vq)
+{
+ mutex_unlock(vq->lock);
+}
+EXPORT_SYMBOL_GPL(vb2_ops_wait_prepare);
+
+void vb2_ops_wait_finish(struct vb2_queue *vq)
+{
+ mutex_lock(vq->lock);
+}
+EXPORT_SYMBOL_GPL(vb2_ops_wait_finish);
+
+MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
+MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index ecb8f0c7f025..1c302743a1fd 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -17,7 +17,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <media/videobuf2-memops.h>