diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-18 15:08:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-18 15:08:02 -0800 |
commit | a310410f616c78f24490de1274487a7b7b137d97 (patch) | |
tree | dbc2fc187800e6e7014263bf83e10d0155620029 /drivers/staging | |
parent | cdd278db0e3dd714e8076e58f723f3c59547591b (diff) | |
parent | 80f93c7b0f4599ffbdac8d964ecd1162b8b618b9 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
"This series include:
- a new Remote Controller driver for ST SoC with the corresponding DT
bindings
- a new frontend (cx24117)
- a new I2C camera flash driver (lm3560)
- a new mem2mem driver for TI SoC (ti-vpe)
- support for Raphael r828d added to r820t driver
- some improvements on buffer allocation at VB2 core
- usual driver fixes and improvements
PS this time, we have a smaller number of patches. While it is hard
to pinpoint to the reasons, I believe that it is mainly due to:
1) there are several patch series ready, but depending on DT review.
I decided to grant some extra time for DT maintainers to look on
it, as they're expecting to have more time with the changes agreed
during ARM mini-summit and KS. If they can't review in time for
3.14, I'll review myself and apply for the next merge window.
2) I suspect that having both LinuxCon EU and LinuxCon NA happening
during the same merge window affected the development
productivity, as several core media developers participated on
both events"
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (151 commits)
[media] media: st-rc: Add ST remote control driver
[media] gpio-ir-recv: Include linux/of.h header
[media] tvp7002: Include linux/of.h header
[media] tvp514x: Include linux/of.h header
[media] ths8200: Include linux/of.h header
[media] adv7343: Include linux/of.h header
[media] v4l: Fix typo in v4l2_subdev_get_try_crop()
[media] media: i2c: add driver for dual LED Flash, lm3560
[media] rtl28xxu: add 15f4:0131 Astrometa DVB-T2
[media] rtl28xxu: add RTL2832P + R828D support
[media] rtl2832: add new tuner R828D
[media] r820t: add support for R828D
[media] media/i2c: ths8200: fix build failure with gcc 4.5.4
[media] Add support for KWorld UB435-Q V2
[media] staging/media: fix msi3101 build errors
[media] ddbridge: Remove casting the return value which is a void pointer
[media] ngene: Remove casting the return value which is a void pointer
[media] dm1105: remove unneeded not-null test
[media] sh_mobile_ceu_camera: remove deprecated IRQF_DISABLED
[media] media: rcar_vin: Add preliminary r8a7790 support
...
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/media/lirc/TODO | 5 | ||||
-rw-r--r-- | drivers/staging/media/lirc/lirc_bt829.c | 33 | ||||
-rw-r--r-- | drivers/staging/media/msi3101/Kconfig | 3 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/solo6x10-disp.c | 25 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c | 170 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/solo6x10.h | 1 |
6 files changed, 152 insertions, 85 deletions
diff --git a/drivers/staging/media/lirc/TODO b/drivers/staging/media/lirc/TODO index b6cb593f55c6..cbea5d84fed3 100644 --- a/drivers/staging/media/lirc/TODO +++ b/drivers/staging/media/lirc/TODO @@ -2,6 +2,11 @@ (see drivers/media/IR/mceusb.c vs. lirc_mceusb.c in lirc cvs for an example of a previously completed port). +- lirc_bt829 uses registers on a Mach64 VT, which has a separate kernel + framebuffer driver (atyfb) and userland X driver (mach64). It can't + simply be converted to a normal PCI driver, but ideally it should be + coordinated with the other drivers. + Please send patches to: Jarod Wilson <jarod@wilsonet.com> Greg Kroah-Hartman <greg@kroah.com> diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c index fbbdce4c119f..30edc740ac25 100644 --- a/drivers/staging/media/lirc/lirc_bt829.c +++ b/drivers/staging/media/lirc/lirc_bt829.c @@ -63,7 +63,7 @@ static bool debug; } while (0) static int atir_minor; -static unsigned long pci_addr_phys; +static phys_addr_t pci_addr_phys; static unsigned char *pci_addr_lin; static struct lirc_driver atir_driver; @@ -78,11 +78,11 @@ static struct pci_dev *do_pci_probe(void) pci_addr_phys = 0; if (my_dev->resource[0].flags & IORESOURCE_MEM) { pci_addr_phys = my_dev->resource[0].start; - pr_info("memory at 0x%08X\n", - (unsigned int)pci_addr_phys); + pr_info("memory at %pa\n", &pci_addr_phys); } if (pci_addr_phys == 0) { pr_err("no memory resource ?\n"); + pci_dev_put(my_dev); return NULL; } } else { @@ -120,13 +120,20 @@ static void atir_set_use_dec(void *data) int init_module(void) { struct pci_dev *pdev; + int rc; pdev = do_pci_probe(); if (pdev == NULL) return -ENODEV; - if (!atir_init_start()) - return -ENODEV; + rc = pci_enable_device(pdev); + if (rc) + goto err_put_dev; + + if (!atir_init_start()) { + rc = -ENODEV; + goto err_disable; + } strcpy(atir_driver.name, "ATIR"); atir_driver.minor = -1; @@ -142,17 +149,31 @@ int init_module(void) atir_minor = lirc_register_driver(&atir_driver); if (atir_minor < 0) { pr_err("failed to register driver!\n"); - return atir_minor; + rc = atir_minor; + goto err_unmap; } dprintk("driver is registered on minor %d\n", atir_minor); return 0; + +err_unmap: + iounmap(pci_addr_lin); +err_disable: + pci_disable_device(pdev); +err_put_dev: + pci_dev_put(pdev); + return rc; } void cleanup_module(void) { + struct pci_dev *pdev = to_pci_dev(atir_driver.dev); + lirc_unregister_driver(atir_minor); + iounmap(pci_addr_lin); + pci_disable_device(pdev); + pci_dev_put(pdev); } diff --git a/drivers/staging/media/msi3101/Kconfig b/drivers/staging/media/msi3101/Kconfig index 76d5bbd4d93c..0c349c8595e4 100644 --- a/drivers/staging/media/msi3101/Kconfig +++ b/drivers/staging/media/msi3101/Kconfig @@ -1,4 +1,5 @@ config USB_MSI3101 tristate "Mirics MSi3101 SDR Dongle" depends on USB && VIDEO_DEV && VIDEO_V4L2 - select VIDEOBUF2_VMALLOC + select VIDEOBUF2_CORE + select VIDEOBUF2_VMALLOC diff --git a/drivers/staging/media/solo6x10/solo6x10-disp.c b/drivers/staging/media/solo6x10/solo6x10-disp.c index 32d9953bc36e..145295a5db72 100644 --- a/drivers/staging/media/solo6x10/solo6x10-disp.c +++ b/drivers/staging/media/solo6x10/solo6x10-disp.c @@ -176,18 +176,27 @@ static void solo_vout_config(struct solo_dev *solo_dev) static int solo_dma_vin_region(struct solo_dev *solo_dev, u32 off, u16 val, int reg_size) { - u16 buf[64]; - int i; - int ret = 0; + u16 *buf; + const int n = 64, size = n * sizeof(*buf); + int i, ret = 0; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; - for (i = 0; i < sizeof(buf) >> 1; i++) + for (i = 0; i < n; i++) buf[i] = cpu_to_le16(val); - for (i = 0; i < reg_size; i += sizeof(buf)) - ret |= solo_p2m_dma(solo_dev, 1, buf, - SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, - sizeof(buf), 0, 0); + for (i = 0; i < reg_size; i += size) { + ret = solo_p2m_dma(solo_dev, 1, buf, + SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, + size, 0, 0); + + if (ret) + break; + } + kfree(buf); return ret; } diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c index a4c589604b02..d582c5b84c14 100644 --- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c @@ -95,38 +95,11 @@ static unsigned char vop_6110_pal_cif[] = { 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00, }; -struct vop_header { - /* VE_STATUS0 */ - u32 mpeg_size:20, sad_motion_flag:1, video_motion_flag:1, vop_type:2, - channel:5, source_fl:1, interlace:1, progressive:1; - - /* VE_STATUS1 */ - u32 vsize:8, hsize:8, last_queue:4, nop0:8, scale:4; - - /* VE_STATUS2 */ - u32 mpeg_off; - - /* VE_STATUS3 */ - u32 jpeg_off; - - /* VE_STATUS4 */ - u32 jpeg_size:20, interval:10, nop1:2; - - /* VE_STATUS5/6 */ - u32 sec, usec; - - /* VE_STATUS7/8/9 */ - u32 nop2[3]; - - /* VE_STATUS10 */ - u32 mpeg_size_alt:20, nop3:12; - - u32 end_nops[5]; -} __packed; +typedef __le32 vop_header[16]; struct solo_enc_buf { enum solo_enc_types type; - struct vop_header *vh; + const vop_header *vh; int motion; }; @@ -346,7 +319,7 @@ static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma, /* Build a descriptor queue out of an SG list and send it to the P2M for * processing. */ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, - struct vb2_dma_sg_desc *vbuf, int off, int size, + struct sg_table *vbuf, int off, int size, unsigned int base, unsigned int base_size) { struct solo_dev *solo_dev = solo_enc->solo_dev; @@ -359,7 +332,7 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, solo_enc->desc_count = 1; - for_each_sg(vbuf->sglist, sg, vbuf->num_pages, i) { + for_each_sg(vbuf->sgl, sg, vbuf->nents, i) { struct solo_p2m_desc *desc; dma_addr_t dma; int len; @@ -430,84 +403,145 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, solo_enc->desc_count - 1); } +/* Extract values from VOP header - VE_STATUSxx */ +static inline int vop_interlaced(const vop_header *vh) +{ + return (__le32_to_cpu((*vh)[0]) >> 30) & 1; +} + +static inline u8 vop_channel(const vop_header *vh) +{ + return (__le32_to_cpu((*vh)[0]) >> 24) & 0x1F; +} + +static inline u8 vop_type(const vop_header *vh) +{ + return (__le32_to_cpu((*vh)[0]) >> 22) & 3; +} + +static inline u32 vop_mpeg_size(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[0]) & 0xFFFFF; +} + +static inline u8 vop_hsize(const vop_header *vh) +{ + return (__le32_to_cpu((*vh)[1]) >> 8) & 0xFF; +} + +static inline u8 vop_vsize(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[1]) & 0xFF; +} + +static inline u32 vop_mpeg_offset(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[2]); +} + +static inline u32 vop_jpeg_offset(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[3]); +} + +static inline u32 vop_jpeg_size(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[4]) & 0xFFFFF; +} + +static inline u32 vop_sec(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[5]); +} + +static inline u32 vop_usec(const vop_header *vh) +{ + return __le32_to_cpu((*vh)[6]); +} + static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, - struct vb2_buffer *vb, struct vop_header *vh) + struct vb2_buffer *vb, const vop_header *vh) { struct solo_dev *solo_dev = solo_enc->solo_dev; - struct vb2_dma_sg_desc *vbuf = vb2_dma_sg_plane_desc(vb, 0); + struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); int frame_size; int ret; vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; - if (vb2_plane_size(vb, 0) < vh->jpeg_size + solo_enc->jpeg_len) + if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len) return -EIO; - sg_copy_from_buffer(vbuf->sglist, vbuf->num_pages, - solo_enc->jpeg_header, - solo_enc->jpeg_len); - - frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) + frame_size = (vop_jpeg_size(vh) + solo_enc->jpeg_len + (DMA_ALIGN - 1)) & ~(DMA_ALIGN - 1); - vb2_set_plane_payload(vb, 0, vh->jpeg_size + solo_enc->jpeg_len); + vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); - dma_map_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, + /* may discard all previous data in vbuf->sgl */ + dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, DMA_FROM_DEVICE); - ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off, - frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), - SOLO_JPEG_EXT_SIZE(solo_dev)); - dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, + ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, + vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev), + frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), + SOLO_JPEG_EXT_SIZE(solo_dev)); + dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, DMA_FROM_DEVICE); + + /* add the header only after dma_unmap_sg() */ + sg_copy_from_buffer(vbuf->sgl, vbuf->nents, + solo_enc->jpeg_header, solo_enc->jpeg_len); + return ret; } static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, - struct vb2_buffer *vb, struct vop_header *vh) + struct vb2_buffer *vb, const vop_header *vh) { struct solo_dev *solo_dev = solo_enc->solo_dev; - struct vb2_dma_sg_desc *vbuf = vb2_dma_sg_plane_desc(vb, 0); + struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); int frame_off, frame_size; int skip = 0; int ret; - if (vb2_plane_size(vb, 0) < vh->mpeg_size) + if (vb2_plane_size(vb, 0) < vop_mpeg_size(vh)) return -EIO; /* If this is a key frame, add extra header */ - if (!vh->vop_type) { - sg_copy_from_buffer(vbuf->sglist, vbuf->num_pages, - solo_enc->vop, - solo_enc->vop_len); - + vb->v4l2_buf.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; - vb2_set_plane_payload(vb, 0, vh->mpeg_size + solo_enc->vop_len); + vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh) + solo_enc->vop_len); } else { vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME; - vb2_set_plane_payload(vb, 0, vh->mpeg_size); + vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh)); } /* Now get the actual mpeg payload */ - frame_off = (vh->mpeg_off + sizeof(*vh)) + frame_off = (vop_mpeg_offset(vh) - SOLO_MP4E_EXT_ADDR(solo_dev) + sizeof(*vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); - frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) + frame_size = (vop_mpeg_size(vh) + skip + (DMA_ALIGN - 1)) & ~(DMA_ALIGN - 1); - dma_map_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, + /* may discard all previous data in vbuf->sgl */ + dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, DMA_FROM_DEVICE); ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, SOLO_MP4E_EXT_ADDR(solo_dev), SOLO_MP4E_EXT_SIZE(solo_dev)); - dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, + dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, DMA_FROM_DEVICE); + + /* add the header only after dma_unmap_sg() */ + if (!vop_type(vh)) + sg_copy_from_buffer(vbuf->sgl, vbuf->nents, + solo_enc->vop, solo_enc->vop_len); return ret; } static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, struct vb2_buffer *vb, struct solo_enc_buf *enc_buf) { - struct vop_header *vh = enc_buf->vh; + const vop_header *vh = enc_buf->vh; int ret; /* Check for motion flags */ @@ -531,8 +565,8 @@ 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 = vh->sec; - vb->v4l2_buf.timestamp.tv_usec = vh->usec; + vb->v4l2_buf.timestamp.tv_sec = vop_sec(vh); + vb->v4l2_buf.timestamp.tv_usec = vop_usec(vh); } vb2_buffer_done(vb, ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); @@ -605,15 +639,13 @@ static void solo_handle_ring(struct solo_dev *solo_dev) /* FAIL... */ if (enc_get_mpeg_dma(solo_dev, solo_dev->vh_dma, off, - sizeof(struct vop_header))) + sizeof(vop_header))) continue; - enc_buf.vh = (struct vop_header *)solo_dev->vh_buf; - enc_buf.vh->mpeg_off -= SOLO_MP4E_EXT_ADDR(solo_dev); - enc_buf.vh->jpeg_off -= SOLO_JPEG_EXT_ADDR(solo_dev); + enc_buf.vh = solo_dev->vh_buf; /* Sanity check */ - if (enc_buf.vh->mpeg_off != off) + if (vop_mpeg_offset(enc_buf.vh) != SOLO_MP4E_EXT_ADDR(solo_dev) + off) continue; if (solo_motion_detected(solo_enc)) @@ -1329,7 +1361,7 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr) init_waitqueue_head(&solo_dev->ring_thread_wait); - solo_dev->vh_size = sizeof(struct vop_header); + solo_dev->vh_size = sizeof(vop_header); solo_dev->vh_buf = pci_alloc_consistent(solo_dev->pdev, solo_dev->vh_size, &solo_dev->vh_dma); diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h index 6f91d2e34b2a..f1bbb8cb74e6 100644 --- a/drivers/staging/media/solo6x10/solo6x10.h +++ b/drivers/staging/media/solo6x10/solo6x10.h @@ -94,7 +94,6 @@ #define SOLO_ENC_MODE_HD1 1 #define SOLO_ENC_MODE_D1 9 -#define SOLO_DEFAULT_GOP 30 #define SOLO_DEFAULT_QP 3 #ifndef V4L2_BUF_FLAG_MOTION_ON |