timblogiw.c revision 7a707b89202f905bd9f9fbde326933c59a81214c
19eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* 29eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * timblogiw.c timberdale FPGA LogiWin Video In driver 39eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * Copyright (c) 2009-2010 Intel Corporation 49eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * 59eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * This program is free software; you can redistribute it and/or modify 69eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * it under the terms of the GNU General Public License version 2 as 79eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * published by the Free Software Foundation. 89eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * 99eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * This program is distributed in the hope that it will be useful, 109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * but WITHOUT ANY WARRANTY; without even the implied warranty of 119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * GNU General Public License for more details. 139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * 149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * You should have received a copy of the GNU General Public License 159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * along with this program; if not, write to the Free Software 169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors */ 189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* Supports: 209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors * Timberdale FPGA LogiWin Video In 219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors */ 229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/platform_device.h> 249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/slab.h> 259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/dmaengine.h> 269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/scatterlist.h> 279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/interrupt.h> 289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/list.h> 299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <linux/i2c.h> 307a707b89202f905bd9f9fbde326933c59a81214cPaul Gortmaker#include <linux/module.h> 319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <media/v4l2-ioctl.h> 329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <media/v4l2-device.h> 339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <media/videobuf-dma-contig.h> 349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#include <media/timb_video.h> 359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#define DRIVER_NAME "timb-video" 379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#define TIMBLOGIWIN_NAME "Timberdale Video-In" 399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#define TIMBLOGIW_VERSION_CODE 0x04 409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#define TIMBLOGIW_LINES_PER_DESC 44 429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#define TIMBLOGIW_MAX_VIDEO_MEM 16 439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors#define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name) 459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstruct timblogiw { 489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device video_dev; 499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_device v4l2_dev; /* mutual exclusion */ 509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct mutex lock; 519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct device *dev; 529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timb_video_platform_data pdata; 539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_subdev *sd_enc; /* encoder */ 549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors bool opened; 559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstruct timblogiw_tvnorm { 589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors v4l2_std_id std; 599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors u16 width; 609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors u16 height; 619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors u8 fps; 629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstruct timblogiw_fh { 659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct videobuf_queue vb_vidq; 669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_tvnorm const *cur_norm; 679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct list_head capture; 689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct dma_chan *chan; 699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spinlock_t queue_lock; /* mutual exclusion */ 709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int frame_count; 719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstruct timblogiw_buffer { 749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* common v4l buffer stuff -- must be first */ 759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct videobuf_buffer vb; 769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct scatterlist sg[16]; 779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_cookie_t cookie; 789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh; 799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsconst struct timblogiw_tvnorm timblogiw_tvnorms[] = { 829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors { 839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .std = V4L2_STD_PAL, 849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .width = 720, 859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .height = 576, 869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .fps = 25 879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors }, 889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors { 899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .std = V4L2_STD_NTSC, 909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .width = 720, 919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .height = 480, 929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .fps = 30 939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm) 979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return norm->width * 2; 999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 1009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_frame_size(const struct timblogiw_tvnorm *norm) 1039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 1049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return norm->height * timblogiw_bytes_per_line(norm); 1059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 1069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std) 1089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 1099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int i; 1109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++) 1119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (timblogiw_tvnorms[i].std & std) 1129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return timblogiw_tvnorms + i; 1139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* default to first element */ 1159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return timblogiw_tvnorms; 1169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 1179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic void timblogiw_dma_cb(void *data) 1199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 1209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_buffer *buf = data; 1219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = buf->fh; 1229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct videobuf_buffer *vb = &buf->vb; 1239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spin_lock(&fh->queue_lock); 1259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* mark the transfer done */ 1279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors buf->cookie = -1; 1289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh->frame_count++; 1309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (vb->state != VIDEOBUF_ERROR) { 1329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors list_del(&vb->queue); 1339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors do_gettimeofday(&vb->ts); 1349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->field_count = fh->frame_count * 2; 1359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_DONE; 1369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors wake_up(&vb->done); 1389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 1399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!list_empty(&fh->capture)) { 1419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb = list_entry(fh->capture.next, struct videobuf_buffer, 1429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors queue); 1439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_ACTIVE; 1449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 1459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spin_unlock(&fh->queue_lock); 1479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 1489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param) 1509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 15161ea3aa5bf309333c6655ccef825b4a765bff219Hans Verkuil return chan->chan_id == (uintptr_t)filter_param; 1529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 1539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* IOCTL functions */ 1559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_g_fmt(struct file *file, void *priv, 1579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_format *format) 1589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 1599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 1609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = video_get_drvdata(vdev); 1619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 1629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s entry\n", __func__); 1649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 1679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_lock(&lw->lock); 1699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors format->fmt.pix.width = fh->cur_norm->width; 1719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors format->fmt.pix.height = fh->cur_norm->height; 1729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; 1739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm); 1749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm); 1759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors format->fmt.pix.field = V4L2_FIELD_NONE; 1769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_unlock(&lw->lock); 1789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 1809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 1819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_try_fmt(struct file *file, void *priv, 1839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_format *format) 1849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 1859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 1869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_pix_format *pix = &format->fmt.pix; 1879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, 1899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors "%s - width=%d, height=%d, pixelformat=%d, field=%d\n" 1909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors "bytes per line %d, size image: %d, colorspace: %d\n", 1919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors __func__, 1929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors pix->width, pix->height, pix->pixelformat, pix->field, 1939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors pix->bytesperline, pix->sizeimage, pix->colorspace); 1949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 1979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 1989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (pix->field != V4L2_FIELD_NONE) 1999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 2009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (pix->pixelformat != V4L2_PIX_FMT_UYVY) 2029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 2039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 2059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 2069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_s_fmt(struct file *file, void *priv, 2089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_format *format) 2099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 2109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 2119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = video_get_drvdata(vdev); 2129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 2139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_pix_format *pix = &format->fmt.pix; 2149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int err; 2159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_lock(&lw->lock); 2179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = timblogiw_try_fmt(file, priv, format); 2199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (err) 2209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 2219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (videobuf_queue_is_busy(&fh->vb_vidq)) { 2239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&vdev->dev, "%s queue busy\n", __func__); 2249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -EBUSY; 2259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 2269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 2279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors pix->width = fh->cur_norm->width; 2299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors pix->height = fh->cur_norm->height; 2309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsout: 2329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_unlock(&lw->lock); 2339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return err; 2349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 2359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_querycap(struct file *file, void *priv, 2379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_capability *cap) 2389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 2399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 2409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: Entry\n", __func__); 2429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors memset(cap, 0, sizeof(*cap)); 2439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1); 244dcd745b723efc875ec5a8f44be028bd0704b12d6Dan Carpenter strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1); 2459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info)); 2469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors cap->version = TIMBLOGIW_VERSION_CODE; 2479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | 2489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors V4L2_CAP_READWRITE; 2499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 2519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 2529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_enum_fmt(struct file *file, void *priv, 2549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_fmtdesc *fmt) 2559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 2569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 2579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index); 2599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (fmt->index != 0) 2619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 2629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors memset(fmt, 0, sizeof(*fmt)); 2639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fmt->index = 0; 2649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors strncpy(fmt->description, "4:2:2, packed, YUYV", 2669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sizeof(fmt->description)-1); 2679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fmt->pixelformat = V4L2_PIX_FMT_UYVY; 2689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 2709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 2719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_g_parm(struct file *file, void *priv, 2739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_streamparm *sp) 2749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 2759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 2769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_captureparm *cp = &sp->parm.capture; 2779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors cp->capability = V4L2_CAP_TIMEPERFRAME; 2799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors cp->timeperframe.numerator = 1; 2809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors cp->timeperframe.denominator = fh->cur_norm->fps; 2819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 2839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 2849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_reqbufs(struct file *file, void *priv, 2869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_requestbuffers *rb) 2879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 2889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 2899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 2909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 2929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_reqbufs(&fh->vb_vidq, rb); 2949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 2959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 2969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_querybuf(struct file *file, void *priv, 2979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_buffer *b) 2989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 2999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 3019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 3039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_querybuf(&fh->vb_vidq, b); 3059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) 3089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 3119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 3139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_qbuf(&fh->vb_vidq, b); 3159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_dqbuf(struct file *file, void *priv, 3189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_buffer *b) 3199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 3229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 3249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); 3269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std) 3299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 3329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 3349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors *std = fh->cur_norm->std; 3369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 3379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std) 3409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = video_get_drvdata(vdev); 3439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 3449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int err = 0; 3459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 3479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_lock(&lw->lock); 3499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (TIMBLOGIW_HAS_DECODER(lw)) 3519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std); 3529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!err) 3549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh->cur_norm = timblogiw_get_norm(*std); 3559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_unlock(&lw->lock); 3579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return err; 3599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_enuminput(struct file *file, void *priv, 3629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_input *inp) 3639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int i; 3669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: Entry\n", __func__); 3689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (inp->index != 0) 3709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 3719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors inp->index = 0; 3739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1); 3759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors inp->type = V4L2_INPUT_TYPE_CAMERA; 3769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors inp->std = 0; 3789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++) 3799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors inp->std |= timblogiw_tvnorms[i].std; 3809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 3829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_g_input(struct file *file, void *priv, 3859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int *input) 3869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: Entry\n", __func__); 3909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors *input = 0; 3929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 3949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 3959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 3969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_s_input(struct file *file, void *priv, unsigned int input) 3979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 3989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 3999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: Entry\n", __func__); 4019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (input != 0) 4039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 4049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 4059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 4069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_streamon(struct file *file, void *priv, unsigned int type) 4089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 4099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 4109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 4119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 4139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 4159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s - No capture device\n", __func__); 4169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 4179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 4189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh->frame_count = 0; 4209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_streamon(&fh->vb_vidq); 4219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 4229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_streamoff(struct file *file, void *priv, 4249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int type) 4259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 4269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 4279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 4289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s entry\n", __func__); 4309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 4329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 4339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_streamoff(&fh->vb_vidq); 4359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 4369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std) 4389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 4399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 4409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = video_get_drvdata(vdev); 4419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 4429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s entry\n", __func__); 4449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (TIMBLOGIW_HAS_DECODER(lw)) 4469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return v4l2_subdev_call(lw->sd_enc, video, querystd, std); 4479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors else { 4489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors *std = fh->cur_norm->std; 4499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 4509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 4519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 4529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_enum_framesizes(struct file *file, void *priv, 4549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct v4l2_frmsizeenum *fsize) 4559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 4569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 4579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = priv; 4589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__, 4609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fsize->index, fsize->pixel_format); 4619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if ((fsize->index != 0) || 4639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors (fsize->pixel_format != V4L2_PIX_FMT_UYVY)) 4649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -EINVAL; 4659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 4679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fsize->discrete.width = fh->cur_norm->width; 4689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fsize->discrete.height = fh->cur_norm->height; 4699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 4719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 4729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* Video buffer functions */ 4749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int buffer_setup(struct videobuf_queue *vq, unsigned int *count, 4769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int *size) 4779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 4789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = vq->priv_data; 4799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors *size = timblogiw_frame_size(fh->cur_norm); 4819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!*count) 4839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors *count = 32; 4849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024) 4869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors (*count)--; 4879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 4899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 4909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 4919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, 4929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors enum v4l2_field field) 4939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 4949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = vq->priv_data; 4959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer, 4969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb); 4979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int data_size = timblogiw_frame_size(fh->cur_norm); 4989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int err = 0; 4999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (vb->baddr && vb->bsize < data_size) 5019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* User provided buffer, but it is too small */ 5029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return -ENOMEM; 5039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->size = data_size; 5059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->width = fh->cur_norm->width; 5069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->height = fh->cur_norm->height; 5079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->field = field; 5089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (vb->state == VIDEOBUF_NEEDS_INIT) { 5109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int i; 5119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int size; 5129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC * 5139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors timblogiw_bytes_per_line(fh->cur_norm); 5149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_addr_t addr; 5159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sg_init_table(buf->sg, ARRAY_SIZE(buf->sg)); 5179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = videobuf_iolock(vq, vb, NULL); 5199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (err) 5209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto err; 5219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors addr = videobuf_to_dma_contig(vb); 5239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors for (i = 0, size = 0; size < data_size; i++) { 5249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sg_dma_address(buf->sg + i) = addr + size; 5259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors size += bytes_per_desc; 5269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sg_dma_len(buf->sg + i) = (size > data_size) ? 5279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors (bytes_per_desc - (size - data_size)) : 5289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors bytes_per_desc; 5299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 5309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_PREPARED; 5329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors buf->cookie = -1; 5339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors buf->fh = fh; 5349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 5359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 5379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforserr: 5399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors videobuf_dma_contig_free(vq, vb); 5409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_NEEDS_INIT; 5419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return err; 5429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 5439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) 5459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 5469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = vq->priv_data; 5479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer, 5489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb); 5499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct dma_async_tx_descriptor *desc; 5509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int sg_elems; 5519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC * 5529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors timblogiw_bytes_per_line(fh->cur_norm); 5539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc; 5559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sg_elems += 5569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0; 5579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (list_empty(&fh->capture)) 5599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_ACTIVE; 5609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors else 5619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_QUEUED; 5629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors list_add_tail(&vb->queue, &fh->capture); 5649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spin_unlock_irq(&fh->queue_lock); 5669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors desc = fh->chan->device->device_prep_slave_sg(fh->chan, 5689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors buf->sg, sg_elems, DMA_FROM_DEVICE, 5699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); 5709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!desc) { 5719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spin_lock_irq(&fh->queue_lock); 5729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors list_del_init(&vb->queue); 5739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_PREPARED; 5749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return; 5759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 5769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors desc->callback_param = buf; 5789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors desc->callback = timblogiw_dma_cb; 5799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors buf->cookie = desc->tx_submit(desc); 5819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spin_lock_irq(&fh->queue_lock); 5839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 5849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic void buffer_release(struct videobuf_queue *vq, 5869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct videobuf_buffer *vb) 5879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 5889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = vq->priv_data; 5899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer, 5909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb); 5919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors videobuf_waiton(vq, vb, 0, 0); 5939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (buf->cookie >= 0) 5949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_sync_wait(fh->chan, buf->cookie); 5959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 5969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors videobuf_dma_contig_free(vq, vb); 5979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors vb->state = VIDEOBUF_NEEDS_INIT; 5989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 5999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic struct videobuf_queue_ops timblogiw_video_qops = { 6019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .buf_setup = buffer_setup, 6029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .buf_prepare = buffer_prepare, 6039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .buf_queue = buffer_queue, 6049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .buf_release = buffer_release, 6059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 6069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* Device Operations functions */ 6089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_open(struct file *file) 6109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 6119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 6129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = video_get_drvdata(vdev); 6139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh; 6149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors v4l2_std_id std; 6159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_cap_mask_t mask; 6169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int err = 0; 6179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 6199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_lock(&lw->lock); 6219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (lw->opened) { 6229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -EBUSY; 6239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 6249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 6259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) { 6279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct i2c_adapter *adapt; 6289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* find the video decoder */ 6309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors adapt = i2c_get_adapter(lw->pdata.i2c_adapter); 6319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!adapt) { 6329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&vdev->dev, "No I2C bus #%d\n", 6339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->pdata.i2c_adapter); 6349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -ENODEV; 6359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 6369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 6379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* now find the encoder */ 6399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt, 6409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->pdata.encoder.info, NULL); 6419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors i2c_put_adapter(adapt); 6439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!lw->sd_enc) { 6459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&vdev->dev, "Failed to get encoder: %s\n", 6469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->pdata.encoder.module_name); 6479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -ENODEV; 6489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 6499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 6509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 6519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh = kzalloc(sizeof(*fh), GFP_KERNEL); 6539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!fh) { 6549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -ENOMEM; 6559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 6569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 6579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh->cur_norm = timblogiw_tvnorms; 6599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors timblogiw_querystd(file, fh, &std); 6609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh->cur_norm = timblogiw_get_norm(std); 6619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors INIT_LIST_HEAD(&fh->capture); 6639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors spin_lock_init(&fh->queue_lock); 6649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_cap_zero(mask); 6669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_cap_set(DMA_SLAVE, mask); 6679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_cap_set(DMA_PRIVATE, mask); 6689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors /* find the DMA channel */ 6709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn, 67161ea3aa5bf309333c6655ccef825b4a765bff219Hans Verkuil (void *)(uintptr_t)lw->pdata.dma_channel); 6729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!fh->chan) { 6739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&vdev->dev, "Failed to get DMA channel\n"); 6749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors kfree(fh); 6759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -ENODEV; 6769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto out; 6779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 6789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors file->private_data = fh; 6809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors videobuf_queue_dma_contig_init(&fh->vb_vidq, 6819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors &timblogiw_video_qops, lw->dev, &fh->queue_lock, 6829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, 6839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors sizeof(struct timblogiw_buffer), fh, NULL); 6849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->opened = true; 6869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsout: 6879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_unlock(&lw->lock); 6889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return err; 6909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 6919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_close(struct file *file) 6939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 6949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 6959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = video_get_drvdata(vdev); 6969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = file->private_data; 6979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 6989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: Entry\n", __func__); 6999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors videobuf_stop(&fh->vb_vidq); 7019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors videobuf_mmap_free(&fh->vb_vidq); 7029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dma_release_channel(fh->chan); 7049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors kfree(fh); 7069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_lock(&lw->lock); 7089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->opened = false; 7099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_unlock(&lw->lock); 7109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 7119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 7129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic ssize_t timblogiw_read(struct file *file, char __user *data, 7149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors size_t count, loff_t *ppos) 7159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 7169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 7179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = file->private_data; 7189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 7209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0, 7229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors file->f_flags & O_NONBLOCK); 7239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 7249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic unsigned int timblogiw_poll(struct file *file, 7269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct poll_table_struct *wait) 7279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 7289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 7299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = file->private_data; 7309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 7329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_poll_stream(file, &fh->vb_vidq, wait); 7349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 7359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int timblogiw_mmap(struct file *file, struct vm_area_struct *vma) 7379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 7389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct video_device *vdev = video_devdata(file); 7399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw_fh *fh = file->private_data; 7409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_dbg(&vdev->dev, "%s: entry\n", __func__); 7429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return videobuf_mmap_mapper(&fh->vb_vidq, vma); 7449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 7459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* Platform device functions */ 7479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 74849aefd2bcda80d33497f0f26702c67e372cacef3Stephen Rothwellstatic __devinitconst struct v4l2_ioctl_ops timblogiw_ioctl_ops = { 7499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_querycap = timblogiw_querycap, 7509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt, 7519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_g_fmt_vid_cap = timblogiw_g_fmt, 7529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_try_fmt_vid_cap = timblogiw_try_fmt, 7539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_s_fmt_vid_cap = timblogiw_s_fmt, 7549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_g_parm = timblogiw_g_parm, 7559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_reqbufs = timblogiw_reqbufs, 7569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_querybuf = timblogiw_querybuf, 7579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_qbuf = timblogiw_qbuf, 7589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_dqbuf = timblogiw_dqbuf, 7599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_g_std = timblogiw_g_std, 7609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_s_std = timblogiw_s_std, 7619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_enum_input = timblogiw_enuminput, 7629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_g_input = timblogiw_g_input, 7639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_s_input = timblogiw_s_input, 7649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_streamon = timblogiw_streamon, 7659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_streamoff = timblogiw_streamoff, 7669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_querystd = timblogiw_querystd, 7679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .vidioc_enum_framesizes = timblogiw_enum_framesizes, 7689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 7699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 77049aefd2bcda80d33497f0f26702c67e372cacef3Stephen Rothwellstatic __devinitconst struct v4l2_file_operations timblogiw_fops = { 7719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .owner = THIS_MODULE, 7729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .open = timblogiw_open, 7739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .release = timblogiw_close, 7749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ 7759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .mmap = timblogiw_mmap, 7769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .read = timblogiw_read, 7779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .poll = timblogiw_poll, 7789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 7799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 78049aefd2bcda80d33497f0f26702c67e372cacef3Stephen Rothwellstatic __devinitconst struct video_device timblogiw_template = { 7819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .name = TIMBLOGIWIN_NAME, 7829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .fops = &timblogiw_fops, 7839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .ioctl_ops = &timblogiw_ioctl_ops, 7849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .release = video_device_release_empty, 7859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .minor = -1, 7869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC 7879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 7889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int __devinit timblogiw_probe(struct platform_device *pdev) 7909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 7919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors int err; 7929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = NULL; 7933271d382c3ffe61ef3d059ef47e635dbe031030eSamuel Ortiz struct timb_video_platform_data *pdata = pdev->dev.platform_data; 7949eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 7959eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!pdata) { 7969eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&pdev->dev, "No platform data\n"); 7979eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -EINVAL; 7989eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto err; 7999eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 8009eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8019eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!pdata->encoder.module_name) 8029eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_info(&pdev->dev, "Running without decoder\n"); 8039eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8049eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw = kzalloc(sizeof(*lw), GFP_KERNEL); 8059eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (!lw) { 8069eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = -ENOMEM; 8079eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto err; 8089eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 8099eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8109eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (pdev->dev.parent) 8119eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->dev = pdev->dev.parent; 8129eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors else 8139eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->dev = &pdev->dev; 8149eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8159eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors memcpy(&lw->pdata, pdata, sizeof(lw->pdata)); 8169eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8179eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors mutex_init(&lw->lock); 8189eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8199eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->video_dev = timblogiw_template; 8209eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8219eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name)); 8229eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = v4l2_device_register(NULL, &lw->v4l2_dev); 8239eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (err) 8249eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto err_register; 8259eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8269eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors lw->video_dev.v4l2_dev = &lw->v4l2_dev; 8279eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8289eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors platform_set_drvdata(pdev, lw); 8299eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors video_set_drvdata(&lw->video_dev, lw); 8309eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8319eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0); 8329eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors if (err) { 8339eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&pdev->dev, "Error reg video: %d\n", err); 8349eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors goto err_request; 8359eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors } 8369eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8379eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8389eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 8399eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8409eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforserr_request: 8419eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors platform_set_drvdata(pdev, NULL); 8429eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors v4l2_device_unregister(&lw->v4l2_dev); 8439eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforserr_register: 8449eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors kfree(lw); 8459eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforserr: 8469eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors dev_err(&pdev->dev, "Failed to register: %d\n", err); 8479eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8489eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return err; 8499eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 8509eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8519eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int __devexit timblogiw_remove(struct platform_device *pdev) 8529eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 8539eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors struct timblogiw *lw = platform_get_drvdata(pdev); 8549eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8559eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors video_unregister_device(&lw->video_dev); 8569eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8579eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors v4l2_device_unregister(&lw->v4l2_dev); 8589eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8599eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors kfree(lw); 8609eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8619eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors platform_set_drvdata(pdev, NULL); 8629eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8639eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return 0; 8649eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 8659eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8669eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic struct platform_driver timblogiw_platform_driver = { 8679eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .driver = { 8689eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .name = DRIVER_NAME, 8699eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .owner = THIS_MODULE, 8709eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors }, 8719eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .probe = timblogiw_probe, 8729eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors .remove = __devexit_p(timblogiw_remove), 8739eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors}; 8749eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8759eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors/* Module functions */ 8769eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8779eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic int __init timblogiw_init(void) 8789eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 8799eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors return platform_driver_register(&timblogiw_platform_driver); 8809eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 8819eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8829eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsstatic void __exit timblogiw_exit(void) 8839eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors{ 8849eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors platform_driver_unregister(&timblogiw_platform_driver); 8859eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors} 8869eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8879eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsmodule_init(timblogiw_init); 8889eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjforsmodule_exit(timblogiw_exit); 8899eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard Röjfors 8909eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard RöjforsMODULE_DESCRIPTION(TIMBLOGIWIN_NAME); 8919eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard RöjforsMODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>"); 8929eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard RöjforsMODULE_LICENSE("GPL v2"); 8939eae42e5a216059a146b3fbbe24b4fdc0b10c723Richard RöjforsMODULE_ALIAS("platform:"DRIVER_NAME); 894