static void solo_fillbuf(struct solo_filehandle *fh, struct videobuf_buffer *vb) { struct solo6010_dev *solo_dev = fh->solo_dev; dma_addr_t vbuf; unsigned int fdma_addr; int frame_size; int error = 1; int i; if (!(vbuf = videobuf_to_dma_contig(vb))) goto finish_buf; if (erase_off(solo_dev)) { void *p = videobuf_queue_to_vaddr(&fh->vidq, vb); int image_size = solo_image_size(solo_dev); for (i = 0; i < image_size; i += 2) { ((u8 *)p)[i] = 0x80; ((u8 *)p)[i + 1] = 0x00; } error = 0; goto finish_buf; } frame_size = SOLO_HW_BPL * solo_vlines(solo_dev); fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * frame_size); for (i = 0; i < frame_size / SOLO_DISP_BUF_SIZE; i++) { int j; for (j = 0; j < (SOLO_DISP_BUF_SIZE / SOLO_HW_BPL); j++) { if (solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_DISP, 0, vbuf, fdma_addr + (j * SOLO_HW_BPL), solo_bytesperline(solo_dev))) goto finish_buf; vbuf += solo_bytesperline(solo_dev); } fdma_addr += SOLO_DISP_BUF_SIZE; } error = 0; finish_buf: if (error) { vb->state = VIDEOBUF_ERROR; } else { vb->state = VIDEOBUF_DONE; vb->field_count++; do_gettimeofday(&vb->ts); } wake_up(&vb->done); return; }
static int solo_buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct solo_filehandle *fh = vq->priv_data; struct solo6010_dev *solo_dev = fh->solo_dev; vb->size = solo_image_size(solo_dev); if (vb->baddr != 0 && vb->bsize < vb->size) return -EINVAL; /* XXX: These properties only change when queue is idle */ vb->width = solo_dev->video_hsize; vb->height = solo_vlines(solo_dev); vb->bytesperline = solo_bytesperline(solo_dev); vb->field = field; if (vb->state == VIDEOBUF_NEEDS_INIT) { int rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { videobuf_dma_contig_free(vq, vb); vb->state = VIDEOBUF_NEEDS_INIT; return rc; } } vb->state = VIDEOBUF_PREPARED; return 0; }
static void solo_fillbuf(struct solo_dev *solo_dev, struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); dma_addr_t addr; unsigned int fdma_addr; int error = -1; int i; addr = vb2_dma_contig_plane_dma_addr(vb, 0); if (!addr) goto finish_buf; if (erase_off(solo_dev)) { void *p = vb2_plane_vaddr(vb, 0); int image_size = solo_image_size(solo_dev); for (i = 0; i < image_size; i += 2) { ((u8 *)p)[i] = 0x80; ((u8 *)p)[i + 1] = 0x00; } error = 0; } else { 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, addr, fdma_addr, solo_bytesperline(solo_dev), solo_vlines(solo_dev), SOLO_HW_BPL); } finish_buf: if (!error) { vb2_set_plane_payload(vb, 0, solo_vlines(solo_dev) * solo_bytesperline(solo_dev)); vbuf->sequence = solo_dev->sequence++; vb->timestamp = ktime_get_ns(); } vb2_buffer_done(vb, error ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); }
static int solo_get_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { struct solo_filehandle *fh = priv; struct solo6010_dev *solo_dev = fh->solo_dev; struct v4l2_pix_format *pix = &f->fmt.pix; pix->width = solo_dev->video_hsize; pix->height = solo_vlines(solo_dev); pix->pixelformat = V4L2_PIX_FMT_UYVY; pix->field = SOLO_DISP_PIX_FIELD; pix->sizeimage = solo_image_size(solo_dev); pix->colorspace = V4L2_COLORSPACE_SMPTE170M; pix->bytesperline = solo_bytesperline(solo_dev); return 0; }
static int solo_get_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { struct solo_dev *solo_dev = video_drvdata(file); struct v4l2_pix_format *pix = &f->fmt.pix; pix->width = solo_dev->video_hsize; pix->height = solo_vlines(solo_dev); pix->pixelformat = V4L2_PIX_FMT_UYVY; pix->field = V4L2_FIELD_INTERLACED; pix->sizeimage = solo_image_size(solo_dev); pix->colorspace = V4L2_COLORSPACE_SMPTE170M; pix->bytesperline = solo_bytesperline(solo_dev); pix->priv = 0; return 0; }
static void solo_fillbuf(struct solo_filehandle *fh, struct videobuf_buffer *vb) { struct solo_dev *solo_dev = fh->solo_dev; dma_addr_t vbuf; unsigned int fdma_addr; int error = -1; int i; vbuf = videobuf_to_dma_contig(vb); if (!vbuf) goto finish_buf; if (erase_off(solo_dev)) { void *p = videobuf_queue_to_vaddr(&fh->vidq, vb); int image_size = solo_image_size(solo_dev); for (i = 0; i < image_size; i += 2) { ((u8 *)p)[i] = 0x80; ((u8 *)p)[i + 1] = 0x00; } error = 0; } else { fdma_addr = SOLO_DISP_EXT_ADDR + (fh->old_write * (SOLO_HW_BPL * solo_vlines(solo_dev))); error = solo_p2m_dma_t(solo_dev, 0, vbuf, fdma_addr, solo_bytesperline(solo_dev), solo_vlines(solo_dev), SOLO_HW_BPL); } finish_buf: if (error) { vb->state = VIDEOBUF_ERROR; } else { vb->state = VIDEOBUF_DONE; vb->field_count++; } wake_up(&vb->done); }